Re-organized nRF24L01.h file to place 'P' features in one
location. Changed some bit value interpretation. Now auto-detects P-vaiants and is queryable. setDataRate now returns a boolean indicating success or failure of the new data rate request. The wide_band state indicator has been added and now tracks the state, including on error fallback. Its now possible to query the current data rate via getDataRate(). The AA retry duration has been changed to 1500us, which is the lowest interval allowed when running at 250Kbs, with AA enabled, and 32-byte packets.
This commit is contained in:
parent
634d0efde5
commit
059efa5ffa
110
RF24.cpp
110
RF24.cpp
|
@ -8,8 +8,8 @@
|
||||||
|
|
||||||
#include <WProgram.h>
|
#include <WProgram.h>
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include "RF24.h"
|
|
||||||
#include "nRF24L01.h"
|
#include "nRF24L01.h"
|
||||||
|
#include "RF24.h"
|
||||||
|
|
||||||
#undef SERIAL_DEBUG
|
#undef SERIAL_DEBUG
|
||||||
#ifdef SERIAL_DEBUG
|
#ifdef SERIAL_DEBUG
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
void RF24::csn(const int mode) const
|
void RF24::csn(const int mode) const
|
||||||
{
|
{
|
||||||
SPI.setDataMode(SPI_MODE0);
|
SPI.setDataMode(SPI_MODE0);
|
||||||
SPI.setClockDivider(SPI_CLOCK_DIV8);
|
SPI.setClockDivider(SPI_CLOCK_DIV2);
|
||||||
digitalWrite(csn_pin,mode);
|
digitalWrite(csn_pin,mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,8 +210,10 @@ void RF24::print_observe_tx(uint8_t value) const
|
||||||
|
|
||||||
RF24::RF24(const uint8_t _cepin, const uint8_t _cspin,
|
RF24::RF24(const uint8_t _cepin, const uint8_t _cspin,
|
||||||
const rf24_datarate_e speed, const uint8_t channel):
|
const rf24_datarate_e speed, const uint8_t channel):
|
||||||
ce_pin(_cepin), csn_pin(_cspin), wide_band(true), payload_size(32), ack_payload_available(false)
|
ce_pin(_cepin), csn_pin(_cspin), wide_band(true), p_variant(false),
|
||||||
|
payload_size(32), ack_payload_available(false)
|
||||||
{
|
{
|
||||||
|
begin() ;
|
||||||
setDataRate( speed ) ;
|
setDataRate( speed ) ;
|
||||||
setChannel( channel ) ;
|
setChannel( channel ) ;
|
||||||
}
|
}
|
||||||
|
@ -283,13 +285,17 @@ void RF24::printDetails(void) const
|
||||||
printf_P(PSTR("RX_PW_P1 = 0x%02x\n\r"),*buffer);
|
printf_P(PSTR("RX_PW_P1 = 0x%02x\n\r"),*buffer);
|
||||||
|
|
||||||
read_register(EN_AA,buffer,1);
|
read_register(EN_AA,buffer,1);
|
||||||
printf_P(PSTR("EN_AA = %02x\n\r"),*buffer);
|
printf_P(PSTR("EN_AA = 0x%02x\n\r"),*buffer);
|
||||||
|
|
||||||
read_register(EN_RXADDR,buffer,1);
|
read_register(EN_RXADDR,buffer,1);
|
||||||
printf_P(PSTR("EN_RXADDR = %02x\n\r"),*buffer);
|
printf_P(PSTR("EN_RXADDR = 0x%02x\n\r"),*buffer);
|
||||||
|
|
||||||
read_register(RF_CH,buffer,1);
|
read_register(RF_CH,buffer,1);
|
||||||
printf_P(PSTR("RF_CH = %02x\n\r"),*buffer);
|
printf_P(PSTR("RF_CH = 0x%02x\n\r"),*buffer);
|
||||||
|
|
||||||
|
read_register(RF_SETUP,buffer,1);
|
||||||
|
printf_P(PSTR("RF_SETUP = 0x%02x (data rate: %d)\n\r"),*buffer,getDataRate());
|
||||||
|
printf_P(PSTR("Hardware; isPVariant: %d\n\r"),isPVariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
|
@ -307,8 +313,10 @@ void RF24::begin(void)
|
||||||
SPI.setDataMode(SPI_MODE0);
|
SPI.setDataMode(SPI_MODE0);
|
||||||
SPI.setClockDivider(SPI_CLOCK_DIV8);
|
SPI.setClockDivider(SPI_CLOCK_DIV8);
|
||||||
|
|
||||||
// Set generous timeouts, to make testing a little easier
|
// Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier
|
||||||
write_register(SETUP_RETR,(B1111 << ARD) | (B1111 << ARC));
|
// WARNING: If this is ever lowered, either 250KBS mode with AA is broken or maximum packet
|
||||||
|
// sizes must never be used. See documentation for a more complete explanation.
|
||||||
|
write_register(SETUP_RETR,(B0100 << ARD) | (B1111 << ARC));
|
||||||
|
|
||||||
// Reset current status
|
// Reset current status
|
||||||
write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
|
write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
|
||||||
|
@ -318,7 +326,16 @@ void RF24::begin(void)
|
||||||
|
|
||||||
// Flush buffers
|
// Flush buffers
|
||||||
flush_rx();
|
flush_rx();
|
||||||
flush_tx();
|
flush_tx();
|
||||||
|
|
||||||
|
// Determine if this is a p or non-p RF24 module and then
|
||||||
|
// reset our data rate back to default value. This works
|
||||||
|
// because a non-P variant won't allow the data rate to
|
||||||
|
// be set to 250KBS.
|
||||||
|
if( setDataRate( RF24_250KBPS ) ) {
|
||||||
|
p_variant = true ;
|
||||||
|
}
|
||||||
|
setDataRate( RF24_2MBPS ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
|
@ -372,7 +389,7 @@ boolean RF24::write( const void* buf, uint8_t len )
|
||||||
ce(HIGH);
|
ce(HIGH);
|
||||||
|
|
||||||
// IN the end, the send should be blocking. It comes back in 60ms worst case, or much faster
|
// IN the end, the send should be blocking. It comes back in 60ms worst case, or much faster
|
||||||
// if I tighted up the retry logic. (Default settings will be 750us.
|
// if I tighted up the retry logic. (Default settings will be 1500us.
|
||||||
// Monitor the send
|
// Monitor the send
|
||||||
uint8_t observe_tx;
|
uint8_t observe_tx;
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
|
@ -600,6 +617,12 @@ boolean RF24::isAckPayloadAvailable(void)
|
||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
|
|
||||||
|
boolean RF24::isPVariant(void) const {
|
||||||
|
return p_variant ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
void RF24::setAutoAck(const bool enable) const
|
void RF24::setAutoAck(const bool enable) const
|
||||||
{
|
{
|
||||||
if ( enable )
|
if ( enable )
|
||||||
|
@ -613,7 +636,7 @@ void RF24::setAutoAck(const bool enable) const
|
||||||
void RF24::setAutoAck( const uint8_t pipe, const bool enable ) const
|
void RF24::setAutoAck( const uint8_t pipe, const bool enable ) const
|
||||||
{
|
{
|
||||||
uint8_t en_aa = read_register( EN_AA ) ;
|
uint8_t en_aa = read_register( EN_AA ) ;
|
||||||
en_aa &= ~((enable?0:1)<<pipe) ;
|
en_aa &= ~((enable?0:1)<<pipe) ;// inverted logic here (1=off, 0=on)
|
||||||
write_register( EN_AA, en_aa ) ;
|
write_register( EN_AA, en_aa ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,24 +664,23 @@ void RF24::setPALevel(const rf24_pa_dbm_e level) const
|
||||||
switch( level )
|
switch( level )
|
||||||
{
|
{
|
||||||
case RF24_PA_MAX:
|
case RF24_PA_MAX:
|
||||||
setup |= RF_PWR_0DB ;
|
setup |= (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ;
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
case RF24_PA_HIGH:
|
case RF24_PA_HIGH:
|
||||||
setup |= RF_PWR_6DB ;
|
setup |= _BV(RF_PWR_HIGH) ;
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
case RF24_PA_LOW:
|
case RF24_PA_LOW:
|
||||||
setup |= RF_PWR_12DB ;
|
setup |= _BV(RF_PWR_LOW) ;
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
case RF24_PA_MIN:
|
case RF24_PA_MIN:
|
||||||
setup |= RF_PWR_18DB ;
|
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
case RF24_PA_ERROR:
|
case RF24_PA_ERROR:
|
||||||
// On error, go to maximum PA
|
// On error, go to maximum PA
|
||||||
setup |= RF_PWR_0DB ;
|
setup |= (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,23 +692,23 @@ void RF24::setPALevel(const rf24_pa_dbm_e level) const
|
||||||
rf24_pa_dbm_e RF24::getPALevel(void) const
|
rf24_pa_dbm_e RF24::getPALevel(void) const
|
||||||
{
|
{
|
||||||
rf24_pa_dbm_e result = RF24_PA_ERROR ;
|
rf24_pa_dbm_e result = RF24_PA_ERROR ;
|
||||||
uint8_t power = read_register(RF_SETUP) & RF_PWR ;
|
uint8_t power = read_register(RF_SETUP) & (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ;
|
||||||
|
|
||||||
switch( power )
|
switch( power )
|
||||||
{
|
{
|
||||||
case RF_PWR_0DB:
|
case (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)):
|
||||||
result = RF24_PA_MAX ;
|
result = RF24_PA_MAX ;
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
case RF_PWR_6DB:
|
case _BV(RF_PWR_HIGH):
|
||||||
result = RF24_PA_HIGH ;
|
result = RF24_PA_HIGH ;
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
case RF_PWR_12DB:
|
case _BV(RF_PWR_LOW):
|
||||||
result = RF24_PA_LOW ;
|
result = RF24_PA_LOW ;
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
case RF_PWR_18DB:
|
default:
|
||||||
result = RF24_PA_MIN ;
|
result = RF24_PA_MIN ;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
|
@ -696,7 +718,7 @@ rf24_pa_dbm_e RF24::getPALevel(void) const
|
||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
|
|
||||||
void RF24::setDataRate(const rf24_datarate_e speed)
|
boolean RF24::setDataRate(const rf24_datarate_e speed)
|
||||||
{
|
{
|
||||||
uint8_t setup = read_register(RF_SETUP) ;
|
uint8_t setup = read_register(RF_SETUP) ;
|
||||||
|
|
||||||
|
@ -707,6 +729,7 @@ void RF24::setDataRate(const rf24_datarate_e speed)
|
||||||
{
|
{
|
||||||
// Must set the RF_DR_LOW to 1; RF_DR_HIGH (used to be RF_DR) is already 0
|
// Must set the RF_DR_LOW to 1; RF_DR_HIGH (used to be RF_DR) is already 0
|
||||||
// Making it '10'.
|
// Making it '10'.
|
||||||
|
wide_band = false ;
|
||||||
setup |= _BV( RF_DR_LOW ) ;
|
setup |= _BV( RF_DR_LOW ) ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -715,13 +738,50 @@ void RF24::setDataRate(const rf24_datarate_e speed)
|
||||||
// Making it '01'
|
// Making it '01'
|
||||||
if ( speed == RF24_2MBPS )
|
if ( speed == RF24_2MBPS )
|
||||||
{
|
{
|
||||||
wide_band = true ;
|
wide_band = true ;
|
||||||
setup |= _BV(RF_DR_HIGH);
|
setup |= _BV(RF_DR_HIGH);
|
||||||
|
} else {
|
||||||
|
// 1Mbs
|
||||||
|
wide_band = false ;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
write_register(RF_SETUP,setup);
|
||||||
|
|
||||||
|
// Verify our result
|
||||||
|
setup = read_register(RF_SETUP) ;
|
||||||
|
if( setup == setup ) {
|
||||||
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
write_register(RF_SETUP,setup);
|
wide_band = false ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
rf24_datarate_e RF24::getDataRate( void ) const {
|
||||||
|
rf24_datarate_e result ;
|
||||||
|
uint8_t setup = read_register(RF_SETUP) ;
|
||||||
|
|
||||||
|
// Order matters in our case below
|
||||||
|
switch( setup & (_BV(RF_DR_LOW) | _BV(RF_DR_HIGH)) ) {
|
||||||
|
case _BV(RF_DR_LOW):
|
||||||
|
// '10' = 250KBPS
|
||||||
|
result = RF24_250KBPS ;
|
||||||
|
break ;
|
||||||
|
|
||||||
|
case _BV(RF_DR_HIGH):
|
||||||
|
// '01' = 2MBPS
|
||||||
|
result = RF24_2MBPS ;
|
||||||
|
break ;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// '00' = 1MBPS
|
||||||
|
result = RF24_1MBPS ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
|
|
30
RF24.h
30
RF24.h
|
@ -25,6 +25,7 @@ private:
|
||||||
uint8_t ce_pin; /**< "Chip Enable" pin, activates the RX or TX role */
|
uint8_t ce_pin; /**< "Chip Enable" pin, activates the RX or TX role */
|
||||||
uint8_t csn_pin; /**< SPI Chip select */
|
uint8_t csn_pin; /**< SPI Chip select */
|
||||||
boolean wide_band; /* 2Mbs data rate in use? */
|
boolean wide_band; /* 2Mbs data rate in use? */
|
||||||
|
boolean p_variant; /* False for RF24L01 and true for RF24L01P */
|
||||||
uint8_t payload_size; /**< Fixed size of payloads */
|
uint8_t payload_size; /**< Fixed size of payloads */
|
||||||
boolean ack_payload_available; /**< Whether there is an ack payload waiting */
|
boolean ack_payload_available; /**< Whether there is an ack payload waiting */
|
||||||
uint8_t ack_payload_length; /**< Dynamic size of pending ack payload. Note: not used. */
|
uint8_t ack_payload_length; /**< Dynamic size of pending ack payload. Note: not used. */
|
||||||
|
@ -42,6 +43,10 @@ protected:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set chip select pin
|
* Set chip select pin
|
||||||
|
* Running SPI bus at PI_CLOCK_DIV2 so we don't waist time transferring data
|
||||||
|
* and best of all, we make use of the radio's FIFO buffers. A lower speed
|
||||||
|
* means we're less likely to effectively leverage our FIFOs and pay a higher
|
||||||
|
* AVR runtime cost as toll.
|
||||||
*
|
*
|
||||||
* @param mode HIGH to take this unit off the SPI bus, LOW to put it on
|
* @param mode HIGH to take this unit off the SPI bus, LOW to put it on
|
||||||
*/
|
*/
|
||||||
|
@ -416,6 +421,12 @@ public:
|
||||||
*/
|
*/
|
||||||
boolean isAckPayloadAvailable(void);
|
boolean isAckPayloadAvailable(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns true if the hardware is RF24L01P (or compatible) and false
|
||||||
|
* if its not.
|
||||||
|
*/
|
||||||
|
boolean isPVariant(void) const ;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable or disable auto-acknowlede packets
|
* Enable or disable auto-acknowlede packets
|
||||||
*
|
*
|
||||||
|
@ -471,8 +482,12 @@ public:
|
||||||
void setPALevel( const rf24_pa_dbm_e level ) const ;
|
void setPALevel( const rf24_pa_dbm_e level ) const ;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches the current PA level. See setPALevel for
|
* Fetches the current PA level.
|
||||||
* return value definitions.
|
*
|
||||||
|
* @return Returns a value from the rf24_pa_dbm_e enum describing
|
||||||
|
* the current PA setting. Please remember, all values represented
|
||||||
|
* by the enum mnemonics are negative dBm. See setPALevel for
|
||||||
|
* return value descriptions.
|
||||||
*/
|
*/
|
||||||
rf24_pa_dbm_e getPALevel( void ) const ;
|
rf24_pa_dbm_e getPALevel( void ) const ;
|
||||||
|
|
||||||
|
@ -481,7 +496,16 @@ public:
|
||||||
*
|
*
|
||||||
* @param speed RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps
|
* @param speed RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps
|
||||||
*/
|
*/
|
||||||
void setDataRate(const rf24_datarate_e speed);
|
boolean setDataRate(const rf24_datarate_e speed);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the transmission data rate
|
||||||
|
*
|
||||||
|
* @return Returns the hardware's currently configured datarate. The value
|
||||||
|
* is one of 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS, as defined in the
|
||||||
|
* rf24_datarate_e enum.
|
||||||
|
*/
|
||||||
|
rf24_datarate_e getDataRate( void ) const ;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the CRC length
|
* Set the CRC length
|
||||||
|
|
23
nRF24L01.h
23
nRF24L01.h
|
@ -33,7 +33,6 @@
|
||||||
#define STATUS 0x07
|
#define STATUS 0x07
|
||||||
#define OBSERVE_TX 0x08
|
#define OBSERVE_TX 0x08
|
||||||
#define CD 0x09
|
#define CD 0x09
|
||||||
#define RPD 0x09
|
|
||||||
#define RX_ADDR_P0 0x0A
|
#define RX_ADDR_P0 0x0A
|
||||||
#define RX_ADDR_P1 0x0B
|
#define RX_ADDR_P1 0x0B
|
||||||
#define RX_ADDR_P2 0x0C
|
#define RX_ADDR_P2 0x0C
|
||||||
|
@ -74,17 +73,9 @@
|
||||||
#define AW 0
|
#define AW 0
|
||||||
#define ARD 4
|
#define ARD 4
|
||||||
#define ARC 0
|
#define ARC 0
|
||||||
#define RF_DR_LOW 5
|
|
||||||
#define PLL_LOCK 4
|
#define PLL_LOCK 4
|
||||||
#define RF_DR_HIGH 3
|
#define RF_DR 3
|
||||||
#define RF_PWR 6
|
#define RF_PWR 6
|
||||||
#define RF_PWR_LOW 1
|
|
||||||
#define RF_PWR_HIGH 2
|
|
||||||
#define RF_PWR_0DB 6
|
|
||||||
#define RF_PWR_6DB 4
|
|
||||||
#define RF_PWR_12DB 2
|
|
||||||
#define RF_PWR_18DB 0
|
|
||||||
#define LNA_HCURR 0
|
|
||||||
#define RX_DR 6
|
#define RX_DR 6
|
||||||
#define TX_DS 5
|
#define TX_DS 5
|
||||||
#define MAX_RT 4
|
#define MAX_RT 4
|
||||||
|
@ -120,3 +111,15 @@
|
||||||
#define FLUSH_RX 0xE2
|
#define FLUSH_RX 0xE2
|
||||||
#define REUSE_TX_PL 0xE3
|
#define REUSE_TX_PL 0xE3
|
||||||
#define NOP 0xFF
|
#define NOP 0xFF
|
||||||
|
|
||||||
|
/* Non-P omissions */
|
||||||
|
#define LNA_HCURR 0
|
||||||
|
|
||||||
|
/* P model memory Map */
|
||||||
|
#define RPD 0x09
|
||||||
|
|
||||||
|
/* P model bit Mnemonics */
|
||||||
|
#define RF_DR_LOW 5
|
||||||
|
#define RF_DR_HIGH 3
|
||||||
|
#define RF_PWR_LOW 1
|
||||||
|
#define RF_PWR_HIGH 2
|
||||||
|
|
Loading…
Reference in New Issue