V148
Fork of RadioHead-148 by
Diff: RH_NRF51.h
- Revision:
- 0:ab4e012489ef
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RH_NRF51.h Thu Oct 15 01:27:00 2015 +0000 @@ -0,0 +1,242 @@ +// RH_NRF51.h +// Author: Mike McCauley +// Copyright (C) 2015 Mike McCauley +// $Id: RH_NRF51.h,v 1.3 2015/08/14 21:20:12 mikem Exp mikem $ +// + +#ifndef RH_NRF51_h +#define RH_NRF51_h + +#include <RHGenericDriver.h> + +// This is the maximum number of bytes that can be carried by the nRF51. +// We use some for headers, keeping fewer for RadioHead messages +#define RH_NRF51_MAX_PAYLOAD_LEN 254 + +// The length of the headers we add. +// The headers are inside the nRF51 payload +#define RH_NRF51_HEADER_LEN 4 + +// This is the maximum RadioHead user message length that can be supported by this library. Limited by +// the supported message lengths in the nRF51 +#define RH_NRF51_MAX_MESSAGE_LEN (RH_NRF51_MAX_PAYLOAD_LEN-RH_NRF51_HEADER_LEN) + +///////////////////////////////////////////////////////////////////// +/// \class RH_NRF51 RH_NRF51.h <RH_NRF51.h> +/// \brief Send and receive addressed datagrams by nRF51 compatible transceivers. +/// +/// Supported transceivers include: +/// - Nordic nRF51 based 2.4GHz radio modules, such as nRF51822 +/// and other compatible chips, such as used in RedBearLabs devices like: +/// http://store.redbearlab.com/products/redbearlab-nrf51822 +/// http://store.redbearlab.com/products/blenano +/// +/// This base class provides basic functions for sending and receiving unaddressed, unreliable datagrams +/// of arbitrary length to 254 octets per packet. Use one of the Manager classes to get addressing and +/// acknowledgement reliability, routing, meshes etc. +/// +/// The nRF51822 (https://www.nordicsemi.com/eng/Products/Bluetooth-Smart-Bluetooth-low-energy/nRF51822) +/// is a complete SoC (system on a chip) with ARM microprocessor and 2.4 GHz radio, which supports a range of channels +/// and transmission bit rates. Chip antenna is on-board. +/// +/// This library provides functions for sending and receiving messages of up to 254 octets on any +/// frequency supported by the nRF51822, at a selected data rate. +/// +/// The nRF51 transceiver is configured to use Enhanced Shockburst with no acknowledgement and no retransmits. +/// TXADDRESS and RXADDRESSES:RXADDR0 (ie pipe 0) are the logical address used. The on-air network address +/// is set in BASE0 and PREFIX0. SHORTS is used to automatically transition the radio between Ready, Start and Disable. +/// No interrupts are used. +/// +/// Naturally, for any 2 radios to communicate that must be configured to use the same frequency and +/// data rate, and with identical network addresses. +/// +/// Example programs are included to show the main modes of use. +/// +/// \par Packet Format +/// +/// All messages sent and received by this class conform to this packet format. It is NOT compatible +/// with the one used by RH_NRF24 and the nRF24L01 product specification, mainly because the nRF24 only suports +/// 6 bits of message length. +/// +/// - 1 octets PREAMBLE +/// - 3 to 5 octets NETWORK ADDRESS +/// - 8 bits PAYLOAD LENGTH +/// - 0 to 254 octets PAYLOAD, consisting of: +/// - 1 octet TO header +/// - 1 octet FROM header +/// - 1 octet ID header +/// - 1 octet FLAGS header +/// - 0 to 250 octets of user message +/// - 2 octets CRC (Algorithm x^16+x^12^x^5+1 with initial value 0xFFFF). +/// +/// \par Example programs +/// +/// Several example programs are provided. +/// +/// The sample programs are designed to be built using Arduino 1.6.4 or later using the procedures outlined +/// in http://redbearlab.com/getting-started-nrf51822/ +/// +/// \par Radio Performance +/// +/// At DataRate2Mbps (2Mb/s), payload length vs airtime: +/// 0 bytes takes about 70us, 128 bytes takes 520us, 254 bytes take 1020us. +/// You can extrapolate linearly to slower data rates. +/// +/// The RF powers claimed by the chip manufacturer have not been independently verified here. +/// +/// \par Memory +/// +/// The compiled client and server sketches are about 42k bytes on Arduino. +/// The reliable client and server sketches compile to about 43k bytes on Arduino. Unfortunately the +/// Arduino build environmnet does not drop unused clsses and code, so the resulting programs include +/// all the unused classes ad code. This needs to be revisited. +/// RAM requirements are minimal. +/// +class RH_NRF51 : public RHGenericDriver +{ +public: + + /// \brief Defines convenient values for setting data rates in setRF() + typedef enum + { + DataRate1Mbps = 0, ///< 1 Mbps + DataRate2Mbps, ///< 2 Mbps + DataRate250kbps ///< 250 kbps + } DataRate; + + /// \brief Convenient values for setting transmitter power in setRF() + typedef enum + { + // Add 20dBm for nRF24L01p with PA and LNA modules + TransmitPower4dBm = 0, ///< 4 dBm + TransmitPower0dBm, ///< 0 dBm + TransmitPowerm4dBm, ///< -4 dBm + TransmitPowerm8dBm, ///< -8 dBm + TransmitPowerm12dBm, ///< -12 dBm + TransmitPowerm16dBm, ///< -16 dBm + TransmitPowerm20dBm, ///< -20 dBm + TransmitPowerm30dBm, ///< -30 dBm + } TransmitPower; + + /// Constructor. + /// After constructing, you must call init() to initialise the interface + /// and the radio module + RH_NRF51(); + + /// Initialises this instance and the radio module connected to it. + /// The following steps are taken: + /// - Start the processors High Frequency clock DC/DC converter and + /// - Disable and reset the radio + /// - Set the logical channel to 0 for transmit and receive (only pipe 0 is used) + /// - Configure the CRC (2 octets, algorithm x^16+x^12^x^5+1 with initial value 0xffff) + /// - Set the default network address of 0xE7E7E7E7E7 + /// - Set channel to 2 + /// - Set data rate to DataRate2Mbps + /// - Set TX power to TransmitPower0dBm + /// \return true if everything was successful + bool init(); + + /// Sets the transmit and receive channel number. + /// The frequency used is (2400 + channel) MHz + /// \return true on success + bool setChannel(uint8_t channel); + + /// Sets the Network address. + /// Only nodes with the same network address can communicate with each other. You + /// can set different network addresses in different sets of nodes to isolate them from each other. + /// Internally, this sets the nRF51 BASE0 and PREFIX0 to be the given network address. + /// The first octet of the address is used for PREFIX0 and the rest is used for BASE0. BALEN is + /// set to the approprtae base length. + /// The default network address is 0xE7E7E7E7E7. + /// \param[in] address The new network address. Must match the network address of any receiving node(s). + /// \param[in] len Number of bytes of address to set (3 to 5). + /// \return true on success, false if len is not in the range 3-5 inclusive. + bool setNetworkAddress(uint8_t* address, uint8_t len); + + /// Sets the data rate and transmitter power to use. + /// \param [in] data_rate The data rate to use for all packets transmitted and received. One of RH_NRF51::DataRate. + /// \param [in] power Transmitter power. One of RH_NRF51::TransmitPower. + /// \return true on success + bool setRF(DataRate data_rate, TransmitPower power); + + /// Sets the radio in power down mode, with the configuration set to the + /// last value from setOpMode(). + /// Sets chip enable to LOW. + void setModeIdle(); + + /// Sets the radio in RX mode. + void setModeRx(); + + /// Sets the radio in TX mode. + void setModeTx(); + + /// Sends data to the address set by setTransmitAddress() + /// Sets the radio to TX mode. + /// \param [in] data Data bytes to send. + /// \param [in] len Number of data bytes to send + /// \return true on success (which does not necessarily mean the receiver got the message, only that the message was + /// successfully transmitted). + bool send(const uint8_t* data, uint8_t len); + + /// Blocks until the current message (if any) + /// has been transmitted + /// \return true on success, false if the chip is not in transmit mode or other transmit failure + virtual bool waitPacketSent(); + + /// Indicates if the chip is in transmit mode and + /// there is a packet currently being transmitted + /// \return true if the chip is in transmit mode and there is a transmission in progress + bool isSending(); + + /// Prints the value of all NRF_RADIO registers. + /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform + /// For debugging purposes only. + /// Caution: there are 1024 of them (many reserved and set to 0). + /// \return true on success + bool printRegisters(); + + /// Checks whether a received message is available. + /// This can be called multiple times in a timeout loop + /// \return true if a complete, valid message has been received and is able to be retrieved by + /// recv() + bool available(); + + /// Turns the receiver on if it not already on. + /// Once a message with CRC correct is received, the receiver will be returned to Idle mode. + /// If there is a valid message available, copy it to buf and return true + /// else return false. + /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted). + /// You should be sure to call this function frequently enough to not miss any messages + /// It is recommended that you call it in your main loop. + /// \param[in] buf Location to copy the received message + /// \param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied. + /// \return true if a valid message was copied to buf + bool recv(uint8_t* buf, uint8_t* len); + + /// The maximum message length supported by this driver + /// \return The maximum message length supported by this driver + uint8_t maxMessageLength(); + +protected: + /// Examine the receive buffer to determine whether the message is for this node + void validateRxBuf(); + + /// Clear our local receive buffer + void clearRxBuf(); + +private: + /// The receiver/transmitter buffer + /// First octet is the payload length, remainder is the payload + uint8_t _buf[RH_NRF51_MAX_PAYLOAD_LEN+1]; + + /// True when there is a valid message in the buffer + bool _rxBufValid; +}; + +/// @example nrf51_client.pde +/// @example nrf51_server.pde +/// @example nrf51_reliable_datagram_client.pde +/// @example nrf51_reliable_datagram_server.pde +/// @example nrf51_audio_tx.pde +/// @example nrf51_audio_rx.pde +#endif