嵌入式开发记录-day32 SPI总线下的 RFID模块rc522

1、SPI驱动总线架构:SPI核心层(x),SPI控制器驱动层(x),SPI设备驱动层(√),这里不详细说总线如何传输数据。
  1、SPI核心层:代码在源码下:ls drivers/spi/*.o
  2、SPI控制器驱动层:ls include/linux/spi/
  3、SPI总线的四根线:
    SPI_0_CLK:SPI传输数据的时钟信号;GPC1_1---->/SPI_2_CLK
    SPI_0_nSS:片选使能控制端;BK_LED---->/SPI_2_nSS
    SPI_0_MISO:总线传输数据线,master input slaver output,主机输入从机输出;I2C_AD6---->SPI_2_MISO
    SPI_0_MOSI:总线传输数据线,主机输出从机输入;I2C_SCL6---->SPI_2_MOSI

    模块需求GPIO:RST--->DC33_EN--->GPK1_0
  4、RFID模块;(与mcp251x的can模块互斥)wifi不能不能使用
    驱动配置: make menuconfig Device Drivers->SPI support->SPI_RC522

2、主要看SPI总线的接口
  1、spi_board_info结构体参数
    .modalias = "rc522", //初始化设备的名称
    .platform_data = NULL,
    .max_speed_hz = 10*1000*1000, //初始化传输速率
    .bus_num = 2, //控制器编号
    .chip_select = 0, //控制器片选的编号
    .mode = SPI_MODE_0, //spi的模式 时钟相位极性
    .controller_data = &spi2_csi[0], //片选IO的信息
  2、spi2_board_info设备描述结构体,设备注册函数spi_register_board_info

3、Linux驱动的四部曲:

  虚拟平台总线 RS485(串口) I2C SPI(RFID)
设备注册

设备描述结构体platform_device

设备注册APIplatform_add_devices

platform_device

platform_add_devices

i2c_board_info

i2c_register_board_info

spi_board_info

spi_register_board_info

驱动注册(probe)

驱动描述结构体platform_driver

驱动注册APIplatform_driver_register

platform_driver

platform_driver_register

i2c_driver

i2c_add_driver

spi_driver

spi_register_driver

传输API(数据下传,和硬件通信) GPIO操作API、外部中断等等 GPIO输出

i2c_msg

i2c_transfer

spi_transfer

spi_sync

数据上传(和文件系统上传)

misc_register

register_chrdev

misc_register

register_chrdev

misc_register

register_chrdev

misc_register

4、配置了SPI后,查询SPI模块

  cat sys/bus/spi/devices/spi2.0/modalias 看到rc522
  增加一个spi设备my_rc522(直接将RC522修改my_rc522),然后去掉rfid和can驱动(精英版不要这一步)
  cat sys/bus/spi/devices/spi2.0/modalias
  rfid的设备名称应该为my_rc522
  #ifdef CONFIG_SPI_RC522
  {
  .modalias = "my_rc522",
  .platform_data = NULL,
  .max_speed_hz = 10*1000*1000,
  .bus_num = 2,
  .chip_select = 0,
  .mode = SPI_MODE_0,
  .controller_data = &spi2_csi[0],
  }
  #endif
  drivers/spi/Makefile中注释掉rc522.c文件的编译 // 取消内核中编译rc522的驱动

  4.直接在probe中做复位,读,写测试
    写:rc522_write→rc522_sync_write→rc522_sync→spi_async
    读:rc522_read→rc522_sync_read→rc522_sync→spi_async

5、注册驱动和卸载

 1 #include <linux/init.h>
 2 #include <linux/module.h>
 3 #include <linux/ioctl.h>
 4 #include <linux/fs.h>
 5 #include <linux/device.h>
 6 #include <linux/err.h>
 7 #include <linux/list.h>
 8 #include <linux/errno.h>
 9 #include <linux/mutex.h>
10 #include <linux/slab.h>
11 #include <linux/compat.h>
12 #include <linux/spi/spi.h>
13 #include <linux/spi/spidev.h>
14 #include <asm/uaccess.h>
15 #include <linux/gpio.h>
16 #include <mach/gpio.h>
17 #include <plat/gpio-cfg.h>
18 #include <linux/delay.h>
19 
20 static int __devinit my_rc522_probe(struct spi_device *spi)
21 {
22     /* reset */
23     //my_rc522_reset();
24     printk("my_rc522_probe!\n");   // 看到输出这句话说明驱动注册成功
25     
26     return 0;
27 }
28 
29 static int __devexit my_rc522_remove(struct spi_device *spi)
30 {
31     printk("my_rc522_remove!\n");
32     return 0;
33 }
34 
35 static struct spi_driver my_rc522_spi_driver = {
36     .driver = {
37         .name  = "my_rc522",
38         .owner = THIS_MODULE,
39     },
40     .probe =    my_rc522_probe,
41     .remove = __devexit_p(my_rc522_remove),
42 
43     /* NOTE:  suspend/resume methods are not necessary here.
44      * We don't do anything except pass the requests to/from
45      * the underlying controller.  The refrigerator handles
46      * most issues; the controller driver handles the rest.
47      */
48 };
49 
50 static int __init my_rc522_init(void)
51 {
52     spi_register_driver(&my_rc522_spi_driver);
53     return 0;
54 }
55 
56 static void __exit my_rc522_exit(void)
57 {
58     spi_unregister_driver(&my_rc522_spi_driver);
59 }
60 
61 module_exit(my_rc522_exit);
62 module_init(my_rc522_init);
63 
64 MODULE_AUTHOR("topeet: rty");
65 MODULE_LICENSE("GPL");

