diff --git a/README.md b/README.md
index 770ced9..8db4309 100644
--- a/README.md
+++ b/README.md
@@ -1,163 +1,15 @@
-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]**
-
-### features added with this fork
-=================================
-
-**Compatible with boards**
-
-[LoRasPI][10], [Raspberry PI Lora Gateway][12], [Dragino Lora GPS HAT][13]
-
-
-
-
-
-- Added moteino modem setting on RF69 to be compatible with lowpowerlab RF69 configuration library
-- Added possibility to work with no IRQ connected for RF69 and RF95
- - for example to get one more GPIO free
- - on Raspberry Pi, we do not have `attachInterrupt()` like with bcm2835 library
-- Added samples for multiples Raspberry Pi boards with RF69 and RF95 modules such as
- - [LoRasPI][10], simple RFM9x or RFM69HCW shield
- - [iC880A or Linklabs Raspberry PI shield][11] with RFM9x or RFM69HCW onboard
- - [Raspberry PI Lora Gateway][12] with multiple RFM9x or RFM69HCW shield
- - [Dragino Lora shield][13]
- - Sample code are in [rf95][21], [rf69][20], [nrf24][22] and [multi_server][23], note that old sample NRF24 sample has been moved to nrf24 folder for consistency.
-- Added 2 samples test tools (for Raspberry PI) do detect RF69 and RF95 modules and check IRQ rising edge
- - [spi_scan][9] sample code, scan and try to detect connected modules
- - [irq_test][8] sample code, check a rising edge on a GPIO
-
-Sample code for Raspberry PI is located under [RadioHead/examples/raspi][7] folder.
-
-### Installation on Raspberry PI
-================================
-
-Clone repository
-```shell
-git clone https://github.com/hallard/RadioHead
-```
-
-**Connection and pins definition**
-
-Boards pins (Chip Select, IRQ line, Reset and LED) definition are set in the new [RadioHead/examples/raspi/RasPiBoards.h][24] file. In your code, you need to define board used and then, include the file definition like this
-```cpp
-// LoRasPi board
-#define BOARD_LORASPI
-
-// Now we include RasPi_Boards.h so this will expose defined
-// constants with CS/IRQ/RESET/on board LED pins definition
-#include "../RasPiBoards.h"
-
-// Your code start here
-#ifdef RF_RST_PIN
-// Blah blah do reset line
-#endif
-
-```
-
-Then in your code you'll have exposed RF_CS_PIN, RF_IRQ_PIN, RF_RST_PIN and RF_LED_PIN and you'll be able to do some `#ifdef RF_LED_LIN` for example. See [rf95_client][25] sample code.
-
-So you have 3 options to define the pins you want
-
-- The board you have is already defined so just need to define it your source code (as explained above)
-- You can add your board into [RasPiBoards.h][24] and then define it your source code as above
-- You can manually define pins in your code and remove the board definition and `#include "../RasPiBoards.h"`
-
-To go further with examples :
-
-go to example folder here spi_scan
-```shell
-cd RadioHead/examples/raspi/spi_scan
-```
-Build executable
-```shell
-root@pi03(rw):~/RadioHead/examples/raspi/spi_scan# make
-g++ -DRASPBERRY_PI -DBCM2835_NO_DELAY_COMPATIBILITY -c -I../../.. spi_scan.c
-g++ spi_scan.o -lbcm2835 -o spi_scan
-root@pi03(rw):~/RadioHead/examples/raspi/spi_scan
-```
-And run
-```shell
-root@pi03(rw):~/RadioHead/examples/raspi/spi_scan# ./spi_scan
-Checking register(0x42) with CS=GPIO06 => Nothing!
-Checking register(0x10) with CS=GPIO06 => Nothing!
-Checking register(0x42) with CS=GPIO08 => SX1276 RF95/96 (V=0x12)
-Checking register(0x10) with CS=GPIO08 => Nothing!
-Checking register(0x42) with CS=GPIO07 => Nothing!
-Checking register(0x10) with CS=GPIO07 => Nothing!
-Checking register(0x42) with CS=GPIO26 => Nothing!
-Checking register(0x10) with CS=GPIO26 => Nothing!
-```
-And voila! with [LoRasPi][10] board RFM95 dedected on SPI with GPIO8 (CE0)
-
-
-If I'm doing same test with [PI Lora Gateway][12] with 2 RFM95 (one 433MHz and one 868MHz) and one RFMHW69 433MHz on board like this
-
-
-
-Here are the results when trying to detect the onboard modules:
-
-```shell
-root@pi01(rw):~/RadioHead/examples/raspi/spi_scan# ./spi_scan
-Checking register(0x42) with CS=GPIO06 => Nothing!
-Checking register(0x10) with CS=GPIO06 => Nothing!
-Checking register(0x42) with CS=GPIO08 => SX1276 RF95/96 (V=0x12)
-Checking register(0x10) with CS=GPIO08 => Nothing!
-Checking register(0x42) with CS=GPIO07 => SX1276 RF95/96 (V=0x12)
-Checking register(0x10) with CS=GPIO07 => Nothing!
-Checking register(0x42) with CS=GPIO26 => Unknown (V=0x01)
-Checking register(0x10) with CS=GPIO26 => SX1231 RFM69 (V=0x24)
-```
-
-Voila! 3 modules are seen, now let's try listenning packets with PI Lora [Gateway][12].
-
-My setup has another Raspberry Pi with RFM95 868MHZ [LoRasPI][10] shield running [`rf95_client`][25] sample and some [ULPnode][6] prototypes always running with on board RFM69 configured as Group ID 69 on 433MHz. I don't have a Lora 433MHz sender running so we won't receive anything on this one.
-
-Here the results starting from scratch
-
-**Client side**
-
-
-
-**multi server side**
-
-
-
-It works!
-
-### Difference with original Author repo
-========================================
-
-Due to easier maintenance to keep in sync with original author lib, I've got 2 repo:
-
-- My master one (this 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/
-[7]: https://github.com/hallard/RadioHead/tree/master/examples/raspi
-[8]: https://github.com/hallard/RadioHead/tree/master/examples/raspi/irq_test
-[9]: https://github.com/hallard/RadioHead/tree/master/examples/raspi/spi_scan
-
-[10]: https://github.com/hallard/LoRasPI
-[11]: https://github.com/ch2i/iC880A-Raspberry-PI
-[12]: https://github.com/hallard/RPI-Lora-Gateway
-[13]: https://github.com/dragino/Lora
-
-[20]: https://github.com/hallard/RadioHead/tree/master/examples/raspi/rf69
-[21]: https://github.com/hallard/RadioHead/tree/master/examples/raspi/rf95
-[22]: https://github.com/hallard/RadioHead/tree/master/examples/raspi/nrf24
-[23]: https://github.com/hallard/RadioHead/tree/master/examples/raspi/multi_server
-[24]: https://github.com/hallard/RadioHead/tree/master/examples/raspi/RasPiBoards.h
-[25]: https://github.com/hallard/RadioHead/tree/master/examples/raspi/rf95/rf95_client.cpp
-
-
+RadioHead Packet Radio library for embedded microprocessors
+===========================================================
+
+###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.
+
+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.67.zip
diff --git a/RHGenericDriver.cpp b/RHGenericDriver.cpp
index 0137f24..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
@@ -72,7 +72,7 @@ bool RHGenericDriver::waitPacketSent(uint16_t timeout)
bool RHGenericDriver::waitCAD()
{
if (!_cad_timeout)
- return true;
+ return true;
// Wait for any channel activity to finish or timeout
// Sophisticated DCF function...
@@ -83,7 +83,7 @@ bool RHGenericDriver::waitCAD()
while (isChannelActive())
{
if (millis() - t > _cad_timeout)
- return false;
+ return false;
delay(random(1, 10) * 100); // Should these values be configurable? Macros?
}
diff --git a/RHGenericDriver.h b/RHGenericDriver.h
index f9b1765..1c8fc53 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
@@ -52,7 +52,7 @@ class RHGenericDriver
RHModeIdle, ///< Transport is idle.
RHModeTx, ///< Transport is in the process of transmitting a message.
RHModeRx, ///< Transport is in the process of receiving a message.
- RHModeCad ///< Transport is in the process of detecting channel activity (if supported)
+ RHModeCad ///< Transport is in the process of detecting channel activity (if supported)
} RHMode;
/// Constructor
@@ -298,6 +298,10 @@ class RHGenericDriver
volatile bool _cad;
unsigned int _cad_timeout;
+ /// Channel activity detected
+ volatile bool _cad;
+ unsigned int _cad_timeout;
+
private:
};
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 a1cd14f..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
@@ -483,7 +483,7 @@ bool RH_ASK::send(const uint8_t* data, uint8_t len)
waitPacketSent();
if (!waitCAD())
- return false; // Check channel activity
+ return false; // Check channel activity
// Encode the message length
crc = RHcrc_ccitt_update(crc, count);
diff --git a/RH_CC110.cpp b/RH_CC110.cpp
index 0938ec7..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
@@ -302,7 +302,7 @@ bool RH_CC110::send(const uint8_t* data, uint8_t len)
setModeIdle();
if (!waitCAD())
- return false; // Check channel activity
+ return false; // Check channel activity
spiWriteRegister(RH_CC110_REG_3F_FIFO, len + RH_CC110_HEADER_LEN);
spiWriteRegister(RH_CC110_REG_3F_FIFO,_txHeaderTo);
diff --git a/RH_MRF89.cpp b/RH_MRF89.cpp
index af386f5..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
@@ -390,10 +390,10 @@ 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
-
+ 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 f4f59e8..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
@@ -189,7 +189,7 @@ bool RH_NRF24::send(const uint8_t* data, uint8_t len)
return false;
if (!waitCAD())
- return false; // Check channel activity
+ return false; // Check channel activity
// Set up the headers
_buf[0] = _txHeaderTo;
diff --git a/RH_NRF51.cpp b/RH_NRF51.cpp
index 6a52f78..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
+ 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 04ee23f..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
@@ -144,7 +144,7 @@ bool RH_NRF905::send(const uint8_t* data, uint8_t len)
return false;
if (!waitCAD())
- return false; // Check channel activity
+ return false; // Check channel activity
// Set up the headers
_buf[0] = _txHeaderTo;
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 c4e4407..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
@@ -589,7 +589,7 @@ bool RH_RF22::send(const uint8_t* data, uint8_t len)
waitPacketSent();
if (!waitCAD())
- return false; // Check channel activity
+ return false; // Check channel activity
ATOMIC_BLOCK_START;
spiWrite(RH_RF22_REG_3A_TRANSMIT_HEADER3, _txHeaderTo);
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 7233ba1..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:
@@ -348,7 +348,7 @@ bool RH_RF24::send(const uint8_t* data, uint8_t len)
setModeIdle(); // Prevent RX while filling the fifo
if (!waitCAD())
- return false; // Check channel activity
+ 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
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 ce143d9..fe4e563 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
@@ -547,7 +547,7 @@ bool RH_RF69::send(const uint8_t* data, uint8_t len)
setModeIdle(); // Prevent RX while filling the fifo
if (!waitCAD())
- return false; // Check channel activity
+ return false; // Check channel activity
ATOMIC_BLOCK_START;
digitalWrite(_slaveSelectPin, LOW);
diff --git a/RH_RF69.h b/RH_RF69.h
index ebb8bc2..98e8763 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 $
//
///
@@ -326,10 +326,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
///
@@ -512,6 +518,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)
@@ -858,6 +874,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);
@@ -866,7 +884,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 8beda8f..3f5e12f 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
@@ -299,7 +299,7 @@ bool RH_RF95::send(const uint8_t* data, uint8_t len)
setModeIdle();
if (!waitCAD())
- return false; // Check channel activity
+ return false; // Check channel activity
// Position at the beginning of the FIFO
spiWrite(RH_RF95_REG_0D_FIFO_ADDR_PTR, 0);
@@ -506,3 +506,12 @@ 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 acb99dc..2ed0c1f 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
@@ -111,6 +111,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
@@ -152,9 +153,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
@@ -190,19 +199,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
@@ -214,9 +228,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
@@ -459,6 +477,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
///
@@ -716,6 +742,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 c7c3f5e..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)
@@ -201,7 +201,7 @@ bool RH_Serial::recv(uint8_t* buf, uint8_t* len)
bool RH_Serial::send(const uint8_t* data, uint8_t len)
{
if (!waitCAD())
- return false; // Check channel activity
+ return false; // Check channel activity
_txFcs = 0xffff; // Initial value
_serial.write(DLE); // Not in FCS
diff --git a/RH_TCP.cpp b/RH_TCP.cpp
index 23d9181..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
@@ -255,7 +255,7 @@ 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?)
+ 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
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