Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1551180
  • 博文数量: 239
  • 博客积分: 1760
  • 博客等级: 上尉
  • 技术积分: 1595
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-08 23:53
文章分类

全部博文(239)

文章存档

2016年(1)

2015年(28)

2014年(53)

2013年(42)

2012年(50)

2011年(65)

分类: Android平台

2015-04-01 15:23:10

原文地址:RC522 模块驱动程序 作者:jerry20000

 

本文主要讲述了基于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));

具体实现见下面代码。


点击(此处)折叠或打开

  1. static struct spi_board_info spi2_board_info[] __initdata = {

  2.          {

  3.                    .modalias = "rfid_rc522",

  4.                    .platform_data = NULL,

  5.                    .max_speed_hz = 10*1000*1000,

  6.                    .bus_num = 2,

  7.                    .chip_select = 0,

  8.                    .mode = SPI_MODE_0,

  9.                    .controller_data = &spi2_csi[0],

  10.          }

  11. };


  12. static struct s3c64xx_spi_csinfo spi2_csi[] = {

  13.          [0] = {

  14.                    .line = EXYNOS4_GPC1(2),

  15.                    .set_level = gpio_set_value,

  16.                    .fb_delay = 0x2,

  17.          },

  18. }

2  spi_driver的构建与注册:


点击(此处)折叠或打开

  1. spi_register_driver(&rc522_driver);


  2. static struct spi_driver rc522_driver = {

  3.     .probe = rc522_probe,

  4.     .remove = rc522_remove,

  5.     .driver = {

  6.         .name = "rfid_rc522",

  7.     },

  8. };


  9. static int rc522_probe(struct spi_device *spi)

  10. {

  11.     //默认读第一块(可选0 ~ 63)

  12.     KuaiN = 1;

  13.     printk("%s\n", __func__);

  14.     rc522_spi = spi;

  15.     return 0;

  16. };

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

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


点击(此处)折叠或打开

  1. static struct miscdevice rc522_misc_device = {

  2.     .minor = MISC_DYNAMIC_MINOR,

  3.     .name = "rfid_rc522_dev",

  4.     .fops = &rc522_fops,

  5. };


  6. static struct file_operations rc522_fops = {

  7.     .owner = THIS_MODULE,

  8.     .open = rc522_open,

  9.     .release = rc522_release,

  10.     .read = rc522_read,

  11.     .write = rc522_write,

  12.     .poll = rc522_poll,

  13.     .unlocked_ioctl = rc522_ioctl,


  14. };

  15. //省略号这里省略了fops里各个操作的具体函数。

  16. ……

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


点击(此处)折叠或打开

  1. //////////////////////////////////////////////////////////////////

  2. //功 能:写RC522寄存器

  3. //参数说明:Address[IN]:寄存器地址

  4. // value[IN]:写入的值

  5. /////////////////////////////////////////////////////////////////////

  6. void WriteRawRC(unsigned char Address, unsigned char value)

  7. {

  8.     unsigned char ucAddr;

  9.     struct spi_transfer st[2];

  10.     struct spi_message msg;


  11.          CLR_SPI_CS;

  12.     ucAddr = ((Address<<1)&0x7E);

  13.     spi_message_init( &msg );

  14.     memset( st, 0, sizeof(st) );


  15.     st[ 0 ].tx_buf = &ucAddr;

  16.     st[ 0 ].len = 1;

  17.     spi_message_add_tail( &st[0], &msg );


  18.     st[ 1 ].tx_buf = &value;

  19.     st[ 1 ].len = 1;

  20.     spi_message_add_tail( &st[1], &msg );

  21.     spi_sync( rc522_spi, &msg );


  22.     SET_SPI_CS;

  23. };

添加定时器

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

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

阅读(1567) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~