6、与rc522模块的数据传输,需要遵循模块所使用的SPI芯片协议,以及命令格式发送接收数据、从rc522驱动中提取spi传输的核心代码

  读寄存器、写寄存器、读数据、写数据、建立连接、获取SPI芯片版本号

  1 #include <linux/init.h>
  2 #include <linux/module.h>
  3 #include <linux/ioctl.h>
  4 #include <linux/fs.h>
  5 #include <linux/device.h>
  6 #include <linux/err.h>
  7 #include <linux/list.h>
  8 #include <linux/errno.h>
  9 #include <linux/mutex.h>
 10 #include <linux/slab.h>
 11 #include <linux/compat.h>
 12 #include <linux/spi/spi.h>
 13 #include <linux/spi/spidev.h>
 14 #include <asm/uaccess.h>
 15 #include <linux/gpio.h>
 16 #include <mach/gpio.h>
 17 #include <plat/gpio-cfg.h>
 18 #include <linux/delay.h>
 19 
 20 #include "spidev_test.h"   // 包含外部头文件
 21 #include "spidev.h"           
 22 
 23 struct spi_device *my_spi;   // 接收返回来得设备
 24 
 25 #define RC522_RESET_PIN    EXYNOS4_GPK1(0)   // 定义模块复位引脚
 26 
 27 // 初始化RC522模块上电的时序
 28 void my_rc522_reset()
 29 {
 30     //printk("************************ %s\n", __FUNCTION__);
 31     if(gpio_request_one(RC522_RESET_PIN, GPIOF_OUT_INIT_HIGH, "RC522_RESET"))
 32                 pr_err("failed to request GPK1_0 for RC522 reset control\n");
 33 
 34         s3c_gpio_setpull(RC522_RESET_PIN, S3C_GPIO_PULL_UP);
 35         gpio_set_value(RC522_RESET_PIN, 0);
 36 
 37         mdelay(5);
 38 
 39         gpio_set_value(RC522_RESET_PIN, 1);
 40         gpio_free(RC522_RESET_PIN);
 41 }
 42 
 43 // 写一个寄存器
 44 static int write_test(unsigned char *buffer, int len)
 45 {
 46     int status;
 47     struct spi_transfer    t = {
 48         .tx_buf        = buffer,
 49         .len        = len,
 50     };
 51     struct spi_message    m;
 52     spi_message_init(&m);
 53     spi_message_add_tail(&t, &m);
 54     DECLARE_COMPLETION_ONSTACK(done);
 55     m.complete = complete;
 56     m.context = &done;
 57     
 58     printk("spi_async send begin!\n");
 59     status = spi_async(my_spi,&m);
 60     if(status == 0){
 61         wait_for_completion(&done);
 62         status = m.status;
 63         if (status == 0)
 64             status = m.actual_length;
 65     }
 66     return status;
 67 }
 68 // 读一个寄存器
 69 static int read_test(unsigned char *buffer, int len)
 70 {
 71     int status;
 72     struct spi_transfer    t = {
 73         .rx_buf        = buffer,
 74         .len        = len,
 75     };
 76     struct spi_message    m;
 77     spi_message_init(&m);
 78     spi_message_add_tail(&t, &m);
 79     DECLARE_COMPLETION_ONSTACK(done);
 80     m.complete = complete;
 81     m.context = &done;
 82     
 83     printk("spi_async read begin!\n");
 84     status = spi_async(my_spi,&m);
 85     if(status == 0){
 86         wait_for_completion(&done);
 87         status = m.status;
 88         if (status == 0)
 89             status = m.actual_length;
 90     }
 91     return status;
 92 }
 93 
 94 // 读数据
 95 static unsigned char ReadRawRC(int addr)
 96 {
 97     int ret;
 98     unsigned char  ReData;
 99     unsigned char  Address;
100     
101     Address  = (unsigned char)addr << 1;
102     Address |= (1 << 7);
103     Address &= ~(1 << 0);
104     
105     ret = write_test(&Address, 1);
106     if (ret < 0)
107         printk("spi:SPI Write error\n");
108 
109     udelay(100);
110 
111     ret = read_test(&ReData, 1);
112     if (ret < 0)
113         printk("spi:SPI Read error\n");
114 
115     return ReData;
116 }
117 // 写数据
118 static int WriteRawRC(int addr, int data)
119 {
120     int ret;
121     unsigned char  TxBuf[2];
122 
123     //bit7:MSB=0,bit6~1:addr,bit0:RFU=0
124     TxBuf[0] = ((unsigned char)addr << 1)&0x7E;
125     //TxBuf[0] &= 0x7E;
126 
127     TxBuf[1] = (unsigned char)data;
128     
129     ret = write_test(TxBuf, 2);
130     
131     if (ret < 0)
132         printk("spi:SPI Write error\n");
133 
134     udelay(10);
135 
136     return ret;
137 }
138 
139 // 模块初始化   建立通信成功
140 static int rc522_init()
141 {
142     int ret;
143     char version = 0;
144 
145     //reset
146     WriteRawRC(CommandReg, PCD_RESETPHASE);
147     udelay(10);
148     WriteRawRC(ModeReg, 0x3D);      // 写寄存器值
149     WriteRawRC(TReloadRegL, 30);
150     WriteRawRC(TReloadRegH, 0);
151     WriteRawRC(TModeReg, 0x8D);
152     WriteRawRC(TPrescalerReg, 0x3E);
153 
154     version = ReadRawRC(VersionReg);   // 读取RFID模块所使用的芯片的版本
155     printk("Chip Version: 0x%x\n", version);
156 
157     return 0;
158 }
159 
160 static int __devinit my_rc522_probe(struct spi_device *spi)
161 {
162     
163     printk("my_rc522_probe!\n");
164     
165     /* reset */
166     my_rc522_reset();  // 初始化上电时序
167     my_spi = spi;      // 将设备传出来
168     rc522_init();       //  模块初始化   确认建立通信成功
169     
170     return 0;
171 }
172 
173 static int __devexit my_rc522_remove(struct spi_device *spi)
174 {
175     printk("my_rc522_remove!\n");
176     return 0;
177 }
178 
179 static struct spi_driver my_rc522_spi_driver = {
180     .driver = {
181         .name  = "my_rc522",
182         .owner = THIS_MODULE,
183     },
184     .probe =    my_rc522_probe,
185     .remove = __devexit_p(my_rc522_remove),
186 
187     /* NOTE:  suspend/resume methods are not necessary here.
188      * We don't do anything except pass the requests to/from
189      * the underlying controller.  The refrigerator handles
190      * most issues; the controller driver handles the rest.
191      */
192 };
193 
194 
195 static int __init my_rc522_init(void)
196 {
197     spi_register_driver(&my_rc522_spi_driver);
198     return 0;
199 }
200 
201 static void __exit my_rc522_exit(void)
202 {
203     spi_unregister_driver(&my_rc522_spi_driver);
204 }
205 
206 module_exit(my_rc522_exit);
207 module_init(my_rc522_init);
208 
209 
210 MODULE_AUTHOR("topeet: rty");
211 MODULE_LICENSE("GPL");
View Code

