zoukankan      html  css  js  c++  java
  • RC522 模块驱动程序

    本文主要讲述了基于SPI总线的RC522驱动程序的设计。描述了主控如何与从设备通过SPI总线进行数据的读写。

    一 在SPI驱动中,有两个重要的结构:spi_device&spi_driver。

    1  spi_device的构建与注册:

    Spi_device板信息用spi_board_info结构体来描述,它描述了SPI外设(RC522模块)使用的主机控制器序号,片选信号,数据比特率,传输方式等。故要先填充struct spi_board_info这个结构体。--4412平台在mach-smdk4x12.c里,三星给的BSP包里面已经配置好了这些,我们要做的只是打开CONFIG_S3C64XX_DEV_SPI这个宏。

    spi_register_board_info(spi2_board_info, ARRAY_SIZE(spi2_board_info));

    具体实现见下面代码。

    [cpp] view plaincopy
     
    1. static struct spi_board_info spi2_board_info[] __initdata = {  
    2.   
    3.          {  
    4.   
    5.                    .modalias = "rfid_rc522",  
    6.   
    7.                    .platform_data = NULL,  
    8.   
    9.                    .max_speed_hz = 10*1000*1000,  
    10.   
    11.                    .bus_num = 2,  
    12.   
    13.                    .chip_select = 0,  
    14.   
    15.                    .mode = SPI_MODE_0,  
    16.   
    17.                    .controller_data = &spi2_csi[0],  
    18.   
    19.          }  
    20.   
    21. };  
    22.   
    23.   
    24. static struct s3c64xx_spi_csinfo spi2_csi[] = {  
    25.   
    26.          [0] = {  
    27.   
    28.                    .line = EXYNOS4_GPC1(2),  
    29.   
    30.                    .set_level = gpio_set_value,  
    31.   
    32.                    .fb_delay = 0x2,  
    33.   
    34.          },  
    35.   
    36. }  



    2  spi_driver的构建与注册:

    [cpp] view plaincopy
     
    1. spi_register_driver(&rc522_driver);  
    2.   
    3.   
    4. static struct spi_driver rc522_driver = {  
    5.   
    6.     .probe = rc522_probe,  
    7.   
    8.     .remove = rc522_remove,  
    9.   
    10.     .driver = {  
    11.   
    12.         .name = "rfid_rc522",  
    13.   
    14.     },  
    15.   
    16. };  
    17.   
    18.   
    19. static int rc522_probe(struct spi_device *spi)  
    20.   
    21. {  
    22.   
    23.     //默认读第一块(可选0 ~ 63)  
    24.   
    25.     KuaiN = 1;   
    26.   
    27.     printk("%s ", __func__);  
    28.   
    29.     rc522_spi = spi;  
    30.   
    31.     return 0;  
    32.   
    33. };  



    二 注册好了SPI设备与驱动,就可以通过SPI总线实现数据读写了。

    这里注册了一个混合设备:misc_register(&rc522_misc_device);

    [cpp] view plaincopy
     
    1. static struct miscdevice rc522_misc_device = {  
    2.   
    3.     .minor = MISC_DYNAMIC_MINOR,  
    4.   
    5.     .name = "rfid_rc522_dev",  
    6.   
    7.     .fops = &rc522_fops,  
    8.   
    9. };  
    10.   
    11.   
    12. static struct file_operations rc522_fops = {  
    13.   
    14.     .owner = THIS_MODULE,  
    15.   
    16.     .open = rc522_open,  
    17.   
    18.     .release = rc522_release,   
    19.   
    20.     .read = rc522_read,  
    21.   
    22.     .write = rc522_write,  
    23.   
    24.     .poll = rc522_poll,   
    25.   
    26.     .unlocked_ioctl = rc522_ioctl,  
    27.   
    28.   
    29. };  
    30.   
    31. //省略号这里省略了fops里各个操作的具体函数。  
    32.   
    33. ……  

    在read, write操作里都会调用到WriteRawRC(unsigned char Address, unsigned char value)函数,在这个函数里才真正实现了通过SPI来对RC522寄存器的读写操作:

    [cpp] view plaincopy
     
    1. //////////////////////////////////////////////////////////////////  
    2.   
    3. //功 能:写RC522寄存器  
    4.   
    5. //参数说明:Address[IN]:寄存器地址  
    6.   
    7. // value[IN]:写入的值  
    8.   
    9. /////////////////////////////////////////////////////////////////////  
    10.   
    11. void WriteRawRC(unsigned char Address, unsigned char value)  
    12.   
    13. {   
    14.   
    15.     unsigned char ucAddr;  
    16.   
    17.     struct spi_transfer st[2];   
    18.   
    19.     struct spi_message msg;   
    20.   
    21.   
    22.          CLR_SPI_CS;  
    23.   
    24.     ucAddr = ((Address<<1)&0x7E);  
    25.   
    26.     spi_message_init( &msg );  
    27.   
    28.     memset( st, 0, sizeof(st) );  
    29.   
    30.   
    31.     st[ 0 ].tx_buf = &ucAddr;   
    32.   
    33.     st[ 0 ].len = 1;   
    34.   
    35.     spi_message_add_tail( &st[0], &msg );   
    36.   
    37.   
    38.     st[ 1 ].tx_buf = &value;   
    39.   
    40.     st[ 1 ].len = 1;   
    41.   
    42.     spi_message_add_tail( &st[1], &msg );   
    43.   
    44.     spi_sync( rc522_spi, &msg );  
    45.   
    46.   
    47.     SET_SPI_CS;  
    48.   
    49. };  

    三 添加定时器

    为了节省CPU资源,需要添加一个定时器,每隔一定的时间才读卡一次。代码略。

    到此为止,驱动的关键部分已经完工,只需把spi_register_driver(&rc522_driver)和misc_register(&rc522_misc_device)放进rfid_rc522_init()函数即可进行编译调试。

  • 相关阅读:
    nginx转发域名小记
    简化kubernetes应用部署工具之Helm应用部署
    docker-compose的使用
    使用二进制包安装k8s
    搭建k8s(一)
    linux环境下安装使用selenium Chrome
    常用User-Agent大全
    缓存之Memcache
    git-commit Angular规范
    Kubernetes介绍及基本概念
  • 原文地址:https://www.cnblogs.com/Ph-one/p/4177789.html
Copyright © 2011-2022 走看看