V148
Fork of RadioHead-148 by
RH_NRF51.h@0:ab4e012489ef, 2015-10-15 (annotated)
- Committer:
- davidr99
- Date:
- Thu Oct 15 01:27:00 2015 +0000
- Revision:
- 0:ab4e012489ef
Messy start, but a port for RadioHead.; Currently the SPI modulus are the only ones that work.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
davidr99 | 0:ab4e012489ef | 1 | // RH_NRF51.h |
davidr99 | 0:ab4e012489ef | 2 | // Author: Mike McCauley |
davidr99 | 0:ab4e012489ef | 3 | // Copyright (C) 2015 Mike McCauley |
davidr99 | 0:ab4e012489ef | 4 | // $Id: RH_NRF51.h,v 1.3 2015/08/14 21:20:12 mikem Exp mikem $ |
davidr99 | 0:ab4e012489ef | 5 | // |
davidr99 | 0:ab4e012489ef | 6 | |
davidr99 | 0:ab4e012489ef | 7 | #ifndef RH_NRF51_h |
davidr99 | 0:ab4e012489ef | 8 | #define RH_NRF51_h |
davidr99 | 0:ab4e012489ef | 9 | |
davidr99 | 0:ab4e012489ef | 10 | #include <RHGenericDriver.h> |
davidr99 | 0:ab4e012489ef | 11 | |
davidr99 | 0:ab4e012489ef | 12 | // This is the maximum number of bytes that can be carried by the nRF51. |
davidr99 | 0:ab4e012489ef | 13 | // We use some for headers, keeping fewer for RadioHead messages |
davidr99 | 0:ab4e012489ef | 14 | #define RH_NRF51_MAX_PAYLOAD_LEN 254 |
davidr99 | 0:ab4e012489ef | 15 | |
davidr99 | 0:ab4e012489ef | 16 | // The length of the headers we add. |
davidr99 | 0:ab4e012489ef | 17 | // The headers are inside the nRF51 payload |
davidr99 | 0:ab4e012489ef | 18 | #define RH_NRF51_HEADER_LEN 4 |
davidr99 | 0:ab4e012489ef | 19 | |
davidr99 | 0:ab4e012489ef | 20 | // This is the maximum RadioHead user message length that can be supported by this library. Limited by |
davidr99 | 0:ab4e012489ef | 21 | // the supported message lengths in the nRF51 |
davidr99 | 0:ab4e012489ef | 22 | #define RH_NRF51_MAX_MESSAGE_LEN (RH_NRF51_MAX_PAYLOAD_LEN-RH_NRF51_HEADER_LEN) |
davidr99 | 0:ab4e012489ef | 23 | |
davidr99 | 0:ab4e012489ef | 24 | ///////////////////////////////////////////////////////////////////// |
davidr99 | 0:ab4e012489ef | 25 | /// \class RH_NRF51 RH_NRF51.h <RH_NRF51.h> |
davidr99 | 0:ab4e012489ef | 26 | /// \brief Send and receive addressed datagrams by nRF51 compatible transceivers. |
davidr99 | 0:ab4e012489ef | 27 | /// |
davidr99 | 0:ab4e012489ef | 28 | /// Supported transceivers include: |
davidr99 | 0:ab4e012489ef | 29 | /// - Nordic nRF51 based 2.4GHz radio modules, such as nRF51822 |
davidr99 | 0:ab4e012489ef | 30 | /// and other compatible chips, such as used in RedBearLabs devices like: |
davidr99 | 0:ab4e012489ef | 31 | /// http://store.redbearlab.com/products/redbearlab-nrf51822 |
davidr99 | 0:ab4e012489ef | 32 | /// http://store.redbearlab.com/products/blenano |
davidr99 | 0:ab4e012489ef | 33 | /// |
davidr99 | 0:ab4e012489ef | 34 | /// This base class provides basic functions for sending and receiving unaddressed, unreliable datagrams |
davidr99 | 0:ab4e012489ef | 35 | /// of arbitrary length to 254 octets per packet. Use one of the Manager classes to get addressing and |
davidr99 | 0:ab4e012489ef | 36 | /// acknowledgement reliability, routing, meshes etc. |
davidr99 | 0:ab4e012489ef | 37 | /// |
davidr99 | 0:ab4e012489ef | 38 | /// The nRF51822 (https://www.nordicsemi.com/eng/Products/Bluetooth-Smart-Bluetooth-low-energy/nRF51822) |
davidr99 | 0:ab4e012489ef | 39 | /// is a complete SoC (system on a chip) with ARM microprocessor and 2.4 GHz radio, which supports a range of channels |
davidr99 | 0:ab4e012489ef | 40 | /// and transmission bit rates. Chip antenna is on-board. |
davidr99 | 0:ab4e012489ef | 41 | /// |
davidr99 | 0:ab4e012489ef | 42 | /// This library provides functions for sending and receiving messages of up to 254 octets on any |
davidr99 | 0:ab4e012489ef | 43 | /// frequency supported by the nRF51822, at a selected data rate. |
davidr99 | 0:ab4e012489ef | 44 | /// |
davidr99 | 0:ab4e012489ef | 45 | /// The nRF51 transceiver is configured to use Enhanced Shockburst with no acknowledgement and no retransmits. |
davidr99 | 0:ab4e012489ef | 46 | /// TXADDRESS and RXADDRESSES:RXADDR0 (ie pipe 0) are the logical address used. The on-air network address |
davidr99 | 0:ab4e012489ef | 47 | /// is set in BASE0 and PREFIX0. SHORTS is used to automatically transition the radio between Ready, Start and Disable. |
davidr99 | 0:ab4e012489ef | 48 | /// No interrupts are used. |
davidr99 | 0:ab4e012489ef | 49 | /// |
davidr99 | 0:ab4e012489ef | 50 | /// Naturally, for any 2 radios to communicate that must be configured to use the same frequency and |
davidr99 | 0:ab4e012489ef | 51 | /// data rate, and with identical network addresses. |
davidr99 | 0:ab4e012489ef | 52 | /// |
davidr99 | 0:ab4e012489ef | 53 | /// Example programs are included to show the main modes of use. |
davidr99 | 0:ab4e012489ef | 54 | /// |
davidr99 | 0:ab4e012489ef | 55 | /// \par Packet Format |
davidr99 | 0:ab4e012489ef | 56 | /// |
davidr99 | 0:ab4e012489ef | 57 | /// All messages sent and received by this class conform to this packet format. It is NOT compatible |
davidr99 | 0:ab4e012489ef | 58 | /// with the one used by RH_NRF24 and the nRF24L01 product specification, mainly because the nRF24 only suports |
davidr99 | 0:ab4e012489ef | 59 | /// 6 bits of message length. |
davidr99 | 0:ab4e012489ef | 60 | /// |
davidr99 | 0:ab4e012489ef | 61 | /// - 1 octets PREAMBLE |
davidr99 | 0:ab4e012489ef | 62 | /// - 3 to 5 octets NETWORK ADDRESS |
davidr99 | 0:ab4e012489ef | 63 | /// - 8 bits PAYLOAD LENGTH |
davidr99 | 0:ab4e012489ef | 64 | /// - 0 to 254 octets PAYLOAD, consisting of: |
davidr99 | 0:ab4e012489ef | 65 | /// - 1 octet TO header |
davidr99 | 0:ab4e012489ef | 66 | /// - 1 octet FROM header |
davidr99 | 0:ab4e012489ef | 67 | /// - 1 octet ID header |
davidr99 | 0:ab4e012489ef | 68 | /// - 1 octet FLAGS header |
davidr99 | 0:ab4e012489ef | 69 | /// - 0 to 250 octets of user message |
davidr99 | 0:ab4e012489ef | 70 | /// - 2 octets CRC (Algorithm x^16+x^12^x^5+1 with initial value 0xFFFF). |
davidr99 | 0:ab4e012489ef | 71 | /// |
davidr99 | 0:ab4e012489ef | 72 | /// \par Example programs |
davidr99 | 0:ab4e012489ef | 73 | /// |
davidr99 | 0:ab4e012489ef | 74 | /// Several example programs are provided. |
davidr99 | 0:ab4e012489ef | 75 | /// |
davidr99 | 0:ab4e012489ef | 76 | /// The sample programs are designed to be built using Arduino 1.6.4 or later using the procedures outlined |
davidr99 | 0:ab4e012489ef | 77 | /// in http://redbearlab.com/getting-started-nrf51822/ |
davidr99 | 0:ab4e012489ef | 78 | /// |
davidr99 | 0:ab4e012489ef | 79 | /// \par Radio Performance |
davidr99 | 0:ab4e012489ef | 80 | /// |
davidr99 | 0:ab4e012489ef | 81 | /// At DataRate2Mbps (2Mb/s), payload length vs airtime: |
davidr99 | 0:ab4e012489ef | 82 | /// 0 bytes takes about 70us, 128 bytes takes 520us, 254 bytes take 1020us. |
davidr99 | 0:ab4e012489ef | 83 | /// You can extrapolate linearly to slower data rates. |
davidr99 | 0:ab4e012489ef | 84 | /// |
davidr99 | 0:ab4e012489ef | 85 | /// The RF powers claimed by the chip manufacturer have not been independently verified here. |
davidr99 | 0:ab4e012489ef | 86 | /// |
davidr99 | 0:ab4e012489ef | 87 | /// \par Memory |
davidr99 | 0:ab4e012489ef | 88 | /// |
davidr99 | 0:ab4e012489ef | 89 | /// The compiled client and server sketches are about 42k bytes on Arduino. |
davidr99 | 0:ab4e012489ef | 90 | /// The reliable client and server sketches compile to about 43k bytes on Arduino. Unfortunately the |
davidr99 | 0:ab4e012489ef | 91 | /// Arduino build environmnet does not drop unused clsses and code, so the resulting programs include |
davidr99 | 0:ab4e012489ef | 92 | /// all the unused classes ad code. This needs to be revisited. |
davidr99 | 0:ab4e012489ef | 93 | /// RAM requirements are minimal. |
davidr99 | 0:ab4e012489ef | 94 | /// |
davidr99 | 0:ab4e012489ef | 95 | class RH_NRF51 : public RHGenericDriver |
davidr99 | 0:ab4e012489ef | 96 | { |
davidr99 | 0:ab4e012489ef | 97 | public: |
davidr99 | 0:ab4e012489ef | 98 | |
davidr99 | 0:ab4e012489ef | 99 | /// \brief Defines convenient values for setting data rates in setRF() |
davidr99 | 0:ab4e012489ef | 100 | typedef enum |
davidr99 | 0:ab4e012489ef | 101 | { |
davidr99 | 0:ab4e012489ef | 102 | DataRate1Mbps = 0, ///< 1 Mbps |
davidr99 | 0:ab4e012489ef | 103 | DataRate2Mbps, ///< 2 Mbps |
davidr99 | 0:ab4e012489ef | 104 | DataRate250kbps ///< 250 kbps |
davidr99 | 0:ab4e012489ef | 105 | } DataRate; |
davidr99 | 0:ab4e012489ef | 106 | |
davidr99 | 0:ab4e012489ef | 107 | /// \brief Convenient values for setting transmitter power in setRF() |
davidr99 | 0:ab4e012489ef | 108 | typedef enum |
davidr99 | 0:ab4e012489ef | 109 | { |
davidr99 | 0:ab4e012489ef | 110 | // Add 20dBm for nRF24L01p with PA and LNA modules |
davidr99 | 0:ab4e012489ef | 111 | TransmitPower4dBm = 0, ///< 4 dBm |
davidr99 | 0:ab4e012489ef | 112 | TransmitPower0dBm, ///< 0 dBm |
davidr99 | 0:ab4e012489ef | 113 | TransmitPowerm4dBm, ///< -4 dBm |
davidr99 | 0:ab4e012489ef | 114 | TransmitPowerm8dBm, ///< -8 dBm |
davidr99 | 0:ab4e012489ef | 115 | TransmitPowerm12dBm, ///< -12 dBm |
davidr99 | 0:ab4e012489ef | 116 | TransmitPowerm16dBm, ///< -16 dBm |
davidr99 | 0:ab4e012489ef | 117 | TransmitPowerm20dBm, ///< -20 dBm |
davidr99 | 0:ab4e012489ef | 118 | TransmitPowerm30dBm, ///< -30 dBm |
davidr99 | 0:ab4e012489ef | 119 | } TransmitPower; |
davidr99 | 0:ab4e012489ef | 120 | |
davidr99 | 0:ab4e012489ef | 121 | /// Constructor. |
davidr99 | 0:ab4e012489ef | 122 | /// After constructing, you must call init() to initialise the interface |
davidr99 | 0:ab4e012489ef | 123 | /// and the radio module |
davidr99 | 0:ab4e012489ef | 124 | RH_NRF51(); |
davidr99 | 0:ab4e012489ef | 125 | |
davidr99 | 0:ab4e012489ef | 126 | /// Initialises this instance and the radio module connected to it. |
davidr99 | 0:ab4e012489ef | 127 | /// The following steps are taken: |
davidr99 | 0:ab4e012489ef | 128 | /// - Start the processors High Frequency clock DC/DC converter and |
davidr99 | 0:ab4e012489ef | 129 | /// - Disable and reset the radio |
davidr99 | 0:ab4e012489ef | 130 | /// - Set the logical channel to 0 for transmit and receive (only pipe 0 is used) |
davidr99 | 0:ab4e012489ef | 131 | /// - Configure the CRC (2 octets, algorithm x^16+x^12^x^5+1 with initial value 0xffff) |
davidr99 | 0:ab4e012489ef | 132 | /// - Set the default network address of 0xE7E7E7E7E7 |
davidr99 | 0:ab4e012489ef | 133 | /// - Set channel to 2 |
davidr99 | 0:ab4e012489ef | 134 | /// - Set data rate to DataRate2Mbps |
davidr99 | 0:ab4e012489ef | 135 | /// - Set TX power to TransmitPower0dBm |
davidr99 | 0:ab4e012489ef | 136 | /// \return true if everything was successful |
davidr99 | 0:ab4e012489ef | 137 | bool init(); |
davidr99 | 0:ab4e012489ef | 138 | |
davidr99 | 0:ab4e012489ef | 139 | /// Sets the transmit and receive channel number. |
davidr99 | 0:ab4e012489ef | 140 | /// The frequency used is (2400 + channel) MHz |
davidr99 | 0:ab4e012489ef | 141 | /// \return true on success |
davidr99 | 0:ab4e012489ef | 142 | bool setChannel(uint8_t channel); |
davidr99 | 0:ab4e012489ef | 143 | |
davidr99 | 0:ab4e012489ef | 144 | /// Sets the Network address. |
davidr99 | 0:ab4e012489ef | 145 | /// Only nodes with the same network address can communicate with each other. You |
davidr99 | 0:ab4e012489ef | 146 | /// can set different network addresses in different sets of nodes to isolate them from each other. |
davidr99 | 0:ab4e012489ef | 147 | /// Internally, this sets the nRF51 BASE0 and PREFIX0 to be the given network address. |
davidr99 | 0:ab4e012489ef | 148 | /// The first octet of the address is used for PREFIX0 and the rest is used for BASE0. BALEN is |
davidr99 | 0:ab4e012489ef | 149 | /// set to the approprtae base length. |
davidr99 | 0:ab4e012489ef | 150 | /// The default network address is 0xE7E7E7E7E7. |
davidr99 | 0:ab4e012489ef | 151 | /// \param[in] address The new network address. Must match the network address of any receiving node(s). |
davidr99 | 0:ab4e012489ef | 152 | /// \param[in] len Number of bytes of address to set (3 to 5). |
davidr99 | 0:ab4e012489ef | 153 | /// \return true on success, false if len is not in the range 3-5 inclusive. |
davidr99 | 0:ab4e012489ef | 154 | bool setNetworkAddress(uint8_t* address, uint8_t len); |
davidr99 | 0:ab4e012489ef | 155 | |
davidr99 | 0:ab4e012489ef | 156 | /// Sets the data rate and transmitter power to use. |
davidr99 | 0:ab4e012489ef | 157 | /// \param [in] data_rate The data rate to use for all packets transmitted and received. One of RH_NRF51::DataRate. |
davidr99 | 0:ab4e012489ef | 158 | /// \param [in] power Transmitter power. One of RH_NRF51::TransmitPower. |
davidr99 | 0:ab4e012489ef | 159 | /// \return true on success |
davidr99 | 0:ab4e012489ef | 160 | bool setRF(DataRate data_rate, TransmitPower power); |
davidr99 | 0:ab4e012489ef | 161 | |
davidr99 | 0:ab4e012489ef | 162 | /// Sets the radio in power down mode, with the configuration set to the |
davidr99 | 0:ab4e012489ef | 163 | /// last value from setOpMode(). |
davidr99 | 0:ab4e012489ef | 164 | /// Sets chip enable to LOW. |
davidr99 | 0:ab4e012489ef | 165 | void setModeIdle(); |
davidr99 | 0:ab4e012489ef | 166 | |
davidr99 | 0:ab4e012489ef | 167 | /// Sets the radio in RX mode. |
davidr99 | 0:ab4e012489ef | 168 | void setModeRx(); |
davidr99 | 0:ab4e012489ef | 169 | |
davidr99 | 0:ab4e012489ef | 170 | /// Sets the radio in TX mode. |
davidr99 | 0:ab4e012489ef | 171 | void setModeTx(); |
davidr99 | 0:ab4e012489ef | 172 | |
davidr99 | 0:ab4e012489ef | 173 | /// Sends data to the address set by setTransmitAddress() |
davidr99 | 0:ab4e012489ef | 174 | /// Sets the radio to TX mode. |
davidr99 | 0:ab4e012489ef | 175 | /// \param [in] data Data bytes to send. |
davidr99 | 0:ab4e012489ef | 176 | /// \param [in] len Number of data bytes to send |
davidr99 | 0:ab4e012489ef | 177 | /// \return true on success (which does not necessarily mean the receiver got the message, only that the message was |
davidr99 | 0:ab4e012489ef | 178 | /// successfully transmitted). |
davidr99 | 0:ab4e012489ef | 179 | bool send(const uint8_t* data, uint8_t len); |
davidr99 | 0:ab4e012489ef | 180 | |
davidr99 | 0:ab4e012489ef | 181 | /// Blocks until the current message (if any) |
davidr99 | 0:ab4e012489ef | 182 | /// has been transmitted |
davidr99 | 0:ab4e012489ef | 183 | /// \return true on success, false if the chip is not in transmit mode or other transmit failure |
davidr99 | 0:ab4e012489ef | 184 | virtual bool waitPacketSent(); |
davidr99 | 0:ab4e012489ef | 185 | |
davidr99 | 0:ab4e012489ef | 186 | /// Indicates if the chip is in transmit mode and |
davidr99 | 0:ab4e012489ef | 187 | /// there is a packet currently being transmitted |
davidr99 | 0:ab4e012489ef | 188 | /// \return true if the chip is in transmit mode and there is a transmission in progress |
davidr99 | 0:ab4e012489ef | 189 | bool isSending(); |
davidr99 | 0:ab4e012489ef | 190 | |
davidr99 | 0:ab4e012489ef | 191 | /// Prints the value of all NRF_RADIO registers. |
davidr99 | 0:ab4e012489ef | 192 | /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform |
davidr99 | 0:ab4e012489ef | 193 | /// For debugging purposes only. |
davidr99 | 0:ab4e012489ef | 194 | /// Caution: there are 1024 of them (many reserved and set to 0). |
davidr99 | 0:ab4e012489ef | 195 | /// \return true on success |
davidr99 | 0:ab4e012489ef | 196 | bool printRegisters(); |
davidr99 | 0:ab4e012489ef | 197 | |
davidr99 | 0:ab4e012489ef | 198 | /// Checks whether a received message is available. |
davidr99 | 0:ab4e012489ef | 199 | /// This can be called multiple times in a timeout loop |
davidr99 | 0:ab4e012489ef | 200 | /// \return true if a complete, valid message has been received and is able to be retrieved by |
davidr99 | 0:ab4e012489ef | 201 | /// recv() |
davidr99 | 0:ab4e012489ef | 202 | bool available(); |
davidr99 | 0:ab4e012489ef | 203 | |
davidr99 | 0:ab4e012489ef | 204 | /// Turns the receiver on if it not already on. |
davidr99 | 0:ab4e012489ef | 205 | /// Once a message with CRC correct is received, the receiver will be returned to Idle mode. |
davidr99 | 0:ab4e012489ef | 206 | /// If there is a valid message available, copy it to buf and return true |
davidr99 | 0:ab4e012489ef | 207 | /// else return false. |
davidr99 | 0:ab4e012489ef | 208 | /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted). |
davidr99 | 0:ab4e012489ef | 209 | /// You should be sure to call this function frequently enough to not miss any messages |
davidr99 | 0:ab4e012489ef | 210 | /// It is recommended that you call it in your main loop. |
davidr99 | 0:ab4e012489ef | 211 | /// \param[in] buf Location to copy the received message |
davidr99 | 0:ab4e012489ef | 212 | /// \param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied. |
davidr99 | 0:ab4e012489ef | 213 | /// \return true if a valid message was copied to buf |
davidr99 | 0:ab4e012489ef | 214 | bool recv(uint8_t* buf, uint8_t* len); |
davidr99 | 0:ab4e012489ef | 215 | |
davidr99 | 0:ab4e012489ef | 216 | /// The maximum message length supported by this driver |
davidr99 | 0:ab4e012489ef | 217 | /// \return The maximum message length supported by this driver |
davidr99 | 0:ab4e012489ef | 218 | uint8_t maxMessageLength(); |
davidr99 | 0:ab4e012489ef | 219 | |
davidr99 | 0:ab4e012489ef | 220 | protected: |
davidr99 | 0:ab4e012489ef | 221 | /// Examine the receive buffer to determine whether the message is for this node |
davidr99 | 0:ab4e012489ef | 222 | void validateRxBuf(); |
davidr99 | 0:ab4e012489ef | 223 | |
davidr99 | 0:ab4e012489ef | 224 | /// Clear our local receive buffer |
davidr99 | 0:ab4e012489ef | 225 | void clearRxBuf(); |
davidr99 | 0:ab4e012489ef | 226 | |
davidr99 | 0:ab4e012489ef | 227 | private: |
davidr99 | 0:ab4e012489ef | 228 | /// The receiver/transmitter buffer |
davidr99 | 0:ab4e012489ef | 229 | /// First octet is the payload length, remainder is the payload |
davidr99 | 0:ab4e012489ef | 230 | uint8_t _buf[RH_NRF51_MAX_PAYLOAD_LEN+1]; |
davidr99 | 0:ab4e012489ef | 231 | |
davidr99 | 0:ab4e012489ef | 232 | /// True when there is a valid message in the buffer |
davidr99 | 0:ab4e012489ef | 233 | bool _rxBufValid; |
davidr99 | 0:ab4e012489ef | 234 | }; |
davidr99 | 0:ab4e012489ef | 235 | |
davidr99 | 0:ab4e012489ef | 236 | /// @example nrf51_client.pde |
davidr99 | 0:ab4e012489ef | 237 | /// @example nrf51_server.pde |
davidr99 | 0:ab4e012489ef | 238 | /// @example nrf51_reliable_datagram_client.pde |
davidr99 | 0:ab4e012489ef | 239 | /// @example nrf51_reliable_datagram_server.pde |
davidr99 | 0:ab4e012489ef | 240 | /// @example nrf51_audio_tx.pde |
davidr99 | 0:ab4e012489ef | 241 | /// @example nrf51_audio_rx.pde |
davidr99 | 0:ab4e012489ef | 242 | #endif |