7、应用层传输数据的驱动

  1 #include <linux/init.h>
  2 #include <linux/module.h>
  3 #include <linux/ioctl.h>
  4 #include <linux/fs.h>
  5 #include <linux/device.h>
  6 #include <linux/err.h>
  7 #include <linux/list.h>
  8 #include <linux/errno.h>
  9 #include <linux/mutex.h>
 10 #include <linux/slab.h>
 11 #include <linux/compat.h>
 12 #include <linux/spi/spi.h>
 13 #include <linux/spi/spidev.h>
 14 #include <asm/uaccess.h>
 15 #include <linux/gpio.h>
 16 #include <mach/gpio.h>
 17 #include <plat/gpio-cfg.h>
 18 #include <linux/delay.h>
 19 #include <linux/miscdevice.h>
 20 
 21 struct spi_device *my_spi;
 22 
 23 #define RC522_RESET_PIN    EXYNOS4_GPK1(0)
 24 void my_rc522_reset()
 25 {
 26     //printk("************************ %s\n", __FUNCTION__);
 27     if(gpio_request_one(RC522_RESET_PIN, GPIOF_OUT_INIT_HIGH, "RC522_RESET"))
 28                 pr_err("failed to request GPK1_0 for RC522 reset control\n");
 29 
 30         s3c_gpio_setpull(RC522_RESET_PIN, S3C_GPIO_PULL_UP);
 31         gpio_set_value(RC522_RESET_PIN, 0);
 32 
 33         mdelay(5);
 34 
 35         gpio_set_value(RC522_RESET_PIN, 1);
 36         gpio_free(RC522_RESET_PIN);
 37 }
 38 
 39 //static ssize_t rc522_write(unsigned char *buffer, int len)
 40 static ssize_t rc522_write(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
 41 {
 42     int status;
 43     unsigned char tx_buf[2];
 44     // 与应用层数据交互
 45     status = copy_from_user(tx_buf,buf,count);
 46     
 47     struct spi_transfer    t = {
 48         .tx_buf        = tx_buf,
 49         .len        = count,
 50     };
 51     struct spi_message    m;
 52     spi_message_init(&m);
 53     spi_message_add_tail(&t, &m);
 54     DECLARE_COMPLETION_ONSTACK(done);
 55     m.complete = complete;
 56     m.context = &done;
 57     
 58     printk("spi_async send begin!\n");
 59     status = spi_async(my_spi,&m);
 60     if(status == 0){
 61         wait_for_completion(&done);
 62         status = m.status;
 63         if (status == 0)
 64             status = m.actual_length;
 65     }
 66     return status;
 67 }
 68 
 69 
 70 //static ssize_t rc522_read(unsigned char *buffer, int len)
 71 static ssize_t rc522_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
 72 {
 73     int status;
 74     unsigned char *rx_buf;
 75     
 76     struct spi_transfer    t = {
 77         .rx_buf        = &rx_buf,
 78         .len        = count,
 79     };
 80     struct spi_message    m;
 81     spi_message_init(&m);
 82     spi_message_add_tail(&t, &m);
 83     DECLARE_COMPLETION_ONSTACK(done);
 84     m.complete = complete;
 85     m.context = &done;
 86     
 87     printk("spi_async read begin!\n");
 88     status = spi_async(my_spi,&m);
 89     if(status == 0){
 90         wait_for_completion(&done);
 91         status = m.status;
 92         if (status == 0)
 93             status = m.actual_length;
 94     }
 95     // 数据返回值应用
 96     status = copy_to_user(buf,&rx_buf,status);
 97     
 98     return status;
 99 }
100 
101 int rc522_open(struct inode *inode,struct file *filp)
102 {
103     return 0;
104 }
105 
106 // 数据交互的文件系统 节点API
107 static struct file_operations rc522_ops = {
108     .owner     = THIS_MODULE,
109     .open     = rc522_open,
110     .read    = rc522_read,
111     .write     = rc522_write,
112 };
113 
114 // 使用杂项设备注册SPI模块,SPI有默认的节点 但是也可以使用杂项设备注册
115 static struct miscdevice rc522_dev = {
116     .minor    = MISC_DYNAMIC_MINOR,
117     .fops    = &rc522_ops,
118     .name    = "rc522",
119 };
120 
121 static int __devinit my_rc522_probe(struct spi_device *spi)
122 {
123     
124     printk("my_rc522_probe!\n");
125     
126     /* reset */
127     my_rc522_reset();
128     my_spi = spi;
129     
130     misc_register(&rc522_dev);
131     
132     return 0;
133 }
134 
135 static int __devexit my_rc522_remove(struct spi_device *spi)
136 {
137     printk("my_rc522_remove!\n");
138     misc_deregister(&rc522_dev);    
139     return 0;
140 }
141 
142 static struct spi_driver my_rc522_spi_driver = {
143     .driver = {
144         .name  = "my_rc522",
145         .owner = THIS_MODULE,
146     },
147     .probe =    my_rc522_probe,
148     .remove = __devexit_p(my_rc522_remove),
149 
150     /* NOTE:  suspend/resume methods are not necessary here.
151      * We don't do anything except pass the requests to/from
152      * the underlying controller.  The refrigerator handles
153      * most issues; the controller driver handles the rest.
154      */
155 };
156 
157 
158 static int __init my_rc522_init(void)
159 {
160     spi_register_driver(&my_rc522_spi_driver);
161     return 0;
162 }
163 
164 static void __exit my_rc522_exit(void)
165 {
166     spi_unregister_driver(&my_rc522_spi_driver);
167 }
168 
169 module_exit(my_rc522_exit);
170 module_init(my_rc522_init);
171 
172 MODULE_AUTHOR("topeet: rty");
173 MODULE_LICENSE("GPL");
View Code

8、应用获取模块数据

  1 /*
  2  * SPI testing utility (using spidev driver)
  3  *
  4  * Copyright (c) 2007  MontaVista Software, Inc.
  5  * Copyright (c) 2007  Anton Vorontsov <avorontsov@ru.mvista.com>
  6  *
  7  * This program is free software; you can redistribute it and/or modify
  8  * it under the terms of the GNU General Public License as published by
  9  * the Free Software Foundation; either version 2 of the License.
 10  *
 11  * Cross-compile with cross-gcc -I/path/to/cross-kernel/include
 12  */
 13 
 14 #include <stdint.h>
 15 #include <unistd.h>
 16 #include <stdio.h>
 17 #include <stdlib.h>
 18 #include <getopt.h>
 19 #include <fcntl.h>
 20 #include <sys/ioctl.h>
 21 #include <linux/types.h>
 22 
 23 #include "spidev.h"
 24 #include "spidev_test.h"
 25 
 26 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 27 
 28 static void pabort(const char *s)
 29 {
 30     perror(s);
 31     
 32     abort();
 33 }
 34 
 35 static const char *device = "/dev/rc522";
 36 static uint8_t mode;
 37 static uint8_t bits = 8;
 38 static uint32_t speed = 400 * 1000;//500000;
 39 static uint16_t delay;
 40 
 41 int g_SPI_Fd = 0;
 42 
 43 unsigned char UID[5], Temp[4];
 44 
 45 /*******************************************
 46 函数名称:tochar
 47 功    能:处理16进制函数
 48 参    数:id
 49 返回值  :无
 50 ********************************************/
 51 #if 0
 52 void tochar(unsigned char id)
 53 {
 54     switch(id) 
 55     {
 56     case 0x00:printf("00");break;
 57     case 0x01:printf("01");break;
 58     case 0x02:printf("02");break;
 59     case 0x03:printf("03");break;
 60     case 0x04:printf("04");break;
 61     case 0x05:printf("05");break;
 62     case 0x06:printf("06");break;
 63     case 0x07:printf("07");break;
 64     case 0x08:printf("08");break;
 65     case 0x09:printf("09");break;
 66     case 0x0a:printf("0a");break;
 67     case 0x0b:printf("0b");break;
 68     case 0x0c:printf("0c");break;
 69     case 0x0d:printf("0d");break;
 70     case 0x0e:printf("0e");break;
 71     case 0x0f:printf("0f");break;
 72     case 0x10:printf("10");break;
 73     case 0x11:printf("11");break;
 74     case 0x12:printf("12");break;
 75     case 0x13:printf("13");break;
 76     case 0x14:printf("14");break;
 77     case 0x15:printf("15");break;
 78     case 0x16:printf("16");break;
 79     case 0x17:printf("17");break;
 80     case 0x18:printf("18");break;
 81     case 0x19:printf("19");break;
 82     case 0x1a:printf("1a");break;
 83     case 0x1b:printf("1b");break;
 84     case 0x1c:printf("1c");break;
 85     case 0x1d:printf("1d");break;
 86     case 0x1e:printf("1e");break;
 87     case 0x1f:printf("1f");break;
 88     case 0x20:printf("20");break;
 89     case 0x21:printf("21");break;
 90     case 0x22:printf("22");break;
 91     case 0x23:printf("23");break;
 92     case 0x24:printf("24");break;
 93     case 0x25:printf("25");break;
 94     case 0x26:printf("26");break;
 95     case 0x27:printf("27");break;
 96     case 0x28:printf("28");break;
 97     case 0x29:printf("29");break;
 98     case 0x2a:printf("2a");break;
 99     case 0x2b:printf("2b");break;
100     case 0x2c:printf("2c");break;
101     case 0x2d:printf("2d");break;
102     case 0x2e:printf("2e");break;
103     case 0x2f:printf("2f");break;
104     case 0x30:printf("30");break;
105     case 0x31:printf("31");break;
106     case 0x32:printf("32");break;
107     case 0x33:printf("33");break;
108     case 0x34:printf("34");break;
109     case 0x35:printf("35");break;
110     case 0x36:printf("36");break;
111     case 0x37:printf("37");break;
112     case 0x38:printf("38");break;
113     case 0x39:printf("39");break;
114     case 0x3a:printf("3a");break;
115     case 0x3b:printf("3b");break;
116     case 0x3c:printf("3c");break;
117     case 0x3d:printf("3d");break;
118     case 0x3e:printf("3e");break;
119     case 0x3f:printf("3f");break;
120     case 0x40:printf("40");break;
121     case 0x41:printf("41");break;
122     case 0x42:printf("42");break;
123     case 0x43:printf("43");break;
124     case 0x44:printf("44");break;
125     case 0x45:printf("45");break;
126     case 0x46:printf("46");break;
127     case 0x47:printf("47");break;
128     case 0x48:printf("48");break;
129     case 0x49:printf("49");break;
130     case 0x4a:printf("4a");break;
131     case 0x4b:printf("4b");break;
132     case 0x4c:printf("4c");break;
133     case 0x4d:printf("4d");break;
134     case 0x4e:printf("4e");break;
135     case 0x4f:printf("4f");break;
136     case 0x50:printf("50");break;
137     case 0x51:printf("51");break;
138     case 0x52:printf("52");break;
139     case 0x53:printf("53");break;
140     case 0x54:printf("54");break;
141     case 0x55:printf("55");break;
142     case 0x56:printf("56");break;
143     case 0x57:printf("57");break;
144     case 0x58:printf("58");break;
145     case 0x59:printf("59");break;
146     case 0x5a:printf("5a");break;
147     case 0x5b:printf("5b");break;
148     case 0x5c:printf("5c");break;
149     case 0x5d:printf("5d");break;
150     case 0x5e:printf("5e");break;
151     case 0x5f:printf("5f");break;
152     case 0x60:printf("60");break;
153     case 0x61:printf("61");break;
154     case 0x62:printf("62");break;
155     case 0x63:printf("63");break;
156     case 0x64:printf("64");break;
157     case 0x65:printf("65");break;
158     case 0x66:printf("66");break;
159     case 0x67:printf("67");break;
160     case 0x68:printf("68");break;
161     case 0x69:printf("69");break;
162     case 0x6a:printf("6a");break;
163     case 0x6b:printf("6b");break;
164     case 0x6c:printf("6c");break;
165     case 0x6d:printf("6d");break;
166     case 0x6e:printf("6e");break;
167     case 0x6f:printf("6f");break;
168     case 0x70:printf("70");break;
169     case 0x71:printf("71");break;
170     case 0x72:printf("72");break;
171     case 0x73:printf("73");break;
172     case 0x74:printf("74");break;
173     case 0x75:printf("75");break;
174     case 0x76:printf("76");break;
175     case 0x77:printf("77");break;
176     case 0x78:printf("78");break;
177     case 0x79:printf("79");break;
178     case 0x7a:printf("7a");break;
179     case 0x7b:printf("7b");break;
180     case 0x7c:printf("7c");break;
181     case 0x7d:printf("7d");break;
182     case 0x7e:printf("7e");break;
183     case 0x7f:printf("7f");break;
184     case 0x80:printf("80");break;
185     case 0x81:printf("81");break;
186     case 0x82:printf("82");break;
187     case 0x83:printf("83");break;
188     case 0x84:printf("84");break;
189     case 0x85:printf("85");break;
190     case 0x86:printf("86");break;
191     case 0x87:printf("87");break;
192     case 0x88:printf("88");break;
193     case 0x89:printf("89");break;
194     case 0x8a:printf("8a");break;
195     case 0x8b:printf("8b");break;
196     case 0x8c:printf("8c");break;
197     case 0x8d:printf("8d");break;
198     case 0x8e:printf("8e");break;
199     case 0x8f:printf("8f");break;
200     case 0x90:printf("90");break;
201     case 0x91:printf("91");break;
202     case 0x92:printf("92");break;
203     case 0x93:printf("93");break;
204     case 0x94:printf("94");break;
205     case 0x95:printf("95");break;
206     case 0x96:printf("96");break;
207     case 0x97:printf("97");break;
208     case 0x98:printf("98");break;
209     case 0x99:printf("99");break;
210     case 0x9a:printf("9a");break;
211     case 0x9b:printf("9b");break;
212     case 0x9c:printf("9c");break;
213     case 0x9d:printf("9d");break;
214     case 0x9e:printf("9e");break;
215     case 0x9f:printf("9f");break;
216     case 0xa0:printf("a0");break;
217     case 0xa1:printf("a1");break;
218     case 0xa2:printf("a2");break;
219     case 0xa3:printf("a3");break;
220     case 0xa4:printf("a4");break;
221     case 0xa5:printf("a5");break;
222     case 0xa6:printf("a6");break;
223     case 0xa7:printf("a7");break;
224     case 0xa8:printf("a8");break;
225     case 0xa9:printf("a9");break;
226     case 0xaa:printf("aa");break;
227     case 0xab:printf("ab");break;
228     case 0xac:printf("ac");break;
229     case 0xad:printf("ad");break;
230     case 0xae:printf("ae");break;
231     case 0xaf:printf("af");break;
232     case 0xb0:printf("b0");break;
233     case 0xb1:printf("b1");break;
234     case 0xb2:printf("b2");break;
235     case 0xb3:printf("b3");break;
236     case 0xb4:printf("b4");break;
237     case 0xb5:printf("b5");break;
238     case 0xb6:printf("b6");break;
239     case 0xb7:printf("b7");break;
240     case 0xb8:printf("b8");break;
241     case 0xb9:printf("b9");break;
242     case 0xba:printf("ba");break;
243     case 0xbb:printf("bb");break;
244     case 0xbc:printf("bc");break;
245     case 0xbd:printf("bd");break;
246     case 0xbe:printf("be");break;
247     case 0xbf:printf("bf");break;
248     case 0xc0:printf("c0");break;
249     case 0xc1:printf("c1");break;
250     case 0xc2:printf("c2");break;
251     case 0xc3:printf("c3");break;
252     case 0xc4:printf("c4");break;
253     case 0xc5:printf("c5");break;
254     case 0xc6:printf("c6");break;
255     case 0xc7:printf("c7");break;
256     case 0xc8:printf("c8");break;
257     case 0xc9:printf("c9");break;
258     case 0xca:printf("ca");break;
259     case 0xcb:printf("cb");break;
260     case 0xcc:printf("cc");break;
261     case 0xcd:printf("cd");break;
262     case 0xce:printf("ce");break;
263     case 0xcf:printf("cf");break;
264     case 0xd0:printf("d0");break;
265     case 0xd1:printf("d1");break;
266     case 0xd2:printf("d2");break;
267     case 0xd3:printf("d3");break;
268     case 0xd4:printf("d4");break;
269     case 0xd5:printf("d5");break;
270     case 0xd6:printf("d6");break;
271     case 0xd7:printf("d7");break;
272     case 0xd8:printf("d8");break;
273     case 0xd9:printf("d9");break;
274     case 0xda:printf("da");break;
275     case 0xdb:printf("db");break;
276     case 0xdc:printf("dc");break;
277     case 0xdd:printf("dd");break;
278     case 0xde:printf("de");break;
279     case 0xdf:printf("df");break;
280     case 0xe0:printf("e0");break;
281     case 0xe1:printf("e1");break;
282     case 0xe2:printf("e2");break;
283     case 0xe3:printf("e3");break;
284     case 0xe4:printf("e4");break;
285     case 0xe5:printf("e5");break;
286     case 0xe6:printf("e6");break;
287     case 0xe7:printf("e7");break;
288     case 0xe8:printf("e8");break;
289     case 0xe9:printf("e9");break;
290     case 0xea:printf("ea");break;
291     case 0xeb:printf("eb");break;
292     case 0xec:printf("ec");break;
293     case 0xed:printf("ed");break;
294     case 0xee:printf("ee");break;
295     case 0xef:printf("ef");break;
296     case 0xf0:printf("f0");break;
297     case 0xf1:printf("f1");break;
298     case 0xf2:printf("f2");break;
299     case 0xf3:printf("f3");break;
300     case 0xf4:printf("f4");break;
301     case 0xf5:printf("f5");break;
302     case 0xf6:printf("f6");break;
303     case 0xf7:printf("f7");break;
304     case 0xf8:printf("f8");break;
305     case 0xf9:printf("f9");break;
306     case 0xfa:printf("fa");break;
307     case 0xfb:printf("fb");break;
308     case 0xfc:printf("fc");break;
309     case 0xfd:printf("fd");break;
310     case 0xfe:printf("fe");break;
311     case 0xff:printf("ff");break;
312     default:
313               ;  
314     }
315 }
316 #endif
317 
318 int WriteRawRC(int addr, int data)
319 {
320     int ret;
321     int fd = g_SPI_Fd;
322     unsigned char  TxBuf[2];
323 
324     //bit7:MSB=0,bit6~1:addr,bit0:RFU=0
325     TxBuf[0] = ((unsigned char)addr << 1)&0x7E;
326     //TxBuf[0] &= 0x7E;
327 
328     TxBuf[1] = (unsigned char)data;
329     
330     ret = write(fd, TxBuf, 2);
331     if (ret < 0)
332         printf("spi:SPI Write error\n");
333 
334     usleep(10);
335 
336     return ret;
337 }
338 
339 unsigned char ReadRawRC(int addr)
340 {
341     int ret;
342     int fd = g_SPI_Fd;
343     unsigned char  ReData;
344     unsigned char  Address;
345     
346     Address  = (unsigned char)addr << 1;
347     Address |= (1 << 7);
348     Address &= ~(1 << 0);
349     
350     ret = write(fd, &Address, 1);
351     if (ret < 0)
352         printf("spi:SPI Write error\n");
353 
354     usleep(100);
355 
356     ret = read(fd, &ReData, 1);
357     if (ret < 0)
358         printf("spi:SPI Read error\n");
359 
360     return ReData;
361 }
362 
363 void SetBitMask(unsigned char reg,unsigned char mask)  
364 {
365       char tmp = 0x0;
366     
367       tmp = ReadRawRC(reg) | mask;
368     
369       WriteRawRC(reg,tmp | mask);
370 }
371 
372 //******************************************************************/
373 //功    能:清RC522寄存器位
374 //参数说明:reg[IN]:寄存器地址
375 //          mask[IN]:清位值
376 //******************************************************************/
377 void ClearBitMask(unsigned char reg, unsigned char mask)  
378 {
379     char tmp = 0x0;
380     
381     tmp = ReadRawRC(reg)&(~mask);
382     
383     WriteRawRC(reg, tmp);  // clear bit mask
384 }
385 
386 int rc522_init()
387 {
388     int ret;
389     char version = 0;
390 
391     //reset
392     WriteRawRC(CommandReg, PCD_RESETPHASE);
393     usleep(10);
394     WriteRawRC(ModeReg, 0x3D);
395     WriteRawRC(TReloadRegL, 30);
396     WriteRawRC(TReloadRegH, 0);
397     WriteRawRC(TModeReg, 0x8D);
398     WriteRawRC(TPrescalerReg, 0x3E);
399 
400     version = ReadRawRC(VersionReg);
401     printf("Chip Version: 0x%x\n", version);
402     usleep(50000);
403 
404     return 0;
405 }
406 
407 void PcdAntennaOn()
408 {
409     unsigned char i;
410   
411     WriteRawRC(TxASKReg, 0x40);
412       usleep(20);
413   
414     i = ReadRawRC(TxControlReg);
415       if(!(i&0x03))
416             SetBitMask(TxControlReg, 0x03);
417       
418     i = ReadRawRC(TxASKReg);
419 }
420 
421 static void print_usage(const char *prog)
422 {
423     printf("Usage: %s [-DsbdlHOLC3]\n", prog);
424     puts("  -D --device   device to use (default /dev/spidev1.1)\n"
425          "  -s --speed    max speed (Hz)\n"
426          "  -d --delay    delay (usec)\n"
427          "  -b --bpw      bits per word \n"
428          "  -l --loop     loopback\n"
429          "  -H --cpha     clock phase\n"
430          "  -O --cpol     clock polarity\n"
431          "  -L --lsb      least significant bit first\n"
432          "  -C --cs-high  chip select active high\n"
433          "  -3 --3wire    SI/SO signals shared\n");
434     exit(1);
435 }
436 
437 static void parse_opts(int argc, char *argv[])
438 {
439     while (1) {
440         static const struct option lopts[] = {
441             { "device",  1, 0, 'D' },
442             { "speed",   1, 0, 's' },
443             { "delay",   1, 0, 'd' },
444             { "bpw",     1, 0, 'b' },
445             { "loop",    0, 0, 'l' },
446             { "cpha",    0, 0, 'H' },
447             { "cpol",    0, 0, 'O' },
448             { "lsb",     0, 0, 'L' },
449             { "cs-high", 0, 0, 'C' },
450             { "3wire",   0, 0, '3' },
451             { "no-cs",   0, 0, 'N' },
452             { "ready",   0, 0, 'R' },
453             { NULL, 0, 0, 0 },
454         };
455         int c;
456 
457         c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL);
458 
459         if (c == -1)
460             break;
461 
462         switch (c) {
463         case 'D':
464             device = optarg;
465             break;
466         case 's':
467             speed = atoi(optarg);
468             break;
469         case 'd':
470             delay = atoi(optarg);
471             break;
472         case 'b':
473             bits = atoi(optarg);
474             break;
475         case 'l':
476             mode |= SPI_LOOP;
477             break;
478         case 'H':
479             mode |= SPI_CPHA;
480             break;
481         case 'O':
482             mode |= SPI_CPOL;
483             break;
484         case 'L':
485             mode |= SPI_LSB_FIRST;
486             break;
487         case 'C':
488             mode |= SPI_CS_HIGH;
489             break;
490         case '3':
491             mode |= SPI_3WIRE;
492             break;
493         case 'N':
494             mode |= SPI_NO_CS;
495             break;
496         case 'R':
497             mode |= SPI_READY;
498             break;
499         default:
500             print_usage(argv[0]);
501             break;
502         }
503     }
504 }
505 
506 //******************************************************************/
507 //功    能:通过RC522和ISO14443卡通讯
508 //参数说明:Command[IN]:RC522命令字
509 //          pInData[IN]:通过RC522发送到卡片的数据
510 //          InLenByte[IN]:发送数据的字节长度
511 //          pOutData[OUT]:接收到的卡片返回数据
512 //          *pOutLenBit[OUT]:返回数据的位长度
513 //******************************************************************/
514 char PcdComMF522(unsigned char Command, unsigned char *pInData, 
515                                  unsigned char InLenByte, unsigned char *pOutData, 
516                                  unsigned int  *pOutLenBit)
517 {
518     char status = MI_ERR;
519     unsigned char irqEn  = 0x00;
520     unsigned char waitFor = 0x00;
521     unsigned char lastBits;
522     unsigned char n;
523     unsigned int  i;
524     
525     switch (Command)
526     {
527         case PCD_AUTHENT:
528               irqEn   = 0x12;
529               waitFor = 0x10;
530               break;
531         case PCD_TRANSCEIVE:
532               irqEn   = 0x77;
533               waitFor = 0x30;
534               break;
535         default:
536               break;
537     }
538     
539     WriteRawRC(ComIEnReg, irqEn|0x80);
540     ClearBitMask(ComIrqReg, 0x80);
541     WriteRawRC(CommandReg, PCD_IDLE);
542     SetBitMask(FIFOLevelReg, 0x80); // 清空FIFO 
543     for(i=0; i<InLenByte; i++)
544         WriteRawRC(FIFODataReg, pInData[i]); // 数据写入FIFO 
545         
546     WriteRawRC(CommandReg, Command); // 命令写入命令寄存器
547 
548     if(Command == PCD_TRANSCEIVE)
549         SetBitMask(BitFramingReg,0x80); // 开始发送     
550 
551     i = 6000; //根据时钟频率调整,操作M1卡最大等待时间25ms
552       do 
553     {
554         n = ReadRawRC(ComIrqReg);
555         i--;
556     }
557     while((i!=0)&&!(n&0x01)&&!(n&waitFor));
558     
559     ClearBitMask(BitFramingReg, 0x80);
560 
561     if(i!=0)
562     {
563         if(!(ReadRawRC(ErrorReg) & 0x1B))
564         {
565             status = MI_OK;
566             if (n&irqEn&0x01)
567                 status = MI_NOTAGERR;
568             if(Command == PCD_TRANSCEIVE)
569             {
570                 n = ReadRawRC(FIFOLevelReg);
571                 
572                 lastBits = ReadRawRC(ControlReg) & 0x07;
573                 if(lastBits)
574                     *pOutLenBit = (n-1)*8 + lastBits;
575                 else
576                     *pOutLenBit = n*8;
577 
578                 if(n == 0)
579                     n = 1;
580                 if(n>MAXRLEN)
581                     n = MAXRLEN;
582 
583                 for (i=0; i<n; i++)
584                     pOutData[i] = ReadRawRC(FIFODataReg); 
585             }
586         }
587         else
588         {
589             status = MI_ERR;
590         }
591     }
592 
593     SetBitMask(ControlReg, 0x80);// stop timer now
594     WriteRawRC(CommandReg, PCD_IDLE); 
595 
596     return status;
597 }
598 
599 char PcdRequest(unsigned char req_code, unsigned char *pTagType)
600 {
601     char status;  
602     unsigned int  unLen;
603     unsigned char ucComMF522Buf[MAXRLEN]; 
604 
605     ClearBitMask(Status2Reg, 0x08);
606     WriteRawRC(BitFramingReg, 0x07);
607     SetBitMask(TxControlReg, 0x03);
608  
609       ucComMF522Buf[0] = req_code;
610 
611       status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf,
612                                        1, ucComMF522Buf, &unLen);
613 
614       if ((status == MI_OK) && (unLen == 0x10))
615       {    
616             *pTagType     = ucComMF522Buf[0];
617             *(pTagType+1) = ucComMF522Buf[1];
618       }
619       else
620     {
621         status = MI_ERR;
622       }
623 
624       return status;
625 }
626 
627 //******************************************************************/
628 //功    能:防冲撞                                                  /
629 //参数说明: pSnr[OUT]:卡片序列号,4字节                             /
630 //返    回: 成功返回MI_OK                                           /
631 //******************************************************************/
632 char PcdAnticoll(unsigned char *pSnr)
633 {
634     char status;
635     unsigned char i, snr_check = 0;
636     unsigned int  unLen;
637     unsigned char ucComMF522Buf[MAXRLEN]; 
638     
639     ClearBitMask(Status2Reg, 0x08);
640     WriteRawRC(BitFramingReg, 0x00);
641     ClearBitMask(CollReg, 0x80);
642  
643     ucComMF522Buf[0] = PICC_ANTICOLL1;
644     ucComMF522Buf[1] = 0x20;
645 
646         status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf,
647                                 2, ucComMF522Buf, &unLen);
648 
649         if(status == MI_OK)
650     {
651         for (i=0; i<4; i++)
652         {   
653             *(pSnr+i)  = ucComMF522Buf[i];
654             snr_check ^= ucComMF522Buf[i];
655         }
656         if (snr_check != ucComMF522Buf[i])
657         {
658             status = MI_ERR;
659         }
660     }
661     
662     SetBitMask(CollReg,0x80);
663     
664     return status;
665 }
666 
667 void Find_Card(void)
668 {
669     if(PcdRequest(0x52, Temp) == MI_OK)
670     {
671           if(Temp[0]==0x04 && Temp[1]==0x00)  
672                   printf("MFOne-S50\n");
673             else if(Temp[0]==0x02 && Temp[1] == 0x00)
674                   printf("MFOne-S70\n");
675             else if(Temp[0]==0x44 && Temp[1]==0x00)
676                   printf("MF-UltraLight\n");
677             else if(Temp[0]==0x08 && Temp[1]==0x00)
678                   printf("MF-Pro\n");
679             else if(Temp[0]==0x44 && Temp[1]==0x03)
680                   printf("MF Desire\n");
681             else
682                   printf("Unknown\n");
683             
684             printf("SUCCESS!\n");
685     }
686     else
687     {
688         printf("No card!\n");
689     }
690 }
691 
692 void Auto_Reader(void)
693 {
694     int i = 0;
695     unsigned long num = 0;
696     
697   //    while(1)
698     //{
699         if(PcdRequest(0x52,Temp) == MI_OK)
700         {
701             if(Temp[0]==0x04 && Temp[1]==0x00)  
702                 printf("MFOne-S50\n");
703             else if(Temp[0]==0x02 && Temp[1]==0x00)
704                 printf("MFOne-S70\n");
705             else if(Temp[0]==0x44 && Temp[1]==0x00)
706                 printf("MF-UltraLight\n");
707             else if(Temp[0]==0x08 && Temp[1]==0x00)
708                 printf("MF-Pro\n");
709             else if(Temp[0]==0x44 && Temp[1]==0x03)
710                 printf("MF Desire\n");
711             else
712                 printf("Unknown\n");
713             
714             if(PcdAnticoll(UID) == MI_OK)
715             { 
716                 printf("Card Id is(%d):", num++);
717 #if 1
718                 for(i=0; i<4; i++)
719                     printf("%x", UID[i]);
720 #else            
721                 tochar(UID[0]);
722                 tochar(UID[1]);
723                 tochar(UID[2]);
724                 tochar(UID[3]);
725 #endif
726                 printf("\n");
727                 
728                 PcdRequest(0x52,Temp);//clear
729             }
730             else
731             {
732                 printf("no serial num read\n");
733             }
734         }
735         else
736         {
737             printf("No Card!\n");
738         }
739 
740         usleep(300000);
741 //    } 
742 }
743 
744 void HandleConfigMenu(unsigned char inputvalue)
745 {
746 #if 0
747     switch(toupper(inputvalue)) 
748     {
749     case 'A':
750               Auto_Reader();
751               break;
752     case 'F':
753               Find_Card();
754               break;
755     default:
756               DisplayConfigMenu();
757     }
758 #endif
759 
760     //Find_Card();
761 
762     Auto_Reader();
763 }
764 
765 int main(int argc, char *argv[])
766 {
767     unsigned char i;
768     
769     int ret = 0;
770     int fd;
771 
772     parse_opts(argc, argv);
773 
774     fd = open(device, O_RDWR);
775     if (fd < 0)
776         pabort("can't open device");
777 
778     g_SPI_Fd = fd;
779 
780 #if 0
781     /*
782      * spi mode
783      */
784     ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
785     if (ret == -1)
786         pabort("can't set spi mode");
787 
788     ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
789     if (ret == -1)
790         pabort("can't get spi mode");
791 
792     /*
793      * bits per word
794      */
795     ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
796     if (ret == -1)
797         pabort("can't set bits per word");
798 
799     ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
800     if (ret == -1)
801         pabort("can't get bits per word");
802 
803     /*
804      * max speed hz
805      */
806     ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
807     if (ret == -1)
808         pabort("can't set max speed hz");
809 
810     ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
811     if (ret == -1)
812         pabort("can't get max speed hz");
813 
814     printf("spi mode: %d\n", mode);
815     printf("bits per word: %d\n", bits);
816     printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
817 #endif
818 
819     rc522_init();
820 
821     PcdAntennaOn();
822 
823     HandleConfigMenu(i);
824 
825     close(fd);
826 
827     return ret;
828 }
View Code

