RC522 模块驱动程序

时间:2021-12-25 22:27:08

本文主要讲述了基于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 plain copy
 
  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 plain copy
 
  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\n", __func__);  
  28.   
  29.     rc522_spi = spi;  
  30.   
  31.     return 0;  
  32.   
  33. };  



 

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

 

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

 

 

[cpp]  view plain copy
 
  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 plain copy
 
  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()函数即可进行编译调试。