nrf24l01.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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 "nrf24l01.h"
  15. uint8_t __IDATA xbuf[NRF24_PLOAD_WIDTH + 1];
  16. uint8_t *xbuf_data = xbuf + 1;
  17. uint16_t NRF24L01_rxsn = 0;
  18. const uint8_t TX_ADDRESS[NRF24_ADDR_WIDTH] = {0x32,0x4E,0x6F,0x64,0x22};
  19. const uint8_t RX_ADDRESS[NRF24_ADDR_WIDTH] = {0x32,0x4E,0x6F,0x64,0x65};
  20. void NRF24L01_WriteReg(uint8_t reg, uint8_t value)
  21. {
  22. NRF_CSN = 0;
  23. xbuf[0] = reg;
  24. xbuf[1] = value;
  25. SPI_TxRxBytes(xbuf, 2);
  26. NRF_CSN = 1;
  27. }
  28. uint8_t NRF24L01_ReadReg(uint8_t reg)
  29. {
  30. NRF_CSN = 0;
  31. xbuf[0] = reg;
  32. xbuf[1] = NRF24_CMD_NOP;
  33. SPI_TxRxBytes(xbuf, 2);
  34. NRF_CSN = 1;
  35. return xbuf[1];
  36. }
  37. void NRF24L01_ReadToBuf(uint8_t reg, uint8_t len)
  38. {
  39. NRF_CSN = 0;
  40. memset(xbuf, NRF24_CMD_NOP, NRF24_PLOAD_WIDTH + 1);
  41. xbuf[0] = reg;
  42. SPI_TxRxBytes(xbuf, len + 1);
  43. NRF_CSN = 1;
  44. }
  45. void NRF24L01_WriteFromBuf(uint8_t reg, const uint8_t *pBuf, uint8_t len)
  46. {
  47. NRF_CSN = 0;
  48. xbuf[0] = reg;
  49. memcpy(xbuf_data, pBuf, len);
  50. SPI_TxRxBytes(xbuf, len + 1);
  51. NRF_CSN = 1;
  52. }
  53. void NRF24L01_PrintBuf(void)
  54. {
  55. uint8_t i;
  56. for (i = 0; i < NRF24_PLOAD_WIDTH + 1; i++)
  57. {
  58. UART1_TxHex(xbuf[i]);
  59. }
  60. UART1_TxString("\r\n");
  61. }
  62. /**
  63. * Flush the RX FIFO
  64. */
  65. void NRF24L01_FlushRX(void)
  66. {
  67. NRF24L01_WriteReg(NRF24_CMD_FLUSH_RX, NRF24_CMD_NOP);
  68. }
  69. /**
  70. * Flush the TX FIFO
  71. */
  72. void NRF24L01_FlushTX(void)
  73. {
  74. NRF24L01_WriteReg(NRF24_CMD_FLUSH_TX, NRF24_CMD_NOP);
  75. }
  76. void NRF24L01_CheckFlag(uint8_t *tx_ds, uint8_t *max_rt, uint8_t *rx_dr)
  77. {
  78. // Read the status & reset the status in one easy call
  79. NRF24L01_WriteReg(NRF24_CMD_W_REGISTER + NRF24_REG_STATUS, NRF24_FLAG_RX_DREADY|NRF24_FLAG_TX_DSENT|NRF24_FLAG_MAX_RT);
  80. // Report to the user what happened
  81. *tx_ds = xbuf[0] & NRF24_FLAG_TX_DSENT;
  82. *max_rt = xbuf[0] & NRF24_FLAG_MAX_RT;
  83. *rx_dr = xbuf[0] & NRF24_FLAG_RX_DREADY;
  84. }
  85. uint8_t NRF24L01_RxAvailable(uint8_t *pipe_num)
  86. {
  87. uint8_t pipe;
  88. NRF24L01_ReadReg(NRF24_REG_STATUS);
  89. pipe = (xbuf[0] >> 1) & 0x07;
  90. if (pipe > 5)
  91. return 0;
  92. // If the caller wants the pipe number, include that
  93. if (pipe_num)
  94. *pipe_num = pipe;
  95. return 1;
  96. }
  97. void NRF24L01_HandelIrqFlag(void)
  98. {
  99. uint8_t tx_ds, max_rt, rx_dr, pipe_num;
  100. NRF24L01_CheckFlag(&tx_ds, &max_rt, &rx_dr);
  101. if (NRF24L01_RxAvailable(&pipe_num) == 1)
  102. {
  103. NRF24L01_ReadToBuf(NRF24_CMD_R_RX_PAYLOAD, NRF24_PLOAD_WIDTH);
  104. NRF24L01_rxsn++;
  105. }
  106. UART1_TxHex(tx_ds);
  107. UART1_TxChar(' ');
  108. UART1_TxHex(max_rt);
  109. UART1_TxChar(' ');
  110. UART1_TxHex(rx_dr);
  111. UART1_TxChar(' ');
  112. UART1_TxHex(pipe_num);
  113. UART1_TxString("\r\n");
  114. NRF24L01_PrintBuf();
  115. }
  116. void NRF24L01_Tx(uint8_t *pBuf)
  117. {
  118. NRF_CE = 0;
  119. NRF24L01_WriteReg(NRF24_CMD_W_REGISTER + NRF24_REG_CONFIG, 0x0E);
  120. NRF24L01_WriteFromBuf(NRF24_CMD_W_TX_PAYLOAD, pBuf, NRF24_PLOAD_WIDTH);
  121. NRF_CE = 1;
  122. SYS_Delay(10); // for reliable DS state when SETUP_RETR is 0x13
  123. NRF_CE = 0;
  124. NRF24L01_WriteReg(NRF24_CMD_W_REGISTER + NRF24_REG_CONFIG, 0x0F);
  125. NRF_CE = 1;
  126. }
  127. void NRF24L01_StartFastWrite(const void* pBuf)
  128. {
  129. NRF24L01_WriteFromBuf(NRF24_CMD_W_TX_PAYLOAD, pBuf, NRF24_PLOAD_WIDTH);
  130. NRF_CE = 1;
  131. }
  132. uint8_t NRF24L01_WriteFast(const void* pBuf)
  133. {
  134. //Blocking only if FIFO is full. This will loop and block until TX is successful or fail
  135. while ((NRF24L01_ReadReg(NRF24_REG_STATUS) & NRF24_FLAG_TX_FULL)) {
  136. if (xbuf[0] & NRF24_FLAG_MAX_RT) {
  137. return 0;
  138. }
  139. }
  140. NRF24L01_StartFastWrite(pBuf);
  141. return 1;
  142. }
  143. void NRF24L01_ResetTX(void)
  144. {
  145. NRF24L01_WriteReg(NRF24_CMD_W_REGISTER + NRF24_REG_STATUS, NRF24_FLAG_MAX_RT);//Clear max retry flag
  146. NRF_CE = 0;
  147. NRF_CE = 1;
  148. }
  149. uint8_t NRF24L01_Check(void)
  150. {
  151. uint8_t i;
  152. const uint8_t *ptr = (const uint8_t *)NRF24_TEST_ADDR;
  153. NRF24L01_WriteFromBuf(NRF24_CMD_W_REGISTER | NRF24_REG_TX_ADDR, ptr, NRF24_ADDR_WIDTH);
  154. NRF24L01_ReadToBuf(NRF24_CMD_R_REGISTER | NRF24_REG_TX_ADDR, NRF24_ADDR_WIDTH);
  155. for (i = 0; i < NRF24_ADDR_WIDTH; i++) {
  156. UART1_TxHex(*(xbuf_data + i));
  157. if (*(xbuf_data + i) != *ptr++) return 1;
  158. }
  159. return 0;
  160. }
  161. void NRF24L01_Init(NRF24_MODE mode)
  162. {
  163. NRF_CE = 0;
  164. NRF24L01_WriteFromBuf(NRF24_CMD_W_REGISTER + NRF24_REG_TX_ADDR, (uint8_t *)TX_ADDRESS, NRF24_ADDR_WIDTH);
  165. NRF24L01_WriteReg(NRF24_CMD_W_REGISTER + NRF24_REG_RX_PW_P0, NRF24_PLOAD_WIDTH);
  166. NRF24L01_WriteFromBuf(NRF24_CMD_W_REGISTER + NRF24_REG_RX_ADDR_P0, (uint8_t *)TX_ADDRESS, NRF24_ADDR_WIDTH);
  167. NRF24L01_WriteReg(NRF24_CMD_W_REGISTER + NRF24_REG_RX_PW_P1, NRF24_PLOAD_WIDTH);
  168. NRF24L01_WriteFromBuf(NRF24_CMD_W_REGISTER + NRF24_REG_RX_ADDR_P1, (uint8_t *)RX_ADDRESS, NRF24_ADDR_WIDTH);
  169. NRF24L01_WriteReg(NRF24_CMD_W_REGISTER + NRF24_REG_EN_AA, 0x3f);
  170. NRF24L01_WriteReg(NRF24_CMD_W_REGISTER + NRF24_REG_EN_RXADDR, 0x3f);
  171. NRF24L01_WriteReg(NRF24_CMD_W_REGISTER + NRF24_REG_SETUP_RETR, 0x13);
  172. NRF24L01_WriteReg(NRF24_CMD_W_REGISTER + NRF24_REG_RF_CH, 40);
  173. NRF24L01_WriteReg(NRF24_CMD_W_REGISTER + NRF24_REG_RF_SETUP, 0x07);
  174. switch (mode)
  175. {
  176. case NRF24_MODE_TX:
  177. NRF24L01_WriteReg(NRF24_CMD_W_REGISTER + NRF24_REG_CONFIG, 0x0E);
  178. break;
  179. case NRF24_MODE_RX:
  180. default:
  181. NRF24L01_WriteReg(NRF24_CMD_W_REGISTER + NRF24_REG_CONFIG, 0x0F);
  182. break;
  183. }
  184. NRF_CE = 1;
  185. }