9、所使用的头文件(来源于讯为)

  spidev_test.h

// spidev_test.h
#define MAXRLEN        18
#define MIN_STRENGTH  228
//******************************************************************/
//                    RC522 FIFO长度定义                            /
//******************************************************************/
#define DEF_FIFO_LENGTH             64           //FIFO size=64byte

//******************************************************************/
//                       RC522命令字                                /
//******************************************************************/
#define PCD_IDLE                  0x00           //取消当前命令
#define PCD_AUTHENT               0x0E           //验证密钥
#define PCD_RECEIVE               0x08           //接收数据
#define PCD_TRANSMIT              0x04           //发送数据
#define PCD_TRANSCEIVE            0x0C           //发送并接收数据
#define PCD_RESETPHASE            0x0F           //复位
#define PCD_CALCCRC               0x03           //CRC计算

//******************************************************************/
//                   Mifare_One卡片命令字                          */
//******************************************************************/
#define PICC_REQIDL               0x26           //寻天线区内未进入休眠状态
#define PICC_REQALL               0x52           //寻天线区内全部卡
#define PICC_ANTICOLL1            0x93           //防冲撞
#define PICC_ANTICOLL2            0x95           //防冲撞
#define PICC_AUTHENT1A            0x60           //验证A密钥
#define PICC_AUTHENT1B            0x61           //验证B密钥
#define PICC_READ                 0x30           //读块
#define PICC_WRITE                0xA0           //写块
#define PICC_DECREMENT            0xC0           //扣款
#define PICC_INCREMENT            0xC1           //充值
#define PICC_RESTORE              0xC2           //调块数据到缓冲区
#define PICC_TRANSFER             0xB0           //保存缓冲区中数据
#define PICC_HALT                 0x50           //休眠

