ci24r1.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. // Copyright 2021 IOsetting <iosetting(at)outlook.com>
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "ci24r1.h"
  15. __IDATA uint8_t cbuf[2], xbuf[CI24R1_PLOAD_MAX_WIDTH + 1];
  16. uint8_t *xbuf_data = xbuf + 1;
  17. void CI24R1_WriteByte(uint8_t value)
  18. {
  19. uint8_t i = 0;
  20. CI24R1_CLK_LOW();
  21. CI24R1_DATA_OUT();
  22. for (i = 0; i < 8; i++)
  23. {
  24. CI24R1_CLK_LOW();
  25. if (value & 0x80)
  26. {
  27. CI24R1_DATA_HIGH();
  28. }
  29. else
  30. {
  31. CI24R1_DATA_LOW();
  32. }
  33. CI24R1_CLK_HIGH();
  34. value = value << 1;
  35. }
  36. CI24R1_CLK_LOW();
  37. }
  38. uint8_t CI24R1_ReadByte(void)
  39. {
  40. uint8_t i = 0, RxData;
  41. CI24R1_DATA_IN();
  42. CI24R1_CLK_LOW();
  43. for (i = 0; i < 8; i++)
  44. {
  45. RxData = RxData << 1;
  46. CI24R1_CLK_HIGH();
  47. if (CI24R1_DATA_READ())
  48. {
  49. RxData |= 0x01;
  50. }
  51. else
  52. {
  53. RxData &= 0xfe;
  54. }
  55. CI24R1_CLK_LOW();
  56. }
  57. CI24R1_CLK_LOW();
  58. return RxData;
  59. }
  60. void CI24R1_WriteReg(uint8_t reg,uint8_t value)
  61. {
  62. CI24R1_NSS_LOW();
  63. CI24R1_WriteByte(reg);
  64. CI24R1_WriteByte(value);
  65. CI24R1_NSS_HIGH();
  66. }
  67. uint8_t CI24R1_ReadReg(uint8_t reg)
  68. {
  69. uint8_t reg_val;
  70. CI24R1_NSS_LOW();
  71. CI24R1_WriteByte(reg);
  72. reg_val = CI24R1_ReadByte();
  73. CI24R1_NSS_HIGH();
  74. return reg_val;
  75. }
  76. void CI24R1_WriteCmd(uint8_t cmd)
  77. {
  78. CI24R1_NSS_LOW();
  79. CI24R1_WriteByte(cmd);
  80. CI24R1_NSS_HIGH();
  81. }
  82. void CI24R1_WriteFromBuf(uint8_t reg, const uint8_t *pBuf, uint8_t len)
  83. {
  84. uint8_t ctr;
  85. CI24R1_NSS_LOW();
  86. CI24R1_WriteByte(reg);
  87. for (ctr = 0; ctr < len; ctr++)
  88. {
  89. CI24R1_WriteByte(*pBuf++);
  90. }
  91. CI24R1_NSS_HIGH();
  92. }
  93. void CI24R1_ReadToBuf(uint8_t reg, uint8_t *pBuf, uint8_t len)
  94. {
  95. uint8_t ctr;
  96. CI24R1_NSS_LOW();
  97. CI24R1_WriteByte(reg);
  98. for (ctr = 0; ctr < len; ctr++)
  99. {
  100. pBuf[ctr] = CI24R1_ReadByte();
  101. }
  102. CI24R1_NSS_HIGH();
  103. }
  104. void CI24R1_SetTxMode(void)
  105. {
  106. uint8_t value;
  107. value = CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_CONFIG);
  108. value &= 0xFE;
  109. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_CONFIG, value);
  110. }
  111. void CI24R1_SetRxMode(void)
  112. {
  113. uint8_t value;
  114. value = CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_CONFIG);
  115. value |= 0x01;
  116. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_CONFIG, value);
  117. }
  118. uint8_t CI24R1_SPI_Test(void)
  119. {
  120. uint8_t i, *ptr = (uint8_t *)CI24R1_TEST_ADDR;
  121. CI24R1_CE_LOW();
  122. CI24R1_WriteReg(CI24R1_CMD_SELSPI, CI24R1_CMD_NOP);
  123. CI24R1_WriteFromBuf(CI24R1_CMD_W_REGISTER | CI24R1_REG_TX_ADDR, ptr, 5);
  124. CI24R1_ReadToBuf(CI24R1_CMD_R_REGISTER | CI24R1_REG_TX_ADDR, xbuf, 5);
  125. for (i = 0; i < 5; i++) {
  126. UART1_TxHex(*(xbuf + i));
  127. if (*(xbuf + i) != *ptr++) return HAL_ERROR;
  128. }
  129. return HAL_OK;
  130. }
  131. void CI24R1_SetTxAddress(uint8_t *address)
  132. {
  133. CI24R1_WriteFromBuf(CI24R1_CMD_W_REGISTER | CI24R1_REG_TX_ADDR, address, 5);
  134. CI24R1_WriteFromBuf(CI24R1_CMD_W_REGISTER | CI24R1_REG_RX_ADDR_P0, address, 5);
  135. }
  136. void CI24R1_SetRxAddress(uint8_t *address)
  137. {
  138. CI24R1_WriteFromBuf(CI24R1_CMD_W_REGISTER | CI24R1_REG_RX_ADDR_P1, address, 5);
  139. }
  140. void CI24R1_SetChannel(uint8_t channel)
  141. {
  142. if (channel > 125) channel = 125;
  143. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_RF_CH, channel);
  144. }
  145. void CI24R1_Init(void)
  146. {
  147. CI24R1_CE_LOW();
  148. #if (CI24R1_PLOAD_WIDTH == 0)
  149. // Enable dynamic payload length on pipe 0 and pipe 1
  150. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_DYNPD, 0x03);
  151. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_FEATURE, 0x07);
  152. #else
  153. // Fixed payload length
  154. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_DYNPD, 0x00);
  155. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_FEATURE, 0x03);
  156. // Length of pipe 0
  157. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_RX_PW_P0, CI24R1_PLOAD_WIDTH);
  158. // Length of pipe 1
  159. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_RX_PW_P1, CI24R1_PLOAD_WIDTH);
  160. #endif
  161. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_CONFIG, 0x0E);
  162. // Enable auto ack all pipes
  163. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_EN_AA, 0x3F);
  164. // Enable all pipes
  165. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_EN_RXADDR, 0x3F);
  166. // Address width, 0x1:3bytes, 0x02:4bytes, 0x3:5bytes
  167. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_SETUP_AW, 0x03);
  168. // Resend 500us and 3 times. interval: 250us * ([0, 15] + 1), retries: [0, 15]
  169. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_SETUP_RETR, (0x01 << 4) | 0x03);
  170. // RF Data Rate 250K 11db
  171. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_RF_SETUP, CI24R1_RF_SETUP_1M | CI24R1_RF_SETUP_11DB);
  172. CI24R1_CE_HIGH();
  173. }
  174. uint8_t CI24R1_Tx(uint8_t *ucPayload, uint8_t length)
  175. {
  176. uint8_t status;
  177. #if (CI24R1_PLOAD_WIDTH == 0)
  178. CI24R1_WriteFromBuf(CI24R1_CMD_W_TX_PAYLOAD, ucPayload, length);
  179. #else
  180. CI24R1_WriteFromBuf(CI24R1_CMD_W_TX_PAYLOAD, ucPayload, CI24R1_PLOAD_WIDTH);
  181. #endif
  182. CI24R1_CE_HIGH();
  183. CI24R1_WriteCmd(CI24R1_CMD_SELIRQ);
  184. CI24R1_DATA_IN();
  185. while (CI24R1_DATA_READ());
  186. CI24R1_DATA_OUT();
  187. CI24R1_WriteCmd(CI24R1_CMD_SELSPI);
  188. status = CI24R1_ReadStatus();
  189. if (status & CI24R1_FLAG_MAX_RT)
  190. {
  191. CI24R1_WriteReg(CI24R1_CMD_FLUSH_TX, CI24R1_CMD_NOP);
  192. }
  193. // Clear status flags
  194. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_STATUS, status);
  195. return status;
  196. }
  197. uint8_t CI24R1_Rx(void)
  198. {
  199. uint8_t i, status, rxplWidth;
  200. CI24R1_WriteReg(CI24R1_CMD_FLUSH_RX, CI24R1_CMD_NOP);
  201. CI24R1_WriteReg(CI24R1_CMD_SELIRQ, CI24R1_CMD_NOP);
  202. CI24R1_DATA_IN();
  203. while(CI24R1_DATA_READ());
  204. CI24R1_DATA_OUT();
  205. CI24R1_WriteReg(CI24R1_CMD_SELSPI, CI24R1_CMD_NOP);
  206. status = CI24R1_ReadStatus();
  207. UART1_TxChar('>');
  208. UART1_TxHex(status);
  209. if (status & CI24R1_FLAG_RX_READY)
  210. {
  211. #if CI24R1_PLOAD_WIDTH == 0
  212. rxplWidth = CI24R1_ReadReg(CI24R1_CMD_R_RX_PL_WID);
  213. #else
  214. rxplWidth = CI24R1_PLOAD_WIDTH;
  215. #endif
  216. // Read RX to buffer
  217. CI24R1_ReadToBuf(CI24R1_CMD_R_RX_PAYLOAD, xbuf, rxplWidth);
  218. // Clear status flags
  219. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_STATUS, status);
  220. UART1_TxChar('>');
  221. for (i = 0; i < rxplWidth; i++)
  222. {
  223. UART1_TxHex(*(xbuf_data + i));
  224. }
  225. }
  226. return status;
  227. }
  228. uint8_t CI24R1_ReadStatus(void)
  229. {
  230. return CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_STATUS);
  231. }
  232. void CI24R1_Switch1F_AF(uint8_t af)
  233. {
  234. uint8_t val;
  235. val = CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_EN_AA);
  236. val &= 0x3F;
  237. val |= (af & 0x03) << 6;
  238. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_EN_AA, val);
  239. val = CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_EN_RXADDR);
  240. val &= 0x3F;
  241. val |= (af & 0x0C) << 4;
  242. CI24R1_WriteReg(CI24R1_CMD_W_REGISTER | CI24R1_REG_EN_RXADDR, val);
  243. }
  244. uint8_t CI24R1_PrintStatus(void)
  245. {
  246. uint8_t i, status;
  247. UART1_TxString("[Config]");
  248. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_CONFIG));
  249. UART1_TxString(" [EN_AA]");
  250. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_EN_AA));
  251. UART1_TxString(" [EN_RxAddr]");
  252. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_EN_RXADDR));
  253. UART1_TxString(" [AddrWidth]");
  254. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_SETUP_AW));
  255. UART1_TxString(" [Retry]");
  256. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_SETUP_RETR));
  257. UART1_TxString("\r\n[RF_Channel]");
  258. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RF_CH));
  259. UART1_TxString(" [RF_Setup]");
  260. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RF_SETUP));
  261. UART1_TxString(" [Observe_Tx]");
  262. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_OBSERVE_TX));
  263. UART1_TxString(" [RSSI]");
  264. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RSSI));
  265. UART1_TxString("\r\n[TxAddr] ");
  266. CI24R1_ReadToBuf(CI24R1_CMD_R_REGISTER | CI24R1_REG_TX_ADDR, xbuf_data, 5);
  267. for (i = 0; i < 5; i++) {
  268. UART1_TxHex(*(xbuf_data + i));
  269. }
  270. UART1_TxString("\r\n[RxAddrP0]");
  271. CI24R1_ReadToBuf(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_ADDR_P0, xbuf_data, 5);
  272. for (i = 0; i < 5; i++) {
  273. UART1_TxHex(*(xbuf_data + i));
  274. }
  275. UART1_TxString(" [RxAddrP1]");
  276. CI24R1_ReadToBuf(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_ADDR_P1, xbuf_data, 5);
  277. for (i = 0; i < 5; i++) {
  278. UART1_TxHex(*(xbuf_data + i));
  279. }
  280. UART1_TxString(" [RxAddrP2]");
  281. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_ADDR_P2));
  282. UART1_TxString(" [RxAddrP3]");
  283. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_ADDR_P3));
  284. UART1_TxString(" [RxAddrP4]");
  285. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_ADDR_P4));
  286. UART1_TxString(" [RxAddrP5]");
  287. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_ADDR_P5AF));
  288. UART1_TxString("\r\n[0F_CRC]");
  289. CI24R1_Switch1F_AF(CI24R1_EN_RXADDR_CRC);
  290. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_ADDR_P5AF));
  291. UART1_TxString(" [0F_OSC_C]");
  292. CI24R1_Switch1F_AF(CI24R1_EN_RXADDR_OSC_C);
  293. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_ADDR_P5AF));
  294. UART1_TxString(" [0F_BT]");
  295. CI24R1_Switch1F_AF(CI24R1_EN_RXADDR_BT);
  296. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_ADDR_P5AF));
  297. UART1_TxString(" [0F_BT_CRC_L/M/H]");
  298. CI24R1_Switch1F_AF(CI24R1_EN_RXADDR_BT_CRC_L);
  299. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_ADDR_P5AF));
  300. CI24R1_Switch1F_AF(CI24R1_EN_RXADDR_BT_CRC_M);
  301. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_ADDR_P5AF));
  302. CI24R1_Switch1F_AF(CI24R1_EN_RXADDR_BT_CRC_H);
  303. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_ADDR_P5AF));
  304. UART1_TxString("\r\n[RX_PW_P0]");
  305. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_PW_P0));
  306. UART1_TxString(" [RX_PW_P1]");
  307. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_PW_P1));
  308. UART1_TxString(" [RX_PW_P2]");
  309. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_PW_P2));
  310. UART1_TxString(" [RX_PW_P3]");
  311. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_PW_P3));
  312. UART1_TxString(" [RX_PW_P4]");
  313. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_PW_P4));
  314. UART1_TxString(" [RX_PW_P5]");
  315. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_RX_PW_P5));
  316. UART1_TxString("\r\n[FIFO_Status]");
  317. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_FIFO_STATUS));
  318. UART1_TxString(" [DynPloadWidth]");
  319. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_DYNPD));
  320. UART1_TxString(" [Feature]");
  321. UART1_TxHex(CI24R1_ReadReg(CI24R1_CMD_R_REGISTER | CI24R1_REG_FEATURE));
  322. status = CI24R1_ReadStatus();
  323. UART1_TxString("\r\n[Status]");
  324. UART1_TxHex(status);
  325. UART1_TxString("\r\n\r\n");
  326. return status;
  327. }