si24r1.lua 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. --[[
  2. @module si24r1
  3. @summary si24r1 驱动
  4. @version 1.0
  5. @date 2022.06.17
  6. @author Dozingfiretruck
  7. @usage
  8. --注意:因使用了sys.wait()所有api需要在协程中使用
  9. -- 用法实例
  10. local si24r1 = require "si24r1"
  11. sys.taskInit(function()
  12. spi_si24r1 = spi.setup(0,nil,0,0,8,10*1000*1000,spi.MSB,1,1)
  13. si24r1.init(0,pin.PB04,pin.PB01,pin.PB00)
  14. if si24r1.chip_check() then
  15. si24r1.set()
  16. end
  17. --发送示例
  18. -- si24r1.set_mode( si24r1.MODE_TX ); --发送模式
  19. -- while 1 do
  20. -- sys.wait(1000)
  21. -- local a = si24r1.txpacket("si24r1test")
  22. -- print("a",a)
  23. -- end
  24. --接收示例
  25. si24r1.set_mode( si24r1.MODE_RX ); --接收模式
  26. while 1 do
  27. local i,data = si24r1.rxpacket( ); --接收字节
  28. print("rxbuf",i,data)
  29. end
  30. end)
  31. ]]
  32. local si24r1 = {}
  33. local sys = require "sys"
  34. local si24r1_device
  35. local si24r1_spi
  36. local si24r1_ce
  37. local si24r1_cs
  38. local si24r1_irq
  39. local si24r1_cspin,si24r1_cepin,si24r1_irqpin
  40. local LM75_ADDRESS_ADR = 0x48
  41. ---器件所用地址
  42. local REPEAT_CNT = 15 --重复次数
  43. local INIT_ADDR = string.char(0x34,0x43,0x10,0x10,0x01)
  44. si24r1.MODE_TX = 0
  45. si24r1.MODE_RX = 1
  46. local NRF_READ_REG = 0x00 --读配置寄存器,低5位为寄存器地址
  47. local NRF_WRITE_REG = 0x20 --写配置寄存器,低5位为寄存器地址
  48. local RD_RX_PLOAD = 0x61 --读RX有效数据,1~32字节
  49. local WR_TX_PLOAD = 0xA0 --写TX有效数据,1~32字节
  50. local FLUSH_TX = 0xE1 --清除TX FIFO寄存器,发射模式下使用
  51. local FLUSH_RX = 0xE2 --清除RX FIFO寄存器,接收模式下使用
  52. local REUSE_TX_PL = 0xE3 --重新使用上一包数据,CE为高,数据包被不断发送
  53. local R_RX_PL_WID = 0x60
  54. local NOP = 0xFF --空操作,可以用来读状态寄存器
  55. local W_ACK_PLOAD = 0xA8
  56. local WR_TX_PLOAD_NACK = 0xB0
  57. local CONFIG = 0x00 --配置寄存器地址,bit0:1接收模式,0发射模式;bit1:电选择;bit2:CRC模式;bit3:CRC使能;
  58. --bit4:中断MAX_RT(达到最大重发次数中断)使能;bit5:中断TX_DS使能;bit6:中断RX_DR使能
  59. local EN_AA = 0x01 --使能自动应答功能 bit0~5 对应通道0~5
  60. local EN_RXADDR = 0x02 --接收地址允许 bit0~5 对应通道0~5
  61. local SETUP_AW = 0x03 --设置地址宽度(所有数据通道) bit0~1: 00,3字节 01,4字节, 02,5字节
  62. local SETUP_RETR = 0x04 --建立自动重发;bit0~3:自动重发计数器;bit4~7:自动重发延时 250*x+86us
  63. local RF_CH = 0x05 --RF通道,bit0~6工作通道频率
  64. local RF_SETUP = 0x06 --RF寄存器,bit3:传输速率( 0:1M 1:2M);bit1~2:发射功率;bit0:噪声放大器增益
  65. local STATUS = 0x07 --状态寄存器;bit0:TX FIFO满标志;bit1~3:接收数据通道号(最大:6);bit4:达到最多次重发次数
  66. --bit5:数据发送完成中断;bit6:接收数据中断
  67. local MAX_TX = 0x10 --达到最大发送次数中断
  68. local TX_OK = 0x20 --TX发送完成中断
  69. local RX_OK = 0x40 --接收到数据中断
  70. local OBSERVE_TX = 0x08 --发送检测寄存器,bit7~4:数据包丢失计数器;bit3~0:重发计数器
  71. local CD = 0x09 --载波检测寄存器,bit0:载波检测
  72. local RX_ADDR_P0 = 0x0A --数据通道0接收地址,最大长度5个字节,低字节在前
  73. local RX_ADDR_P1 = 0x0B --数据通道1接收地址,最大长度5个字节,低字节在前
  74. local RX_ADDR_P2 = 0x0C --数据通道2接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等
  75. local RX_ADDR_P3 = 0x0D --数据通道3接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等
  76. local RX_ADDR_P4 = 0x0E --数据通道4接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等
  77. local RX_ADDR_P5 = 0x0F --数据通道5接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等
  78. local TX_ADDR = 0x10 --发送地址(低字节在前),ShockBurstTM模式下,RX_ADDR_P0与地址相等
  79. local RX_PW_P0 = 0x11 --接收数据通道0有效数据宽度(1~32字节),设置为0则非法
  80. local RX_PW_P1 = 0x12 --接收数据通道1有效数据宽度(1~32字节),设置为0则非法
  81. local RX_PW_P2 = 0x13 --接收数据通道2有效数据宽度(1~32字节),设置为0则非法
  82. local RX_PW_P3 = 0x14 --接收数据通道3有效数据宽度(1~32字节),设置为0则非法
  83. local RX_PW_P4 = 0x15 --接收数据通道4有效数据宽度(1~32字节),设置为0则非法
  84. local RX_PW_P5 = 0x16 --接收数据通道5有效数据宽度(1~32字节),设置为0则非法
  85. local NRF_FIFO_STATUS = 0x17 --FIFO状态寄存器;bit0:RX FIFO寄存器空标志;bit1:RX FIFO满标志;bit2~3保留
  86. --bit4:TX FIFO 空标志;bit5:TX FIFO满标志;bit6:1,循环发送上一数据包.0,不循环
  87. local DYNPD = 0x1C
  88. local FEATRUE = 0x1D
  89. local MASK_RX_DR = 6
  90. local MASK_TX_DS = 5
  91. local MASK_MAX_RT = 4
  92. local EN_CRC = 3
  93. local CRCO = 2
  94. local PWR_UP = 1
  95. local PRIM_RX = 0
  96. local ENAA_P5 = 5
  97. local ENAA_P4 = 4
  98. local ENAA_P3 = 3
  99. local ENAA_P2 = 2
  100. local ENAA_P1 = 1
  101. local ENAA_P0 = 0
  102. local ERX_P5 = 5
  103. local ERX_P4 = 4
  104. local ERX_P3 = 3
  105. local ERX_P2 = 2
  106. local ERX_P1 = 1
  107. local ERX_P0 = 0
  108. local AW_RERSERVED = 0x0
  109. local AW_3BYTES = 0x1
  110. local AW_4BYTES = 0x2
  111. local AW_5BYTES = 0x3
  112. local ARD_250US = (0x00<<4)
  113. local ARD_500US = (0x01<<4)
  114. local ARD_750US = (0x02<<4)
  115. local ARD_1000US = (0x03<<4)
  116. local ARD_2000US = (0x07<<4)
  117. local ARD_4000US = (0x0F<<4)
  118. local ARC_DISABLE = 0x00
  119. local ARC_15 = 0x0F
  120. local CONT_WAVE = 7
  121. local RF_DR_LOW = 5
  122. local PLL_LOCK = 4
  123. local RF_DR_HIGH = 3
  124. -- bit2-bit1:
  125. local PWR_18DB = (0x00<<1)
  126. local PWR_12DB = (0x01<<1)
  127. local PWR_6DB = (0x02<<1)
  128. local PWR_0DB = (0x03<<1)
  129. local RX_DR = 6
  130. local TX_DS = 5
  131. local MAX_RT = 4
  132. -- for bit3-bit1,
  133. local TX_FULL_0 = 0
  134. local RPD = 0
  135. local TX_REUSE = 6
  136. local TX_FULL_1 = 5
  137. local TX_EMPTY = 4
  138. -- bit3-bit2, reserved, only '00'
  139. local RX_FULL = 1
  140. local RX_EMPTY = 0
  141. local DPL_P5 = 5
  142. local DPL_P4 = 4
  143. local DPL_P3 = 3
  144. local DPL_P2 = 2
  145. local DPL_P1 = 1
  146. local DPL_P0 = 0
  147. local EN_DPL = 2
  148. local EN_ACK_PAY = 1
  149. local EN_DYN_ACK = 0
  150. local IRQ_ALL = ( (1<<RX_DR) | (1<<TX_DS) | (1<<MAX_RT) )
  151. local check_string = string.char(0X11, 0X22, 0X33, 0X44, 0X55)
  152. local function write_reg(address, value)
  153. si24r1_cs(0)
  154. if value then
  155. spi.send(si24r1_spi,string.char(NRF_WRITE_REG|address).. value)
  156. else
  157. spi.send(si24r1_spi,string.char(NRF_WRITE_REG|address))
  158. end
  159. si24r1_cs(1)
  160. end
  161. local function read_reg(address,len)
  162. si24r1_cs(0)
  163. spi.send(si24r1_spi, string.char(NRF_READ_REG|address))
  164. local val = spi.recv(si24r1_spi,len or 1)
  165. si24r1_cs(1)
  166. return val
  167. end
  168. --[[
  169. si24r1 器件检测
  170. @api si24r1.chip_check()
  171. @return bool 成功返回true
  172. @usage
  173. if si24r1.chip_check() then
  174. si24r1.set()
  175. end
  176. ]]
  177. function si24r1.chip_check()
  178. write_reg(TX_ADDR, check_string)
  179. local recv_string = read_reg(TX_ADDR,5)
  180. if recv_string == check_string then
  181. return true
  182. end
  183. log.info("si24r1","Can't find si24r1 device")
  184. return false
  185. end
  186. local function read_status_register()
  187. return read_reg(NRF_READ_REG + STATUS);
  188. end
  189. local function clear_iqr_flag(IRQ_Source)
  190. local btmp = 0;
  191. IRQ_Source = IRQ_Source & ( 1 << RX_DR ) | ( 1 << TX_DS ) | ( 1 << MAX_RT ); --中断标志处理
  192. btmp = read_status_register():byte(1); --读状态寄存器
  193. write_reg(NRF_WRITE_REG + STATUS)
  194. write_reg(IRQ_Source | btmp)
  195. return ( read_status_register():byte(1)) --返回状态寄存器状态
  196. end
  197. local function set_txaddr( pAddr )
  198. write_reg( TX_ADDR, pAddr) --写地址
  199. end
  200. local function set_rxaddr( PipeNum,pAddr )
  201. write_reg( RX_ADDR_P0 + PipeNum, pAddr) --写地址
  202. end
  203. --[[
  204. si24r1 设置模式
  205. @api si24r1.set_mode( Mode )
  206. @number Mode si24r1.MODE_TX si24r1.MODE_RX
  207. @usage
  208. si24r1.set_mode( si24r1.MODE_TX )
  209. ]]
  210. function si24r1.set_mode( Mode )
  211. local controlreg = 0;
  212. controlreg = read_reg( CONFIG ):byte(1);
  213. if ( Mode == si24r1.MODE_TX ) then
  214. controlreg =controlreg & ~( 1<< PRIM_RX );
  215. elseif ( Mode == si24r1.MODE_RX ) then
  216. controlreg = controlreg|( 1<< PRIM_RX );
  217. end
  218. write_reg( CONFIG, string.char(controlreg) );
  219. end
  220. --[[
  221. si24r1 发送
  222. @api si24r1.txpacket(buff)
  223. @string buff
  224. @return number 0x20:发送成功 0x10:达到最大发送次数中断 0xff:发送失败
  225. @usage
  226. local a = si24r1.txpacket("si24r1test")
  227. ]]
  228. function si24r1.txpacket(buff)
  229. local l_Status = 0
  230. local l_RxLength = 0
  231. local l_10MsTimes = 0
  232. spi.send(si24r1_spi,string.char(FLUSH_TX))
  233. si24r1_ce(0)
  234. write_reg(WR_TX_PLOAD, buff)
  235. si24r1_ce(1)
  236. while( 0 ~= si24r1_irq())do
  237. sys.wait(10)
  238. if( 50 == l_10MsTimes )then
  239. si24r1.init(si24r1_spi,si24r1_cspin,si24r1_cepin,si24r1_irqpin)
  240. si24r1.set()
  241. si24r1.set_mode( si24r1.MODE_TX )
  242. break;
  243. end
  244. l_10MsTimes = l_10MsTimes+1
  245. end
  246. l_Status = read_reg( STATUS ) --读状态寄存器
  247. write_reg( STATUS,l_Status ) --清中断标志
  248. if( l_Status:byte(1) & MAX_TX )~=0then --接收到数据
  249. write_reg( FLUSH_TX,string.char(0xff) ) --清除TX FIFO
  250. return MAX_TX
  251. end
  252. if( l_Status:byte(1) & TX_OK ~=0 )~=0then --接收到数据
  253. return TX_OK
  254. end
  255. return 0xFF
  256. end
  257. --[[
  258. si24r1 接收
  259. @api si24r1.rxpacket()
  260. @return number len,buff 长度 数据
  261. @usage
  262. local i,data = si24r1.rxpacket() --接收字节
  263. print("rxbuf",i,data)
  264. ]]
  265. function si24r1.rxpacket()
  266. local l_Status = 0
  267. local l_RxLength = 0
  268. local l_100MsTimes = 0
  269. spi.send(si24r1_spi,string.char(FLUSH_RX))
  270. while( 0 ~= si24r1_irq())do
  271. sys.wait( 100 )
  272. if( 30 == l_100MsTimes )then --3s没接收过数据,重新初始化模块
  273. si24r1.init(si24r1_spi,si24r1_cspin,si24r1_cepin,si24r1_irqpin)
  274. si24r1.set()
  275. si24r1.set_mode( si24r1.MODE_RX )
  276. break;
  277. end
  278. l_100MsTimes = l_100MsTimes+1
  279. end
  280. l_Status = read_reg( STATUS ) --读状态寄存器
  281. write_reg( STATUS,l_Status ) --清中断标志
  282. if( l_Status:byte(1) & RX_OK ~=0 )~=0then --接收到数据
  283. l_RxLength = read_reg( R_RX_PL_WID ) --读取接收到的数据个数
  284. local rxbuf = read_reg( RD_RX_PLOAD,l_RxLength:byte(1) ) --接收到数据
  285. write_reg( FLUSH_RX,string.char(0xff) ) --清除RX FIFO
  286. return l_RxLength:byte(1),rxbuf
  287. end
  288. return 0; --没有收到数据
  289. end
  290. --[[
  291. si24r1 配置参数
  292. @api si24r1.set()
  293. @usage
  294. si24r1.set()
  295. ]]
  296. function si24r1.set()
  297. si24r1_ce(1)
  298. clear_iqr_flag(IRQ_ALL)
  299. write_reg( DYNPD, string.char( 1 << 0 ) ) --使能通道1动态数据长度
  300. write_reg( FEATRUE, string.char(0x07) )
  301. write_reg( DYNPD )
  302. write_reg( FEATRUE )
  303. write_reg( CONFIG,string.char(( 1 << EN_CRC ) | ( 1 << PWR_UP )) )
  304. write_reg( EN_AA, string.char( 1 << ENAA_P0 ) ) --通道0自动应答
  305. write_reg( EN_RXADDR, string.char( 1 << ERX_P0 ) ) --通道0接收
  306. write_reg( SETUP_AW, string.char(AW_5BYTES) ) --地址宽度 5个字节
  307. write_reg( SETUP_RETR, string.char(ARD_4000US | ( REPEAT_CNT & 0x0F )) ) --重复等待时间 250us
  308. write_reg( RF_CH, string.char(60) ) --初始化通道
  309. write_reg( RF_SETUP, string.char(0x26) )
  310. set_txaddr( INIT_ADDR) --设置TX地址
  311. set_rxaddr( 0, INIT_ADDR) --设置RX地址
  312. end
  313. --[[
  314. si24r1 初始化
  315. @api si24r1.init(spi_id,cs,ce,irq)
  316. @number spi_id spi_id
  317. @return bool 成功返回true
  318. @usage
  319. lm75_data.init(0)
  320. ]]
  321. function si24r1.init(spi_id,cs,ce,irq)
  322. -- si24r1_device = spi_device
  323. si24r1_spi = spi_id
  324. si24r1_cspin = cs
  325. si24r1_cepin = ce
  326. si24r1_irqpin = irq
  327. si24r1_cs = gpio.setup(si24r1_cspin, 0, gpio.PULLUP)
  328. si24r1_cs(1)
  329. si24r1_irq= gpio.setup(si24r1_irqpin, nil,gpio.PULLUP)
  330. si24r1_ce= gpio.setup(si24r1_cepin, 0)
  331. si24r1_ce(0)
  332. end
  333. return si24r1