//******************************************************************/
//                        MF522寄存器定义                           /
//******************************************************************/
// PAGE 0
#define     RFU00                 0x00    
#define     CommandReg            0x01    
#define     ComIEnReg             0x02    
#define     DivlEnReg             0x03    
#define     ComIrqReg             0x04    
#define     DivIrqReg             0x05
#define     ErrorReg              0x06    
#define     Status1Reg            0x07    
#define     Status2Reg            0x08    
#define     FIFODataReg           0x09
#define     FIFOLevelReg          0x0A
#define     WaterLevelReg         0x0B
#define     ControlReg            0x0C
#define     BitFramingReg         0x0D
#define     CollReg               0x0E
#define     RFU0F                 0x0F
// PAGE 1     
#define     RFU10                 0x10
#define     ModeReg               0x11
#define     TxModeReg             0x12
#define     RxModeReg             0x13
#define     TxControlReg          0x14
#define     TxASKReg              0x15
#define     TxSelReg              0x16
#define     RxSelReg              0x17
#define     RxThresholdReg        0x18
#define     DemodReg              0x19
#define     RFU1A                 0x1A
#define     RFU1B                 0x1B
#define     MifareReg             0x1C
#define     RFU1D                 0x1D
#define     RFU1E                 0x1E
#define     SerialSpeedReg        0x1F
// PAGE 2    
#define     RFU20                 0x20  
#define     CRCResultRegM         0x21
#define     CRCResultRegL         0x22
#define     RFU23                 0x23
#define     ModWidthReg           0x24
#define     RFU25                 0x25
#define     RFCfgReg              0x26
#define     GsNReg                0x27
#define     CWGsCfgReg            0x28
#define     ModGsCfgReg           0x29
#define     TModeReg              0x2A
#define     TPrescalerReg         0x2B
#define     TReloadRegH           0x2C
#define     TReloadRegL           0x2D
#define     TCounterValueRegH     0x2E
#define     TCounterValueRegL     0x2F
// PAGE 3      
#define     RFU30                 0x30
#define     TestSel1Reg           0x31
#define     TestSel2Reg           0x32
#define     TestPinEnReg          0x33
#define     TestPinValueReg       0x34
#define     TestBusReg            0x35
#define     AutoTestReg           0x36
#define     VersionReg            0x37
#define     AnalogTestReg         0x38
#define     TestDAC1Reg           0x39  
#define     TestDAC2Reg           0x3A   
#define     TestADCReg            0x3B   
#define     RFU3C                 0x3C   
#define     RFU3D                 0x3D   
#define     RFU3E                 0x3E   
#define     RFU3F          0x3F

