PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

RH_NRF905.cpp 6.6KB

3 anos atrás
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. // RH_NRF905.cpp
  2. //
  3. // Copyright (C) 2012 Mike McCauley
  4. // $Id: RH_NRF905.cpp,v 1.6 2015/12/11 01:10:24 mikem Exp $
  5. #include <RH_NRF905.h>
  6. RH_NRF905::RH_NRF905(uint8_t chipEnablePin, uint8_t txEnablePin, uint8_t slaveSelectPin, RHGenericSPI& spi)
  7. :
  8. RHNRFSPIDriver(slaveSelectPin, spi)
  9. {
  10. _chipEnablePin = chipEnablePin;
  11. _txEnablePin = txEnablePin;
  12. }
  13. bool RH_NRF905::init()
  14. {
  15. #if defined (__MK20DX128__) || defined (__MK20DX256__)
  16. // Teensy is unreliable at 8MHz:
  17. _spi.setFrequency(RHGenericSPI::Frequency1MHz);
  18. #else
  19. _spi.setFrequency(RHGenericSPI::Frequency8MHz);
  20. #endif
  21. if (!RHNRFSPIDriver::init())
  22. return false;
  23. // Initialise the slave select pin and the tx Enable pin
  24. pinMode(_chipEnablePin, OUTPUT);
  25. pinMode(_txEnablePin, OUTPUT);
  26. digitalWrite(_chipEnablePin, LOW);
  27. digitalWrite(_txEnablePin, LOW);
  28. // Configure the chip
  29. // CRC 16 bits enabled. 16MHz crystal freq
  30. spiWriteRegister(RH_NRF905_CONFIG_9, RH_NRF905_CONFIG_9_CRC_EN | RH_NRF905_CONFIG_9_CRC_MODE_16BIT | RH_NRF905_CONFIG_9_XOF_16MHZ);
  31. // Make sure we are powered down
  32. setModeIdle();
  33. // Some innocuous defaults
  34. setChannel(108, LOW); // 433.2 MHz
  35. setRF(RH_NRF905::TransmitPowerm10dBm);
  36. return true;
  37. }
  38. // Use the register commands to read and write the registers
  39. uint8_t RH_NRF905::spiReadRegister(uint8_t reg)
  40. {
  41. return spiRead((reg & RH_NRF905_REG_MASK) | RH_NRF905_REG_R_CONFIG);
  42. }
  43. uint8_t RH_NRF905::spiWriteRegister(uint8_t reg, uint8_t val)
  44. {
  45. return spiWrite((reg & RH_NRF905_REG_MASK) | RH_NRF905_REG_W_CONFIG, val);
  46. }
  47. uint8_t RH_NRF905::spiBurstReadRegister(uint8_t reg, uint8_t* dest, uint8_t len)
  48. {
  49. return spiBurstRead((reg & RH_NRF905_REG_MASK) | RH_NRF905_REG_R_CONFIG, dest, len);
  50. }
  51. uint8_t RH_NRF905::spiBurstWriteRegister(uint8_t reg, uint8_t* src, uint8_t len)
  52. {
  53. return spiBurstWrite((reg & RH_NRF905_REG_MASK) | RH_NRF905_REG_W_CONFIG, src, len);
  54. }
  55. uint8_t RH_NRF905::statusRead()
  56. {
  57. // The status is a byproduct of sending a command
  58. return spiCommand(0);
  59. }
  60. bool RH_NRF905::setChannel(uint16_t channel, bool hiFrequency)
  61. {
  62. spiWriteRegister(RH_NRF905_CONFIG_0, channel & RH_NRF905_CONFIG_0_CH_NO);
  63. // Set or clear the high bit of the channel
  64. uint8_t bit8 = (channel >> 8) & 0x01;
  65. uint8_t reg1 = spiReadRegister(RH_NRF905_CONFIG_1);
  66. reg1 = (reg1 & ~0x01) | bit8;
  67. // Set or clear the HFREQ_PLL bit
  68. reg1 &= ~RH_NRF905_CONFIG_1_HFREQ_PLL;
  69. if (hiFrequency)
  70. reg1 |= RH_NRF905_CONFIG_1_HFREQ_PLL;
  71. spiWriteRegister(RH_NRF905_CONFIG_1, reg1);
  72. return true;
  73. }
  74. bool RH_NRF905::setNetworkAddress(uint8_t* address, uint8_t len)
  75. {
  76. if (len < 1 || len > 4)
  77. return false;
  78. // Set RX_AFW and TX_AFW
  79. spiWriteRegister(RH_NRF905_CONFIG_2, len | (len << 4));
  80. spiBurstWrite(RH_NRF905_REG_W_TX_ADDRESS, address, len);
  81. spiBurstWriteRegister(RH_NRF905_CONFIG_5, address, len);
  82. return true;
  83. }
  84. bool RH_NRF905::setRF(TransmitPower power)
  85. {
  86. // Enum definitions of power are the same numerical values as the register
  87. uint8_t reg1 = spiReadRegister(RH_NRF905_CONFIG_1);
  88. reg1 &= ~RH_NRF905_CONFIG_1_PA_PWR;
  89. reg1 |= ((power & 0x3) << 2) & RH_NRF905_CONFIG_1_PA_PWR;
  90. spiWriteRegister(RH_NRF905_CONFIG_1, reg1);
  91. return true;
  92. }
  93. void RH_NRF905::setModeIdle()
  94. {
  95. if (_mode != RHModeIdle)
  96. {
  97. digitalWrite(_chipEnablePin, LOW);
  98. digitalWrite(_txEnablePin, LOW);
  99. _mode = RHModeIdle;
  100. }
  101. }
  102. void RH_NRF905::setModeRx()
  103. {
  104. if (_mode != RHModeRx)
  105. {
  106. digitalWrite(_txEnablePin, LOW);
  107. digitalWrite(_chipEnablePin, HIGH);
  108. _mode = RHModeRx;
  109. }
  110. }
  111. void RH_NRF905::setModeTx()
  112. {
  113. if (_mode != RHModeTx)
  114. {
  115. // Its the high transition that puts us into TX mode
  116. digitalWrite(_txEnablePin, HIGH);
  117. digitalWrite(_chipEnablePin, HIGH);
  118. _mode = RHModeTx;
  119. }
  120. }
  121. bool RH_NRF905::send(const uint8_t* data, uint8_t len)
  122. {
  123. if (len > RH_NRF905_MAX_MESSAGE_LEN)
  124. return false;
  125. // Set up the headers
  126. _buf[0] = _txHeaderTo;
  127. _buf[1] = _txHeaderFrom;
  128. _buf[2] = _txHeaderId;
  129. _buf[3] = _txHeaderFlags;
  130. _buf[4] = len;
  131. memcpy(_buf+RH_NRF905_HEADER_LEN, data, len);
  132. spiBurstWrite(RH_NRF905_REG_W_TX_PAYLOAD, _buf, len + RH_NRF905_HEADER_LEN);
  133. setModeTx();
  134. // Radio will return to Standby mode after transmission is complete
  135. _txGood++;
  136. return true;
  137. }
  138. bool RH_NRF905::waitPacketSent()
  139. {
  140. if (_mode != RHModeTx)
  141. return false;
  142. while (!(statusRead() & RH_NRF905_STATUS_DR))
  143. YIELD;
  144. setModeIdle();
  145. return true;
  146. }
  147. bool RH_NRF905::isSending()
  148. {
  149. if (_mode != RHModeTx)
  150. return false;
  151. return !(statusRead() & RH_NRF905_STATUS_DR);
  152. }
  153. bool RH_NRF905::printRegister(uint8_t reg)
  154. {
  155. #ifdef RH_HAVE_SERIAL
  156. Serial.print(reg, HEX);
  157. Serial.print(": ");
  158. Serial.println(spiReadRegister(reg), HEX);
  159. #endif
  160. return true;
  161. }
  162. bool RH_NRF905::printRegisters()
  163. {
  164. uint8_t registers[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
  165. uint8_t i;
  166. for (i = 0; i < sizeof(registers); i++)
  167. printRegister(registers[i]);
  168. return true;
  169. }
  170. // Check whether the latest received message is complete and uncorrupted
  171. void RH_NRF905::validateRxBuf()
  172. {
  173. // Check the length
  174. uint8_t len = _buf[4];
  175. if (len > RH_NRF905_MAX_MESSAGE_LEN)
  176. return; // Silly LEN header
  177. // Extract the 4 headers
  178. _rxHeaderTo = _buf[0];
  179. _rxHeaderFrom = _buf[1];
  180. _rxHeaderId = _buf[2];
  181. _rxHeaderFlags = _buf[3];
  182. if (_promiscuous ||
  183. _rxHeaderTo == _thisAddress ||
  184. _rxHeaderTo == RH_BROADCAST_ADDRESS)
  185. {
  186. _rxGood++;
  187. _bufLen = len + RH_NRF905_HEADER_LEN; // _buf still includes the headers
  188. _rxBufValid = true;
  189. }
  190. }
  191. bool RH_NRF905::available()
  192. {
  193. if (!_rxBufValid)
  194. {
  195. if (_mode == RHModeTx)
  196. return false;
  197. setModeRx();
  198. if (!(statusRead() & RH_NRF905_STATUS_DR))
  199. return false;
  200. // Get the message into the RX buffer, so we can inspect the headers
  201. // we still dont know how long is the user message
  202. spiBurstRead(RH_NRF905_REG_R_RX_PAYLOAD, _buf, RH_NRF905_MAX_PAYLOAD_LEN);
  203. validateRxBuf();
  204. if (_rxBufValid)
  205. setModeIdle(); // Got one
  206. }
  207. return _rxBufValid;
  208. }
  209. void RH_NRF905::clearRxBuf()
  210. {
  211. _rxBufValid = false;
  212. _bufLen = 0;
  213. }
  214. bool RH_NRF905::recv(uint8_t* buf, uint8_t* len)
  215. {
  216. if (!available())
  217. return false;
  218. if (buf && len)
  219. {
  220. // Skip the 4 headers that are at the beginning of the rxBuf
  221. if (*len > _bufLen-RH_NRF905_HEADER_LEN)
  222. *len = _bufLen-RH_NRF905_HEADER_LEN;
  223. memcpy(buf, _buf+RH_NRF905_HEADER_LEN, *len);
  224. }
  225. clearRxBuf(); // This message accepted and cleared
  226. return true;
  227. }
  228. uint8_t RH_NRF905::maxMessageLength()
  229. {
  230. return RH_NRF905_MAX_MESSAGE_LEN;
  231. }