Merge pull request #392 from tekka007/refactoring_RF24

Major RF24 library rework: minimal driver at full specs
This commit is contained in:
Olivier
2016-04-27 19:46:05 +02:00
7 changed files with 509 additions and 2815 deletions
+33 -8
View File
@@ -35,11 +35,6 @@
// final sketch but is helpful to see what is actually is happening during development
//#define MY_DEBUG
// Enable MY_DEBUG_VERBOSE flag for verbose debug prints related to RF24 radio.
// Requires DEBUG to be enabled.
// This will add even more to the size of the final sketch!
//#define MY_DEBUG_VERBOSE
// Enable MY_DEBUG_VERBOSE_SIGNING flag for verbose debug prints related to signing.
// Requires DEBUG to be enabled.
// This will add even more to the size of the final sketch!
@@ -327,12 +322,24 @@
#endif
/**********************************
* NRF24L01 Driver Defaults
* NRF24L01P Driver Defaults
***********************************/
// Enables RF24 encryption (all nodes and gateway must have this enabled, and all must be personalized with the same AES key)
//#define MY_RF24_ENABLE_ENCRYPTION
/**
* @def MY_DEBUG_VERBOSE_RF24
* @brief Enable MY_DEBUG_VERBOSE_RF24 flag for verbose debug prints related to the RF24 driver. Requires DEBUG to be enabled.
*/
//#define MY_DEBUG_VERBOSE_RF24
/**
* @def MY_RF24_SPI_MAX_SPEED
* @brief MY_RF24_SPI_MAX_SPEED to overrule default nRF24L01+ SPI speed.
*/
//#define MY_RF24_SPI_MAX_SPEED 4000000
/**
* @def MY_RF24_CE_PIN
* @brief Default RF24 chip enable pin setting. Override in sketch if needed.
@@ -399,12 +406,30 @@
* @def MY_RF24_BASE_RADIO_ID
* @brief RF24 radio network identifier.
*
* This is also act as base value for sensor nodeId addresses. Change this (or channel) if you have more than one sensor network.
* This acts as base value for sensor nodeId addresses. Change this (or channel) if you have more than one sensor network.
*/
#ifndef MY_RF24_BASE_RADIO_ID
#define MY_RF24_BASE_RADIO_ID ((uint64_t)0xA8A8E1FC00LL)
#define MY_RF24_BASE_RADIO_ID 0x00,0xFC,0xE1,0xA8,0xA8
#endif
/**
* @def MY_RF24_ADDR_WIDTH
* @brief RF24 address width.
*
* This defines the width of the base address.
*/
#ifndef MY_RF24_ADDR_WIDTH
#define MY_RF24_ADDR_WIDTH 5
#endif
/**
* @def MY_RF24_SANITY_CHECK
* @brief RF24 sanity check to verify functional RF module
*
* This reads back and compares configuration registers. Disable if using non-P modules
*/
#define MY_RF24_SANITY_CHECK
// Enable SOFTSPI for NRF24L01, useful for the W5100 Ethernet module
//#define MY_SOFTSPI
+31 -76
View File
@@ -19,22 +19,12 @@
#include "MyConfig.h"
#include "MyTransport.h"
#include <stdint.h>
#include "drivers/RF24/RF24.h"
#include "drivers/RF24/RF24_config.h"
#if defined(MY_RF24_ENABLE_ENCRYPTION)
#include "drivers/AES/AES.h"
#include "drivers/AES/AES.h"
#endif
#define TO_ADDR(x) (MY_RF24_BASE_RADIO_ID + x)
#define WRITE_PIPE ((uint8_t)0)
#define CURRENT_NODE_PIPE ((uint8_t)1)
#define BROADCAST_PIPE ((uint8_t)2)
RF24 _rf24(MY_RF24_CE_PIN, MY_RF24_CS_PIN);
uint8_t _address;
#if defined(MY_RF24_ENABLE_ENCRYPTION)
AES _aes;
uint8_t _dataenc[32] = {0};
@@ -42,95 +32,60 @@ uint8_t _address;
#endif
bool transportInit() {
// Start up the radio library
_rf24.begin();
if (!_rf24.isPVariant()) {
return false;
}
_rf24.setAutoAck(1);
_rf24.setAutoAck(BROADCAST_PIPE,false); // Turn off auto ack for broadcast
_rf24.enableAckPayload();
_rf24.setChannel(MY_RF24_CHANNEL);
_rf24.setPALevel(MY_RF24_PA_LEVEL);
if (!_rf24.setDataRate(MY_RF24_DATARATE)) {
return false;
}
_rf24.setRetries(5,15);
_rf24.setCRCLength(RF24_CRC_16);
_rf24.enableDynamicPayloads();
// All nodes listen to broadcast pipe (for FIND_PARENT_RESPONSE messages)
_rf24.openReadingPipe(BROADCAST_PIPE, TO_ADDR(BROADCAST_ADDRESS));
#if defined(MY_RF24_ENABLE_ENCRYPTION)
hwReadConfigBlock((void*)_psk, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
_aes.set_key(_psk, 16); //set up AES-key
memset(_psk, 0, 16); // Make sure it is purged from memory when set
//set up AES-key
_aes.set_key(_psk, 16);
// Make sure it is purged from memory when set
memset(_psk, 0, 16);
#endif
//_rf24.printDetails();
return true;
return initializeRF24();
}
void transportSetAddress(uint8_t address) {
_address = address;
_rf24.openReadingPipe(WRITE_PIPE, TO_ADDR(address));
_rf24.openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(address));
_rf24.startListening();
setNodeAddress(address);
startListening();
}
uint8_t transportGetAddress() {
return _address;
return getNodeID();
}
bool transportSend(uint8_t to, const void* data, uint8_t len) {
bool transportSend(uint8_t recipient, const void* data, uint8_t len) {
#if defined(MY_RF24_ENABLE_ENCRYPTION)
memcpy(_dataenc,data,len); // copy input data because it is read-only
_aes.set_IV(0);//not sure if necessary
// copy input data because it is read-only
memcpy(_dataenc,data,len);
// has to be adjusted, WIP!
_aes.set_IV(0);
len = len > 16 ? 32 : 16;
_aes.cbc_encrypt(_dataenc, _dataenc, len/16); //encrypt
#endif
// Make sure radio has powered up
_rf24.powerUp();
_rf24.stopListening();
_rf24.openWritingPipe(TO_ADDR(to));
#if defined(MY_RF24_ENABLE_ENCRYPTION)
bool ok = _rf24.write(_dataenc, len, to == BROADCAST_ADDRESS);
//encrypt data
_aes.cbc_encrypt(_dataenc, _dataenc, len/16);
bool status = sendMessage( recipient, _dataenc, len );
#else
bool ok = _rf24.write(data, len, to == BROADCAST_ADDRESS);
bool status = sendMessage( recipient, data, len );
#endif
_rf24.startListening();
return ok;
return status;
}
bool transportAvailable(uint8_t *to) {
uint8_t pipe = 255;
boolean avail = _rf24.available(&pipe);
(void)avail; //until somebody makes use of 'avail'
if (pipe == CURRENT_NODE_PIPE)
*to = _address;
else if (pipe == BROADCAST_PIPE)
*to = BROADCAST_ADDRESS;
return (_rf24.available() && pipe < 6);
bool avail = IsDataAvailable(to);
return avail;
}
uint8_t transportReceive(void* data) {
uint8_t len = _rf24.getDynamicPayloadSize();
_rf24.read(data, len);
uint8_t len = readMessage(data);
#if defined(MY_RF24_ENABLE_ENCRYPTION)
_aes.set_IV(0);//not sure if necessary
_aes.cbc_decrypt((byte*)(data), (byte*)(data), len>16?2:1); // decrypt
// has to be adjusted, WIP!
_aes.set_IV(0);
// decrypt data
_aes.cbc_decrypt((byte*)(data), (byte*)(data), len>16?2:1);
#endif
return len;
}
void transportPowerDown() {
_rf24.powerDown();
powerDown();
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,163 +0,0 @@
/*
Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
Added Arduino Due support from https://github.com/mcrosson/
*/
#ifndef __RF24_CONFIG_H__
#define __RF24_CONFIG_H__
#include "MyConfig.h"
#if ARDUINO < 100
#include <WProgram.h>
#else
#include <Arduino.h>
#endif
#include <stddef.h>
/*** USER DEFINES: ***/
//#define FAILURE_HANDLING
//#define SPI_UART // Requires library from https://github.com/TMRh20/Sketches/tree/master/SPI_UART
//#define MY_SOFTSPI // Requires library from https://github.com/greiman/DigitalIO
/**********************/
// Define _BV for non-Arduino platforms and for Arduino DUE
#if defined (ARDUINO) && !defined (__arm__) && !defined(_SPI)
#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
#define RF24_TINY
#define _SPI SPI
#elif defined SPI_UART
#include <SPI_UART.h>
#define _SPI uspi
#elif defined MY_SOFTSPI
#include "drivers/AVR/DigitalIO/DigitalIO.h"
// change these pins to your liking
const uint8_t SOFT_SPI_MISO_PIN = MY_SOFT_SPI_MOSI_PIN;
const uint8_t SOFT_SPI_MOSI_PIN = MY_SOFT_SPI_MISO_PIN;
const uint8_t SOFT_SPI_SCK_PIN = MY_SOFT_SPI_SCK_PIN;
const uint8_t SPI_MODE = 0;
#define _SPI spi
#elif defined(ARDUINO_ARCH_SAMD)
#include <SPI.h>
#define _SPI SPI1
#else
#include <SPI.h>
#define _SPI SPI
#endif
#else
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#if defined(__arm__) || defined (CORE_TEENSY)
#include <SPI.h>
#endif
#if !defined(CORE_TEENSY)
#define _BV(x) (1<<(x))
#if !defined(__arm__)
extern HardwareSPI SPI;
#endif
#else
#define printf Serial.printf
#endif
#if ! defined(_SPI)
#define _SPI SPI
#endif
#endif
// Avoid spurious warnings
// Arduino DUE is arm and uses traditional PROGMEM constructs
#if 1
#if ! defined( NATIVE ) && defined( ARDUINO ) && ! defined(__arm__) && ! defined( CORE_TEENSY3 ) && ! defined(ESP8266)
#undef PROGMEM
#define PROGMEM __attribute__(( section(".progmem.data") ))
#undef PSTR
#define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))
#endif
#endif
// Progmem is Arduino-specific
// Arduino DUE is arm and does not include avr/pgmspace
#if defined(__AVR__)
#include <avr/pgmspace.h>
#else
#if defined(ESP8266)
#include <pgmspace.h>
#else
#if ! defined(ARDUINO) // This doesn't work on Arduino DUE
typedef char const char;
#else // Fill in pgm_read_byte that is used, but missing from DUE
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#endif
#endif
#if !defined ( CORE_TEENSY ) && ! defined(ESP8266) && ! defined(ARDUINO_ARCH_SAMD)
typedef uint16_t prog_uint16_t;
#define PSTR(x) (x)
#define printf_P printf
#define strlen_P strlen
#define PROGMEM
#define pgm_read_word(p) (*(p))
#endif
#endif
// ATTiny support code is from https://github.com/jscrane/RF24
#if defined(RF24_TINY)
#include <stdio.h>
#include <Arduino.h>
#include <avr/pgmspace.h>
#define SPI_CLOCK_DIV4 0x00
#define SPI_CLOCK_DIV16 0x01
#define SPI_CLOCK_DIV64 0x02
#define SPI_CLOCK_DIV128 0x03
#define SPI_CLOCK_DIV2 0x04
#define SPI_CLOCK_DIV8 0x05
#define SPI_CLOCK_DIV32 0x06
//#define SPI_CLOCK_DIV64 0x07
#define SPI_MODE0 0x00
#define SPI_MODE1 0x04
#define SPI_MODE2 0x08
#define SPI_MODE3 0x0C
#define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR
#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR
#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR
class SPIClass {
public:
static byte transfer(byte _data);
// SPI Configuration methods
inline static void attachInterrupt();
inline static void detachInterrupt(); // Default
static void begin(); // Default
static void end();
static void setBitOrder(uint8_t);
static void setDataMode(uint8_t);
static void setClockDivider(uint8_t);
};
extern SPIClass SPI;
#endif //ATTiny
#endif // __RF24_CONFIG_H__
-127
View File
@@ -1,127 +0,0 @@
/*
Copyright (c) 2007 Stefan Engelke <mbox@stefanengelke.de>
Portions Copyright (C) 2011 Greg Copeland
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
/* Memory Map */
#define NRF_CONFIG 0x00
#define EN_AA 0x01
#define EN_RXADDR 0x02
#define SETUP_AW 0x03
#define SETUP_RETR 0x04
#define RF_CH 0x05
#define RF_SETUP 0x06
#define RF24_STATUS 0x07
#define OBSERVE_TX 0x08
#define CD 0x09
#define RX_ADDR_P0 0x0A
#define RX_ADDR_P1 0x0B
#define RX_ADDR_P2 0x0C
#define RX_ADDR_P3 0x0D
#define RX_ADDR_P4 0x0E
#define RX_ADDR_P5 0x0F
#define TX_ADDR 0x10
#define RX_PW_P0 0x11
#define RX_PW_P1 0x12
#define RX_PW_P2 0x13
#define RX_PW_P3 0x14
#define RX_PW_P4 0x15
#define RX_PW_P5 0x16
#define FIFO_STATUS 0x17
#define DYNPD 0x1C
#define FEATURE 0x1D
/* Bit Mnemonics */
#define MASK_RX_DR 6
#define MASK_TX_DS 5
#define MASK_MAX_RT 4
#define EN_CRC 3
#define CRCO 2
#define PWR_UP 1
#define PRIM_RX 0
#define ENAA_P5 5
#define ENAA_P4 4
#define ENAA_P3 3
#define ENAA_P2 2
#define ENAA_P1 1
#define ENAA_P0 0
#define ERX_P5 5
#define ERX_P4 4
#define ERX_P3 3
#define ERX_P2 2
#define ERX_P1 1
#define ERX_P0 0
#define AW 0
#define ARD 4
#define ARC 0
#define PLL_LOCK 4
#define RF_DR 3
#define RF_PWR 6
#define RX_DR 6
#define TX_DS 5
#define MAX_RT 4
#define RX_P_NO 1
#define TX_FULL 0
#define PLOS_CNT 4
#define ARC_CNT 0
#define TX_REUSE 6
#define FIFO_FULL 5
#define TX_EMPTY 4
#define RX_FULL 1
#define RX_EMPTY 0
#define DPL_P5 5
#define DPL_P4 4
#define DPL_P3 3
#define DPL_P2 2
#define DPL_P1 1
#define DPL_P0 0
#define EN_DPL 2
#define EN_ACK_PAY 1
#define EN_DYN_ACK 0
/* Instruction Mnemonics */
#define R_REGISTER 0x00
#define W_REGISTER 0x20
#define REGISTER_MASK 0x1F
#define ACTIVATE 0x50
#define R_RX_PL_WID 0x60
#define R_RX_PAYLOAD 0x61
#define W_TX_PAYLOAD 0xA0
#define W_ACK_PAYLOAD 0xA8
#define FLUSH_TX 0xE1
#define FLUSH_RX 0xE2
#define REUSE_TX_PL 0xE3
#define NOP 0xFF
/* Non-P omissions */
#define LNA_HCURR 0
/* P model memory Map */
#define RPD 0x09
#define W_TX_PAYLOAD_NO_ACK 0xB0
/* P model bit Mnemonics */
#define RF_DR_LOW 5
#define RF_DR_HIGH 3
#define RF_PWR_LOW 1
#define RF_PWR_HIGH 2
+2
View File
@@ -34,6 +34,7 @@ AUTO LITERAL1
MY_DEBUG LITERAL1
MY_CORE_ONLY LITERAL1
MY_DEBUG_VERBOSE LITERAL1
MY_DEBUG_VERBOSE_RF24 LITERAL1
MY_DEBUG_VERBOSE_SIGNING LITERAL1
MY_REPEATER_FEATURE LITERAL1
MY_RADIO_NRF24 LITERAL1
@@ -62,6 +63,7 @@ MY_SIGNING_NODE_WHITELISTING LITERAL1
MY_SIGNING_ATSHA204_PIN LITERAL1
MY_SIGNING_SOFT_RANDOMSEED_PIN LITERAL1
MY_RF24_ENABLE_ENCRYPTION LITERAL1
MY_RF24_SPI_MAX_SPEED LITERAL1
MY_RF24_CE_PIN LITERAL1
MY_RF24_CS_PIN LITERAL1
MY_RF24_PA_LEVEL LITERAL1