//******************************************************************/
//                    RC522通讯返回错误代码                         /
//******************************************************************/
#define MI_ERR                      0xFE 
//#define MI_ERR                         //(-2)


// Mifare Error Codes 
// Each function returns a status value, which corresponds to the 
// mifare error codes. 

#define MI_OK                          0 
#define MI_CHK_OK                      0 
#define MI_CRC_ZERO                    0 

#define MI_CRC_NOTZERO                 1 

#define MI_NOTAGERR                 0xFF 
#define MI_CHK_FAILED               0xFF 
#define MI_CRCERR                   0xFE 
#define MI_CHK_COMPERR              0xFE 
#define MI_EMPTY                    0xFD 
#define MI_AUTHERR                  0xFC 
#define MI_PARITYERR                0xFB 
#define MI_CODEERR                  0xFA 

#define MI_SERNRERR                 0xF8 
#define MI_KEYERR                   0xF7 
#define MI_NOTAUTHERR               0xF6 
#define MI_BITCOUNTERR              0xF5 
#define MI_BYTECOUNTERR             0xF4 
#define MI_IDLE                     0xF3 
#define MI_TRANSERR                 0xF2 
#define MI_WRITEERR                 0xF1 
#define MI_INCRERR                  0xF0 
#define MI_DECRERR                  0xEF 
#define MI_READERR                  0xEE 
#define MI_OVFLERR                  0xED 
#define MI_POLLING                  0xEC 
#define MI_FRAMINGERR               0xEB 
#define MI_ACCESSERR                0xEA 
#define MI_UNKNOWN_COMMAND          0xE9 
#define MI_COLLERR                  0xE8 
#define MI_RESETERR                 0xE7 
#define MI_INITERR                  0xE7 
#define MI_INTERFACEERR             0xE7 
#define MI_ACCESSTIMEOUT            0xE5 
#define MI_NOBITWISEANTICOLL        0xE4 
#define MI_QUIT                     0xE2 

