PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

339 lines
9.3KB

  1. // NRF24.cpp
  2. //
  3. // Copyright (C) 2012 Mike McCauley
  4. // $Id: RH_NRF24.cpp,v 1.22 2016/04/04 01:40:12 mikem Exp $
  5. #include <RH_NRF24.h>
  6. RH_NRF24::RH_NRF24(uint8_t chipEnablePin, uint8_t slaveSelectPin, RHGenericSPI& spi)
  7. :
  8. RHNRFSPIDriver(slaveSelectPin, spi),
  9. _rxBufValid(0)
  10. {
  11. _configuration = RH_NRF24_EN_CRC | RH_NRF24_CRCO; // Default: 2 byte CRC enabled
  12. _chipEnablePin = chipEnablePin;
  13. }
  14. bool RH_NRF24::init()
  15. {
  16. // Teensy with nRF24 is unreliable at 8MHz:
  17. // so is Arduino with RF73
  18. _spi.setFrequency(RHGenericSPI::Frequency1MHz);
  19. if (!RHNRFSPIDriver::init())
  20. return false;
  21. // Initialise the slave select pin
  22. pinMode(_chipEnablePin, OUTPUT);
  23. digitalWrite(_chipEnablePin, LOW);
  24. // Clear interrupts
  25. spiWriteRegister(RH_NRF24_REG_07_STATUS, RH_NRF24_RX_DR | RH_NRF24_TX_DS | RH_NRF24_MAX_RT);
  26. // Enable dynamic payload length on all pipes
  27. spiWriteRegister(RH_NRF24_REG_1C_DYNPD, RH_NRF24_DPL_ALL);
  28. // Enable dynamic payload length, disable payload-with-ack, enable noack
  29. spiWriteRegister(RH_NRF24_REG_1D_FEATURE, RH_NRF24_EN_DPL | RH_NRF24_EN_DYN_ACK);
  30. // Test if there is actually a device connected and responding
  31. // CAUTION: RFM73 and version 2.0 silicon may require ACTIVATE
  32. if (spiReadRegister(RH_NRF24_REG_1D_FEATURE) != (RH_NRF24_EN_DPL | RH_NRF24_EN_DYN_ACK))
  33. {
  34. spiWrite(RH_NRF24_COMMAND_ACTIVATE, 0x73);
  35. // Enable dynamic payload length, disable payload-with-ack, enable noack
  36. spiWriteRegister(RH_NRF24_REG_1D_FEATURE, RH_NRF24_EN_DPL | RH_NRF24_EN_DYN_ACK);
  37. if (spiReadRegister(RH_NRF24_REG_1D_FEATURE) != (RH_NRF24_EN_DPL | RH_NRF24_EN_DYN_ACK))
  38. return false;
  39. }
  40. // Make sure we are powered down
  41. setModeIdle();
  42. // Flush FIFOs
  43. flushTx();
  44. flushRx();
  45. setChannel(2); // The default, in case it was set by another app without powering down
  46. setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm);
  47. return true;
  48. }
  49. // Use the register commands to read and write the registers
  50. uint8_t RH_NRF24::spiReadRegister(uint8_t reg)
  51. {
  52. return spiRead((reg & RH_NRF24_REGISTER_MASK) | RH_NRF24_COMMAND_R_REGISTER);
  53. }
  54. uint8_t RH_NRF24::spiWriteRegister(uint8_t reg, uint8_t val)
  55. {
  56. return spiWrite((reg & RH_NRF24_REGISTER_MASK) | RH_NRF24_COMMAND_W_REGISTER, val);
  57. }
  58. uint8_t RH_NRF24::spiBurstReadRegister(uint8_t reg, uint8_t* dest, uint8_t len)
  59. {
  60. return spiBurstRead((reg & RH_NRF24_REGISTER_MASK) | RH_NRF24_COMMAND_R_REGISTER, dest, len);
  61. }
  62. uint8_t RH_NRF24::spiBurstWriteRegister(uint8_t reg, uint8_t* src, uint8_t len)
  63. {
  64. return spiBurstWrite((reg & RH_NRF24_REGISTER_MASK) | RH_NRF24_COMMAND_W_REGISTER, src, len);
  65. }
  66. uint8_t RH_NRF24::statusRead()
  67. {
  68. // status is a side-effect of NOP, faster than reading reg 07
  69. return spiCommand(RH_NRF24_COMMAND_NOP);
  70. }
  71. uint8_t RH_NRF24::flushTx()
  72. {
  73. return spiCommand(RH_NRF24_COMMAND_FLUSH_TX);
  74. }
  75. uint8_t RH_NRF24::flushRx()
  76. {
  77. return spiCommand(RH_NRF24_COMMAND_FLUSH_RX);
  78. }
  79. bool RH_NRF24::setChannel(uint8_t channel)
  80. {
  81. spiWriteRegister(RH_NRF24_REG_05_RF_CH, channel & RH_NRF24_RF_CH);
  82. return true;
  83. }
  84. bool RH_NRF24::setOpMode(uint8_t mode)
  85. {
  86. _configuration = mode;
  87. return true;
  88. }
  89. bool RH_NRF24::setNetworkAddress(uint8_t* address, uint8_t len)
  90. {
  91. if (len < 3 || len > 5)
  92. return false;
  93. // Set both TX_ADDR and RX_ADDR_P0 for auto-ack with Enhanced shockwave
  94. spiWriteRegister(RH_NRF24_REG_03_SETUP_AW, len-2); // Mapping [3..5] = [1..3]
  95. spiBurstWriteRegister(RH_NRF24_REG_0A_RX_ADDR_P0, address, len);
  96. spiBurstWriteRegister(RH_NRF24_REG_10_TX_ADDR, address, len);
  97. return true;
  98. }
  99. bool RH_NRF24::setRF(DataRate data_rate, TransmitPower power)
  100. {
  101. uint8_t value = (power << 1) & RH_NRF24_PWR;
  102. // Ugly mapping of data rates to noncontiguous 2 bits:
  103. if (data_rate == DataRate250kbps)
  104. value |= RH_NRF24_RF_DR_LOW;
  105. else if (data_rate == DataRate2Mbps)
  106. value |= RH_NRF24_RF_DR_HIGH;
  107. // else DataRate1Mbps, 00
  108. // RFM73 needs this:
  109. value |= RH_NRF24_LNA_HCURR;
  110. spiWriteRegister(RH_NRF24_REG_06_RF_SETUP, value);
  111. // If we were using auto-ack, we would have to set the appropriate timeout in reg 4 here
  112. // see NRF24::setRF()
  113. return true;
  114. }
  115. void RH_NRF24::setModeIdle()
  116. {
  117. if (_mode != RHModeIdle)
  118. {
  119. spiWriteRegister(RH_NRF24_REG_00_CONFIG, _configuration);
  120. digitalWrite(_chipEnablePin, LOW);
  121. _mode = RHModeIdle;
  122. }
  123. }
  124. bool RH_NRF24::sleep()
  125. {
  126. if (_mode != RHModeSleep)
  127. {
  128. spiWriteRegister(RH_NRF24_REG_00_CONFIG, 0); // Power Down mode
  129. digitalWrite(_chipEnablePin, LOW);
  130. _mode = RHModeSleep;
  131. return true;
  132. }
  133. return false; // Already there?
  134. }
  135. void RH_NRF24::setModeRx()
  136. {
  137. if (_mode != RHModeRx)
  138. {
  139. spiWriteRegister(RH_NRF24_REG_00_CONFIG, _configuration | RH_NRF24_PWR_UP | RH_NRF24_PRIM_RX);
  140. digitalWrite(_chipEnablePin, HIGH);
  141. _mode = RHModeRx;
  142. }
  143. }
  144. void RH_NRF24::setModeTx()
  145. {
  146. if (_mode != RHModeTx)
  147. {
  148. // Its the CE rising edge that puts us into TX mode
  149. // CE staying high makes us go to standby-II when the packet is sent
  150. digitalWrite(_chipEnablePin, LOW);
  151. // Ensure DS is not set
  152. spiWriteRegister(RH_NRF24_REG_07_STATUS, RH_NRF24_TX_DS | RH_NRF24_MAX_RT);
  153. spiWriteRegister(RH_NRF24_REG_00_CONFIG, _configuration | RH_NRF24_PWR_UP);
  154. digitalWrite(_chipEnablePin, HIGH);
  155. _mode = RHModeTx;
  156. }
  157. }
  158. bool RH_NRF24::send(const uint8_t* data, uint8_t len)
  159. {
  160. if (len > RH_NRF24_MAX_MESSAGE_LEN)
  161. return false;
  162. // Set up the headers
  163. _buf[0] = _txHeaderTo;
  164. _buf[1] = _txHeaderFrom;
  165. _buf[2] = _txHeaderId;
  166. _buf[3] = _txHeaderFlags;
  167. memcpy(_buf+RH_NRF24_HEADER_LEN, data, len);
  168. spiBurstWrite(RH_NRF24_COMMAND_W_TX_PAYLOAD_NOACK, _buf, len + RH_NRF24_HEADER_LEN);
  169. setModeTx();
  170. // Radio will return to Standby II mode after transmission is complete
  171. _txGood++;
  172. return true;
  173. }
  174. bool RH_NRF24::waitPacketSent()
  175. {
  176. // If we are not currently in transmit mode, there is no packet to wait for
  177. if (_mode != RHModeTx)
  178. return false;
  179. // Wait for either the Data Sent or Max ReTries flag, signalling the
  180. // end of transmission
  181. // We dont actually use auto-ack, so prob dont expect to see RH_NRF24_MAX_RT
  182. uint8_t status;
  183. while (!((status = statusRead()) & (RH_NRF24_TX_DS | RH_NRF24_MAX_RT)))
  184. YIELD;
  185. // Must clear RH_NRF24_MAX_RT if it is set, else no further comm
  186. if (status & RH_NRF24_MAX_RT)
  187. flushTx();
  188. setModeIdle();
  189. spiWriteRegister(RH_NRF24_REG_07_STATUS, RH_NRF24_TX_DS | RH_NRF24_MAX_RT);
  190. // Return true if data sent, false if MAX_RT
  191. return status & RH_NRF24_TX_DS;
  192. }
  193. bool RH_NRF24::isSending()
  194. {
  195. return !(spiReadRegister(RH_NRF24_REG_00_CONFIG) & RH_NRF24_PRIM_RX) &&
  196. !(statusRead() & (RH_NRF24_TX_DS | RH_NRF24_MAX_RT));
  197. }
  198. bool RH_NRF24::printRegisters()
  199. {
  200. #ifdef RH_HAVE_SERIAL
  201. // Iterate over register range, but don't process registers not in use.
  202. for (uint8_t r = RH_NRF24_REG_00_CONFIG; r <= RH_NRF24_REG_1D_FEATURE; r++)
  203. {
  204. if ((r <= RH_NRF24_REG_17_FIFO_STATUS) || (r >= RH_NRF24_REG_1C_DYNPD))
  205. {
  206. Serial.print(r, HEX);
  207. Serial.print(": ");
  208. uint8_t len = 1;
  209. // Address registers are 5 bytes in size
  210. if ( (RH_NRF24_REG_0A_RX_ADDR_P0 == r)
  211. || (RH_NRF24_REG_0B_RX_ADDR_P1 == r)
  212. || (RH_NRF24_REG_10_TX_ADDR == r) )
  213. {
  214. len = 5;
  215. }
  216. uint8_t buf[5];
  217. spiBurstReadRegister(r, buf, len);
  218. for (uint8_t j = 0; j < len; ++j)
  219. {
  220. Serial.print(buf[j], HEX);
  221. Serial.print(" ");
  222. }
  223. Serial.println("");
  224. }
  225. }
  226. #endif
  227. return true;
  228. }
  229. // Check whether the latest received message is complete and uncorrupted
  230. void RH_NRF24::validateRxBuf()
  231. {
  232. if (_bufLen < 4)
  233. return; // Too short to be a real message
  234. // Extract the 4 headers
  235. _rxHeaderTo = _buf[0];
  236. _rxHeaderFrom = _buf[1];
  237. _rxHeaderId = _buf[2];
  238. _rxHeaderFlags = _buf[3];
  239. if (_promiscuous ||
  240. _rxHeaderTo == _thisAddress ||
  241. _rxHeaderTo == RH_BROADCAST_ADDRESS)
  242. {
  243. _rxGood++;
  244. _rxBufValid = true;
  245. }
  246. }
  247. bool RH_NRF24::available()
  248. {
  249. if (!_rxBufValid)
  250. {
  251. if (_mode == RHModeTx)
  252. return false;
  253. setModeRx();
  254. if (spiReadRegister(RH_NRF24_REG_17_FIFO_STATUS) & RH_NRF24_RX_EMPTY)
  255. return false;
  256. // Manual says that messages > 32 octets should be discarded
  257. uint8_t len = spiRead(RH_NRF24_COMMAND_R_RX_PL_WID);
  258. if (len > 32)
  259. {
  260. flushRx();
  261. clearRxBuf();
  262. setModeIdle();
  263. return false;
  264. }
  265. // Clear read interrupt
  266. spiWriteRegister(RH_NRF24_REG_07_STATUS, RH_NRF24_RX_DR);
  267. // Get the message into the RX buffer, so we can inspect the headers
  268. spiBurstRead(RH_NRF24_COMMAND_R_RX_PAYLOAD, _buf, len);
  269. _bufLen = len;
  270. // 140 microsecs (32 octet payload)
  271. validateRxBuf();
  272. if (_rxBufValid)
  273. setModeIdle(); // Got one
  274. }
  275. return _rxBufValid;
  276. }
  277. void RH_NRF24::clearRxBuf()
  278. {
  279. _rxBufValid = false;
  280. _bufLen = 0;
  281. }
  282. bool RH_NRF24::recv(uint8_t* buf, uint8_t* len)
  283. {
  284. if (!available())
  285. return false;
  286. if (buf && len)
  287. {
  288. // Skip the 4 headers that are at the beginning of the rxBuf
  289. if (*len > _bufLen-RH_NRF24_HEADER_LEN)
  290. *len = _bufLen-RH_NRF24_HEADER_LEN;
  291. memcpy(buf, _buf+RH_NRF24_HEADER_LEN, *len);
  292. }
  293. clearRxBuf(); // This message accepted and cleared
  294. return true;
  295. }
  296. uint8_t RH_NRF24::maxMessageLength()
  297. {
  298. return RH_NRF24_MAX_MESSAGE_LEN;
  299. }