rc522.lua 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. --[[
  2. @module rc522
  3. @summary rc522 非接触式读写卡驱动
  4. @version 1.0
  5. @date 2022.06.14
  6. @author Dozingfiretruck
  7. @usage
  8. --注意:因使用了sys.wait()所有api需要在task中使用
  9. -- 用法实例
  10. local rc522 = require "rc522"
  11. local function rc522_test()
  12. spi_rc522 = spi.setup(0,nil,0,0,8,10*1000*1000,spi.MSB, spi.master,spi.half)
  13. rc522.init(0,12,16)
  14. wdata = {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
  15. while 1 do
  16. rc522.write_datablock(8,wdata)
  17. for i=0,63 do
  18. local a,b = rc522.read_datablock(i)
  19. if a then
  20. log.info("read",i,b:toHex())
  21. end
  22. end
  23. sys.wait(500)
  24. end
  25. end)
  26. sys.taskInit(rc522_test)
  27. ]]
  28. local rc522 = {}
  29. local rc522_spi, rc522_rst, rc522_irq, rc522_cs
  30. ---器件所用地址
  31. local rc522_idle = 0x00 --取消当前命令
  32. local rc522_authent = 0x0E --验证密钥
  33. local rc522_receive = 0x08 --接收数据
  34. local rc522_transmit = 0x04 --发送数据
  35. local rc522_transceive = 0x0C --发送并接收数据
  36. local rc522_resetphase = 0x0F --复位
  37. local rc522_calccrc = 0x03 --CRC计算
  38. --Mifare_One卡片命令字
  39. rc522.reqidl = 0x26 --寻天线区内未进入休眠状态
  40. rc522.reqall = 0x52 --寻天线区内全部卡
  41. local rc522_anticoll1 = 0x93 --防冲撞
  42. local rc522_anticoll2 = 0x95 --防冲撞
  43. local rc522_authent1a = 0x60 --验证A密钥
  44. local rc522_authent1b = 0x61 --验证B密钥
  45. local rc522_read = 0x30 --读块
  46. local rc522_write = 0xA0 --写块
  47. local rc522_decrement = 0xC0 --扣款
  48. local rc522_increment = 0xC1 --充值
  49. local rc522_restore = 0xC2 --调块数据到缓冲区
  50. local rc522_transfer = 0xB0 --保存缓冲区中数据
  51. local rc522_halt = 0x50 --休眠
  52. --MF522寄存器定义
  53. -- PAGE 0
  54. local rc522_rfu00 = 0x00 --保留为将来之用
  55. local rc522_com_mand = 0x01 --启动和停止命令的执行
  56. local rc522_com_ie = 0x02 --中断请求传递的使能和禁能控制位
  57. local rc522_divl_en = 0x03 --中断请求传递的使能和禁能控制位
  58. local rc522_com_irq = 0x04 --包含中断请求标志
  59. local rc522_div_irq = 0x05 --包含中断请求标志
  60. local rc522_error = 0x06 --错误标志,指示执行的上个命令的错误状态
  61. local rc522_status1 = 0x07 --包含通信的状态标志
  62. local rc522_status2 = 0x08 --包含接收器和发送器的状态标志
  63. local rc522_fifo_data = 0x09 --64 字节 FIFO 缓冲区的输入和输出
  64. local rc522_fifo_level = 0x0A --指示 FIFO 中存储的字节数
  65. local rc522_water_level = 0x0B --定义 FIFO 下溢和上溢报警的 FIFO 深度
  66. local rc522_control = 0x0C --不同的控制寄存器
  67. local rc522_bit_framing = 0x0D --面向位的帧的调节
  68. local rc522_coll = 0x0E --RF 接口上检测到的第一个位冲突的位的位置
  69. local rc522_rfu0f = 0x0F --保留为将来之用
  70. -- PAGE 1
  71. local RFU10 = 0x10 --保留为将来之用
  72. local rc522_mode = 0x11 --定义发送和接收的常用模式
  73. local rc522_tx_mode = 0x12 --定义发送过程的数据传输速率
  74. local rc522_rx_mode = 0x13 --定义接收过程中的数据传输速率
  75. local rc522_tx_control = 0x14 --控制天线驱动器管脚 TX1 和 TX2 的逻辑特性
  76. local rc522_tx_ayto = 0x15 --控制天线驱动器的设置
  77. local rc522_tx_sel = 0x16 --选择天线驱动器的内部源
  78. local rc522_rx_sel = 0x17 --选择内部的接收器设置
  79. local rc522_rx_threshold = 0x18 --选择位译码器的阈值
  80. local rc522_demod = 0x19 --定义解调器的设置
  81. local rc522_rfu1a = 0x1A --保留为将来之用
  82. local rc522_rfu1b = 0x1B --保留为将来之用
  83. local rc522_mifare = 0x1C --控制 ISO 14443/MIFARE 模式中 106kbit/s 的通信
  84. local rc522_rfu1d = 0x1D --保留为将来之用
  85. local rc522_rfu1e = 0x1E --保留为将来之用
  86. local rc522_serial_speed = 0x1F --选择串行 UART 接口的速率
  87. -- PAGE 2
  88. local rc522_rfu20 = 0x20 --保留为将来之用
  89. local rc522_crcresult_m = 0x21 --显示 CRC 计算的实际 MSB 值
  90. local rc522_crcresult_l = 0x22 --显示 CRC 计算的实际 LSB 值
  91. local rc522_rfu23 = 0x23 --保留为将来之用
  92. local rc522_mod_width = 0x24 --控制 ModWidth 的设置
  93. local rc522_rfu25 = 0x25 --保留为将来之用
  94. local rc522_rfcfg = 0x26 --配置接收器增益
  95. local rc522_gsn = 0x27 --选择天线驱动器管脚 TX1 和 TX2 的调制电导
  96. local rc522_cwgscfg = 0x28 --选择天线驱动器管脚 TX1 和 TX2 的调制电导
  97. local rc522_modgscfg = 0x29 --选择天线驱动器管脚 TX1 和 TX2 的调制电导
  98. local rc522_tmode = 0x2A --定义内部定时器的设置
  99. local rc522_tprescaler = 0x2B --定义内部定时器的设置
  100. local rc522_tpreload_h = 0x2C --描述 16 位长的定时器重装值
  101. local rc522_tpreload_l = 0x2D --描述 16 位长的定时器重装值
  102. local rc522_tcounter_value_h = 0x2E --描述 16 位长的定时器重装值
  103. local rc522_tcounter_value_l = 0x2F --描述 16 位长的定时器重装值
  104. -- PAGE 3
  105. local rc522_rfu30 = 0x30 --保留为将来之用
  106. local rc522_testsel1 = 0x31 --常用测试信号的配置
  107. local rc522_testsel2 = 0x32 --常用测试信号的配置和 PRBS 控制
  108. local rc522_testpin_en = 0x33 --D1-D7 输出驱动器的使能管脚(注:仅用于串行接口)
  109. local rc522_testpin_value = 0x34 --定义 D1-D7 用作 I/O 总线时的值
  110. local rc522_testbus = 0x35 --显示内部测试总线的状态
  111. local rc522_autotest = 0x36 --控制数字自测试
  112. local rc522_version = 0x37 --显示版本
  113. local rc522_analogtest = 0x38 --控制管脚 AUX1 和 AUX2
  114. local rc522_testadc1 = 0x39 --定义 TestDAC1 的测试值
  115. local rc522_testadc2 = 0x3A --定义 TestDAC2 的测试值
  116. local rc522_testadc = 0x3B --显示 ADC I 和 Q 通道的实际值
  117. local rc522_rfu3c = 0x3C --保留用于产品测试
  118. local rc522_rfu3d = 0x3D --保留用于产品测试
  119. local rc522_rfu3e = 0x3E --保留用于产品测试
  120. local rc522_rfu3f = 0x3F --保留用于产品测试
  121. local Key_A = string.char(0xff, 0xff, 0xff, 0xff, 0xff, 0xff)
  122. local Key_B = string.char(0xff, 0xff, 0xff, 0xff, 0xff, 0xff)
  123. --[[
  124. 写rc522寄存器
  125. @api rc522.set_bit_mask(address, value)
  126. @number address 地址
  127. @number value 值
  128. @usage
  129. write_rawrc(rc522_bit_framing,0x07)
  130. ]]
  131. local function write_rawrc(address, value)
  132. rc522_cs(0)
  133. local data = string.char((address << 1) & 0x7E) .. string.char(value)
  134. spi.send(rc522_spi, data)
  135. -- rc522_spi:send(data)
  136. rc522_cs(1)
  137. end
  138. --[[
  139. 读rc522寄存器
  140. @api rc522.read_rawrc(address)
  141. @number address 地址
  142. @return number 寄存器值
  143. @usage
  144. local n = read_rawrc(rc522_com_irq)
  145. ]]
  146. local function read_rawrc(address)
  147. rc522_cs(0)
  148. local data = string.char(((address << 1) & 0x7E)|0x80)
  149. spi.send(rc522_spi, data)
  150. local val = spi.recv(rc522_spi, 1)
  151. -- rc522_spi:send(data)
  152. -- local val = rc522_spi:recv(1)
  153. rc522_cs(1)
  154. return string.byte(val)
  155. end
  156. --[[
  157. 对rc522寄存器置位
  158. @api rc522.set_bit_mask(address, mask)
  159. @number address 地址
  160. @number mask 置位值
  161. @usage
  162. rc522.set_bit_mask (rc522_fifo_level, 0x80)
  163. ]]
  164. function rc522.set_bit_mask(address, mask)
  165. local current = read_rawrc(address)
  166. write_rawrc(address, bit.bor(current, mask))
  167. end
  168. --[[
  169. 对rc522寄存器清位
  170. @api rc522.clear_bit_mask(address, mask)
  171. @number address 地址
  172. @number mask 清位值
  173. @usage
  174. rc522.clear_bit_mask(rc522_com_irq, 0x80 )
  175. ]]
  176. function rc522.clear_bit_mask(address, mask)
  177. local current = read_rawrc(address)
  178. write_rawrc(address, bit.band(current, bit.bnot(mask)))
  179. end
  180. --[[
  181. 命令通讯
  182. @api rc522.command(command,data)
  183. @number command
  184. @number data
  185. @return status data len 结果,返回数据,收到的位长度
  186. @usage
  187. rc522.version()
  188. ]]
  189. function rc522.command(command, data)
  190. local out_data = {}
  191. local len = 0
  192. local status = false
  193. local Irq_en = 0x00
  194. local waitfor = 0x00
  195. local last_bits, n, l
  196. if command == rc522_authent then
  197. Irq_en = 0x12
  198. waitfor = 0x10
  199. elseif command == rc522_transceive then
  200. Irq_en = 0x77
  201. waitfor = 0x30
  202. end
  203. write_rawrc(0x02, bit.bor(Irq_en, 0x80))
  204. rc522.clear_bit_mask(rc522_com_irq, 0x80)
  205. write_rawrc(rc522_com_mand, rc522_idle)
  206. rc522.set_bit_mask(rc522_fifo_level, 0x80)
  207. for i = 1, #data do
  208. write_rawrc(rc522_fifo_data, data[i])
  209. end
  210. write_rawrc(rc522_com_mand, command)
  211. if (command == rc522_transceive) then
  212. rc522.set_bit_mask(rc522_bit_framing, 0x80)
  213. end
  214. l = 12
  215. while true do
  216. sys.wait(1)
  217. n = read_rawrc(rc522_com_irq)
  218. l = l - 1
  219. if not ((l ~= 0) and (bit.band(n, 0x01) == 0) and (bit.band(n, waitfor) == 0)) then
  220. break
  221. end
  222. end
  223. rc522.clear_bit_mask(rc522_bit_framing, 0x80)
  224. if (l ~= 0) then
  225. if bit.band(read_rawrc(rc522_error), 0x1B) == 0x00 then
  226. status = true
  227. if bit.band(n, Irq_en, 0x01) ~= 0 then
  228. status = false
  229. end
  230. if (command == rc522_transceive) then
  231. n = read_rawrc(rc522_fifo_level)
  232. last_bits = bit.band(read_rawrc(rc522_control), 0x07)
  233. if last_bits ~= 0 then
  234. len = (n - 1) * 8 + last_bits
  235. else
  236. len = n * 8
  237. end
  238. if n == 0 then
  239. n = 1
  240. end
  241. for i = 1, n do
  242. out_data[i] = read_rawrc(rc522_fifo_data)
  243. end
  244. end
  245. end
  246. else
  247. status = false
  248. end
  249. rc522.set_bit_mask(rc522_control, 0x80)
  250. write_rawrc(rc522_com_mand, rc522_idle)
  251. return status, out_data, len
  252. end
  253. --[[
  254. 防冲撞
  255. @api rc522.anticoll(id)
  256. @string id 卡片序列号,4字节
  257. @return status uid 结果,uid
  258. @usage
  259. local status,uid = rc522.anticoll(array_id)
  260. ]]
  261. function rc522.anticoll(id)
  262. local check = 0
  263. local uid
  264. rc522.clear_bit_mask(rc522_status2, 0x08)
  265. write_rawrc(rc522_bit_framing, 0x00)
  266. rc522.clear_bit_mask(rc522_coll, 0x80)
  267. local status, back_data = rc522.command(rc522_transceive, { 0x93, 0x20 })
  268. if back_data and #back_data >= 5 then
  269. for i = 1, 4 do
  270. check = bit.bxor(check, back_data[i])
  271. end
  272. if check ~= back_data[5] then
  273. status = false
  274. end
  275. uid = string.char(table.unpack(back_data, 1, 4))
  276. end
  277. rc522.clear_bit_mask(rc522_coll, 0x80)
  278. return status, uid
  279. end
  280. --[[
  281. crc计算
  282. @api calculate_crc(data)
  283. @table data 数据
  284. @return table crc值
  285. @usage
  286. local crc = calculate_crc(buff)
  287. ]]
  288. local function calculate_crc(data)
  289. local ret_data = {}
  290. rc522.clear_bit_mask(rc522_div_irq, 0x04)
  291. write_rawrc(rc522_com_mand, rc522_idle)
  292. rc522.set_bit_mask(rc522_fifo_level, 0x80)
  293. for i = 1, #data do
  294. write_rawrc(rc522_fifo_data, data[i])
  295. end
  296. write_rawrc(rc522_com_mand, rc522_calccrc)
  297. local i = 0xFF
  298. while true do
  299. local n = read_rawrc(0x05)
  300. i = i - 1
  301. if not ((i ~= 0) and not (n & 0x04)) then
  302. break
  303. end
  304. end
  305. ret_data[1] = read_rawrc(0x22)
  306. ret_data[2] = read_rawrc(0x21)
  307. return ret_data
  308. end
  309. --[[
  310. 验证卡片密码
  311. @api authstate(mode, addr,key,uid )
  312. @number mode 模式
  313. @number addr 地址
  314. @string key 密码
  315. @string uid uid
  316. @return bool 结果
  317. @usage
  318. status = authstate(rc522_authent1b, addr,Key_B,uid )
  319. ]]
  320. local function authstate(mode, addr, key, uid)
  321. local buff = {}
  322. buff[1] = mode
  323. buff[2] = addr
  324. for i = 1, 6 do
  325. buff[i + 2] = key:byte(i)
  326. end
  327. for i = 1, 4 do
  328. buff[i + 8] = uid:byte(i)
  329. end
  330. local status, back_data = rc522.command(rc522_authent, buff)
  331. if status == true and (read_rawrc(rc522_status2) & 0x08) ~= 0 then
  332. return true
  333. end
  334. return false
  335. end
  336. --[[
  337. 写数据到M1卡一块
  338. @api rc522.write(addr, data)
  339. @number addr 块地址(0-63)M1卡总共有16个扇区(每个扇区有:3个数据块+1个控制块),共64个块
  340. @table data 数据
  341. @return bool 结果
  342. @usage
  343. rc522.write(addr, data)
  344. ]]
  345. function rc522.write(addr, data)
  346. local buff = {}
  347. buff[1] = rc522_write
  348. buff[2] = addr
  349. local crc = calculate_crc(buff)
  350. buff[3] = crc[1]
  351. buff[4] = crc[2]
  352. local status, back_data, back_bits = rc522.command(rc522_transceive, buff)
  353. if status == true and back_bits == 4 and (back_data[1] & 0x0F) == 0x0A then
  354. local buf_w = {}
  355. for i = 0, 16 do
  356. table.insert(buf_w, data[i])
  357. end
  358. local crc = calculate_crc(buf_w)
  359. table.insert(buf_w, crc[1])
  360. table.insert(buf_w, crc[2])
  361. status, back_data, back_bits = rc522.command(rc522_transceive, buf_w)
  362. if status == true and back_bits == 4 and (back_data[1] & 0x0F) == 0x0A then
  363. return status
  364. end
  365. end
  366. return status
  367. end
  368. --[[
  369. 写数据到M1卡一块
  370. @api rc522.read(addr)
  371. @number addr 块地址(0-63)M1卡总共有16个扇区(每个扇区有:3个数据块+1个控制块),共64个块
  372. @return bool,string 结果,数据
  373. @usage
  374. rc522.read(addr, data)
  375. ]]
  376. local function read(addr)
  377. local buff = {}
  378. buff[1] = rc522_read
  379. buff[2] = addr
  380. local crc = calculate_crc(buff)
  381. buff[3] = crc[1]
  382. buff[4] = crc[2]
  383. local status, back_data, back_bits = rc522.command(rc522_transceive, buff)
  384. if status == true and back_bits == 0x90 then
  385. local data = string.char(table.unpack(back_data, 1, 16))
  386. return status, data
  387. end
  388. return false
  389. end
  390. --[[
  391. rc522 硬件版本
  392. @api rc522.version()
  393. @return number 硬件版本
  394. @usage
  395. rc522.version()
  396. ]]
  397. function rc522.version()
  398. return read_rawrc(rc522_version)
  399. end
  400. --[[
  401. rc522 命令卡片进入休眠状态
  402. @api rc522.halt()
  403. @return bool 结果
  404. @usage
  405. rc522.halt()
  406. ]]
  407. function rc522.halt()
  408. local buff = {}
  409. buff[1] = rc522_halt
  410. buff[2] = 0
  411. local crc = calculate_crc(buff)
  412. buff[3] = crc[1]
  413. buff[4] = crc[2]
  414. local status = rc522.command(rc522_transceive, buff)
  415. return status
  416. end
  417. --[[
  418. rc522 复位
  419. @api rc522.reset()
  420. @usage
  421. rc522.reset()
  422. ]]
  423. function rc522.reset()
  424. rc522_rst(1)
  425. rc522_rst(0)
  426. rc522_rst(1)
  427. write_rawrc(rc522_com_mand, 0x0f)
  428. write_rawrc(rc522_mode, 0x3D)
  429. write_rawrc(rc522_tpreload_l, 30)
  430. write_rawrc(rc522_tpreload_h, 0)
  431. write_rawrc(rc522_tmode, 0x8D)
  432. write_rawrc(rc522_tprescaler, 0x3E)
  433. write_rawrc(rc522_tx_ayto, 0x40)
  434. end
  435. --[[
  436. 开启天线
  437. @api rc522.antenna_on()
  438. @usage
  439. rc522.antenna_on()
  440. ]]
  441. function rc522.antenna_on()
  442. local uc = read_rawrc(rc522_tx_control)
  443. if ((uc & 0x03) == 0) then
  444. rc522.set_bit_mask(rc522_tx_control, 0x03)
  445. end
  446. end
  447. --[[
  448. 关闭天线
  449. @api rc522.antenna_on()
  450. @usage
  451. rc522.antenna_on()
  452. ]]
  453. function rc522.antenna_off()
  454. rc522.clear_bit_mask(rc522_tx_control, 0x03)
  455. end
  456. --[[
  457. 设置rc522工作方式为ISO14443_A
  458. @api rc522_config_isotype()
  459. @usage
  460. rc522_config_isotype()
  461. ]]
  462. local function rc522_config_isotype()
  463. rc522.clear_bit_mask(rc522_status2, 0x08)
  464. write_rawrc(rc522_mode, 0x3D)
  465. write_rawrc(rc522_rx_sel, 0x86)
  466. write_rawrc(rc522_rfcfg, 0x7F)
  467. write_rawrc(rc522_tpreload_l, 30)
  468. write_rawrc(rc522_tpreload_h, 0)
  469. write_rawrc(rc522_tmode, 0x8D)
  470. write_rawrc(rc522_tprescaler, 0x3E)
  471. rc522.antenna_on()
  472. end
  473. --[[
  474. rc522 寻卡
  475. @api rc522.request(req_code)
  476. @number req_code rc522.reqidl 寻天线区内未进入休眠状态 rc522.reqall 寻天线区内全部卡
  477. @return bool tagtype 结果,卡类型
  478. @usage
  479. status,array_id = rc522.request(rc522.reqall)
  480. ]]
  481. function rc522.request(req_code)
  482. rc522.clear_bit_mask(rc522_status2, 0x08)
  483. write_rawrc(rc522_bit_framing, 0x07)
  484. rc522.set_bit_mask(rc522_tx_control, 0x03)
  485. local tagtype
  486. local status, back_data, back_bits = rc522.command(rc522_transceive, { req_code })
  487. if status == true and back_bits == 0x10 then
  488. tagtype = string.char(table.unpack(back_data, 1, 2))
  489. return status, tagtype
  490. end
  491. return false
  492. end
  493. --[[
  494. 选定卡片
  495. @api rc522.select(id)
  496. @number id 卡片序列号,4字节
  497. @return bool 结果
  498. @usage
  499. status = rc522.select(id)
  500. ]]
  501. function rc522.select(id)
  502. if not id then
  503. return false
  504. end
  505. local buff = {}
  506. buff[1] = rc522_anticoll1
  507. buff[2] = 0x70
  508. buff[7] = 0
  509. for i = 1, 4 do
  510. buff[i + 2] = id:byte(i)
  511. buff[7] = bit.bxor(buff[7], id:byte(i))
  512. end
  513. local crc = calculate_crc(buff)
  514. buff[8] = crc[1]
  515. buff[9] = crc[2]
  516. rc522.clear_bit_mask(rc522_status2, 0x08)
  517. local status, back_data, back_bits = rc522.command(rc522_transceive, buff)
  518. if status == true and back_bits == 0x18 then
  519. return true
  520. end
  521. return false
  522. end
  523. --[[
  524. 按照rc522操作流程写入16字节数据到块
  525. @api rc522.write_datablock(addr,data)
  526. @number addr 任意块地址.M1卡总共有16个扇区(每个扇区有:3个数据块+1个控制块),共64个块
  527. @table data 指向要写入的数据,必须为16个字符
  528. @return bool 结果
  529. @usage
  530. rc522.write_datablock(addr,data)
  531. ]]
  532. function rc522.write_datablock(addr, data)
  533. if #data ~= 16 then
  534. return false
  535. end
  536. local status, array_id = rc522.request(rc522.reqall)
  537. if status ~= true then
  538. status, array_id = rc522.request(rc522.reqall)
  539. end
  540. if status == true then
  541. local status, uid = rc522.anticoll(array_id)
  542. if not uid then
  543. return false
  544. end
  545. if status == true and uid then
  546. rc522.select(uid)
  547. status = authstate(rc522_authent1b, addr, Key_B, uid)
  548. if status == true then
  549. status = rc522.write(addr, data)
  550. rc522.halt()
  551. return status
  552. end
  553. end
  554. end
  555. return false
  556. end
  557. --[[
  558. 按照rc522操作流程读取块
  559. @api rc522.read_datablock(addr)
  560. @number addr 任意块地址.M1卡总共有16个扇区(每个扇区有:3个数据块+1个控制块),共64个块
  561. @return bool string 结果 数据
  562. @usage
  563. for i=0,63 do
  564. local a,b = rc522.read_datablock(i)
  565. if a then
  566. print("read",i,b:toHex())
  567. end
  568. end
  569. ]]
  570. function rc522.read_datablock(addr)
  571. local status, array_id = rc522.request(rc522.reqall)
  572. if status ~= true then
  573. status, array_id = rc522.request(rc522.reqall)
  574. end
  575. if status == true then
  576. local status, uid = rc522.anticoll(array_id)
  577. if status == true and uid then
  578. rc522.select(uid)
  579. status = authstate(rc522_authent1b, addr, Key_B, uid)
  580. if status == true then
  581. local status, data = read(addr)
  582. if status == true then
  583. return true, data
  584. end
  585. rc522.halt()
  586. end
  587. end
  588. end
  589. return false
  590. end
  591. --[[
  592. rc522 初始化
  593. @api rc522.init(spi_id, cs, rst)
  594. @number spi_id spi端口号
  595. @number cs cs引脚
  596. @number rst rst引脚
  597. @return bool 初始化结果
  598. @usage
  599. spi_rc522 = spi.setup(0,nil,0,0,8,10*1000*1000,spi.MSB,1,1)
  600. rc522.init(0,pin.PB04,pin.PB01)
  601. ]]
  602. function rc522.init(spi_id, cs, rst)
  603. rc522_spi = spi_id
  604. rc522_cs = gpio.setup(cs, 0, gpio.PULLUP)
  605. rc522_cs(1)
  606. rc522_rst = gpio.setup(rst, 0, gpio.PULLUP)
  607. rc522_rst(1)
  608. rc522.reset()
  609. rc522_config_isotype()
  610. log.debug("rc522.version", rc522.version())
  611. return true
  612. end
  613. function rc522.test()
  614. end
  615. return rc522