#define MI_RECBUF_OVERFLOW          0xCF 
#define MI_SENDBYTENR               0xCE 

#define MI_SENDBUF_OVERFLOW         0xCC 
#define MI_BAUDRATE_NOT_SUPPORTED   0xCB 
#define MI_SAME_BAUDRATE_REQUIRED   0xCA 

#define MI_WRONG_PARAMETER_VALUE    0xC5 

#define MI_BREAK                    0x9E 
#define MI_NY_IMPLEMENTED           0x9D 
#define MI_NO_MFRC                  0x9C 
#define MI_MFRC_NOTAUTH             0x9B 
#define MI_WRONG_DES_MODE           0x9A 
#define MI_HOST_AUTH_FAILED         0x99 

#define MI_WRONG_LOAD_MODE          0x97 
#define MI_WRONG_DESKEY             0x96 
#define MI_MKLOAD_FAILED            0x95 
#define MI_FIFOERR                  0x94 
#define MI_WRONG_ADDR               0x93 
#define MI_DESKEYLOAD_FAILED        0x92 

#define MI_WRONG_SEL_CNT            0x8F 
#define MI_RC531_WRONG_READVALUE    0x8E //LI ADDED 09-4-24 
#define MI_WRONG_TEST_MODE          0x8C 
#define MI_TEST_FAILED              0x8B 
#define MI_TOC_ERROR                0x8A 
#define MI_COMM_ABORT               0x89 
#define MI_INVALID_BASE             0x88 
#define MI_MFRC_RESET               0x87 
#define MI_WRONG_VALUE              0x86 
#define MI_VALERR                   0x85
View Code

  spidev.h

