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.

пре 3 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. // RH_NRF905.h
  2. // Author: Mike McCauley (mikem@airspayce.com)
  3. // Copyright (C) 2014 Mike McCauley
  4. // $Id: RH_NRF905.h,v 1.9 2016/04/04 01:40:12 mikem Exp $
  5. //
  6. #ifndef RH_NRF905_h
  7. #define RH_NRF905_h
  8. #include <RHGenericSPI.h>
  9. #include <RHNRFSPIDriver.h>
  10. // This is the maximum (and only) number of bytes that can be carried by the nRF905.
  11. // We use some for headers, leaving fewer for RadioHead messages
  12. #define RH_NRF905_MAX_PAYLOAD_LEN 32
  13. // The length of the headers we add.
  14. // The headers are inside the nRF905 payload
  15. // As well as the usual TO, FROM, ID, FLAGS, we also need LEN, since
  16. // nRF905 only has fixed width messages.
  17. // REVISIT: could we have put the LEN into the FLAGS field?
  18. #define RH_NRF905_HEADER_LEN 5
  19. // This is the maximum RadioHead user message length that can be supported by this library. Limited by
  20. // the supported message lengths in the nRF905
  21. #define RH_NRF905_MAX_MESSAGE_LEN (RH_NRF905_MAX_PAYLOAD_LEN-RH_NRF905_HEADER_LEN)
  22. // Register names
  23. #define RH_NRF905_REG_MASK 0x0f
  24. #define RH_NRF905_REG_W_CONFIG 0x00
  25. #define RH_NRF905_REG_R_CONFIG 0x10
  26. #define RH_NRF905_REG_W_TX_PAYLOAD 0x20
  27. #define RH_NRF905_REG_R_TX_PAYLOAD 0x21
  28. #define RH_NRF905_REG_W_TX_ADDRESS 0x22
  29. #define RH_NRF905_REG_R_TX_ADDRESS 0x23
  30. #define RH_NRF905_REG_R_RX_PAYLOAD 0x24
  31. #define RH_NRF905_REG_CHANNEL_CONFIG 0x80
  32. // Configuration register
  33. #define RH_NRF905_CONFIG_0 0x00
  34. #define RH_NRF905_CONFIG_0_CH_NO 0xff
  35. #define RH_NRF905_CONFIG_1 0x01
  36. #define RH_NRF905_CONFIG_1_AUTO_RETRAN 0x20
  37. #define RH_NRF905_CONFIG_1_RX_RED_PWR 0x10
  38. #define RH_NRF905_CONFIG_1_PA_PWR 0x0c
  39. #define RH_NRF905_CONFIG_1_PA_PWR_N10DBM 0x00
  40. #define RH_NRF905_CONFIG_1_PA_PWR_N2DBM 0x04
  41. #define RH_NRF905_CONFIG_1_PA_PWR_6DBM 0x08
  42. #define RH_NRF905_CONFIG_1_PA_PWR_10DBM 0x0c
  43. #define RH_NRF905_CONFIG_1_HFREQ_PLL 0x02
  44. #define RH_NRF905_CONFIG_1_CH_NO 0x01
  45. #define RH_NRF905_CONFIG_2 0x02
  46. #define RH_NRF905_CONFIG_2_TX_AFW 0x70
  47. #define RH_NRF905_CONFIG_2_RX_AFW 0x07
  48. #define RH_NRF905_CONFIG_3 0x03
  49. #define RH_NRF905_CONFIG_3_RX_PW 0x3f
  50. #define RH_NRF905_CONFIG_4 0x04
  51. #define RH_NRF905_CONFIG_4_TX_PW 0x3f
  52. #define RH_NRF905_CONFIG_5 0x05
  53. #define RH_NRF905_CONFIG_5_RX_ADDRESS 0xff
  54. #define RH_NRF905_CONFIG_6 0x06
  55. #define RH_NRF905_CONFIG_6_RX_ADDRESS 0xff
  56. #define RH_NRF905_CONFIG_7 0x07
  57. #define RH_NRF905_CONFIG_7_RX_ADDRESS 0xff
  58. #define RH_NRF905_CONFIG_8 0x08
  59. #define RH_NRF905_CONFIG_8_RX_ADDRESS 0xff
  60. #define RH_NRF905_CONFIG_9 0x09
  61. #define RH_NRF905_CONFIG_9_CRC_MODE_16BIT 0x80
  62. #define RH_NRF905_CONFIG_9_CRC_EN 0x40
  63. #define RH_NRF905_CONFIG_9_XOF 0x38
  64. #define RH_NRF905_CONFIG_9_XOF_4MHZ 0x00
  65. #define RH_NRF905_CONFIG_9_XOF_8MHZ 0x08
  66. #define RH_NRF905_CONFIG_9_XOF_12MHZ 0x10
  67. #define RH_NRF905_CONFIG_9_XOF_16MHZ 0x18
  68. #define RH_NRF905_CONFIG_9_XOF_20MHZ 0x20
  69. #define RH_NRF905_CONFIG_9_UP_CLK_EN 0x04
  70. #define RH_NRF905_CONFIG_9_UP_CLK_FREQ 0x03
  71. #define RH_NRF905_CONFIG_9_UP_CLK_FREQ_4MHZ 0x00
  72. #define RH_NRF905_CONFIG_9_UP_CLK_FREQ_2MHZ 0x01
  73. #define RH_NRF905_CONFIG_9_UP_CLK_FREQ_1MHZ 0x02
  74. #define RH_NRF905_CONFIG_9_UP_CLK_FREQ_500KHZ 0x03
  75. // Status register is always read as first byte
  76. #define RH_NRF905_STATUS_AM 0x80
  77. #define RH_NRF905_STATUS_DR 0x20
  78. /////////////////////////////////////////////////////////////////////
  79. /// \class RH_NRF905 RH_NRF905.h <RH_NRF905.h>
  80. /// \brief Send and receive addressed, reliable, acknowledged datagrams by nRF905 and compatible transceivers.
  81. ///
  82. /// This base class provides basic functions for sending and receiving unaddressed, unreliable datagrams
  83. /// of arbitrary length to 28 octets per packet. Use one of the Manager classes to get addressing and
  84. /// acknowledgement reliability, routing, meshes etc.
  85. ///
  86. /// The nRF905 transceiver is configured to use Enhanced Shockburst with 16 Bit CRC, and 32 octet packets.
  87. ///
  88. /// Naturally, for any 2 radios to communicate that must be configured to use the same frequency
  89. /// and with identical network addresses.
  90. ///
  91. /// The nRF905 from Nordic Semiconductor http://www.nordicsemi.com/eng/Products/Sub-1-GHz-RF/nRF905
  92. /// (http://www.nordicsemi.com/jpn/nordic/content_download/2452/29528/file/Product_Specification_nRF905_v1.5.pdf)
  93. /// is a low-cost 433/868/915 MHz ISM transceiver module. It supports a number of channel frequencies at
  94. /// 100kHz deviation and 50kHz bandwidth with Manchester encoding.
  95. ///
  96. /// We tested with inexpensive nRF905 modules from eBay, similar to:
  97. /// http://www.aliexpress.com/store/product/Free-ship-NRF905-433MHz-Wireless-Transmission-Module-Transceiver-Module-with-Antenna-for-the-433MHz-ISM-band/513046_607163305.html
  98. ///
  99. /// This library provides functions for sending and receiving messages of up to 27 octets on any
  100. /// frequency supported by the nRF905.
  101. ///
  102. /// Several nRF905 modules can be connected to an Arduino, permitting the construction of translators
  103. /// and frequency changers, etc.
  104. ///
  105. /// Example Arduino programs are included to show the main modes of use.
  106. ///
  107. /// \par Packet Format
  108. ///
  109. /// All messages sent and received by this class conform to this fixed length packet format
  110. ///
  111. /// - 4 octets NETWORK ADDRESS
  112. /// - 32 octets PAYLOAD, consisting of:
  113. /// - 1 octet TO header
  114. /// - 1 octet FROM header
  115. /// - 1 octet ID header
  116. /// - 1 octet FLAGS header
  117. /// - 1 octet user message length header
  118. /// - 0 to 27 octets of user message, trailing octets after the user message length are ignored
  119. /// - 2 octets CRC
  120. ///
  121. /// All messages sent and received by this driver are 32 octets. The user message length is embedded in the message.
  122. ///
  123. /// \par Connecting nRF905
  124. ///
  125. /// The nRF905 is a 3.3V part is is *NOT* 5V tolerant. So you MUST use a 3.3V CPU such as Teensy, Arduino Due etc
  126. /// or else provide for level shifters between the CPU and the nRF905. Failure to consider this will probably
  127. /// break your nRF905.
  128. ///
  129. /// The electrical connection between the nRF905 and the CPU require 3.3V, the 3 x SPI pins (SCK, SDI, SDO),
  130. /// a Chip Enable pin, a Transmit Enable pin and a Slave Select pin.
  131. ///
  132. /// The examples below assume the commonly found cheap Chinese nRF905 modules. The RH_RF905 driver assumes the
  133. /// the nRF905 has a 16MHz crystal.
  134. ///
  135. /// Connect the nRF905 to Teensy (or Arduino with suitable level shifters) like this
  136. /// \code
  137. /// CPU nRF905 module
  138. /// 3V3----------VCC (3.3V)
  139. /// pin D8-----------CE (chip enable in)
  140. /// pin D9-----------TX_EN (transmit enable in)
  141. /// SS pin D10----------CSN (chip select in)
  142. /// SCK pin D13----------SCK (SPI clock in)
  143. /// MOSI pin D11----------MOSI (SPI Data in)
  144. /// MISO pin D12----------MISO (SPI data out)
  145. /// GND----------GND (ground in)
  146. /// \endcode
  147. ///
  148. /// Caution: Arduino Due is a 3.3V part and is not 5V tolerant (so too is the nRF905 module
  149. /// so they can be connected directly together. Unlike other Arduinos the Due has it default SPI
  150. /// connections on a dedicated 6 pin SPI header in the center of the board, which is
  151. /// physically compatible with Uno, Leonardo and Mega2560. A little dot marks pin 1 on the header.
  152. /// You must connect to these
  153. /// and *not* to the usual Arduino SPI pins Digital 11, 12 and 13.
  154. /// See http://21stdigitalhome.blogspot.com.au/2013/02/arduino-due-hardware-spi.html
  155. ///
  156. /// Connect the nRF905 to Arduino Due like this
  157. /// \code
  158. /// CPU nRF905 module
  159. /// 3V3----------VCC (3.3V)
  160. /// pin D8-----------CE (chip enable in)
  161. /// pin D9-----------TX_EN (transmit enable in)
  162. /// SS pin D10----------CSN (chip select in)
  163. /// SCK on SPI header pin 3----------SCK (SPI clock in)
  164. /// MOSI on SPI header pin 4----------MOSI (SPI Data in)
  165. /// MISO on SPI header pin 1----------MISO (SPI data out)
  166. /// GND----------GND (ground in)
  167. /// \endcode
  168. ///
  169. /// and you can then use the default constructor RH_NRF905().
  170. /// You can override the default settings for the CE, TX_EN and CSN pins
  171. /// in the NRF905() constructor if you wish to connect the slave select CSN to other than the normal one for your
  172. /// CPU.
  173. ///
  174. /// It is possible to have 2 radios conected to one CPU, provided each radio has its own
  175. /// CSN, TX_EN and CE line (SCK, MOSI and MISO are common to both radios)
  176. ///
  177. /// \par Transmitter Power
  178. ///
  179. /// You can control the transmitter power to be one of 4 power levels: -10, -2, 6 or 10dBm,
  180. /// using the setRF() function, eg:
  181. /// \code
  182. /// nrf905.setRF(RH_NRF905::TransmitPower10dBm);
  183. /// \endcode
  184. ///
  185. /// We have made some actual power measurements against
  186. /// programmed power for an nRF905 module from www.rfinchina.com under the following conditions:
  187. /// - Teensy 3.1
  188. /// - nRF905 module (with SMA antenna connector) wired to Teensy as described above, channel 108.
  189. /// - 20cm SMA-SMA cable
  190. /// - MiniKits AD8307 HF/VHF Power Head (calibrated against Rohde&Schwartz 806.2020 test set)
  191. /// - Tektronix TDS220 scope to measure the Vout from power head
  192. /// \code
  193. /// Program power Measured Power
  194. /// dBm dBm
  195. /// -10 -16
  196. /// -2 -8
  197. /// 6 0
  198. /// 10 8
  199. /// \endcode
  200. /// (Caution: we dont claim laboratory accuracy for these measurements)
  201. /// You would not expect to get anywhere near these powers to air with a simple 1/4 wavelength wire antenna.
  202. ///
  203. /// \par Example programs
  204. ///
  205. /// Several example programs are provided. They work out of the box with Teensy 3.1 and Arduino Due
  206. /// connected as show above.
  207. ///
  208. /// \par Radio Performance
  209. ///
  210. /// Frequency accuracy may be debatable.
  211. ///
  212. /// \par Memory
  213. ///
  214. /// Memory usage of this class is minimal. The compiled client and server sketches are about 16000 bytes on Teensy.
  215. ///
  216. class RH_NRF905 : public RHNRFSPIDriver
  217. {
  218. public:
  219. /// \brief Convenient values for setting transmitter power in setRF()
  220. /// These are designed to agree with the values for RH_NRF905_CONFIG_1_PA_PWR after
  221. /// left shifting by 2
  222. /// To be passed to setRF();
  223. typedef enum
  224. {
  225. TransmitPowerm10dBm = 0, ///< -10 dBm
  226. TransmitPowerm2dBm, ///< -2 dBm
  227. TransmitPower6dBm, ///< 6 dBm
  228. TransmitPower10dBm ///< 10 dBm
  229. } TransmitPower;
  230. /// Constructor. You can have multiple instances, but each instance must have its own
  231. /// chip enable and slave select pin.
  232. /// After constructing, you must call init() to initialise the interface
  233. /// and the radio module
  234. /// \param[in] chipEnablePin the Arduino pin to use to enable the chip for transmit/receive
  235. /// \param[in] txEnablePin the Arduino pin cponnected to the txEn pin on the radio that enable transmit mode
  236. /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the NRF905 before
  237. /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega,
  238. /// D10 for Maple, Teensy)
  239. /// \param[in] spi Pointer to the SPI interface object to use.
  240. /// Defaults to the standard Arduino hardware SPI interface
  241. RH_NRF905(uint8_t chipEnablePin = 8, uint8_t txEnablePin = 9, uint8_t slaveSelectPin = SS, RHGenericSPI& spi = hardware_spi);
  242. /// Initialises this instance and the radio module connected to it.
  243. /// The following steps are taken:g
  244. /// - Set the chip enable and chip select pins to output LOW, HIGH respectively.
  245. /// - Initialise the SPI output pins
  246. /// - Initialise the SPI interface library to 8MHz (Hint, if you want to lower
  247. /// the SPI frequency (perhaps where you have other SPI shields, low voltages etc),
  248. /// call SPI.setClockDivider() after init()).
  249. /// -Flush the receiver and transmitter buffers
  250. /// - Set the radio to receive with powerUpRx();
  251. /// \return true if everything was successful
  252. bool init();
  253. /// Reads a single register from the NRF905
  254. /// \param[in] reg Register number, one of NR905_REG_*
  255. /// \return The value of the register
  256. uint8_t spiReadRegister(uint8_t reg);
  257. /// Writes a single byte to the NRF905, and at the ame time reads the current STATUS register
  258. /// \param[in] reg Register number, one of NRF905_REG_*
  259. /// \param[in] val The value to write
  260. /// \return the current STATUS (read while the command is sent)
  261. uint8_t spiWriteRegister(uint8_t reg, uint8_t val);
  262. /// Reads a number of consecutive registers from the NRF905 using burst read mode
  263. /// \param[in] reg Register number of the first register, one of NRF905_REG_*
  264. /// \param[in] dest Array to write the register values to. Must be at least len bytes
  265. /// \param[in] len Number of bytes to read
  266. /// \return the current STATUS (read while the command is sent)
  267. uint8_t spiBurstReadRegister(uint8_t reg, uint8_t* dest, uint8_t len);
  268. /// Write a number of consecutive registers using burst write mode
  269. /// \param[in] reg Register number of the first register, one of NRF905_REG_*
  270. /// \param[in] src Array of new register values to write. Must be at least len bytes
  271. /// \param[in] len Number of bytes to write
  272. /// \return the current STATUS (read while the command is sent)
  273. uint8_t spiBurstWriteRegister(uint8_t reg, uint8_t* src, uint8_t len);
  274. /// Reads and returns the device status register NRF905_REG_02_DEVICE_STATUS
  275. /// \return The value of the device status register
  276. uint8_t statusRead();
  277. /// Sets the transmit and receive channel number.
  278. /// The RF frequency used is (422.4 + channel/10) * (1+hiFrequency) MHz
  279. /// \param[in] channel The channel number.
  280. /// \param[in] hiFrequency false for low frequency band (422.4MHz and up), true for high frequency band (845MHz and up)
  281. /// \return true on success
  282. bool setChannel(uint16_t channel, bool hiFrequency = false);
  283. /// Sets the Network address.
  284. /// Only nodes with the same network address can communicate with each other. You
  285. /// can set different network addresses in different sets of nodes to isolate them from each other.
  286. /// The default network address is 0xE7E7E7E7
  287. /// \param[in] address The new network address. Must match the network address of any receiving node(s).
  288. /// \param[in] len Number of bytes of address to set (1 to 4).
  289. /// \return true on success, false if len is not in the range 1-4 inclusive.
  290. bool setNetworkAddress(uint8_t* address, uint8_t len);
  291. /// Sets the transmitter power to use
  292. /// \param [in] power Transmitter power. One of NRF905::TransmitPower.
  293. /// \return true on success
  294. bool setRF(TransmitPower power);
  295. /// Sets the radio in power down mode.
  296. /// Sets chip enable to LOW.
  297. /// \return true on success
  298. void setModeIdle();
  299. /// Sets the radio in RX mode.
  300. /// Sets chip enable to HIGH to enable the chip in RX mode.
  301. /// \return true on success
  302. void setModeRx();
  303. /// Sets the radio in TX mode.
  304. /// Pulses the chip enable LOW then HIGH to enable the chip in TX mode.
  305. /// \return true on success
  306. void setModeTx();
  307. /// Sends data to the address set by setTransmitAddress()
  308. /// Sets the radio to TX mode
  309. /// \param [in] data Data bytes to send.
  310. /// \param [in] len Number of data bytes to set in teh TX buffer. The actual size of the
  311. /// transmitted data payload is set by setPayloadSize
  312. /// \return true on success (which does not necessarily mean the receiver got the message, only that the message was
  313. /// successfully transmitted).
  314. bool send(const uint8_t* data, uint8_t len);
  315. /// Blocks until the current message (if any)
  316. /// has been transmitted
  317. /// \return true on success, false if the chip is not in transmit mode
  318. virtual bool waitPacketSent();
  319. /// Indicates if the chip is in transmit mode and
  320. /// there is a packet currently being transmitted
  321. /// \return true if the chip is in transmit mode and there is a transmission in progress
  322. bool isSending();
  323. /// Prints the value of a single chip register
  324. /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform
  325. /// For debugging purposes only.
  326. /// \return true on success
  327. bool printRegister(uint8_t reg);
  328. /// Prints the value of all chip registers
  329. /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform
  330. /// For debugging purposes only.
  331. /// \return true on success
  332. bool printRegisters();
  333. /// Checks whether a received message is available.
  334. /// This can be called multiple times in a timeout loop
  335. /// \return true if a complete, valid message has been received and is able to be retrieved by
  336. /// recv()
  337. bool available();
  338. /// Turns the receiver on if it not already on.
  339. /// If there is a valid message available, copy it to buf and return true
  340. /// else return false.
  341. /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).
  342. /// You should be sure to call this function frequently enough to not miss any messages
  343. /// It is recommended that you call it in your main loop.
  344. /// \param[in] buf Location to copy the received message
  345. /// \param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.
  346. /// \return true if a valid message was copied to buf
  347. bool recv(uint8_t* buf, uint8_t* len);
  348. /// The maximum message length supported by this driver
  349. /// \return The maximum message length supported by this driver
  350. uint8_t maxMessageLength();
  351. protected:
  352. /// Examine the revceive buffer to determine whether the message is for this node
  353. void validateRxBuf();
  354. /// Clear our local receive buffer
  355. void clearRxBuf();
  356. private:
  357. /// This idle mode chip configuration
  358. uint8_t _configuration;
  359. /// the number of the chip enable pin
  360. uint8_t _chipEnablePin;
  361. /// The number of the transmit enable pin
  362. uint8_t _txEnablePin;
  363. /// Number of octets in the buffer
  364. uint8_t _bufLen;
  365. /// The receiver/transmitter buffer
  366. uint8_t _buf[RH_NRF905_MAX_PAYLOAD_LEN];
  367. /// True when there is a valid message in the buffer
  368. bool _rxBufValid;
  369. };
  370. /// @example nrf905_client.pde
  371. /// @example nrf905_server.pde
  372. /// @example nrf905_reliable_datagram_client.pde
  373. /// @example nrf905_reliable_datagram_server.pde
  374. #endif