From f1a8783778188769580481d7f8851459a39b4e39 Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 22 Jul 2016 15:49:53 +0200 Subject: [PATCH 1/6] Cosmetic --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e4a2ff..5ef50a9 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,21 @@ RadioHead Packet Radio library for embedded microprocessors This is a fork of the original RadioHead Packet Radio library for embedded microprocessors. It provides a complete object-oriented library for sending and receiving packetized messages via a variety of common data radios and other transports on a range of embedded microprocessors. -Please read the full documentation and licensing from the original author [site][3], here it's just a copy to keep in sync my custom forked [version][1] with [original version][4]. +**Please read the full documentation and licensing from the original author [site][3]** + +Since I sometime need to add custom (Example for [ULPNode][6]) features to the lib but keep it in sync with the original one, I've got 2 repo: + +- My master one https://github.com/hallard/RadioHead that is the one you need if you want to use my projects or lib added features. +- The one above has been forked to https://github.com/ch2i/RadioHead where I put the original version released by the author. + + +Like this, I can do Pull Request from [ch2i][4] to [hallard][1] to add new features added by the author to my version. This mean that this [one][4] is just a github copy version of the latest original done by Mike, I don't do any change on this one. I know it's not the best way, but I didn't found a better solution for now, if you have better idea, just let me know. + + [1]: https://github.com/hallard/RadioHead [2]: https://hallard.me [3]: http://www.airspayce.com/mikem/arduino/RadioHead/ [4]: http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.61.zip +[5]: https://github.com/ch2i/RadioHead +[6]: http://hallard.me/category/ulpnode/ From cb6cf38d265a6f9c682840866ee5e29e574e1def Mon Sep 17 00:00:00 2001 From: Charles Date: Sat, 20 Aug 2016 16:57:12 +0200 Subject: [PATCH 2/6] Bump to Version 1.62 --- README.md | 2 +- RHGenericDriver.cpp | 36 +++++++++++++- RHGenericDriver.h | 47 +++++++++++++++++-- RHHardwareSPI.cpp | 2 +- RH_ASK.cpp | 8 +++- RH_ASK.h | 2 +- RH_CC110.cpp | 3 ++ RH_MRF89.cpp | 3 ++ RH_NRF24.cpp | 4 ++ RH_NRF24.h | 2 +- RH_NRF51.cpp | 4 ++ RH_NRF905.cpp | 4 ++ RH_RF22.cpp | 4 ++ RH_RF22.h | 4 +- RH_RF24.cpp | 11 +++-- RH_RF24.h | 7 ++- RH_RF69.cpp | 3 ++ RH_RF69.h | 2 +- RH_RF95.cpp | 24 ++++++++++ RH_RF95.h | 20 +++++++- RH_Serial.cpp | 3 ++ RH_TCP.cpp | 3 ++ RadioHead.h | 12 +++-- .../rf95_reliable_datagram_client.pde | 4 ++ .../rf95_reliable_datagram_server.pde | 4 ++ 25 files changed, 196 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 0e4a2ff..9d2cf9d 100644 --- a/README.md +++ b/README.md @@ -8,4 +8,4 @@ Please read the full documentation and licensing from the original author [site] [1]: https://github.com/hallard/RadioHead [2]: https://hallard.me [3]: http://www.airspayce.com/mikem/arduino/RadioHead/ -[4]: http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.61.zip +[4]: http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.62.zip diff --git a/RHGenericDriver.cpp b/RHGenericDriver.cpp index 7a21e3e..19567cf 100644 --- a/RHGenericDriver.cpp +++ b/RHGenericDriver.cpp @@ -15,7 +15,8 @@ RHGenericDriver::RHGenericDriver() _txHeaderFlags(0), _rxBad(0), _rxGood(0), - _txGood(0) + _txGood(0), + _cad_timeout(0) { } @@ -67,6 +68,34 @@ bool RHGenericDriver::waitPacketSent(uint16_t timeout) return false; } +// Wait until no channel activity detected or timeout +bool RHGenericDriver::waitCAD() +{ + if (!_cad_timeout) + return true; + + // Wait for any channel activity to finish or timeout + // Sophisticated DCF function... + // DCF : BackoffTime = random() x aSlotTime + // 100 - 1000 ms + // 10 sec timeout + unsigned long t = millis(); + while (isChannelActive()) + { + if (millis() - t > _cad_timeout) + return false; + delay(random(1, 10) * 100); // Should these values be configurable? Macros? + } + + return true; +} + +// subclasses are expected to override if CAD is available for that radio +bool RHGenericDriver::isChannelActive() +{ + return false; +} + void RHGenericDriver::setPromiscuous(bool promiscuous) { _promiscuous = promiscuous; @@ -174,6 +203,11 @@ uint16_t RHGenericDriver::txGood() return _txGood; } +void RHGenericDriver::setCADTimeout(unsigned long cad_timeout) +{ + _cad_timeout = cad_timeout; +} + #if (RH_PLATFORM == RH_PLATFORM_ARDUINO) && defined(RH_PLATFORM_ATTINY) // Tinycore does not have __cxa_pure_virtual, so without this we // get linking complaints from the default code generated for pure virtual functions diff --git a/RHGenericDriver.h b/RHGenericDriver.h index 11ad607..3e3c9a9 100644 --- a/RHGenericDriver.h +++ b/RHGenericDriver.h @@ -14,6 +14,9 @@ #define RH_FLAGS_APPLICATION_SPECIFIC 0x0f #define RH_FLAGS_NONE 0 +// Default timeout for waitCAD() in ms +#define RH_CAD_DEFAULT_TIMEOUT 10000 + ///////////////////////////////////////////////////////////////////// /// \class RHGenericDriver RHGenericDriver.h /// \brief Abstract base class for a RadioHead driver. @@ -48,7 +51,8 @@ class RHGenericDriver RHModeSleep, ///< Transport hardware is in low power sleep mode (if supported) RHModeIdle, ///< Transport is idle. RHModeTx, ///< Transport is in the process of transmitting a message. - RHModeRx ///< Transport is in the process of receiving a message. + RHModeRx, ///< Transport is in the process of receiving a message. + RHModeCad ///< Transport is in the process of detecting channel activity (if supported) } RHMode; /// Constructor @@ -80,12 +84,16 @@ class RHGenericDriver virtual bool recv(uint8_t* buf, uint8_t* len) = 0; /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent(). + /// Then optionally waits for Channel Activity Detection (CAD) + /// to show the channnel is clear (if the radio supports CAD) by calling waitCAD(). /// Then loads a message into the transmitter and starts the transmitter. Note that a message length /// of 0 is NOT permitted. If the message is too long for the underlying radio technology, send() will /// return false and will not send the message. /// \param[in] data Array of data to be sent /// \param[in] len Number of bytes of data to send (> 0) - /// \return true if the message length was valid and it was correctly queued for transmit + /// specify the maximum time in ms to wait. If 0 (the default) do not wait for CAD before transmitting. + /// \return true if the message length was valid and it was correctly queued for transmit. Return false + /// if CAD was requested and the CAD timeout timed out before clear channel was detected. virtual bool send(const uint8_t* data, uint8_t len) = 0; /// Returns the maximum message length @@ -104,7 +112,7 @@ class RHGenericDriver /// Blocks until the transmitter is no longer transmitting. /// or until the timeout occuers, whichever happens first /// \param[in] timeout Maximum time to wait in milliseconds. - /// \return true if the RF22 completed transmission within the timeout period. False if it timed out. + /// \return true if the radio completed transmission within the timeout period. False if it timed out. virtual bool waitPacketSent(uint16_t timeout); /// Starts the receiver and blocks until a received message is available or a timeout @@ -112,6 +120,35 @@ class RHGenericDriver /// \return true if a message is available virtual bool waitAvailableTimeout(uint16_t timeout); + // Bent G Christensen (bentor@gmail.com), 08/15/2016 + /// Channel Activity Detection (CAD). + /// Blocks until channel activity is finished or CAD timeout occurs. + /// Uses the radio's CAD function (if supported) to detect channel activity. + /// Implements random delays of 100 to 1000ms while activity is detected and until timeout. + /// Caution: the random() function is not seeded. If you want non-deterministic behaviour, consider + /// using something like randomSeed(analogRead(A0)); in your sketch. + /// Permits the implementation of listen-before-talk mechanism (Collision Avoidance). + /// Calls the isChannelActive() member function for the radio (if supported) + /// to determine if the channel is active. If the radio does not support isChannelActive(), + /// always returns true immediately + /// \return true if the radio-specific CAD (as returned by isChannelActive()) + /// shows the channel is clear within the timeout period (or the timeout period is 0), else returns false. + virtual bool waitCAD(); + + /// Sets the Channel Activity Detection timeout in milliseconds to be used by waitCAD(). + /// The default is 0, which means do not wait for CAD detection. + /// CAD detection depends on support for isChannelActive() by your particular radio. + void setCADTimeout(unsigned long cad_timeout); + + /// Determine if the currently selected radio channel is active. + /// This is expected to be subclassed by specific radios to implement their Channel Activity Detection + /// if supported. If the radio does not support CAD, returns true immediately. If a RadioHead radio + /// supports isChannelActive() it will be documented in the radio specific documentation. + /// This is called automatically by waitCAD(). + /// \return true if the radio-specific CAD (as returned by override of isChannelActive()) shows the + /// current radio channel as active, else false. If there is no radio-specific CAD, returns false. + virtual bool isChannelActive(); + /// Sets the address of this node. Defaults to 0xFF. Subclasses or the user may want to change this. /// This will be used to test the adddress in incoming messages. In non-promiscuous mode, /// only messages with a TO header the same as thisAddress or the broadcast addess (0xFF) will be accepted. @@ -257,6 +294,10 @@ class RHGenericDriver /// Count of the number of bad messages (correct checksum etc) received volatile uint16_t _txGood; + /// Channel activity detected + volatile bool _cad; + unsigned int _cad_timeout; + private: }; diff --git a/RHHardwareSPI.cpp b/RHHardwareSPI.cpp index ef3b90d..12d2e02 100644 --- a/RHHardwareSPI.cpp +++ b/RHHardwareSPI.cpp @@ -2,7 +2,7 @@ // Author: Mike McCauley (mikem@airspayce.com) // Copyright (C) 2011 Mike McCauley // Contributed by Joanna Rutkowska -// $Id: RHHardwareSPI.cpp,v 1.16 2016/07/07 00:02:53 mikem Exp mikem $ +// $Id: RHHardwareSPI.cpp,v 1.16 2016/07/07 00:02:53 mikem Exp $ #include diff --git a/RH_ASK.cpp b/RH_ASK.cpp index 70fe0c5..f9a8d02 100644 --- a/RH_ASK.cpp +++ b/RH_ASK.cpp @@ -1,7 +1,7 @@ // RH_ASK.cpp // // Copyright (C) 2014 Mike McCauley -// $Id: RH_ASK.cpp,v 1.18 2016/07/07 00:02:53 mikem Exp mikem $ +// $Id: RH_ASK.cpp,v 1.19 2016/08/17 01:53:21 mikem Exp mikem $ #include #include @@ -47,7 +47,8 @@ RH_ASK::RH_ASK(uint16_t speed, uint8_t rxPin, uint8_t txPin, uint8_t pttPin, boo _rxPin(rxPin), _txPin(txPin), _pttPin(pttPin), - _pttInverted(pttInverted) + _pttInverted(pttInverted), + _rxInverted(false) { // Initialise the first 8 nibbles of the tx buffer to be the standard // preamble. We will append messages after that. 0x38, 0x2c is the start symbol before @@ -481,6 +482,9 @@ bool RH_ASK::send(const uint8_t* data, uint8_t len) // Wait for transmitter to become available waitPacketSent(); + if (!waitCAD()) + return false; // Check channel activity + // Encode the message length crc = RHcrc_ccitt_update(crc, count); p[index++] = symbols[count >> 4]; diff --git a/RH_ASK.h b/RH_ASK.h index 8e1dfa8..9c6d6e9 100644 --- a/RH_ASK.h +++ b/RH_ASK.h @@ -1,7 +1,7 @@ // RH_ASK.h // // Copyright (C) 2014 Mike McCauley -// $Id: RH_ASK.h,v 1.16 2016/07/07 00:02:53 mikem Exp mikem $ +// $Id: RH_ASK.h,v 1.16 2016/07/07 00:02:53 mikem Exp $ #ifndef RH_ASK_h #define RH_ASK_h diff --git a/RH_CC110.cpp b/RH_CC110.cpp index 3a3ebbf..f51e1b3 100644 --- a/RH_CC110.cpp +++ b/RH_CC110.cpp @@ -301,6 +301,9 @@ bool RH_CC110::send(const uint8_t* data, uint8_t len) waitPacketSent(); // Make sure we dont interrupt an outgoing message setModeIdle(); + if (!waitCAD()) + return false; // Check channel activity + spiWriteRegister(RH_CC110_REG_3F_FIFO, len + RH_CC110_HEADER_LEN); spiWriteRegister(RH_CC110_REG_3F_FIFO,_txHeaderTo); spiWriteRegister(RH_CC110_REG_3F_FIFO,_txHeaderFrom); diff --git a/RH_MRF89.cpp b/RH_MRF89.cpp index 199fa37..613da7d 100644 --- a/RH_MRF89.cpp +++ b/RH_MRF89.cpp @@ -391,6 +391,9 @@ bool RH_MRF89::send(const uint8_t* data, uint8_t len) waitPacketSent(); // Make sure we dont interrupt an outgoing message setModeIdle(); + if (!waitCAD()) + return false; // Check channel activity + // First octet is the length of the chip payload // 0 length messages are transmitted but never trigger a receive! spiWriteData(len + RH_MRF89_HEADER_LEN); diff --git a/RH_NRF24.cpp b/RH_NRF24.cpp index 909acb1..3f42a68 100644 --- a/RH_NRF24.cpp +++ b/RH_NRF24.cpp @@ -187,6 +187,10 @@ bool RH_NRF24::send(const uint8_t* data, uint8_t len) { if (len > RH_NRF24_MAX_MESSAGE_LEN) return false; + + if (!waitCAD()) + return false; // Check channel activity + // Set up the headers _buf[0] = _txHeaderTo; _buf[1] = _txHeaderFrom; diff --git a/RH_NRF24.h b/RH_NRF24.h index 5adb4d9..6eb9d6b 100644 --- a/RH_NRF24.h +++ b/RH_NRF24.h @@ -1,7 +1,7 @@ // RH_NRF24.h // Author: Mike McCauley // Copyright (C) 2012 Mike McCauley -// $Id: RH_NRF24.h,v 1.19 2016/07/07 00:02:53 mikem Exp mikem $ +// $Id: RH_NRF24.h,v 1.19 2016/07/07 00:02:53 mikem Exp $ // #ifndef RH_NRF24_h diff --git a/RH_NRF51.cpp b/RH_NRF51.cpp index d6d788d..bc6896e 100644 --- a/RH_NRF51.cpp +++ b/RH_NRF51.cpp @@ -166,6 +166,10 @@ bool RH_NRF51::send(const uint8_t* data, uint8_t len) { if (len > RH_NRF51_MAX_MESSAGE_LEN) return false; + + if (!waitCAD()) + return false; // Check channel activity + // Set up the headers _buf[0] = len + RH_NRF51_HEADER_LEN; _buf[1] = _txHeaderTo; diff --git a/RH_NRF905.cpp b/RH_NRF905.cpp index 9f1ee07..bd572ac 100644 --- a/RH_NRF905.cpp +++ b/RH_NRF905.cpp @@ -142,6 +142,10 @@ bool RH_NRF905::send(const uint8_t* data, uint8_t len) { if (len > RH_NRF905_MAX_MESSAGE_LEN) return false; + + if (!waitCAD()) + return false; // Check channel activity + // Set up the headers _buf[0] = _txHeaderTo; _buf[1] = _txHeaderFrom; diff --git a/RH_RF22.cpp b/RH_RF22.cpp index e185251..c3d7578 100644 --- a/RH_RF22.cpp +++ b/RH_RF22.cpp @@ -587,6 +587,10 @@ bool RH_RF22::send(const uint8_t* data, uint8_t len) { bool ret = true; waitPacketSent(); + + if (!waitCAD()) + return false; // Check channel activity + ATOMIC_BLOCK_START; spiWrite(RH_RF22_REG_3A_TRANSMIT_HEADER3, _txHeaderTo); spiWrite(RH_RF22_REG_3B_TRANSMIT_HEADER2, _txHeaderFrom); diff --git a/RH_RF22.h b/RH_RF22.h index 9fddd76..bb636ff 100644 --- a/RH_RF22.h +++ b/RH_RF22.h @@ -1,7 +1,7 @@ // RH_RF22.h // Author: Mike McCauley (mikem@airspayce.com) // Copyright (C) 2011 Mike McCauley -// $Id: RH_RF22.h,v 1.30 2016/07/07 00:02:53 mikem Exp mikem $ +// $Id: RH_RF22.h,v 1.31 2016/08/17 01:53:21 mikem Exp mikem $ // #ifndef RH_RF22_h @@ -486,6 +486,8 @@ /// The physical connection between the RF22B and the Arduino requires 3.3V, /// the 3 x SPI pins (SCK, SDI, SDO), a Slave Select pin and an interrupt pin. /// +/// Note: some devices may need a pullup resister on the SDO line. +/// /// Note also that on the RFM22B (but not the RFM23B), it is required to control the TX_ANT and /// RX_ANT pins of the RFM22 in order to control the antenna connection properly. The RH_RF22 /// driver is configured by default so that GPIO0 and GPIO1 outputs can diff --git a/RH_RF24.cpp b/RH_RF24.cpp index 49de5e3..fc29b0b 100644 --- a/RH_RF24.cpp +++ b/RH_RF24.cpp @@ -1,7 +1,7 @@ // RH_RF24.cpp // // Copyright (C) 2011 Mike McCauley -// $Id: RH_RF24.cpp,v 1.16 2016/04/04 01:40:12 mikem Exp $ +// $Id: RH_RF24.cpp,v 1.17 2016/08/17 01:53:21 mikem Exp mikem $ #include // Generated with Silicon Labs WDS software: @@ -17,11 +17,13 @@ uint8_t RH_RF24::_interruptCount = 0; // Index into _deviceForInterrupt for next // which was generated with the Silicon Labs WDS program PROGMEM const uint8_t RFM26_CONFIGURATION_DATA[] = RADIO_CONFIGURATION_DATA_ARRAY; -// These configurations were all generated originally by the Silicon LAbs WDS configuration tool. +// These configurations were all generated originally by the Silicon LAbs WDS configuration tool, configured with +// a 30MHz XO. // The configurations were imported into RH_RF24, the complete properties set dumped to a file with printRegisters, then // RH_RF24_property_data/convert.pl was used to generate the entry for this table. // Contributions of new complete and tested ModemConfigs ready to add to this list will be readily accepted. -// Casual suggestions of new schemes without working examples will probably be passed over +// Casual suggestions of new schemes without working examples will probably be passed over. +// Devices with an XO of other than 30MHz will result in incorrect radio frequency and other settings. PROGMEM static const RH_RF24::ModemConfig MODEM_CONFIG_TABLE[] = { // These were generated with convert.pl from data in RH_RF24_property_data @@ -345,6 +347,9 @@ bool RH_RF24::send(const uint8_t* data, uint8_t len) waitPacketSent(); // Make sure we dont interrupt an outgoing message setModeIdle(); // Prevent RX while filling the fifo + if (!waitCAD()) + return false; // Check channel activity + // Put the payload in the FIFO // First the length in fixed length field 1. This wont appear in the receiver fifo since // we have turned off IN_FIFO in PKT_LEN diff --git a/RH_RF24.h b/RH_RF24.h index e38d16a..dddc208 100644 --- a/RH_RF24.h +++ b/RH_RF24.h @@ -1,7 +1,7 @@ // RH_RF24.h // Author: Mike McCauley (mikem@airspayce.com) // Copyright (C) 2014 Mike McCauley -// $Id: RH_RF24.h,v 1.14 2015/12/11 01:10:24 mikem Exp $ +// $Id: RH_RF24.h,v 1.15 2016/08/17 01:53:21 mikem Exp mikem $ // // Supports RF24/RF26 and RFM24/RFM26 modules in FIFO mode // also Si4464/63/62/61/60-A1 @@ -581,7 +581,8 @@ /// /// \par Customising /// -/// The library will work out of the box with the provided examples, over the full frequency range and with +/// The library will work out of the box with the provided examples on a radio with a 30MHz crystal, +/// over the full frequency range and with /// a wide range of predefined modem configurations schemes and speeds. However, you may want to /// change the default behaviour of this library. There are several ways you can do this: /// @@ -590,6 +591,8 @@ /// - Generate a new radio_config_Si4460.h using the Silicon Labs WDS software package /// - Write directly to the radio registers and properties using command() and set_properties() /// +/// If your radio module has an XO crystal of other than 30MHz, you can change the value of +/// RADIO_CONFIGURATION_DATA_RADIO_XO_FREQ in radio_config_Si4460.h /// \par RSSI /// /// The RSSI (Received Signal Strength Indicator) is measured and latched after the message sync bytes are received. diff --git a/RH_RF69.cpp b/RH_RF69.cpp index 1eff6be..1e95327 100644 --- a/RH_RF69.cpp +++ b/RH_RF69.cpp @@ -499,6 +499,9 @@ bool RH_RF69::send(const uint8_t* data, uint8_t len) waitPacketSent(); // Make sure we dont interrupt an outgoing message setModeIdle(); // Prevent RX while filling the fifo + if (!waitCAD()) + return false; // Check channel activity + ATOMIC_BLOCK_START; digitalWrite(_slaveSelectPin, LOW); _spi.transfer(RH_RF69_REG_00_FIFO | RH_RF69_SPI_WRITE_MASK); // Send the start address with the write mask on diff --git a/RH_RF69.h b/RH_RF69.h index c4b4b0d..f52ecef 100644 --- a/RH_RF69.h +++ b/RH_RF69.h @@ -1,7 +1,7 @@ // RH_RF69.h // Author: Mike McCauley (mikem@airspayce.com) // Copyright (C) 2014 Mike McCauley -// $Id: RH_RF69.h,v 1.32 2016/07/07 00:02:53 mikem Exp mikem $ +// $Id: RH_RF69.h,v 1.32 2016/07/07 00:02:53 mikem Exp $ // /// diff --git a/RH_RF95.cpp b/RH_RF95.cpp index 53fd455..8bc8178 100644 --- a/RH_RF95.cpp +++ b/RH_RF95.cpp @@ -152,6 +152,11 @@ void RH_RF95::handleInterrupt() _txGood++; setModeIdle(); } + else if (_mode == RHModeCad && irq_flags & RH_RF95_CAD_DONE) + { + _cad = irq_flags & RH_RF95_CAD_DETECTED; + setModeIdle(); + } spiWrite(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags } @@ -235,6 +240,9 @@ bool RH_RF95::send(const uint8_t* data, uint8_t len) waitPacketSent(); // Make sure we dont interrupt an outgoing message setModeIdle(); + if (!waitCAD()) + return false; // Check channel activity + // Position at the beginning of the FIFO spiWrite(RH_RF95_REG_0D_FIFO_ADDR_PTR, 0); // The headers @@ -392,3 +400,19 @@ void RH_RF95::setPreambleLength(uint16_t bytes) spiWrite(RH_RF95_REG_21_PREAMBLE_LSB, bytes & 0xff); } +bool RH_RF95::isChannelActive() +{ + // Set mode RHModeCad + if (_mode != RHModeCad) + { + spiWrite(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_CAD); + spiWrite(RH_RF95_REG_40_DIO_MAPPING1, 0x80); // Interrupt on CadDone + _mode = RHModeCad; + } + + while (_mode == RHModeCad) + YIELD; + + return _cad; +} + diff --git a/RH_RF95.h b/RH_RF95.h index 2c70b3b..066d5f8 100644 --- a/RH_RF95.h +++ b/RH_RF95.h @@ -6,7 +6,7 @@ // // Author: Mike McCauley (mikem@airspayce.com) // Copyright (C) 2014 Mike McCauley -// $Id: RH_RF95.h,v 1.11 2016/07/07 00:02:53 mikem Exp mikem $ +// $Id: RH_RF95.h,v 1.12 2016/08/17 01:53:21 mikem Exp mikem $ // #ifndef RH_RF95_h @@ -535,6 +535,9 @@ class RH_RF95 : public RHSPIDriver /// introduced in later versions (though we will try to avoid it). /// Caution: if you are using slow packet rates and long packets with RHReliableDatagram or subclasses /// you may need to change the RHReliableDatagram timeout for reliable operations. + /// Caution: for some slow rates nad with ReliableDatagrams youi may need to increase the reply timeout + /// with manager.setTimeout() to + /// deal with the long transmission times. typedef enum { Bw125Cr45Sf128 = 0, ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range @@ -607,11 +610,15 @@ class RH_RF95 : public RHSPIDriver virtual bool recv(uint8_t* buf, uint8_t* len); /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent(). + /// Then optionally waits for Channel Activity Detection (CAD) + /// to show the channnel is clear (if the radio supports CAD) by calling waitCAD(). /// Then loads a message into the transmitter and starts the transmitter. Note that a message length /// of 0 is permitted. /// \param[in] data Array of data to be sent /// \param[in] len Number of bytes of data to send - /// \return true if the message length was valid and it was correctly queued for transmit + /// specify the maximum time in ms to wait. If 0 (the default) do not wait for CAD before transmitting. + /// \return true if the message length was valid and it was correctly queued for transmit. Return false + /// if CAD was requested and the CAD timeout timed out before clear channel was detected. virtual bool send(const uint8_t* data, uint8_t len); /// Sets the length of the preamble @@ -674,6 +681,15 @@ class RH_RF95 : public RHSPIDriver /// \return true if sleep mode was successfully entered. virtual bool sleep(); + // Bent G Christensen (bentor@gmail.com), 08/15/2016 + /// Use the radio's Channel Activity Detect (CAD) function to detect channel activity. + /// Sets the RF95 radio into CAD mode and waits until CAD detection is complete. + /// To be used in a listen-before-talk mechanism (Collision Avoidance) + /// with a reasonable time backoff algorithm. + /// This is called automatically by waitCAD(). + /// \return true if channel is in use. + virtual bool isChannelActive(); + protected: /// This is a low level function to handle the interrupts for one instance of RH_RF95. /// Called automatically by isr*() diff --git a/RH_Serial.cpp b/RH_Serial.cpp index 97e6fd0..e67e84d 100644 --- a/RH_Serial.cpp +++ b/RH_Serial.cpp @@ -200,6 +200,9 @@ bool RH_Serial::recv(uint8_t* buf, uint8_t* len) // Caution: this may block bool RH_Serial::send(const uint8_t* data, uint8_t len) { + if (!waitCAD()) + return false; // Check channel activity + _txFcs = 0xffff; // Initial value _serial.write(DLE); // Not in FCS _serial.write(STX); // Not in FCS diff --git a/RH_TCP.cpp b/RH_TCP.cpp index 5c817d8..1da94cc 100644 --- a/RH_TCP.cpp +++ b/RH_TCP.cpp @@ -254,6 +254,9 @@ bool RH_TCP::recv(uint8_t* buf, uint8_t* len) bool RH_TCP::send(const uint8_t* data, uint8_t len) { + if (!waitCAD()) + return false; // Check channel activity (prob not possible for this driver?) + bool ret = sendPacket(data, len); delay(10); // Wait for transmit to succeed. REVISIT: depends on length and speed return ret; diff --git a/RadioHead.h b/RadioHead.h index 3979c18..0d6ef30 100644 --- a/RadioHead.h +++ b/RadioHead.h @@ -1,7 +1,7 @@ // RadioHead.h // Author: Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY // Copyright (C) 2014 Mike McCauley -// $Id: RadioHead.h,v 1.56 2016/07/07 00:02:53 mikem Exp mikem $ +// $Id: RadioHead.h,v 1.57 2016/08/17 01:53:21 mikem Exp mikem $ /// \mainpage RadioHead Packet Radio library for embedded microprocessors /// @@ -10,7 +10,7 @@ /// via a variety of common data radios and other transports on a range of embedded microprocessors. /// /// The version of the package that this documentation refers to can be downloaded -/// from http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.61.zip +/// from http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.62.zip /// You can find the latest version at http://www.airspayce.com/mikem/arduino/RadioHead /// /// You can also find online help and discussion at @@ -662,6 +662,12 @@ /// Added support for ESP8266 SPI, provided by David Skinner. /// \version 1.61 2016-07-07 /// Patch to RH_ASK.cpp for ESP8266, to prevent crashes in interrupt handlers. Patch from Alexander Mamchits. +/// \version 1.62 2016-08-17 +/// Fixed a problem in RH_ASK where _rxInverted was not properly initialised. Reported by "gno.sun.sop". +/// Added support for waitCAD() and isChannelActive() and setCADTimeout() to RHGeneric. +/// Implementation of RH_RF95::isChannelActive() allows the RF95 module to support +/// Channel Activity Detection (CAD). Based on code contributed by Bent Guldbjerg Christensen. +/// Implmentations of isChannelActive() plus documentation for other radio modules wil be welcomed. /// /// \author Mike McCauley. DO NOT CONTACT THE AUTHOR DIRECTLY. USE THE MAILING LIST GIVEN ABOVE @@ -670,7 +676,7 @@ // Official version numbers are maintained automatically by Makefile: #define RH_VERSION_MAJOR 1 -#define RH_VERSION_MINOR 61 +#define RH_VERSION_MINOR 62 // Symbolic names for currently supported platform types #define RH_PLATFORM_ARDUINO 1 diff --git a/examples/rf95/rf95_reliable_datagram_client/rf95_reliable_datagram_client.pde b/examples/rf95/rf95_reliable_datagram_client/rf95_reliable_datagram_client.pde index c904ce5..976554c 100644 --- a/examples/rf95/rf95_reliable_datagram_client/rf95_reliable_datagram_client.pde +++ b/examples/rf95/rf95_reliable_datagram_client/rf95_reliable_datagram_client.pde @@ -44,6 +44,10 @@ void setup() // then you can configure the power transmitter power for -1 to 14 dBm and with useRFO true. // Failure to do that will result in extremely low transmit powers. // driver.setTxPower(14, true); + // You can optionally require this module to wait until Channel Activity + // Detection shows no activity on the channel before transmitting by setting + // the CAD timeout to non-zero: +// driver.setCADTimeout(10000); } uint8_t data[] = "Hello World!"; diff --git a/examples/rf95/rf95_reliable_datagram_server/rf95_reliable_datagram_server.pde b/examples/rf95/rf95_reliable_datagram_server/rf95_reliable_datagram_server.pde index 615a01a..fc5caa7 100644 --- a/examples/rf95/rf95_reliable_datagram_server/rf95_reliable_datagram_server.pde +++ b/examples/rf95/rf95_reliable_datagram_server/rf95_reliable_datagram_server.pde @@ -44,6 +44,10 @@ void setup() // then you can configure the power transmitter power for -1 to 14 dBm and with useRFO true. // Failure to do that will result in extremely low transmit powers. // driver.setTxPower(14, true); + // You can optionally require this module to wait until Channel Activity + // Detection shows no activity on the channel before transmitting by setting + // the CAD timeout to non-zero: +// driver.setCADTimeout(10000); } uint8_t data[] = "And hello back to you"; From ed69396aac6d7cb4eb3107ae8eb2ad4326dafe7c Mon Sep 17 00:00:00 2001 From: Charles Date: Sat, 20 Aug 2016 17:07:34 +0200 Subject: [PATCH 3/6] Creation --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..0b5c8be --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +RadioHead Packet Radio library for embedded microprocessors +=========================================================== + +**Version 1.62** + +This is a copy of the original RadioHead Packet Radio library for embedded microprocessors. It provides a complete object-oriented library for sending and receiving packetized messages via a variety of common data radios and other transports on a range of embedded microprocessors. + +Please read the full documentation and licensing from the original author [site][3], here it's just a copy to keep in sync my custom featured [version][1] with this [original version][4]. + +[1]: https://github.com/hallard/RadioHead +[2]: https://hallard.me +[3]: http://www.airspayce.com/mikem/arduino/RadioHead/ +[4]: http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.62.zip \ No newline at end of file From 4dbddbd039f79036e6b2a1652ea471b2a543171d Mon Sep 17 00:00:00 2001 From: Charles Date: Sat, 20 Aug 2016 17:10:50 +0200 Subject: [PATCH 4/6] Added Link to forked repo --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0b5c8be..b8f019d 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,15 @@ RadioHead Packet Radio library for embedded microprocessors =========================================================== -**Version 1.62** +###Version 1.62 This is a copy of the original RadioHead Packet Radio library for embedded microprocessors. It provides a complete object-oriented library for sending and receiving packetized messages via a variety of common data radios and other transports on a range of embedded microprocessors. Please read the full documentation and licensing from the original author [site][3], here it's just a copy to keep in sync my custom featured [version][1] with this [original version][4]. + +**If you want to know what features have been added for my custom needs, please see my [repo version README][1]** [1]: https://github.com/hallard/RadioHead [2]: https://hallard.me [3]: http://www.airspayce.com/mikem/arduino/RadioHead/ -[4]: http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.62.zip \ No newline at end of file +[4]: http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.62.zip From f54eae59f25c882e040de643164cbf85e1c64358 Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 20 Jan 2017 00:26:47 +0100 Subject: [PATCH 5/6] Bump to V1.67 --- RHGenericDriver.cpp | 2 +- RHGenericDriver.h | 2 +- RHHardwareSPI.h | 4 +- RHReliableDatagram.cpp | 3 +- RH_ASK.cpp | 2 +- RH_CC110.cpp | 2 +- RH_MRF89.cpp | 2 +- RH_NRF24.cpp | 2 +- RH_NRF51.cpp | 173 ++++++++++++++---- RH_NRF51.h | 76 +++++++- RH_NRF905.cpp | 2 +- RH_NRF905.h | 9 +- RH_RF22.cpp | 2 +- RH_RF22.h | 2 +- RH_RF24.cpp | 2 +- RH_RF24.h | 2 +- RH_RF69.cpp | 2 +- RH_RF69.h | 30 ++- RH_RF95.cpp | 10 +- RH_RF95.h | 71 +++++-- RH_Serial.cpp | 2 +- RH_TCP.cpp | 2 +- RadioHead.h | 41 ++++- examples/nrf51/nrf51_client/nrf51_client.pde | 13 +- .../nrf51_reliable_datagram_client.pde | 2 + .../nrf51_reliable_datagram_server.pde | 2 + examples/nrf51/nrf51_server/nrf51_server.pde | 7 + examples/rf69/rf69_client/rf69_client.pde | 4 + .../rf69_reliable_datagram_client.pde | 5 +- .../rf69_reliable_datagram_server.pde | 3 + examples/rf69/rf69_server/rf69_server.pde | 3 + project.cfg | 145 ++++++++++----- 32 files changed, 486 insertions(+), 143 deletions(-) diff --git a/RHGenericDriver.cpp b/RHGenericDriver.cpp index 19567cf..4956771 100644 --- a/RHGenericDriver.cpp +++ b/RHGenericDriver.cpp @@ -1,7 +1,7 @@ // RHGenericDriver.cpp // // Copyright (C) 2014 Mike McCauley -// $Id: RHGenericDriver.cpp,v 1.19 2015/12/11 01:10:24 mikem Exp $ +// $Id: RHGenericDriver.cpp,v 1.20 2017/01/12 23:58:00 mikem Exp $ #include diff --git a/RHGenericDriver.h b/RHGenericDriver.h index 3e3c9a9..8eca374 100644 --- a/RHGenericDriver.h +++ b/RHGenericDriver.h @@ -1,7 +1,7 @@ // RHGenericDriver.h // Author: Mike McCauley (mikem@airspayce.com) // Copyright (C) 2014 Mike McCauley -// $Id: RHGenericDriver.h,v 1.17 2016/04/04 01:40:12 mikem Exp $ +// $Id: RHGenericDriver.h,v 1.18 2017/01/12 23:58:00 mikem Exp $ #ifndef RHGenericDriver_h #define RHGenericDriver_h diff --git a/RHHardwareSPI.h b/RHHardwareSPI.h index c5c8fae..dc66c1a 100644 --- a/RHHardwareSPI.h +++ b/RHHardwareSPI.h @@ -2,7 +2,7 @@ // Author: Mike McCauley (mikem@airspayce.com) // Copyright (C) 2011 Mike McCauley // Contributed by Joanna Rutkowska -// $Id: RHHardwareSPI.h,v 1.9 2014/08/12 00:54:52 mikem Exp $ +// $Id: RHHardwareSPI.h,v 1.10 2017/01/12 23:58:00 mikem Exp $ #ifndef RHHardwareSPI_h #define RHHardwareSPI_h @@ -54,7 +54,7 @@ class RHHardwareSPI : public RHGenericSPI void end(); #else // not supported on ATTiny etc - uint8_t transfer(uint8_t data) {return 0;} + uint8_t transfer(uint8_t /*data*/) {return 0;} void begin(){} void end(){} diff --git a/RHReliableDatagram.cpp b/RHReliableDatagram.cpp index a69b091..b8aa22e 100644 --- a/RHReliableDatagram.cpp +++ b/RHReliableDatagram.cpp @@ -9,7 +9,7 @@ // // Author: Mike McCauley (mikem@airspayce.com) // Copyright (C) 2011 Mike McCauley -// $Id: RHReliableDatagram.cpp,v 1.15 2015/12/11 01:10:24 mikem Exp $ +// $Id: RHReliableDatagram.cpp,v 1.16 2017/01/12 23:58:00 mikem Exp $ #include @@ -22,6 +22,7 @@ RHReliableDatagram::RHReliableDatagram(RHGenericDriver& driver, uint8_t thisAddr _lastSequenceNumber = 0; _timeout = RH_DEFAULT_TIMEOUT; _retries = RH_DEFAULT_RETRIES; + memset(_seenIds, 0, sizeof(_seenIds)); } //////////////////////////////////////////////////////////////////// diff --git a/RH_ASK.cpp b/RH_ASK.cpp index f9a8d02..e7ca2de 100644 --- a/RH_ASK.cpp +++ b/RH_ASK.cpp @@ -1,7 +1,7 @@ // RH_ASK.cpp // // Copyright (C) 2014 Mike McCauley -// $Id: RH_ASK.cpp,v 1.19 2016/08/17 01:53:21 mikem Exp mikem $ +// $Id: RH_ASK.cpp,v 1.20 2017/01/12 23:58:00 mikem Exp $ #include #include diff --git a/RH_CC110.cpp b/RH_CC110.cpp index f51e1b3..29fdada 100644 --- a/RH_CC110.cpp +++ b/RH_CC110.cpp @@ -3,7 +3,7 @@ // Driver for Texas Instruments CC110L transceiver. // // Copyright (C) 2016 Mike McCauley -// $Id: RH_CC110.cpp,v 1.4 2016/01/02 01:46:34 mikem Exp $ +// $Id: RH_CC110.cpp,v 1.5 2017/01/12 23:58:00 mikem Exp $ #include diff --git a/RH_MRF89.cpp b/RH_MRF89.cpp index 613da7d..d208b65 100644 --- a/RH_MRF89.cpp +++ b/RH_MRF89.cpp @@ -1,7 +1,7 @@ // RH_MRF89.cpp // // Copyright (C) 2015 Mike McCauley -// $Id: RH_MRF89.cpp,v 1.7 2015/12/31 04:23:12 mikem Exp $ +// $Id: RH_MRF89.cpp,v 1.8 2017/01/12 23:58:00 mikem Exp $ #include #define BAND_915 diff --git a/RH_NRF24.cpp b/RH_NRF24.cpp index 3f42a68..380c57a 100644 --- a/RH_NRF24.cpp +++ b/RH_NRF24.cpp @@ -1,7 +1,7 @@ // NRF24.cpp // // Copyright (C) 2012 Mike McCauley -// $Id: RH_NRF24.cpp,v 1.22 2016/04/04 01:40:12 mikem Exp $ +// $Id: RH_NRF24.cpp,v 1.23 2017/01/12 23:58:00 mikem Exp $ #include diff --git a/RH_NRF51.cpp b/RH_NRF51.cpp index bc6896e..95c0f5f 100644 --- a/RH_NRF51.cpp +++ b/RH_NRF51.cpp @@ -2,15 +2,20 @@ // // Per: nRF51_Series_Reference_manual v3.0.pdf // Copyright (C) 2012 Mike McCauley -// $Id: RH_NRF51.cpp,v 1.1 2015/07/01 00:46:05 mikem Exp $ +// $Id: RH_NRF51.cpp,v 1.3 2017/01/13 01:29:36 mikem Exp mikem $ -// Set by Arduino IDE when compiling for nRF51 chips: -#ifdef NRF51 +// Set by Arduino IDE and RadioHead.h when compiling for nRF51 or nRF52 chips: #include +#if RH_PLATFORM==RH_PLATFORM_NRF51 + + RH_NRF51::RH_NRF51() : _rxBufValid(false) +#if RH_NRF51_HAVE_ENCRYPTION + , _encrypting(false) +#endif { } @@ -20,11 +25,9 @@ bool RH_NRF51::init() NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->TASKS_HFCLKSTART = 1; /* Wait for the external oscillator to start up */ - while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) { } + while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) + ; - // Enables the DC/DC converter when the radio is enabled. Need this! - NRF_POWER->DCDCEN = 0x00000001; - // Disable and reset the radio NRF_RADIO->POWER = RADIO_POWER_POWER_Disabled; NRF_RADIO->POWER = RADIO_POWER_POWER_Enabled; @@ -47,7 +50,9 @@ bool RH_NRF51::init() NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Enabled << RADIO_SHORTS_READY_START_Pos) | (RADIO_SHORTS_END_DISABLE_Enabled << RADIO_SHORTS_END_DISABLE_Pos); - NRF_RADIO->PCNF0 = ((8 << RADIO_PCNF0_LFLEN_Pos) & RADIO_PCNF0_LFLEN_Msk); // Payload length in bits + NRF_RADIO->PCNF0 = (8 << RADIO_PCNF0_LFLEN_Pos) // Payload size length in bits + | (1 << RADIO_PCNF0_S0LEN_Pos) // S0 is 1 octet + | (8 << RADIO_PCNF0_S1LEN_Pos); // S1 is 1 octet // Make sure we are powered down setModeIdle(); @@ -58,7 +63,7 @@ bool RH_NRF51::init() setChannel(2); // The default, in case it was set by another app without powering down setRF(RH_NRF51::DataRate2Mbps, RH_NRF51::TransmitPower0dBm); - + setEncryptionKey(NULL); return true; } @@ -131,7 +136,11 @@ void RH_NRF51::setModeIdle() { if (_mode != RHModeIdle) { + NRF_RADIO->EVENTS_DISABLED = 0U; NRF_RADIO->TASKS_DISABLE = 1; + while (NRF_RADIO->EVENTS_DISABLED == 0U) + ; // wait for the radio to be disabled + NRF_RADIO->EVENTS_END = 0U; _mode = RHModeIdle; } } @@ -141,10 +150,19 @@ void RH_NRF51::setModeRx() if (_mode != RHModeRx) { setModeIdle(); // Can only start RX from DISABLE state - // Radio will transition automatically to Disable state when a messageis received + +#if RH_NRF51_HAVE_ENCRYPTION + // Maybe set the AES CCA module for the correct encryption mode + if (_encrypting) + NRF_CCM->MODE = (CCM_MODE_MODE_Decryption << CCM_MODE_MODE_Pos); // Decrypt + NRF_CCM->MICSTATUS = 0; +#endif + + // Radio will transition automatically to Disable state when a message is received NRF_RADIO->PACKETPTR = (uint32_t)_buf; - NRF_RADIO->EVENTS_DISABLED = 0U; // So we can detect end of transmission + NRF_RADIO->EVENTS_READY = 0U; NRF_RADIO->TASKS_RXEN = 1; + NRF_RADIO->EVENTS_END = 0U; // So we can detect end of reception _mode = RHModeRx; } } @@ -154,10 +172,23 @@ void RH_NRF51::setModeTx() if (_mode != RHModeTx) { setModeIdle(); // Can only start RX from DISABLE state + + // Sigh: it seems that it takes longer to start the receiver than the transmitter for this type + // of radio, so if a message is received and an ACK or reply is sent to soon, the original transmitter + // may not see the reply. So we delay here to make sure the receiver is ready. + // Yes, I know this is very ugly + delay(1); + +#if RH_NRF51_HAVE_ENCRYPTION + // Maybe set the AES CCA module for the correct encryption mode + if (_encrypting) + NRF_CCM->MODE = (CCM_MODE_MODE_Encryption << CCM_MODE_MODE_Pos); // Encrypt +#endif // Radio will transition automatically to Disable state at the end of transmission NRF_RADIO->PACKETPTR = (uint32_t)_buf; - NRF_RADIO->EVENTS_DISABLED = 0U; // So we can detect end of transmission + NRF_RADIO->EVENTS_READY = 0U; NRF_RADIO->TASKS_TXEN = 1; + NRF_RADIO->EVENTS_END = 0U; // So we can detect end of transmission _mode = RHModeTx; } } @@ -167,19 +198,27 @@ bool RH_NRF51::send(const uint8_t* data, uint8_t len) if (len > RH_NRF51_MAX_MESSAGE_LEN) return false; +#if RH_NRF51_HAVE_ENCRYPTION + if (_encrypting && len > RH_NRF51_MAX_ENCRYPTED_MESSAGE_LEN) + return false; +#endif + if (!waitCAD()) return false; // Check channel activity // Set up the headers - _buf[0] = len + RH_NRF51_HEADER_LEN; - _buf[1] = _txHeaderTo; - _buf[2] = _txHeaderFrom; - _buf[3] = _txHeaderId; - _buf[4] = _txHeaderFlags; - memcpy(_buf+RH_NRF51_HEADER_LEN+1, data, len); - + _buf[0] = 0; // S0 + _buf[1] = len + RH_NRF51_HEADER_LEN; + _buf[2] = 0; // S1 + // The following octets are subject to encryption + _buf[3] = _txHeaderTo; + _buf[4] = _txHeaderFrom; + _buf[5] = _txHeaderId; + _buf[6] = _txHeaderFlags; + memcpy(_buf+RH_NRF51_HEADER_LEN, data, len); _rxBufValid = false; setModeTx(); + // Radio will return to Disabled state after transmission is complete _txGood++; return true; @@ -192,7 +231,7 @@ bool RH_NRF51::waitPacketSent() return false; // When the Disabled event occurs we know the transmission has completed - while (NRF_RADIO->EVENTS_DISABLED == 0U) + while (!NRF_RADIO->EVENTS_END) { YIELD; } @@ -226,13 +265,14 @@ bool RH_NRF51::printRegisters() // Check whether the latest received message is complete and uncorrupted void RH_NRF51::validateRxBuf() { - if (_buf[0] < 4) + if (_buf[1] < RH_NRF51_HEADER_LEN) return; // Too short to be a real message - // Extract the 4 headers - _rxHeaderTo = _buf[1]; - _rxHeaderFrom = _buf[2]; - _rxHeaderId = _buf[3]; - _rxHeaderFlags = _buf[4]; + // Extract the 4 headers following S0, LEN and S1 + _rxHeaderTo = _buf[3]; + _rxHeaderFrom = _buf[4]; + _rxHeaderId = _buf[5]; + _rxHeaderFlags = _buf[6]; + if (_promiscuous || _rxHeaderTo == _thisAddress || _rxHeaderTo == RH_BROADCAST_ADDRESS) @@ -242,6 +282,50 @@ void RH_NRF51::validateRxBuf() } } +void RH_NRF51::setEncryptionKey(uint8_t* key) +{ +#if RH_NRF51_HAVE_ENCRYPTION + if (key) + { + // Configure for on-the-fly encryption + // Set the key + memset(_encryption_cnf, 0, sizeof(_encryption_cnf)); + memcpy(_encryption_cnf, key, RH_NRF51_ENCRYPTION_KEY_LENGTH); + // AES configuration data area + // Note that the IV (Nonce) is not set, defaults to 0s + NRF_CCM->CNFPTR = (uint32_t)_encryption_cnf; + + // Set AES CCM input and putput buffers + // Make sure the _buf is encrypted and put back into _buf + NRF_CCM->INPTR = (uint32_t)_buf; + NRF_CCM->OUTPTR = (uint32_t)_buf; + // Also need to set SCRATCHPTR temp buffer os size 16+MAXPACKETSIZE in RAM + // FIXME: shared buffers if several radios + NRF_CCM->SCRATCHPTR = (uint32_t)_scratch; + + // SHORT from RADIO READY to AESCCM KSGEN using PPI predefined channel 24 + // Also RADIO ADDRESS to AESCCM CRYPT using PPI predefined channel 25 + NRF_PPI->CHENSET = (PPI_CHENSET_CH24_Enabled << PPI_CHENSET_CH24_Pos) + | (PPI_CHENSET_CH25_Enabled << PPI_CHENSET_CH25_Pos) + ; + + // SHORT from AESCCM ENDKSGEN to AESCCM CRYPT + NRF_CCM->SHORTS = (CCM_SHORTS_ENDKSGEN_CRYPT_Enabled << CCM_SHORTS_ENDKSGEN_CRYPT_Pos); + + // Enable the CCM module + NRF_CCM->ENABLE = (CCM_ENABLE_ENABLE_Enabled << CCM_ENABLE_ENABLE_Pos); + + _encrypting = true; + } + else + { + // Disable the CCM module + NRF_CCM->ENABLE = (CCM_ENABLE_ENABLE_Disabled << CCM_ENABLE_ENABLE_Pos); + _encrypting = false; + } +#endif +} + bool RH_NRF51::available() { if (!_rxBufValid) @@ -249,9 +333,16 @@ bool RH_NRF51::available() if (_mode == RHModeTx) return false; setModeRx(); - if (NRF_RADIO->EVENTS_DISABLED == 0U) + if (!NRF_RADIO->EVENTS_END) return false; // No message yet - if (NRF_RADIO->CRCSTATUS == ((RADIO_CRCSTATUS_CRCSTATUS_CRCError << RADIO_CRCSTATUS_CRCSTATUS_Pos) & RADIO_CRCSTATUS_CRCSTATUS_Msk)) + setModeIdle(); +#if RH_NRF51_HAVE_ENCRYPTION + // If encryption is enabled, the decrypted message is not available yet, and there seems + // to be no way to be sure when its ready, but a delay of 2ms is enough + if (_encrypting) + delay(2); +#endif + if (!NRF_RADIO->CRCSTATUS) { // Bad CRC, restart the radio _rxBad++; @@ -259,8 +350,8 @@ bool RH_NRF51::available() return false; } validateRxBuf(); - if (_rxBufValid) - setModeIdle(); // Got one + if (!_rxBufValid) + setModeRx(); // Try for another } return _rxBufValid; } @@ -268,7 +359,7 @@ bool RH_NRF51::available() void RH_NRF51::clearRxBuf() { _rxBufValid = false; - _buf[0] = 0; + _buf[1] = 0; } bool RH_NRF51::recv(uint8_t* buf, uint8_t* len) @@ -279,9 +370,9 @@ bool RH_NRF51::recv(uint8_t* buf, uint8_t* len) { // Skip the 4 headers that are at the beginning of the rxBuf // the payload length is the first octet in _buf - if (*len > _buf[0]-RH_NRF51_HEADER_LEN) - *len = _buf[0]-RH_NRF51_HEADER_LEN; - memcpy(buf, _buf+RH_NRF51_HEADER_LEN+1, *len); + if (*len > _buf[1]-RH_NRF51_HEADER_LEN) + *len = _buf[1]-RH_NRF51_HEADER_LEN; + memcpy(buf, _buf+RH_NRF51_HEADER_LEN, *len); } clearRxBuf(); // This message accepted and cleared return true; @@ -289,7 +380,21 @@ bool RH_NRF51::recv(uint8_t* buf, uint8_t* len) uint8_t RH_NRF51::maxMessageLength() { +#if RH_NRF51_HAVE_ENCRYPTION + if (_encrypting) + return RH_NRF51_MAX_ENCRYPTED_MESSAGE_LEN; +#endif return RH_NRF51_MAX_MESSAGE_LEN; } +float RH_NRF51::get_temperature() +{ + NRF_TEMP->EVENTS_DATARDY = 0; + NRF_TEMP->TASKS_START = 1; + + while (!NRF_TEMP->EVENTS_DATARDY) + ; + return NRF_TEMP->TEMP * 0.25; +} + #endif // NRF51 diff --git a/RH_NRF51.h b/RH_NRF51.h index aec6fbc..2b8042f 100644 --- a/RH_NRF51.h +++ b/RH_NRF51.h @@ -1,7 +1,7 @@ // 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 $ +// $Id: RH_NRF51.h,v 1.4 2017/01/12 23:58:00 mikem Exp $ // #ifndef RH_NRF51_h @@ -15,32 +15,58 @@ // The length of the headers we add. // The headers are inside the nRF51 payload -#define RH_NRF51_HEADER_LEN 4 +// We add: +// S0 (not used) +// LEN +// S1 (not used) +// to +// from +// id +// flags +#define RH_NRF51_HEADER_LEN 7 // 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) +// Define to be 1 if you want to support AES CCA encryption using the built-in +// encryption engine. +#define RH_NRF51_HAVE_ENCRYPTION 1 + +// When encryption is enabled, have a much shorter max message length +#define RH_NRF51_MAX_ENCRYPTED_MESSAGE_LEN (27-4) + +// The required length of the AES encryption key +#define RH_NRF51_ENCRYPTION_KEY_LENGTH 16 + +// This is the size of the CCM data structure for AES encryption +// REVISIT: use a struct? +#define RH_NRF51_AES_CCM_CNF_SIZE 33 + ///////////////////////////////////////////////////////////////////// /// \class RH_NRF51 RH_NRF51.h -/// \brief Send and receive addressed datagrams by nRF51 compatible transceivers. +/// \brief Send and receive addressed datagrams by nRF51 and nRF52 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 +/// and +/// Sparkfun nRF52832 breakout board, with Arduino 1.6.13 and +/// Sparkfun nRF52 boards manager 0.2.3 /// /// 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) +/// and nRF52832 (https://learn.sparkfun.com/tutorials/nrf52832-breakout-board-hookup-guide) /// 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. +/// frequency supported by the nRF51822/nRF52832, 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 @@ -55,18 +81,20 @@ /// \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 +/// with the one used by RH_NRF24 and the nRF24L01 product specification, mainly because the nRF24 only supports /// 6 bits of message length. /// /// - 1 octets PREAMBLE /// - 3 to 5 octets NETWORK ADDRESS +/// - 1 octet S0 (not used, required if encryption used) /// - 8 bits PAYLOAD LENGTH -/// - 0 to 254 octets PAYLOAD, consisting of: +/// - 1 octet S1 (not used, required if encryption used) +/// - 0 to 251 octets PAYLOAD (possibly encrypted), 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 +/// - 0 to 247 octets of user message /// - 2 octets CRC (Algorithm x^16+x^12^x^5+1 with initial value 0xFFFF). /// /// \par Example programs @@ -75,6 +103,9 @@ /// /// 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/ +/// or with Sparkfun nRF52832 breakout board, with Arduino 1.6.13 and +/// Sparkfun nRF52 boards manager 0.2.3 using the procedures outlined in +/// https://learn.sparkfun.com/tutorials/nrf52832-breakout-board-hookup-guide /// /// \par Radio Performance /// @@ -172,10 +203,11 @@ class RH_NRF51 : public RHGenericDriver /// Sends data to the address set by setTransmitAddress() /// Sets the radio to TX mode. + /// Caution: when encryption is enabled, the maximum message length is reduced to 23 octets. /// \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). + /// successfully transmitted). False if the message is too long or was otherwise not transmitted. bool send(const uint8_t* data, uint8_t len); /// Blocks until the current message (if any) @@ -213,10 +245,26 @@ class RH_NRF51 : public RHGenericDriver /// \return true if a valid message was copied to buf bool recv(uint8_t* buf, uint8_t* len); + /// Enables AES encryption and sets the AES encryption key, used + /// to encrypt and decrypt all messages using the on-chip AES CCM mode encryption engine. + /// The default is disabled. + /// In the AES configuration, the message counter and IV is always set to 0, which + /// means the same keystream is used for every message with a given key. + /// Caution: when encryption is enabled, the maximum message length is reduced to 23 octets. + /// \param[in] key The key to use. Must be 16 bytes long. The same key must be installed + /// in other instances of RH_RF51, otherwise communications will not work correctly. If key is NULL, + /// encryption is disabled, which is the default. + void setEncryptionKey(uint8_t* key = NULL); + /// The maximum message length supported by this driver /// \return The maximum message length supported by this driver uint8_t maxMessageLength(); + /// Reeads the current die temperature using the built in TEMP peripheral. + /// Blocks while the temperature is measured, which takes about 30 microseconds. + // \return the current die temperature in degrees C. + float get_temperature(); + protected: /// Examine the receive buffer to determine whether the message is for this node void validateRxBuf(); @@ -231,6 +279,18 @@ class RH_NRF51 : public RHGenericDriver /// True when there is a valid message in the buffer bool _rxBufValid; + +#if RH_NRF51_HAVE_ENCRYPTION + /// True if an AES key has been specified and that we are therfore encrypting + /// and decrypting messages on the fly + bool _encrypting; + + /// Scratch area for AES encryption + uint8_t _scratch[RH_NRF51_MAX_PAYLOAD_LEN+1+16]; + + /// Where the AES encryption key and IV are stored + uint8_t _encryption_cnf[RH_NRF51_AES_CCM_CNF_SIZE]; +#endif }; /// @example nrf51_client.pde diff --git a/RH_NRF905.cpp b/RH_NRF905.cpp index bd572ac..3706e5c 100644 --- a/RH_NRF905.cpp +++ b/RH_NRF905.cpp @@ -1,7 +1,7 @@ // RH_NRF905.cpp // // Copyright (C) 2012 Mike McCauley -// $Id: RH_NRF905.cpp,v 1.6 2015/12/11 01:10:24 mikem Exp $ +// $Id: RH_NRF905.cpp,v 1.7 2017/01/12 23:58:00 mikem Exp $ #include diff --git a/RH_NRF905.h b/RH_NRF905.h index 26c35ac..e9ba85c 100644 --- a/RH_NRF905.h +++ b/RH_NRF905.h @@ -1,7 +1,7 @@ // RH_NRF905.h // Author: Mike McCauley (mikem@airspayce.com) // Copyright (C) 2014 Mike McCauley -// $Id: RH_NRF905.h,v 1.9 2016/04/04 01:40:12 mikem Exp $ +// $Id: RH_NRF905.h,v 1.10 2017/01/12 23:58:00 mikem Exp $ // #ifndef RH_NRF905_h @@ -339,10 +339,11 @@ class RH_NRF905 : public RHNRFSPIDriver /// 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 set in teh TX buffer. The actual size of the - /// transmitted data payload is set by setPayloadSize + /// \param [in] len Number of data bytes to set in the TX buffer. The actual size of the + /// transmitted data payload is set by setPayloadSize. Maximum message length actually + /// transmitted is RH_NRF905_MAX_MESSAGE_LEN = 27. /// \return true on success (which does not necessarily mean the receiver got the message, only that the message was - /// successfully transmitted). + /// successfully transmitted). Returns false if the requested message length exceeds RH_NRF905_MAX_MESSAGE_LEN. bool send(const uint8_t* data, uint8_t len); /// Blocks until the current message (if any) diff --git a/RH_RF22.cpp b/RH_RF22.cpp index c3d7578..61ec1e2 100644 --- a/RH_RF22.cpp +++ b/RH_RF22.cpp @@ -1,7 +1,7 @@ // RH_RF22.cpp // // Copyright (C) 2011 Mike McCauley -// $Id: RH_RF22.cpp,v 1.26 2016/04/04 01:40:12 mikem Exp $ +// $Id: RH_RF22.cpp,v 1.27 2017/01/12 23:58:00 mikem Exp $ #include diff --git a/RH_RF22.h b/RH_RF22.h index bb636ff..768853c 100644 --- a/RH_RF22.h +++ b/RH_RF22.h @@ -1,7 +1,7 @@ // RH_RF22.h // Author: Mike McCauley (mikem@airspayce.com) // Copyright (C) 2011 Mike McCauley -// $Id: RH_RF22.h,v 1.31 2016/08/17 01:53:21 mikem Exp mikem $ +// $Id: RH_RF22.h,v 1.31 2016/08/17 01:53:21 mikem Exp $ // #ifndef RH_RF22_h diff --git a/RH_RF24.cpp b/RH_RF24.cpp index fc29b0b..c340b31 100644 --- a/RH_RF24.cpp +++ b/RH_RF24.cpp @@ -1,7 +1,7 @@ // RH_RF24.cpp // // Copyright (C) 2011 Mike McCauley -// $Id: RH_RF24.cpp,v 1.17 2016/08/17 01:53:21 mikem Exp mikem $ +// $Id: RH_RF24.cpp,v 1.18 2017/01/12 23:58:00 mikem Exp $ #include // Generated with Silicon Labs WDS software: diff --git a/RH_RF24.h b/RH_RF24.h index dddc208..db49fc7 100644 --- a/RH_RF24.h +++ b/RH_RF24.h @@ -1,7 +1,7 @@ // RH_RF24.h // Author: Mike McCauley (mikem@airspayce.com) // Copyright (C) 2014 Mike McCauley -// $Id: RH_RF24.h,v 1.15 2016/08/17 01:53:21 mikem Exp mikem $ +// $Id: RH_RF24.h,v 1.15 2016/08/17 01:53:21 mikem Exp $ // // Supports RF24/RF26 and RFM24/RFM26 modules in FIFO mode // also Si4464/63/62/61/60-A1 diff --git a/RH_RF69.cpp b/RH_RF69.cpp index 1e95327..3304c0c 100644 --- a/RH_RF69.cpp +++ b/RH_RF69.cpp @@ -1,7 +1,7 @@ // RH_RF69.cpp // // Copyright (C) 2011 Mike McCauley -// $Id: RH_RF69.cpp,v 1.26 2015/12/11 01:10:24 mikem Exp $ +// $Id: RH_RF69.cpp,v 1.27 2017/01/12 23:58:00 mikem Exp $ #include diff --git a/RH_RF69.h b/RH_RF69.h index f52ecef..7189816 100644 --- a/RH_RF69.h +++ b/RH_RF69.h @@ -1,7 +1,7 @@ // RH_RF69.h // Author: Mike McCauley (mikem@airspayce.com) // Copyright (C) 2014 Mike McCauley -// $Id: RH_RF69.h,v 1.32 2016/07/07 00:02:53 mikem Exp $ +// $Id: RH_RF69.h,v 1.33 2017/01/12 23:58:00 mikem Exp $ // /// @@ -301,10 +301,16 @@ /// the marvellous high powered MinWireless-HW (with 20dBm output for excellent range) /// - the excellent Rocket Scream Mini Ultra Pro with the RFM69HCW /// http://www.rocketscream.com/blog/product/mini-ultra-pro-with-radio/ -/// - The excellent talk2 Whisper Node boards -/// (https://talk2.wisen.com.au/ and https://bitbucket.org/talk2/), -/// an Arduino Nano compatible board, which include an on-board RF69 radio, external antenna, -/// run on 2xAA batteries and support low power operations. RF69 examples work without modification. +/// - The excellent Talk2 Whisper Node boards +/// (https://talk2.wisen.com.au/ and https://bitbucket.org/talk2/whisper-node-avr), +/// an Arduino compatible board, which include an on-board RF69 radio, external antenna, +/// run on 2xAAA batteries and support low power operations. RF69 examples work without modification. +/// Use Arduino Board Manager to install the Talk2 code support as described in +/// https://bitbucket.org/talk2/whisper-node-avr +/// - The excellent Adafruit Feather. These are excellent boards that are available with a variety of radios. +/// We tested with the +/// Feather 32u4 with RFM69HCW radio, with Arduino IDE 1.6.8 and the Adafruit AVR Boards board manager version 1.6.10. +/// https://www.adafruit.com/products/3076 /// /// \par Overview /// @@ -487,6 +493,16 @@ /// RH_RF69 driver; /// \endcode /// +/// If you have a Feather 32u4 with RFM69HCW you need to initialise the driver like: +/// \code +/// RH_RF69 driver(8, 7); +/// \endcode +/// and since the radio is the high power HCW model, you must set the Tx power in the +/// range 14 to 20 like this: +/// \code +/// driver.setTxPower(14); +/// \endcode +/// /// It is possible to have 2 or more radios connected to one Arduino, provided /// each radio has its own SS and interrupt line (SCK, SDI and SDO are common /// to all radios) @@ -818,6 +834,8 @@ class RH_RF69 : public RHSPIDriver /// value on all nodes in your network. Nodes with different SyncWords set will never receive /// each others messages, so different SyncWords can be used to isolate different /// networks from each other. Default is { 0x2d, 0xd4 }. + /// Caution: tests here show that with a single sync word (ie where len == 1), + /// RFM69 reception can be unreliable. /// \param[in] syncWords Array of sync words, 1 to 4 octets long. NULL if no sync words to be used. /// \param[in] len Number of sync words to set, 1 to 4. 0 if no sync words to be used. void setSyncWords(const uint8_t* syncWords = NULL, uint8_t len = 0); @@ -826,7 +844,7 @@ class RH_RF69 : public RHSPIDriver /// to encrypt and decrypt all messages. The default is disabled. /// \param[in] key The key to use. Must be 16 bytes long. The same key must be installed /// in other instances of RF69, otherwise communications will not work correctly. If key is NULL, - /// encryption is disabled. + /// encryption is disabled, which is the default. void setEncryptionKey(uint8_t* key = NULL); /// Returns the time in millis since the most recent preamble was received, and when the most recent diff --git a/RH_RF95.cpp b/RH_RF95.cpp index 8bc8178..d6a8e46 100644 --- a/RH_RF95.cpp +++ b/RH_RF95.cpp @@ -1,7 +1,7 @@ // RH_RF95.cpp // // Copyright (C) 2011 Mike McCauley -// $Id: RH_RF95.cpp,v 1.11 2016/04/04 01:40:12 mikem Exp $ +// $Id: RH_RF95.cpp,v 1.12 2017/01/12 23:58:00 mikem Exp $ #include @@ -416,3 +416,11 @@ bool RH_RF95::isChannelActive() return _cad; } +void RH_RF95::enableTCXO() +{ + while ((spiRead(RH_RF95_REG_4B_TCXO) & RH_RF95_TCXO_TCXO_INPUT_ON) != RH_RF95_TCXO_TCXO_INPUT_ON) + { + sleep(); + spiWrite(RH_RF95_REG_4B_TCXO, (spiRead(RH_RF95_REG_4B_TCXO) | RH_RF95_TCXO_TCXO_INPUT_ON)); + } +} diff --git a/RH_RF95.h b/RH_RF95.h index 066d5f8..e66706b 100644 --- a/RH_RF95.h +++ b/RH_RF95.h @@ -6,7 +6,7 @@ // // Author: Mike McCauley (mikem@airspayce.com) // Copyright (C) 2014 Mike McCauley -// $Id: RH_RF95.h,v 1.12 2016/08/17 01:53:21 mikem Exp mikem $ +// $Id: RH_RF95.h,v 1.14 2017/01/13 01:29:36 mikem Exp mikem $ // #ifndef RH_RF95_h @@ -99,6 +99,7 @@ // RH_RF95_REG_01_OP_MODE 0x01 #define RH_RF95_LONG_RANGE_MODE 0x80 #define RH_RF95_ACCESS_SHARED_REG 0x40 +#define RH_RF95_LOW_FREQUENCY_MODE 0x08 #define RH_RF95_MODE 0x07 #define RH_RF95_MODE_SLEEP 0x00 #define RH_RF95_MODE_STDBY 0x01 @@ -140,9 +141,17 @@ // RH_RF95_REG_0C_LNA 0x0c #define RH_RF95_LNA_GAIN 0xe0 -#define RH_RF95_LNA_BOOST 0x03 -#define RH_RF95_LNA_BOOST_DEFAULT 0x00 -#define RH_RF95_LNA_BOOST_150PC 0x11 +#define RH_RF95_LNA_GAIN_G1 0x20 +#define RH_RF95_LNA_GAIN_G2 0x40 +#define RH_RF95_LNA_GAIN_G3 0x60 +#define RH_RF95_LNA_GAIN_G4 0x80 +#define RH_RF95_LNA_GAIN_G5 0xa0 +#define RH_RF95_LNA_GAIN_G6 0xc0 +#define RH_RF95_LNA_BOOST_LF 0x18 +#define RH_RF95_LNA_BOOST_LF_DEFAULT 0x00 +#define RH_RF95_LNA_BOOST_HF 0x03 +#define RH_RF95_LNA_BOOST_HF_DEFAULT 0x00 +#define RH_RF95_LNA_BOOST_HF_150PC 0x11 // RH_RF95_REG_11_IRQ_FLAGS_MASK 0x11 #define RH_RF95_RX_TIMEOUT_MASK 0x80 @@ -178,19 +187,24 @@ #define RH_RF95_FHSS_PRESENT_CHANNEL 0x3f // RH_RF95_REG_1D_MODEM_CONFIG1 0x1d -#define RH_RF95_BW 0xc0 -#define RH_RF95_BW_125KHZ 0x00 -#define RH_RF95_BW_250KHZ 0x40 -#define RH_RF95_BW_500KHZ 0x80 -#define RH_RF95_BW_RESERVED 0xc0 -#define RH_RF95_CODING_RATE 0x38 -#define RH_RF95_CODING_RATE_4_5 0x00 -#define RH_RF95_CODING_RATE_4_6 0x08 -#define RH_RF95_CODING_RATE_4_7 0x10 -#define RH_RF95_CODING_RATE_4_8 0x18 -#define RH_RF95_IMPLICIT_HEADER_MODE_ON 0x04 -#define RH_RF95_RX_PAYLOAD_CRC_ON 0x02 -#define RH_RF95_LOW_DATA_RATE_OPTIMIZE 0x01 +#define RH_RF95_BW 0xf0 + +#define RH_RF95_BW_7_8KHZ 0x00 +#define RH_RF95_BW_10_4KHZ 0x10 +#define RH_RF95_BW_15_6KHZ 0x20 +#define RH_RF95_BW_20_8KHZ 0x30 +#define RH_RF95_BW_31_25KHZ 0x40 +#define RH_RF95_BW_41_7KHZ 0x50 +#define RH_RF95_BW_62_5KHZ 0x60 +#define RH_RF95_BW_125KHZ 0x70 +#define RH_RF95_BW_250KHZ 0x80 +#define RH_RF95_BW_500KHZ 0x90 +#define RH_RF95_CODING_RATE 0x0e +#define RH_RF95_CODING_RATE_4_5 0x02 +#define RH_RF95_CODING_RATE_4_6 0x04 +#define RH_RF95_CODING_RATE_4_7 0x06 +#define RH_RF95_CODING_RATE_4_8 0x08 +#define RH_RF95_IMPLICIT_HEADER_MODE_ON 0x01 // RH_RF95_REG_1E_MODEM_CONFIG2 0x1e #define RH_RF95_SPREADING_FACTOR 0xf0 @@ -202,9 +216,13 @@ #define RH_RF95_SPREADING_FACTOR_2048CPS 0xb0 #define RH_RF95_SPREADING_FACTOR_4096CPS 0xc0 #define RH_RF95_TX_CONTINUOUS_MOE 0x08 -#define RH_RF95_AGC_AUTO_ON 0x04 + +#define RH_RF95_PAYLOAD_CRC_ON 0x04 #define RH_RF95_SYM_TIMEOUT_MSB 0x03 +// RH_RF95_REG_4B_TCXO 0x4b +#define RH_RF95_TCXO_TCXO_INPUT_ON 0x10 + // RH_RF95_REG_4D_PA_DAC 0x4d #define RH_RF95_PA_DAC_DISABLE 0x04 #define RH_RF95_PA_DAC_ENABLE 0x07 @@ -447,6 +465,14 @@ /// At 20dBm (100mW) with Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. /// (Default medium range) in the conditions described above. /// - Range over flat ground through heavy trees and vegetation approx 2km. +/// +/// Caution: the performance of this radio, especially with narrow bandwidths is strongly dependent on the +/// accuracy and stability of the chip clock. HopeRF and Semtech do not appear to +/// recommend bandwidths of less than 62.5 kHz +/// unless you have the optional Temperature Compensated Crystal Oscillator (TCXO) installed and +/// enabled on your radio module. See the refernece manual for more data. +/// Also https://lowpowerlab.com/forum/rf-range-antennas-rfm69-library/lora-library-experiences-range/15/ +/// and http://www.semtech.com/images/datasheet/an120014-xo-guidance-lora-modulation.pdf /// /// \par Transmitter Power /// @@ -690,6 +716,15 @@ class RH_RF95 : public RHSPIDriver /// \return true if channel is in use. virtual bool isChannelActive(); + /// Enable TCXO mode + /// Call this immediately after init(), to force your radio to use an external + /// frequency source, such as a Temperature Compensated Crystal Oscillator (TCXO). + /// See the comments in the main documentation about the sensitivity of this radio to + /// clock frequency especially when using narrow bandwidths. + /// Leaves the module in sleep mode. + /// Caution, this function has not been tested by us. + void enableTCXO(); + protected: /// This is a low level function to handle the interrupts for one instance of RH_RF95. /// Called automatically by isr*() diff --git a/RH_Serial.cpp b/RH_Serial.cpp index e67e84d..3a26251 100644 --- a/RH_Serial.cpp +++ b/RH_Serial.cpp @@ -1,7 +1,7 @@ // RH_Serial.cpp // // Copyright (C) 2014 Mike McCauley -// $Id: RH_Serial.cpp,v 1.12 2016/04/04 01:40:12 mikem Exp $ +// $Id: RH_Serial.cpp,v 1.13 2017/01/12 23:58:00 mikem Exp $ #include #if (RH_PLATFORM == RH_PLATFORM_STM32F2) diff --git a/RH_TCP.cpp b/RH_TCP.cpp index 1da94cc..317aad0 100644 --- a/RH_TCP.cpp +++ b/RH_TCP.cpp @@ -1,7 +1,7 @@ // RH_TCP.cpp // // Copyright (C) 2014 Mike McCauley -// $Id: RH_TCP.cpp,v 1.5 2015/08/13 02:45:47 mikem Exp $ +// $Id: RH_TCP.cpp,v 1.6 2017/01/12 23:58:00 mikem Exp $ #include diff --git a/RadioHead.h b/RadioHead.h index 0d6ef30..ec29de0 100644 --- a/RadioHead.h +++ b/RadioHead.h @@ -1,7 +1,7 @@ // RadioHead.h // Author: Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY // Copyright (C) 2014 Mike McCauley -// $Id: RadioHead.h,v 1.57 2016/08/17 01:53:21 mikem Exp mikem $ +// $Id: RadioHead.h,v 1.59 2017/01/13 01:29:36 mikem Exp mikem $ /// \mainpage RadioHead Packet Radio library for embedded microprocessors /// @@ -10,7 +10,7 @@ /// via a variety of common data radios and other transports on a range of embedded microprocessors. /// /// The version of the package that this documentation refers to can be downloaded -/// from http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.62.zip +/// from http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.67.zip /// You can find the latest version at http://www.airspayce.com/mikem/arduino/RadioHead /// /// You can also find online help and discussion at @@ -87,6 +87,8 @@ /// /// - RH_NRF51 /// Works with Nordic nRF51 compatible 2.4 GHz SoC/devices such as the nRF51822. +/// Also works with Sparkfun nRF52832 breakout board, with Arduino 1.6.13 and +/// Sparkfun nRF52 boards manager 0.2.3 /// /// - RH_RF95 /// Works with Semtech SX1276/77/78/79, Modtronix inAir4 and inAir9, @@ -183,6 +185,10 @@ /// - nRF51 compatible Arm chips such as nRF51822 with Arduino 1.6.4 and later using the procedures /// in http://redbearlab.com/getting-started-nrf51822/ /// +/// - Adafruit Feather. These are excellent boards that are available with a variety of radios. We tested with the +/// Feather 32u4 with RFM69HCW radio, with Arduino IDE 1.6.8 and the Adafruit AVR Boards board manager version 1.6.10. +/// https://www.adafruit.com/products/3076 +/// /// - Raspberry Pi /// Uses BCM2835 library for GPIO http://www.airspayce.com/mikem/bcm2835/ /// Currently works only with RH_NRF24 driver or other drivers that do not require interrupt support. @@ -668,6 +674,32 @@ /// Implementation of RH_RF95::isChannelActive() allows the RF95 module to support /// Channel Activity Detection (CAD). Based on code contributed by Bent Guldbjerg Christensen. /// Implmentations of isChannelActive() plus documentation for other radio modules wil be welcomed. +/// \version 1.63 2016-10-20 +/// Testing with Adafruit Feather 32u4 with RFM69HCW. Updated documentation to reflect.
+/// \version 1.64 2016-12-10 +/// RHReliableDatagram now initialises _seenids. Fix from Ben Lim.
+/// In RH_NRF51, added get_temperature().
+/// In RH_NRF51, added support for AES packet encryption, which required a slight change +/// to the on-air message format.
+/// \version 1.65 2017-01-11 +/// Fixed a race condition with RH_NRF51 that prevented ACKs being reliably received.
+/// Removed code in RH_NRF51 that enabled the DC-DC converter. This seems not to be a necessary condition +/// for the radio to work and is now left to the application if that is required.
+/// Proven interoperation between nRF51822 and nRF52832.
+/// Modification and testing of RH_NRF51 so it works with nRF52 family processors, +/// such Sparkfun nRF52832 breakout board, with Arduino 1.6.13 and +/// Sparkfun nRF52 boards manager 0.2.3 using the procedures outlined in +/// https://learn.sparkfun.com/tutorials/nrf52832-breakout-board-hookup-guide
+/// Caution, the Sparkfun development system for Arduino is still immature. We had to +/// rebuild the nrfutil program since the supplied one was not suitable for +/// the Linux host we were developing on. See https://forum.sparkfun.com/viewtopic.php?f=32&t=45071 +/// Also, after downloading a sketch in the nRF52832, the program does not start executing cleanly: +/// you have to reset the processor again by pressing the reset button. +/// This appears to be a problem with nrfutil, rather than a bug in RadioHead. +/// \version 1.66 2017-01-15 +/// Fixed some errors in (unused) register definitions in RH_RF95.h.
+/// Fixed a problem that caused compilation errors in RH_NRF51 if the appropriate board +/// support was not installed. /// /// \author Mike McCauley. DO NOT CONTACT THE AUTHOR DIRECTLY. USE THE MAILING LIST GIVEN ABOVE @@ -676,7 +708,7 @@ // Official version numbers are maintained automatically by Makefile: #define RH_VERSION_MAJOR 1 -#define RH_VERSION_MINOR 62 +#define RH_VERSION_MINOR 67 // Symbolic names for currently supported platform types #define RH_PLATFORM_ARDUINO 1 @@ -688,6 +720,7 @@ #define RH_PLATFORM_STM32STD 7 #define RH_PLATFORM_STM32F4_HAL 8 #define RH_PLATFORM_RASPI 9 +// Also nRF52 family: #define RH_PLATFORM_NRF51 10 #define RH_PLATFORM_ESP8266 11 #define RH_PLATFORM_STM32F2 12 @@ -702,7 +735,7 @@ #elif defined(MPIDE) // Uno32 under old MPIDE, which has been discontinued: #define RH_PLATFORM RH_PLATFORM_UNO32 - #elif defined(NRF51) +#elif defined(NRF51) || defined(NRF52) #define RH_PLATFORM RH_PLATFORM_NRF51 #elif defined(ESP8266) #define RH_PLATFORM RH_PLATFORM_ESP8266 diff --git a/examples/nrf51/nrf51_client/nrf51_client.pde b/examples/nrf51/nrf51_client/nrf51_client.pde index 53fcd09..03e857b 100644 --- a/examples/nrf51/nrf51_client/nrf51_client.pde +++ b/examples/nrf51/nrf51_client/nrf51_client.pde @@ -8,7 +8,8 @@ // Tested on RedBearLabs nRF51822 and BLE Nano kit, built with Arduino 1.6.4. // See http://redbearlab.com/getting-started-nrf51822/ // for how to set up your Arduino build environment - +// Also tested with Sparkfun nRF52832 breakout board, witth Arduino 1.6.13 and +// Sparkfun nRF52 boards manager 0.2.3 #include // Singleton instance of the radio driver @@ -26,8 +27,14 @@ void setup() if (!nrf51.setChannel(1)) Serial.println("setChannel failed"); if (!nrf51.setRF(RH_NRF51::DataRate2Mbps, RH_NRF51::TransmitPower0dBm)) - Serial.println("setRF failed"); - nrf51.printRegisters(); + Serial.println("setRF failed"); + + // AES encryption can be enabled by setting the same key in the sender and receiver +// uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, +// 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; +// nrf51.setEncryptionKey(key); + +// nrf51.printRegisters(); } diff --git a/examples/nrf51/nrf51_reliable_datagram_client/nrf51_reliable_datagram_client.pde b/examples/nrf51/nrf51_reliable_datagram_client/nrf51_reliable_datagram_client.pde index 7ff4216..2f9c3ca 100644 --- a/examples/nrf51/nrf51_reliable_datagram_client/nrf51_reliable_datagram_client.pde +++ b/examples/nrf51/nrf51_reliable_datagram_client/nrf51_reliable_datagram_client.pde @@ -6,6 +6,8 @@ // Tested on RedBearLabs nRF51822 and BLE Nano kit, built with Arduino 1.6.4. // See http://redbearlab.com/getting-started-nrf51822/ // for how to set up your Arduino build environment +// Also tested with Sparkfun nRF52832 breakout board, witth Arduino 1.6.13 and +// Sparkfun nRF52 boards manager 0.2.3 #include #include diff --git a/examples/nrf51/nrf51_reliable_datagram_server/nrf51_reliable_datagram_server.pde b/examples/nrf51/nrf51_reliable_datagram_server/nrf51_reliable_datagram_server.pde index d2ac9fe..9e105b4 100644 --- a/examples/nrf51/nrf51_reliable_datagram_server/nrf51_reliable_datagram_server.pde +++ b/examples/nrf51/nrf51_reliable_datagram_server/nrf51_reliable_datagram_server.pde @@ -6,6 +6,8 @@ // Tested on RedBearLabs nRF51822 and BLE Nano kit, built with Arduino 1.6.4. // See http://redbearlab.com/getting-started-nrf51822/ // for how to set up your Arduino build environment +// Also tested with Sparkfun nRF52832 breakout board, witth Arduino 1.6.13 and +// Sparkfun nRF52 boards manager 0.2.3 #include diff --git a/examples/nrf51/nrf51_server/nrf51_server.pde b/examples/nrf51/nrf51_server/nrf51_server.pde index edf7784..f9b1f45 100644 --- a/examples/nrf51/nrf51_server/nrf51_server.pde +++ b/examples/nrf51/nrf51_server/nrf51_server.pde @@ -8,6 +8,8 @@ // Tested on RedBearLabs nRF51822 and BLE Nano kit, built with Arduino 1.6.4. // See http://redbearlab.com/getting-started-nrf51822/ // for how to set up your Arduino build environment +// Also tested with Sparkfun nRF52832 breakout board, witth Arduino 1.6.13 and +// Sparkfun nRF52 boards manager 0.2.3 #include @@ -27,6 +29,11 @@ void setup() Serial.println("setChannel failed"); if (!nrf51.setRF(RH_NRF51::DataRate2Mbps, RH_NRF51::TransmitPower0dBm)) Serial.println("setRF failed"); + + // AES encryption can be enabled by setting the same key in the sender and receiver +// uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, +// 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; +// nrf51.setEncryptionKey(key); } void loop() diff --git a/examples/rf69/rf69_client/rf69_client.pde b/examples/rf69/rf69_client/rf69_client.pde index f2701d5..0710b6b 100644 --- a/examples/rf69/rf69_client/rf69_client.pde +++ b/examples/rf69/rf69_client/rf69_client.pde @@ -17,10 +17,14 @@ // Singleton instance of the radio driver RH_RF69 rf69; //RH_RF69 rf69(15, 16); // For RF69 on PJRC breakout board with Teensy 3.1 +//RH_RF69 rf69(4, 2); // For MoteinoMEGA https://lowpowerlab.com/shop/moteinomega +//RH_RF69 rf69(8, 7); // Adafruit Feather 32u4 void setup() { Serial.begin(9600); + while (!Serial) + ; if (!rf69.init()) Serial.println("init failed"); // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM diff --git a/examples/rf69/rf69_reliable_datagram_client/rf69_reliable_datagram_client.pde b/examples/rf69/rf69_reliable_datagram_client/rf69_reliable_datagram_client.pde index 24b9238..4a7c79e 100644 --- a/examples/rf69/rf69_reliable_datagram_client/rf69_reliable_datagram_client.pde +++ b/examples/rf69/rf69_reliable_datagram_client/rf69_reliable_datagram_client.pde @@ -17,7 +17,8 @@ // Singleton instance of the radio driver RH_RF69 driver; //RH_RF69 driver(15, 16); // For RF69 on PJRC breakout board with Teensy 3.1 -//RH_RF69 rf69(4, 2); // For MoteinoMEGA https://lowpowerlab.com/shop/moteinomega +//RH_RF69 driver(4, 2); // For MoteinoMEGA https://lowpowerlab.com/shop/moteinomega +//RH_RF69 driver(8, 7); // Adafruit Feather 32u4 // Class to manage message delivery and receipt, using the driver declared above RHReliableDatagram manager(driver, CLIENT_ADDRESS); @@ -25,6 +26,8 @@ RHReliableDatagram manager(driver, CLIENT_ADDRESS); void setup() { Serial.begin(9600); + while (!Serial) + ; if (!manager.init()) Serial.println("init failed"); // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM diff --git a/examples/rf69/rf69_reliable_datagram_server/rf69_reliable_datagram_server.pde b/examples/rf69/rf69_reliable_datagram_server/rf69_reliable_datagram_server.pde index b1aef20..77e35ff 100644 --- a/examples/rf69/rf69_reliable_datagram_server/rf69_reliable_datagram_server.pde +++ b/examples/rf69/rf69_reliable_datagram_server/rf69_reliable_datagram_server.pde @@ -18,6 +18,7 @@ RH_RF69 driver; //RH_RF69 driver(15, 16); // For RF69 on PJRC breakout board with Teensy 3.1 //RH_RF69 rf69(4, 2); // For MoteinoMEGA https://lowpowerlab.com/shop/moteinomega +//RH_RF69 driver(8, 7); // Adafruit Feather 32u4 // Class to manage message delivery and receipt, using the driver declared above RHReliableDatagram manager(driver, SERVER_ADDRESS); @@ -25,6 +26,8 @@ RHReliableDatagram manager(driver, SERVER_ADDRESS); void setup() { Serial.begin(9600); + while (!Serial) + ; if (!manager.init()) Serial.println("init failed"); // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM diff --git a/examples/rf69/rf69_server/rf69_server.pde b/examples/rf69/rf69_server/rf69_server.pde index 05baccc..b056b6b 100644 --- a/examples/rf69/rf69_server/rf69_server.pde +++ b/examples/rf69/rf69_server/rf69_server.pde @@ -18,10 +18,13 @@ RH_RF69 rf69; //RH_RF69 rf69(15, 16); // For RF69 on PJRC breakout board with Teensy 3.1 //RH_RF69 rf69(4, 2); // For MoteinoMEGA https://lowpowerlab.com/shop/moteinomega +//RH_RF69 rf69(8, 7); // Adafruit Feather 32u4 void setup() { Serial.begin(9600); + while (!Serial) + ; if (!rf69.init()) Serial.println("init failed"); // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM diff --git a/project.cfg b/project.cfg index 8cf756b..722757c 100644 --- a/project.cfg +++ b/project.cfg @@ -1,4 +1,4 @@ -# Doxyfile 1.8.5 +# Doxyfile 1.8.8 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -70,15 +70,25 @@ OUTPUT_DIRECTORY = CREATE_SUBDIRS = NO +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese- -# Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi, -# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en, -# Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish, -# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, -# Turkish, Ukrainian and Vietnamese. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English @@ -259,9 +269,12 @@ OPTIMIZE_OUTPUT_VHDL = NO # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. # # Note For files without extension you can use no_extension as a placeholder. # @@ -500,6 +513,13 @@ HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. @@ -521,7 +541,8 @@ SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member -# name. If set to NO the members will appear in declaration order. +# name. If set to NO the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. # The default value is: NO. SORT_BRIEF_DOCS = NO @@ -659,8 +680,7 @@ LAYOUT_FILE = # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. Do not use file names with spaces, bibtex cannot handle them. See -# also \cite for info how to create references. +# search path. See also \cite for info how to create references. CITE_BIB_FILES = @@ -1049,13 +1069,15 @@ HTML_FOOTER = HTML_STYLESHEET = -# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- -# defined cascading style sheet that is included after the standard style sheets +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefor more robust against future updates. -# Doxygen will copy the style sheet file to the output directory. For an example -# see the documentation. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra stylesheet files is of importance (e.g. the last +# stylesheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = @@ -1103,7 +1125,7 @@ HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to NO can help when comparing the output of multiple runs. -# The default value is: NO. +# The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = NO @@ -1220,7 +1242,8 @@ GENERATE_CHI = NO CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated ( -# YES) or a normal table of contents ( NO) in the .chm file. +# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1460,11 +1483,11 @@ SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. There -# are two flavours of web server based searching depending on the -# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for -# searching and an index file used by the script. When EXTERNAL_SEARCH is -# enabled the indexing and searching needs to be provided by external tools. See -# the section "External Indexing and Searching" for details. +# are two flavors of web server based searching depending on the EXTERNAL_SEARCH +# setting. When disabled, doxygen will generate a PHP script for searching and +# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing +# and searching needs to be provided by external tools. See the section +# "External Indexing and Searching" for details. # The default value is: NO. # This tag requires that the tag SEARCHENGINE is set to YES. @@ -1592,17 +1615,19 @@ EXTRA_PACKAGES = # # Note: Only use a user-defined header if you know what you are doing! The # following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will -# replace them by respectively the title of the page, the current date and time, -# only the current date, the version number of doxygen, the project name (see -# PROJECT_NAME), or the project number (see PROJECT_NUMBER). +# $datetime, $date, $doxygenversion, $projectname, $projectnumber, +# $projectbrief, $projectlogo. Doxygen will replace $title with the empy string, +# for the replacement values of the other commands the user is refered to +# HTML_HEADER. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the # generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. +# chapter. If it is left blank doxygen will generate a standard footer. See +# LATEX_HEADER for more information on how to generate a default footer and what +# special commands can be used inside the footer. # # Note: Only use a user-defined footer if you know what you are doing! # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1626,7 +1651,7 @@ LATEX_EXTRA_FILES = PDF_HYPERLINKS = NO -# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate +# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate # the PDF file directly from the LaTeX files. Set this option to YES to get a # higher quality PDF documentation. # The default value is: YES. @@ -1752,6 +1777,13 @@ MAN_OUTPUT = man MAN_EXTENSION = .3 +# The MAN_SUBDIR tag determines the name of the directory created within +# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by +# MAN_EXTENSION with the initial . removed. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_SUBDIR = + # If the MAN_LINKS tag is set to YES and doxygen generates man output, then it # will generate one additional man file for each entity documented in the real # man page(s). These additional files only source the real man page, but without @@ -1779,18 +1811,6 @@ GENERATE_XML = NO XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify a XML DTD, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_DTD = - # If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program # listings (including syntax highlighting and cross-referencing information) to # the XML output. Note that enabling this will significantly increase the size @@ -1818,6 +1838,15 @@ GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook +# If the DOCBOOK_PROGRAMLISTING tag is set to YES doxygen will include the +# program listings (including syntax highlighting and cross-referencing +# information) to the DOCBOOK output. Note that enabling this will significantly +# increase the size of the DOCBOOK output. +# The default value is: NO. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_PROGRAMLISTING = NO + #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- @@ -1937,9 +1966,9 @@ PREDEFINED = EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will -# remove all refrences to function-like macros that are alone on a line, have an -# all uppercase name, and do not end with a semicolon. Such function macros are -# typically used for boiler-plate code, and will confuse the parser if not +# remove all references to function-like macros that are alone on a line, have +# an all uppercase name, and do not end with a semicolon. Such function macros +# are typically used for boiler-plate code, and will confuse the parser if not # removed. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. @@ -1959,7 +1988,7 @@ SKIP_FUNCTION_MACROS = YES # where loc1 and loc2 can be relative or absolute paths or URLs. See the # section "Linking to external documentation" for more information about the use # of tag files. -# Note: Each tag file must have an unique name (where the name does NOT include +# Note: Each tag file must have a unique name (where the name does NOT include # the path). If a tag file is not located in the directory in which doxygen is # run, you must also specify the path to the tagfile here. @@ -2019,6 +2048,13 @@ CLASS_DIAGRAMS = YES MSCGEN_PATH = +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. + +DIA_PATH = + # If set to YES, the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. @@ -2044,7 +2080,7 @@ HAVE_DOT = NO DOT_NUM_THREADS = 0 -# When you want a differently looking font n the dot files that doxygen +# When you want a differently looking font in the dot files that doxygen # generates you can specify the font name using DOT_FONTNAME. You need to make # sure dot is able to find the font, which can be done by putting it in a # standard location or by setting the DOTFONTPATH environment variable or by @@ -2219,6 +2255,21 @@ DOTFILE_DIRS = MSCFILE_DIRS = +# The DIAFILE_DIRS tag can be used to specify one or more directories that +# contain dia files that are included in the documentation (see the \diafile +# command). + +DIAFILE_DIRS = + +# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the +# path where java can find the plantuml.jar file. If left blank, it is assumed +# PlantUML is not used or called during a preprocessing step. Doxygen will +# generate a warning when it encounters a \startuml command in this case and +# will not generate output for the diagram. +# This tag requires that the tag HAVE_DOT is set to YES. + +PLANTUML_JAR_PATH = + # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # that will be shown in the graph. If the number of nodes in a graph becomes # larger than this value, doxygen will truncate the graph, which is visualized From 0cb351650b00025badc40db613cd43cfd37c5f0a Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 20 Jan 2017 00:28:45 +0100 Subject: [PATCH 6/6] Update Version V1.67 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b8f019d..8db4309 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ RadioHead Packet Radio library for embedded microprocessors =========================================================== -###Version 1.62 +###Version 1.67 This is a copy of the original RadioHead Packet Radio library for embedded microprocessors. It provides a complete object-oriented library for sending and receiving packetized messages via a variety of common data radios and other transports on a range of embedded microprocessors. @@ -12,4 +12,4 @@ Please read the full documentation and licensing from the original author [site] [1]: https://github.com/hallard/RadioHead [2]: https://hallard.me [3]: http://www.airspayce.com/mikem/arduino/RadioHead/ -[4]: http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.62.zip +[4]: http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.67.zip