/*spidev.h
 * include/linux/spi/spidev.h
 *
 * Copyright (C) 2006 SWAPP
 *    Andrea Paterniani <a.paterniani@swapp-eng.it>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */

#ifndef SPIDEV_H
#define SPIDEV_H

#include <linux/types.h>

/* User space versions of kernel symbols for SPI clocking modes,
 * matching <linux/spi/spi.h>
 */

#define SPI_CPHA        0x01
#define SPI_CPOL        0x02

#define SPI_MODE_0        (0|0)
#define SPI_MODE_1        (0|SPI_CPHA)
#define SPI_MODE_2        (SPI_CPOL|0)
#define SPI_MODE_3        (SPI_CPOL|SPI_CPHA)

#define SPI_CS_HIGH        0x04
#define SPI_LSB_FIRST        0x08
#define SPI_3WIRE        0x10
#define SPI_LOOP        0x20
#define SPI_NO_CS        0x40
#define SPI_READY        0x80

/*---------------------------------------------------------------------------*/

/* IOCTL commands */

#define SPI_IOC_MAGIC            'k'

/**
 * struct spi_ioc_transfer - describes a single SPI transfer
 * @tx_buf: Holds pointer to userspace buffer with transmit data, or null.
 *    If no data is provided, zeroes are shifted out.
 * @rx_buf: Holds pointer to userspace buffer for receive data, or null.
 * @len: Length of tx and rx buffers, in bytes.
 * @speed_hz: Temporary override of the device's bitrate.
 * @bits_per_word: Temporary override of the device's wordsize.
 * @delay_usecs: If nonzero, how long to delay after the last bit transfer
 *    before optionally deselecting the device before the next transfer.
 * @cs_change: True to deselect device before starting the next transfer.
 *
 * This structure is mapped directly to the kernel spi_transfer structure;
 * the fields have the same meanings, except of course that the pointers
 * are in a different address space (and may be of different sizes in some
 * cases, such as 32-bit i386 userspace over a 64-bit x86_64 kernel).
 * Zero-initialize the structure, including currently unused fields, to
 * accommodate potential future updates.
 *
 * SPI_IOC_MESSAGE gives userspace the equivalent of kernel spi_sync().
 * Pass it an array of related transfers, they'll execute together.
 * Each transfer may be half duplex (either direction) or full duplex.
 *
 *    struct spi_ioc_transfer mesg[4];
 *    ...
 *    status = ioctl(fd, SPI_IOC_MESSAGE(4), mesg);
 *
 * So for example one transfer might send a nine bit command (right aligned
 * in a 16-bit word), the next could read a block of 8-bit data before
 * terminating that command by temporarily deselecting the chip; the next
 * could send a different nine bit command (re-selecting the chip), and the
 * last transfer might write some register values.
 */
struct spi_ioc_transfer {
    __u64        tx_buf;
    __u64        rx_buf;

    __u32        len;
    __u32        speed_hz;

    __u16        delay_usecs;
    __u8        bits_per_word;
    __u8        cs_change;
    __u32        pad;

    /* If the contents of 'struct spi_ioc_transfer' ever change
     * incompatibly, then the ioctl number (currently 0) must change;
     * ioctls with constant size fields get a bit more in the way of
     * error checking than ones (like this) where that field varies.
     *
     * NOTE: struct layout is the same in 64bit and 32bit userspace.
     */
};

/* not all platforms use <asm-generic/ioctl.h> or _IOC_TYPECHECK() ... */
#define SPI_MSGSIZE(N) \
    ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \
        ? ((N)*(sizeof (struct spi_ioc_transfer))) : 0)
#define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)])


/* Read / Write of SPI mode (SPI_MODE_0..SPI_MODE_3) */
#define SPI_IOC_RD_MODE            _IOR(SPI_IOC_MAGIC, 1, __u8)
#define SPI_IOC_WR_MODE            _IOW(SPI_IOC_MAGIC, 1, __u8)

/* Read / Write SPI bit justification */
#define SPI_IOC_RD_LSB_FIRST        _IOR(SPI_IOC_MAGIC, 2, __u8)
#define SPI_IOC_WR_LSB_FIRST        _IOW(SPI_IOC_MAGIC, 2, __u8)

/* Read / Write SPI device word length (1..N) */
#define SPI_IOC_RD_BITS_PER_WORD    _IOR(SPI_IOC_MAGIC, 3, __u8)
#define SPI_IOC_WR_BITS_PER_WORD    _IOW(SPI_IOC_MAGIC, 3, __u8)

/* Read / Write SPI device default max speed hz */
#define SPI_IOC_RD_MAX_SPEED_HZ        _IOR(SPI_IOC_MAGIC, 4, __u32)
#define SPI_IOC_WR_MAX_SPEED_HZ        _IOW(SPI_IOC_MAGIC, 4, __u32)



#endif /* SPIDEV_H */
View Code

 

posted @ 2020-08-18 22:30  笑不出花的旦旦  阅读(948)  评论(0编辑  收藏  举报