From 1a37c1cd0ff12675ea983f921b445771b0e699da Mon Sep 17 00:00:00 2001 From: Greg Copeland Date: Tue, 21 Jun 2011 10:26:16 -0500 Subject: [PATCH 1/9] New P variant feature support with corresponding defines. RF_DR is now broken into two bits to support P variant and is now obsolete. RF_DR is now RF_DR_HIGH and RF_DR_LOW; with RF_DR_HIGH corresponding to the original RF_DR bit. Data rate can now select 250kbs mode on supporting hardware. Its now possible to both get and set the current PA level. LNA is obsolete in P variant. CD is obsoleted in P variant. Can now check both CD and RDP levels. Will follow through in the future to determine if there is any real difference. Aside from dBm floor and slight changes in internal behavior, they appear identical in interface and function. Fixes a bug in openReadingPipe which was excluding the 5th pipline. We have 6-pipelines, 0-5, so excluding the 5th (<5) would only allow for four active pipelines. --- RF24.cpp | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++---- RF24.h | 34 ++++++++++++++++++-- nRF24L01.h | 14 ++++++-- 3 files changed, 131 insertions(+), 11 deletions(-) diff --git a/RF24.cpp b/RF24.cpp index d3854fb..f443dbe 100644 --- a/RF24.cpp +++ b/RF24.cpp @@ -514,7 +514,7 @@ void RF24::openReadingPipe(uint8_t child, uint64_t value) if (child == 0) pipe0_reading_address = value; - if (child < 5) + if (child < 6) { // For pipes 2-5, only write the LSB if ( child < 2 ) @@ -524,7 +524,7 @@ void RF24::openReadingPipe(uint8_t child, uint64_t value) write_register(child_payload_size[child],payload_size); - // Note this is kind of an inefficient way to set up these enable bits, bit I thought it made + // Note this is kind of an inefficient way to set up these enable bits, but I thought it made // the calling code more simple uint8_t en_rx; read_register(EN_RXADDR,&en_rx,1); @@ -613,13 +613,95 @@ boolean RF24::testCarrier(void) /******************************************************************/ +boolean RF24::testRPD(void) +{ + return ( read_register(RPD) & 1 ) ; +} + +/******************************************************************/ + +void RF24::setPALevel(rf24_pa_dbm_e level) +{ + uint8_t setup = read_register(RF_SETUP) ; + setup &= ~(_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ; + + switch( level ) + { + case RF24_PA_MAX: + setup |= RF_PWR_0DB ; + break ; + + case RF24_PA_HIGH: + setup |= RF_PWR_6DB ; + break ; + + case RF24_PA_LOW: + setup |= RF_PWR_12DB ; + break ; + + case RF24_PA_MIN: + setup |= RF_PWR_18DB ; + break ; + } + + write_register( RF_SETUP, setup ) ; +} + +/******************************************************************/ + +rf24_pa_dbm_e RF24::getPALevel(void) +{ + rf24_pa_dbm_e result = RF24_PA_ERROR ; + uint8_t power = read_register(RF_SETUP) & RF_PWR ; + + switch( power ) + { + case RF_PWR_0DB: + result = RF24_PA_MAX ; + break ; + + case RF_PWR_6DB: + result = RF24_PA_HIGH ; + break ; + + case RF_PWR_12DB: + result = RF24_PA_LOW ; + break ; + + case RF_PWR_18DB: + result = RF24_PA_MIN ; + break ; + } + + return result ; +} + +/******************************************************************/ + void RF24::setDataRate(rf24_datarate_e speed) { - uint8_t setup = read_register(RF_SETUP) & RF_DR; - if (speed == RF24_2MBPS) - setup |= _BV(RF_DR); - write_register(RF_SETUP,setup); + uint8_t setup = read_register(RF_SETUP) ; + // HIGH and LOW '00' is 1Mbs - our default + setup &= ~(_BV(RF_DR_LOW) | _BV(RF_DR_HIGH)) ; + if( speed == RF24_250KBPS ) + { + // Must set the RF_DR_LOW to 1; RF_DR_HIGH (used to be RF_DR) is already 0 + // Making it '10'. + setup |= _BV( RF_DR_LOW ) ; + } + else + { + // Set 2Mbs, RF_DR (RF_DR_HIGH) is set 1 + // Making it '01' + if ( speed == RF24_2MBPS ) + { + setup |= _BV(RF_DR_HIGH); + } + + } + + write_register(RF_SETUP,setup); } /******************************************************************/ diff --git a/RF24.h b/RF24.h index 386b628..70c5028 100644 --- a/RF24.h +++ b/RF24.h @@ -11,7 +11,8 @@ #include -typedef enum { RF24_1MBPS = 0, RF24_2MBPS } rf24_datarate_e; +typedef enum { RF24_PA_MIN = 0,RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX, RF24_PA_ERROR } rf24_pa_dbm_e ; +typedef enum { RF24_1MBPS = 0, RF24_2MBPS, RF24_250KBPS } rf24_datarate_e; typedef enum { RF24_CRC_8 = 0, RF24_CRC_16 } rf24_crclength_e; /** @@ -423,10 +424,39 @@ public: */ boolean testCarrier(void); + /** + * Test whether a signal (carrier or otherwise) greater than + * or equal to -64dBm is present on the channel. Valid only + * on nRF24L01P (+) hardware. On nRF24L01, use testCarrier(). + * + * Useful to check for interference on the current channel and + * channel hopping strategies. + * + * @return true if signal => -64dBm, false if not + */ + boolean testRPD(void); + + /** + * Set Power Amplifier (PA) level to one of four levels. + * Relative mnemonics have been used to allow for future PA level + * changes. According to 6.5 of the nRF24L01+ specification sheet, + * they translate to: RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, + * RF24_PA_MED=-6dBM, and RF24_PA_HIGH=0dBm. + * + * @param Desired PA level. + */ + void setPALevel( rf24_pa_dbm_e level ) ; + + /** + * Fetches the current PA level. See setPALevel for + * return value definitions. + */ + rf24_pa_dbm_e getPALevel( void ) ; + /** * Set the transmission data rate * - * @param speed 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(rf24_datarate_e speed); diff --git a/nRF24L01.h b/nRF24L01.h index 5f4d1b8..cc3b5bd 100644 --- a/nRF24L01.h +++ b/nRF24L01.h @@ -33,6 +33,7 @@ #define STATUS 0x07 #define OBSERVE_TX 0x08 #define CD 0x09 +#define RPD 0x09 #define RX_ADDR_P0 0x0A #define RX_ADDR_P1 0x0B #define RX_ADDR_P2 0x0C @@ -73,10 +74,17 @@ #define AW 0 #define ARD 4 #define ARC 0 +#define RF_DR_LOW 5 #define PLL_LOCK 4 -#define RF_DR 3 -#define RF_PWR 1 -#define LNA_HCURR 0 +#define RF_DR_HIGH 3 +#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 TX_DS 5 #define MAX_RT 4 From b1a7dc7d54d51d5ffa7291ecbd6d9dd0f2e53b64 Mon Sep 17 00:00:00 2001 From: Greg Copeland Date: Tue, 21 Jun 2011 14:36:02 -0500 Subject: [PATCH 2/9] Adds constantness to method declarations and arguments where possible. Added the concept of wide band. Currently not used but state is properly tracked in accordance with data rate selection. Default channel is changed to 64 in begin method. That needs to move anyways. Automatic ACKs can now be adjusted on a per pipeline bases. --- RF24.cpp | 95 ++++++++++++++++++++++++++++++++++---------------------- RF24.h | 74 +++++++++++++++++++++++++------------------ 2 files changed, 102 insertions(+), 67 deletions(-) diff --git a/RF24.cpp b/RF24.cpp index f443dbe..155908a 100644 --- a/RF24.cpp +++ b/RF24.cpp @@ -26,7 +26,7 @@ /******************************************************************/ -void RF24::csn(int mode) +void RF24::csn(const int mode) const { SPI.setDataMode(SPI_MODE0); SPI.setClockDivider(SPI_CLOCK_DIV8); @@ -35,14 +35,14 @@ void RF24::csn(int mode) /******************************************************************/ -void RF24::ce(int mode) +void RF24::ce(const int mode) const { digitalWrite(ce_pin,mode); } /******************************************************************/ -uint8_t RF24::read_register(uint8_t reg, uint8_t* buf, uint8_t len) +uint8_t RF24::read_register(const uint8_t reg, uint8_t* buf, uint8_t len) const { uint8_t status; @@ -58,7 +58,7 @@ uint8_t RF24::read_register(uint8_t reg, uint8_t* buf, uint8_t len) /******************************************************************/ -uint8_t RF24::read_register(uint8_t reg) +uint8_t RF24::read_register(const uint8_t reg) const { csn(LOW); SPI.transfer( R_REGISTER | ( REGISTER_MASK & reg ) ); @@ -70,7 +70,7 @@ uint8_t RF24::read_register(uint8_t reg) /******************************************************************/ -uint8_t RF24::write_register(uint8_t reg, const uint8_t* buf, uint8_t len) +uint8_t RF24::write_register(const uint8_t reg, const uint8_t* buf, uint8_t len) const { uint8_t status; @@ -86,7 +86,7 @@ uint8_t RF24::write_register(uint8_t reg, const uint8_t* buf, uint8_t len) /******************************************************************/ -uint8_t RF24::write_register(uint8_t reg, uint8_t value) +uint8_t RF24::write_register(const uint8_t reg, const uint8_t value) const { uint8_t status; @@ -144,7 +144,7 @@ uint8_t RF24::read_payload(void* buf, uint8_t len) /******************************************************************/ -uint8_t RF24::flush_rx(void) +uint8_t RF24::flush_rx(void) const { uint8_t status; @@ -157,7 +157,7 @@ uint8_t RF24::flush_rx(void) /******************************************************************/ -uint8_t RF24::flush_tx(void) +uint8_t RF24::flush_tx(void) const { uint8_t status; @@ -170,7 +170,7 @@ uint8_t RF24::flush_tx(void) /******************************************************************/ -uint8_t RF24::get_status(void) +uint8_t RF24::get_status(void) const { uint8_t status; @@ -183,7 +183,7 @@ uint8_t RF24::get_status(void) /******************************************************************/ -void RF24::print_status(uint8_t status) +void RF24::print_status(uint8_t status) const { printf_P(PSTR("STATUS=%02x: RX_DR=%x TX_DS=%x MAX_RT=%x RX_P_NO=%x TX_FULL=%x\n\r"), status, @@ -197,7 +197,7 @@ void RF24::print_status(uint8_t status) /******************************************************************/ -void RF24::print_observe_tx(uint8_t value) +void RF24::print_observe_tx(uint8_t value) const { printf_P(PSTR("OBSERVE_TX=%02x: POLS_CNT=%x ARC_CNT=%x\n\r"), value, @@ -209,7 +209,7 @@ void RF24::print_observe_tx(uint8_t value) /******************************************************************/ RF24::RF24(uint8_t _cepin, uint8_t _cspin): - ce_pin(_cepin), csn_pin(_cspin), payload_size(32), ack_payload_available(false) + wide_band(true), ce_pin(_cepin), csn_pin(_cspin), payload_size(32), ack_payload_available(false) { } @@ -217,12 +217,16 @@ RF24::RF24(uint8_t _cepin, uint8_t _cspin): void RF24::setChannel(uint8_t channel) { - write_register(RF_CH,min(channel,127)); + if( wide_band ) { + write_register(RF_CH,min(channel,127)); + } else { + write_register(RF_CH,min(channel,127)); + } } /******************************************************************/ -void RF24::setPayloadSize(uint8_t size) +void RF24::setPayloadSize(const uint8_t size) { payload_size = min(size,32); } @@ -236,7 +240,7 @@ uint8_t RF24::getPayloadSize(void) /******************************************************************/ -void RF24::printDetails(void) +void RF24::printDetails(void) const { uint8_t buffer[5]; uint8_t status = read_register(RX_ADDR_P0,buffer,5); @@ -314,18 +318,19 @@ void RF24::begin(void) flush_tx(); // Set up default configuration. Callers can always change it later. - setChannel(1); + // Hardware default is channel 2 - even spacing implied. + setChannel(64); } /******************************************************************/ -void RF24::startListening(void) +void RF24::startListening(void) const { write_register(CONFIG, read_register(CONFIG) | _BV(PWR_UP) | _BV(PRIM_RX)); write_register(STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); // Restore the pipe0 adddress - write_register(RX_ADDR_P0, reinterpret_cast(&pipe0_reading_address), 5); + write_register(RX_ADDR_P0, reinterpret_cast(&pipe0_reading_address), 5); // Flush buffers flush_rx(); @@ -339,14 +344,14 @@ void RF24::startListening(void) /******************************************************************/ -void RF24::stopListening(void) +void RF24::stopListening(void) const { ce(LOW); } /******************************************************************/ -void RF24::powerDown(void) +void RF24::powerDown(void) const { write_register(CONFIG,read_register(CONFIG) & ~_BV(PWR_UP)); } @@ -431,14 +436,14 @@ uint8_t RF24::read_payload_length(void) /******************************************************************/ -boolean RF24::available(void) +boolean RF24::available(void) const { return available(NULL); } /******************************************************************/ -boolean RF24::available(uint8_t* pipe_num) +boolean RF24::available(uint8_t* pipe_num) const { uint8_t status = get_status(); IF_SERIAL_DEBUG(print_status(status)); @@ -489,7 +494,7 @@ boolean RF24::read( void* buf, uint8_t len ) void RF24::openWritingPipe(uint64_t value) { - // Note that AVR 8-bit uC's store this LSB first, and the NRF24L01 + // Note that AVR 8-bit uC's store this LSB first, and the NRF24L01(+) // expects it LSB first too, so we're good. write_register(RX_ADDR_P0, reinterpret_cast(&value), 5); @@ -499,7 +504,7 @@ void RF24::openWritingPipe(uint64_t value) /******************************************************************/ -void RF24::openReadingPipe(uint8_t child, uint64_t value) +void RF24::openReadingPipe(const uint8_t child, const uint64_t address) { const uint8_t child_pipe[] = { RX_ADDR_P0, RX_ADDR_P1, RX_ADDR_P2, RX_ADDR_P3, RX_ADDR_P4, RX_ADDR_P5 }; @@ -512,15 +517,15 @@ void RF24::openReadingPipe(uint8_t child, uint64_t value) // openWritingPipe() will overwrite the pipe 0 address, so // startListening() will have to restore it. if (child == 0) - pipe0_reading_address = value; + pipe0_reading_address = address; if (child < 6) { // For pipes 2-5, only write the LSB if ( child < 2 ) - write_register(child_pipe[child], reinterpret_cast(&value), 5); + write_register(child_pipe[child], reinterpret_cast(&address), 5); else - write_register(child_pipe[child], reinterpret_cast(&value), 1); + write_register(child_pipe[child], reinterpret_cast(&address), 1); write_register(child_payload_size[child],payload_size); @@ -535,7 +540,7 @@ void RF24::openReadingPipe(uint8_t child, uint64_t value) /******************************************************************/ -void RF24::toggle_features(void) +void RF24::toggle_features(void) const { csn(LOW); SPI.transfer( ACTIVATE ); @@ -545,7 +550,7 @@ void RF24::toggle_features(void) /******************************************************************/ -void RF24::enableAckPayload(void) +void RF24::enableAckPayload(void) const { // // enable ack payload and dynamic payload features @@ -572,7 +577,7 @@ void RF24::enableAckPayload(void) /******************************************************************/ -void RF24::writeAckPayload(uint8_t pipe, const void* buf, uint8_t len) +void RF24::writeAckPayload(const uint8_t pipe, const void* buf, uint8_t len) const { const uint8_t* current = (const uint8_t*)buf; @@ -596,7 +601,7 @@ boolean RF24::isAckPayloadAvailable(void) /******************************************************************/ -void RF24::setAutoAck(bool enable) +void RF24::setAutoAck(const bool enable) const { if ( enable ) write_register(EN_AA, B111111); @@ -606,21 +611,30 @@ void RF24::setAutoAck(bool enable) /******************************************************************/ -boolean RF24::testCarrier(void) +void RF24::setAutoAck( const uint8_t pipe, const bool enable ) const +{ + uint8_t en_aa = read_register( EN_AA ) ; + en_aa &= ~((enable?0:1)< -64dBm, false if not */ - boolean testRPD(void); + boolean testRPD(void) const ; /** * Set Power Amplifier (PA) level to one of four levels. @@ -445,27 +459,27 @@ public: * * @param Desired PA level. */ - void setPALevel( rf24_pa_dbm_e level ) ; + void setPALevel( const rf24_pa_dbm_e level ) const ; /** * Fetches the current PA level. See setPALevel for * return value definitions. */ - rf24_pa_dbm_e getPALevel( void ) ; + rf24_pa_dbm_e getPALevel( void ) const ; /** * Set the transmission data rate * * @param speed RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps */ - void setDataRate(rf24_datarate_e speed); + void setDataRate(const rf24_datarate_e speed); /** * Set the CRC length * * @param length RF24_CRC_8 for 8-bit or RF24_CRC_16 for 16-bit */ - void setCRCLength(rf24_crclength_e length); + void setCRCLength(const rf24_crclength_e length) const ; /**@}*/ }; From aac2c3dba33b163521dc6a00bdb7d81761af1fbc Mon Sep 17 00:00:00 2001 From: Greg Copeland Date: Tue, 21 Jun 2011 14:58:19 -0500 Subject: [PATCH 3/9] Added two default values to the RF24 constructor; speed and channel. Some additional constantness cleanup. --- RF24.cpp | 11 +++++------ RF24.h | 11 ++++++++++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/RF24.cpp b/RF24.cpp index 155908a..c23b18b 100644 --- a/RF24.cpp +++ b/RF24.cpp @@ -208,14 +208,17 @@ void RF24::print_observe_tx(uint8_t value) const /******************************************************************/ -RF24::RF24(uint8_t _cepin, uint8_t _cspin): +RF24::RF24(const uint8_t _cepin, const uint8_t _cspin, + const rf24_datarate_e speed, const uint8_t channel): wide_band(true), ce_pin(_cepin), csn_pin(_cspin), payload_size(32), ack_payload_available(false) { + setDataRate( speed ) ; + setChannel( channel ) ; } /******************************************************************/ -void RF24::setChannel(uint8_t channel) +void RF24::setChannel(const uint8_t channel) { if( wide_band ) { write_register(RF_CH,min(channel,127)); @@ -316,10 +319,6 @@ void RF24::begin(void) // Flush buffers flush_rx(); flush_tx(); - - // Set up default configuration. Callers can always change it later. - // Hardware default is channel 2 - even spacing implied. - setChannel(64); } /******************************************************************/ diff --git a/RF24.h b/RF24.h index ffe6554..956fa27 100644 --- a/RF24.h +++ b/RF24.h @@ -188,8 +188,17 @@ public: * * @param _cepin The pin attached to Chip Enable on the RF module * @param _cspin The pin attached to Chip Select + * @param speed The desired data rate of this network; default is 2Mbs + * @param channel The channel to use for this network; default is 64 + * + * @warning Addition features enabled/set in the begin method should be + * migrated into our constructor. Basically features which are network + * specific should be variable and assignable here; including timeouts, + * retries, and CRC length. */ - RF24(uint8_t _cepin, uint8_t _cspin); + RF24(const uint8_t _cepin, const uint8_t _cspin, + const rf24_datarate_e speed=RF24_2MBPS, + const uint8_t channel=64 ) ; /** * Begin operation of the chip From 634d0efde5930e79d1bc2a51972f83e942394d62 Mon Sep 17 00:00:00 2001 From: Greg Copeland Date: Tue, 21 Jun 2011 15:01:10 -0500 Subject: [PATCH 4/9] Moved the wide_band variable and initializer cleanup. --- RF24.cpp | 2 +- RF24.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/RF24.cpp b/RF24.cpp index c23b18b..fed43c3 100644 --- a/RF24.cpp +++ b/RF24.cpp @@ -210,7 +210,7 @@ void RF24::print_observe_tx(uint8_t value) const RF24::RF24(const uint8_t _cepin, const uint8_t _cspin, const rf24_datarate_e speed, const uint8_t channel): - wide_band(true), ce_pin(_cepin), csn_pin(_cspin), payload_size(32), ack_payload_available(false) + ce_pin(_cepin), csn_pin(_cspin), wide_band(true), payload_size(32), ack_payload_available(false) { setDataRate( speed ) ; setChannel( channel ) ; diff --git a/RF24.h b/RF24.h index 956fa27..84feb6d 100644 --- a/RF24.h +++ b/RF24.h @@ -22,9 +22,9 @@ typedef enum { RF24_CRC_8 = 0, RF24_CRC_16 } rf24_crclength_e; class RF24 { private: - boolean wide_band; /* 2Mbs data rate in use? */ uint8_t ce_pin; /**< "Chip Enable" pin, activates the RX or TX role */ uint8_t csn_pin; /**< SPI Chip select */ + boolean wide_band; /* 2Mbs data rate in use? */ uint8_t payload_size; /**< Fixed size of payloads */ 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. */ From 059efa5ffa03d544c80d0101c6c6de14a1e5f582 Mon Sep 17 00:00:00 2001 From: Greg Copeland Date: Mon, 27 Jun 2011 15:02:33 -0500 Subject: [PATCH 5/9] 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. --- RF24.cpp | 110 +++++++++++++++++++++++++++++++++++++++++------------ RF24.h | 30 +++++++++++++-- nRF24L01.h | 23 ++++++----- 3 files changed, 125 insertions(+), 38 deletions(-) diff --git a/RF24.cpp b/RF24.cpp index fed43c3..9c897ff 100644 --- a/RF24.cpp +++ b/RF24.cpp @@ -8,8 +8,8 @@ #include #include -#include "RF24.h" #include "nRF24L01.h" +#include "RF24.h" #undef SERIAL_DEBUG #ifdef SERIAL_DEBUG @@ -29,7 +29,7 @@ void RF24::csn(const int mode) const { SPI.setDataMode(SPI_MODE0); - SPI.setClockDivider(SPI_CLOCK_DIV8); + SPI.setClockDivider(SPI_CLOCK_DIV2); 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, 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 ) ; setChannel( channel ) ; } @@ -283,13 +285,17 @@ void RF24::printDetails(void) const printf_P(PSTR("RX_PW_P1 = 0x%02x\n\r"),*buffer); 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); - 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); - 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.setClockDivider(SPI_CLOCK_DIV8); - // Set generous timeouts, to make testing a little easier - write_register(SETUP_RETR,(B1111 << ARD) | (B1111 << ARC)); + // Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier + // 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 write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); @@ -318,7 +326,16 @@ void RF24::begin(void) // Flush buffers 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); // 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 uint8_t observe_tx; 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 { if ( enable ) @@ -613,7 +636,7 @@ void RF24::setAutoAck(const bool enable) const void RF24::setAutoAck( const uint8_t pipe, const bool enable ) const { uint8_t en_aa = read_register( EN_AA ) ; - en_aa &= ~((enable?0:1)< Date: Sat, 16 Jul 2011 10:36:36 -0500 Subject: [PATCH 6/9] Reverted constructor changes. Changed SPI bus speed. Fixed setAutoAck for specific pipelines per suggestion. --- RF24.cpp | 22 +++++++++++----------- RF24.h | 16 ++++------------ 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/RF24.cpp b/RF24.cpp index 9c897ff..bd6cf34 100644 --- a/RF24.cpp +++ b/RF24.cpp @@ -35,9 +35,9 @@ void RF24::csn(const int mode) const /******************************************************************/ -void RF24::ce(const int mode) const +void RF24::ce(const int level) const { - digitalWrite(ce_pin,mode); + digitalWrite(ce_pin,level); } /******************************************************************/ @@ -208,14 +208,11 @@ void RF24::print_observe_tx(uint8_t value) const /******************************************************************/ -RF24::RF24(const uint8_t _cepin, const uint8_t _cspin, - const rf24_datarate_e speed, const uint8_t channel): +RF24::RF24(const uint8_t _cepin, const uint8_t _cspin): ce_pin(_cepin), csn_pin(_cspin), wide_band(true), p_variant(false), payload_size(32), ack_payload_available(false) { begin() ; - setDataRate( speed ) ; - setChannel( channel ) ; } /******************************************************************/ @@ -305,13 +302,12 @@ void RF24::begin(void) pinMode(ce_pin,OUTPUT); pinMode(csn_pin,OUTPUT); + SPI.begin(); ce(LOW); csn(HIGH); - - SPI.begin(); SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE0); - SPI.setClockDivider(SPI_CLOCK_DIV8); + SPI.setClockDivider(SPI_CLOCK_DIV2); // Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier // WARNING: If this is ever lowered, either 250KBS mode with AA is broken or maximum packet @@ -331,7 +327,7 @@ void RF24::begin(void) // 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. + // be set to 250Kbps. if( setDataRate( RF24_250KBPS ) ) { p_variant = true ; } @@ -636,7 +632,11 @@ void RF24::setAutoAck(const bool enable) const void RF24::setAutoAck( const uint8_t pipe, const bool enable ) const { uint8_t en_aa = read_register( EN_AA ) ; - en_aa &= ~((enable?0:1)< Date: Sat, 16 Jul 2011 11:36:10 -0500 Subject: [PATCH 7/9] Removed method argument const qualifiers. --- RF24.cpp | 32 ++++++++++++++++---------------- RF24.h | 30 +++++++++++++++--------------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/RF24.cpp b/RF24.cpp index bd6cf34..b7e3cbb 100644 --- a/RF24.cpp +++ b/RF24.cpp @@ -26,7 +26,7 @@ /******************************************************************/ -void RF24::csn(const int mode) const +void RF24::csn(int mode) const { SPI.setDataMode(SPI_MODE0); SPI.setClockDivider(SPI_CLOCK_DIV2); @@ -35,14 +35,14 @@ void RF24::csn(const int mode) const /******************************************************************/ -void RF24::ce(const int level) const +void RF24::ce(int level) const { digitalWrite(ce_pin,level); } /******************************************************************/ -uint8_t RF24::read_register(const uint8_t reg, uint8_t* buf, uint8_t len) const +uint8_t RF24::read_register(uint8_t reg, uint8_t* buf, uint8_t len) const { uint8_t status; @@ -58,7 +58,7 @@ uint8_t RF24::read_register(const uint8_t reg, uint8_t* buf, uint8_t len) const /******************************************************************/ -uint8_t RF24::read_register(const uint8_t reg) const +uint8_t RF24::read_register(uint8_t reg) const { csn(LOW); SPI.transfer( R_REGISTER | ( REGISTER_MASK & reg ) ); @@ -70,7 +70,7 @@ uint8_t RF24::read_register(const uint8_t reg) const /******************************************************************/ -uint8_t RF24::write_register(const uint8_t reg, const uint8_t* buf, uint8_t len) const +uint8_t RF24::write_register(uint8_t reg, const uint8_t* buf, uint8_t len) const { uint8_t status; @@ -86,7 +86,7 @@ uint8_t RF24::write_register(const uint8_t reg, const uint8_t* buf, uint8_t len) /******************************************************************/ -uint8_t RF24::write_register(const uint8_t reg, const uint8_t value) const +uint8_t RF24::write_register(uint8_t reg, uint8_t value) const { uint8_t status; @@ -208,7 +208,7 @@ void RF24::print_observe_tx(uint8_t value) const /******************************************************************/ -RF24::RF24(const uint8_t _cepin, const uint8_t _cspin): +RF24::RF24(uint8_t _cepin, uint8_t _cspin): ce_pin(_cepin), csn_pin(_cspin), wide_band(true), p_variant(false), payload_size(32), ack_payload_available(false) { @@ -217,7 +217,7 @@ RF24::RF24(const uint8_t _cepin, const uint8_t _cspin): /******************************************************************/ -void RF24::setChannel(const uint8_t channel) +void RF24::setChannel(uint8_t channel) { if( wide_band ) { write_register(RF_CH,min(channel,127)); @@ -228,7 +228,7 @@ void RF24::setChannel(const uint8_t channel) /******************************************************************/ -void RF24::setPayloadSize(const uint8_t size) +void RF24::setPayloadSize(uint8_t size) { payload_size = min(size,32); } @@ -516,7 +516,7 @@ void RF24::openWritingPipe(uint64_t value) /******************************************************************/ -void RF24::openReadingPipe(const uint8_t child, const uint64_t address) +void RF24::openReadingPipe(uint8_t child, uint64_t address) { const uint8_t child_pipe[] = { RX_ADDR_P0, RX_ADDR_P1, RX_ADDR_P2, RX_ADDR_P3, RX_ADDR_P4, RX_ADDR_P5 }; @@ -589,7 +589,7 @@ void RF24::enableAckPayload(void) const /******************************************************************/ -void RF24::writeAckPayload(const uint8_t pipe, const void* buf, uint8_t len) const +void RF24::writeAckPayload(uint8_t pipe, const void* buf, uint8_t len) const { const uint8_t* current = (const uint8_t*)buf; @@ -619,7 +619,7 @@ boolean RF24::isPVariant(void) const { /******************************************************************/ -void RF24::setAutoAck(const bool enable) const +void RF24::setAutoAck(bool enable) const { if ( enable ) write_register(EN_AA, B111111); @@ -629,7 +629,7 @@ void RF24::setAutoAck(const bool enable) const /******************************************************************/ -void RF24::setAutoAck( const uint8_t pipe, const bool enable ) const +void RF24::setAutoAck( uint8_t pipe, bool enable ) const { uint8_t en_aa = read_register( EN_AA ) ; if( enable ) { @@ -656,7 +656,7 @@ boolean RF24::testRPD(void) const /******************************************************************/ -void RF24::setPALevel(const rf24_pa_dbm_e level) const +void RF24::setPALevel(rf24_pa_dbm_e level) const { uint8_t setup = read_register(RF_SETUP) ; setup &= ~(_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ; @@ -718,7 +718,7 @@ rf24_pa_dbm_e RF24::getPALevel(void) const /******************************************************************/ -boolean RF24::setDataRate(const rf24_datarate_e speed) +boolean RF24::setDataRate(rf24_datarate_e speed) { uint8_t setup = read_register(RF_SETUP) ; @@ -786,7 +786,7 @@ rf24_datarate_e RF24::getDataRate( void ) const { /******************************************************************/ -void RF24::setCRCLength(const rf24_crclength_e length) const +void RF24::setCRCLength(rf24_crclength_e length) const { uint8_t config = read_register(CONFIG) & _BV(CRCO); if (length == RF24_CRC_16) diff --git a/RF24.h b/RF24.h index 4c7d942..8542807 100644 --- a/RF24.h +++ b/RF24.h @@ -50,7 +50,7 @@ protected: * * @param mode HIGH to take this unit off the SPI bus, LOW to put it on */ - void csn(const int mode) const ; + void csn(int mode) const ; /** * Set chip enable @@ -58,7 +58,7 @@ protected: * @param level HIGH to actively begin transmission or LOW to put in standby. Please see data sheet * for a much more detailed description of this pin. */ - void ce(const int level) const ; + void ce(int level) const ; /** * Read a chunk of data in from a register @@ -68,7 +68,7 @@ protected: * @param len How many bytes of data to transfer * @return Current value of status register */ - uint8_t read_register(const uint8_t reg, uint8_t* buf, uint8_t len) const ; + uint8_t read_register(uint8_t reg, uint8_t* buf, uint8_t len) const ; /** * Read single byte from a register @@ -76,7 +76,7 @@ protected: * @param reg Which register. Use constants from nRF24L01.h * @return Current value of register @p reg */ - uint8_t read_register(const uint8_t reg) const ; + uint8_t read_register(uint8_t reg) const ; /** * Write a chunk of data to a register @@ -86,7 +86,7 @@ protected: * @param len How many bytes of data to transfer * @return Current value of status register */ - uint8_t write_register(const uint8_t reg, const uint8_t* buf, uint8_t len) const ; + uint8_t write_register(uint8_t reg, const uint8_t* buf, uint8_t len) const ; /** * Write a single byte to a register @@ -95,7 +95,7 @@ protected: * @param value The new value to write * @return Current value of status register */ - uint8_t write_register(const uint8_t reg, const uint8_t value) const ; + uint8_t write_register(uint8_t reg, uint8_t value) const ; /** * Write the transmit payload @@ -195,7 +195,7 @@ public: * @param _cspin The pin attached to Chip Select * */ - RF24(const uint8_t _cepin, const uint8_t _cspin) ; + RF24(uint8_t _cepin, uint8_t _cspin) ; /** * Begin operation of the chip @@ -304,7 +304,7 @@ public: * @param number Which pipe# to open, 0-5. * @param address The 40-bit address of the pipe to open. */ - void openReadingPipe(const uint8_t number, const uint64_t address); + void openReadingPipe(uint8_t number, uint64_t address); /**@}*/ /** @@ -335,7 +335,7 @@ public: * * @param size The number of bytes in the payload */ - void setPayloadSize(const uint8_t size); + void setPayloadSize(uint8_t size); /** * Get Payload Size @@ -396,7 +396,7 @@ public: * @param len Length of the data to send, up to 32 bytes max. Not affected * by the static payload set by setPayloadSize(). */ - void writeAckPayload(const uint8_t pipe, const void* buf, uint8_t len) const ; + void writeAckPayload(uint8_t pipe, const void* buf, uint8_t len) const ; /** * Determine if an ack payload was received in the most recent call to @@ -427,7 +427,7 @@ public: * * @param enable Whether to enable (true) or disable (false) auto-acks */ - void setAutoAck(const bool enable) const ; + void setAutoAck(bool enable) const ; /** * Enable or disable auto-acknowlede packets on a per pipeline basis. @@ -438,7 +438,7 @@ public: * @param which pipeline to modify * @param enable Whether to enable (true) or disable (false) auto-acks */ - void setAutoAck( const uint8_t pipe, const bool enable ) const ; + void setAutoAck( uint8_t pipe, bool enable ) const ; /** * Test whether there was a carrier on the line for the @@ -471,7 +471,7 @@ public: * * @param Desired PA level. */ - void setPALevel( const rf24_pa_dbm_e level ) const ; + void setPALevel( rf24_pa_dbm_e level ) const ; /** * Fetches the current PA level. @@ -488,7 +488,7 @@ public: * * @param speed RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps */ - boolean setDataRate(const rf24_datarate_e speed); + boolean setDataRate(rf24_datarate_e speed); /** * Set the transmission data rate @@ -504,7 +504,7 @@ public: * * @param length RF24_CRC_8 for 8-bit or RF24_CRC_16 for 16-bit */ - void setCRCLength(const rf24_crclength_e length) const ; + void setCRCLength(rf24_crclength_e length) const ; /**@}*/ }; From 158164746b59d32eb10a8017e1ad03b1f858df86 Mon Sep 17 00:00:00 2001 From: Greg Copeland Date: Mon, 18 Jul 2011 15:37:30 -0500 Subject: [PATCH 8/9] Adds explicit CRC width and PA level. Changes hardware initialization order to minimize noisy/false message reception. Removed begin call from constructor as begin now has delay which creates timer race initialization. The delay exists to allow for power on/reset radio settling which can otherwise prevent CONFIG bits from holding. Added a method to allow CRC hardware validation to be disabled. This is a requirement for various promiscuous listening RF applications. Setting CRC width now forces CRC hardware validation enable. --- RF24.cpp | 86 ++++++++++++++++++++++++++++++++++++++++++++------------ RF24.h | 6 ++++ 2 files changed, 74 insertions(+), 18 deletions(-) diff --git a/RF24.cpp b/RF24.cpp index bd6cf34..e95fa3c 100644 --- a/RF24.cpp +++ b/RF24.cpp @@ -28,8 +28,9 @@ void RF24::csn(const int mode) const { + SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE0); - SPI.setClockDivider(SPI_CLOCK_DIV2); + SPI.setClockDivider(SPI_CLOCK_DIV2); digitalWrite(csn_pin,mode); } @@ -212,7 +213,6 @@ RF24::RF24(const uint8_t _cepin, const uint8_t _cspin): ce_pin(_cepin), csn_pin(_cspin), wide_band(true), p_variant(false), payload_size(32), ack_payload_available(false) { - begin() ; } /******************************************************************/ @@ -268,6 +268,14 @@ void RF24::printDetails(void) const printf_P(PSTR("RX_ADDR_P3 = 0x%02x"),*buffer); printf_P(PSTR("\n\r")); + status = read_register(RX_ADDR_P4,buffer,1); + printf_P(PSTR("RX_ADDR_P4 = 0x%02x"),*buffer); + printf_P(PSTR("\n\r")); + + status = read_register(RX_ADDR_P5,buffer,1); + printf_P(PSTR("RX_ADDR_P5 = 0x%02x"),*buffer); + printf_P(PSTR("\n\r")); + status = read_register(TX_ADDR,buffer,5); printf_P(PSTR("TX_ADDR = 0x")); bufptr = buffer + 5; @@ -293,36 +301,52 @@ void RF24::printDetails(void) const 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()); + + read_register(CONFIG,buffer,1); + printf_P(PSTR("CONFIG = 0x%02x (CRC enable: %d; CRC16: %d)\n\r"), + *buffer,(*buffer)&_BV(EN_CRC)?1:0, + (*buffer)&_BV(CRCO)?1:0); } /******************************************************************/ void RF24::begin(void) { + // Initialize pins pinMode(ce_pin,OUTPUT); pinMode(csn_pin,OUTPUT); + // Initialize SPI bus + // Minimum ideal SPI bus speed is 2x data rate + // If we assume 2Mbs data rate and 16Mhz clock, a + // divider of 4 is the minimum we want. + // CLK:BUS 8Mhz:2Mhz, 16Mhz:4Mhz, or 20Mhz:5Mhz + // We'll use a divider of 2 which will work up to + // MCU speeds of 20Mhz. + // CLK:BUS 8Mhz:4Mhz, 16Mhz:8Mhz, or 20Mhz:10Mhz (max) SPI.begin(); - ce(LOW); - csn(HIGH); SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE0); - SPI.setClockDivider(SPI_CLOCK_DIV2); + SPI.setClockDivider(SPI_CLOCK_DIV2); + + ce(LOW); + csn(HIGH); + + // Must allow the radio time to settle else configuration bits will not necessarily stick. + // This is actually only required following power up but some settling time also appears to + // be required after resets too. For full coverage, we'll always assume the worst. + // Enabling 16b CRC is by far the most obvious case if the wrong timing is used - or skipped. + // Technically we require 4.5ms + 14us as a worst case. We'll just call it 5ms for good measure. + // WARNING: Delay is based on P-variant whereby non-P *may* require different timing. + delay( 5 ) ; // Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier // 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 - write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); - - // Initialize CRC - write_register(CONFIG, _BV(EN_CRC) ); - - // Flush buffers - flush_rx(); - flush_tx(); + // Restore our default PA level + setPALevel( RF24_PA_MAX ) ; // Determine if this is a p or non-p RF24 module and then // reset our data rate back to default value. This works @@ -332,6 +356,17 @@ void RF24::begin(void) p_variant = true ; } setDataRate( RF24_2MBPS ) ; + + // Initialize CRC and request 2-byte (16bit) CRC + setCRCLength( RF24_CRC_16 ) ; + + // Reset current status + // Notice reset and flush is the last thing we do + write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); + + // Flush buffers + flush_rx(); + flush_tx(); } /******************************************************************/ @@ -788,11 +823,26 @@ rf24_datarate_e RF24::getDataRate( void ) const { void RF24::setCRCLength(const rf24_crclength_e length) const { - uint8_t config = read_register(CONFIG) & _BV(CRCO); - if (length == RF24_CRC_16) - config |= _BV(CRCO); - write_register(CONFIG,config); + uint8_t config = read_register(CONFIG) & ~_BV(CRCO) ; + + // Always make sure CRC hardware validation is actually on + config |= _BV(EN_CRC) ; + + // Now config 8 or 16 bit CRCs - only 16bit need be turned on + // 8b is the default. + if( length == RF24_CRC_16 ) { + config |= _BV( CRCO ) ; + } + + write_register( CONFIG, config ) ; } +/******************************************************************/ + +void RF24::disableCRC( void ) const +{ + uint8_t disable = read_register(CONFIG) & ~_BV(EN_CRC) ; + write_register( CONFIG, disable ) ; +} // vim:ai:cin:sts=2 sw=2 ft=cpp diff --git a/RF24.h b/RF24.h index 4c7d942..e50b80c 100644 --- a/RF24.h +++ b/RF24.h @@ -506,6 +506,12 @@ public: */ void setCRCLength(const rf24_crclength_e length) const ; + /** + * Disable CRC validation + * + */ + void disableCRC( void ) const ; + /**@}*/ }; From 0c2515df19d180c82303bcda074f06a239f6ff2c Mon Sep 17 00:00:00 2001 From: Greg Copeland Date: Tue, 19 Jul 2011 11:05:18 -0500 Subject: [PATCH 9/9] As a just in case I misunderstood some of the constant-ness changes, I completely took out all of the constant correctness enahcements. Also added a powerUp() method. --- RF24.cpp | 67 ++++++++++++++++++++++++++++------------------------ RF24.h | 71 +++++++++++++++++++++++++++++++------------------------- 2 files changed, 76 insertions(+), 62 deletions(-) diff --git a/RF24.cpp b/RF24.cpp index d2073b5..7ad8056 100644 --- a/RF24.cpp +++ b/RF24.cpp @@ -26,7 +26,7 @@ /******************************************************************/ -void RF24::csn(int mode) const +void RF24::csn(int mode) { SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE0); @@ -36,14 +36,14 @@ void RF24::csn(int mode) const /******************************************************************/ -void RF24::ce(int level) const +void RF24::ce(int level) { digitalWrite(ce_pin,level); } /******************************************************************/ -uint8_t RF24::read_register(uint8_t reg, uint8_t* buf, uint8_t len) const +uint8_t RF24::read_register(uint8_t reg, uint8_t* buf, uint8_t len) { uint8_t status; @@ -59,7 +59,7 @@ uint8_t RF24::read_register(uint8_t reg, uint8_t* buf, uint8_t len) const /******************************************************************/ -uint8_t RF24::read_register(uint8_t reg) const +uint8_t RF24::read_register(uint8_t reg) { csn(LOW); SPI.transfer( R_REGISTER | ( REGISTER_MASK & reg ) ); @@ -71,7 +71,7 @@ uint8_t RF24::read_register(uint8_t reg) const /******************************************************************/ -uint8_t RF24::write_register(uint8_t reg, const uint8_t* buf, uint8_t len) const +uint8_t RF24::write_register(uint8_t reg, const uint8_t* buf, uint8_t len) { uint8_t status; @@ -87,7 +87,7 @@ uint8_t RF24::write_register(uint8_t reg, const uint8_t* buf, uint8_t len) const /******************************************************************/ -uint8_t RF24::write_register(uint8_t reg, uint8_t value) const +uint8_t RF24::write_register(uint8_t reg, uint8_t value) { uint8_t status; @@ -145,7 +145,7 @@ uint8_t RF24::read_payload(void* buf, uint8_t len) /******************************************************************/ -uint8_t RF24::flush_rx(void) const +uint8_t RF24::flush_rx(void) { uint8_t status; @@ -158,7 +158,7 @@ uint8_t RF24::flush_rx(void) const /******************************************************************/ -uint8_t RF24::flush_tx(void) const +uint8_t RF24::flush_tx(void) { uint8_t status; @@ -171,7 +171,7 @@ uint8_t RF24::flush_tx(void) const /******************************************************************/ -uint8_t RF24::get_status(void) const +uint8_t RF24::get_status(void) { uint8_t status; @@ -184,7 +184,7 @@ uint8_t RF24::get_status(void) const /******************************************************************/ -void RF24::print_status(uint8_t status) const +void RF24::print_status(uint8_t status) { printf_P(PSTR("STATUS=%02x: RX_DR=%x TX_DS=%x MAX_RT=%x RX_P_NO=%x TX_FULL=%x\n\r"), status, @@ -198,7 +198,7 @@ void RF24::print_status(uint8_t status) const /******************************************************************/ -void RF24::print_observe_tx(uint8_t value) const +void RF24::print_observe_tx(uint8_t value) { printf_P(PSTR("OBSERVE_TX=%02x: POLS_CNT=%x ARC_CNT=%x\n\r"), value, @@ -242,7 +242,7 @@ uint8_t RF24::getPayloadSize(void) /******************************************************************/ -void RF24::printDetails(void) const +void RF24::printDetails(void) { uint8_t buffer[5]; uint8_t status = read_register(RX_ADDR_P0,buffer,5); @@ -371,7 +371,7 @@ void RF24::begin(void) /******************************************************************/ -void RF24::startListening(void) const +void RF24::startListening(void) { write_register(CONFIG, read_register(CONFIG) | _BV(PWR_UP) | _BV(PRIM_RX)); write_register(STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); @@ -391,20 +391,27 @@ void RF24::startListening(void) const /******************************************************************/ -void RF24::stopListening(void) const +void RF24::stopListening(void) { ce(LOW); } /******************************************************************/ -void RF24::powerDown(void) const +void RF24::powerDown(void) { write_register(CONFIG,read_register(CONFIG) & ~_BV(PWR_UP)); } /******************************************************************/ +void RF24::powerUp(void) +{ + write_register(CONFIG,read_register(CONFIG) | _BV(PWR_UP)); +} + +/******************************************************************/ + boolean RF24::write( const void* buf, uint8_t len ) { boolean result = false; @@ -483,14 +490,14 @@ uint8_t RF24::read_payload_length(void) /******************************************************************/ -boolean RF24::available(void) const +boolean RF24::available(void) { return available(NULL); } /******************************************************************/ -boolean RF24::available(uint8_t* pipe_num) const +boolean RF24::available(uint8_t* pipe_num) { uint8_t status = get_status(); IF_SERIAL_DEBUG(print_status(status)); @@ -587,7 +594,7 @@ void RF24::openReadingPipe(uint8_t child, uint64_t address) /******************************************************************/ -void RF24::toggle_features(void) const +void RF24::toggle_features(void) { csn(LOW); SPI.transfer( ACTIVATE ); @@ -597,7 +604,7 @@ void RF24::toggle_features(void) const /******************************************************************/ -void RF24::enableAckPayload(void) const +void RF24::enableAckPayload(void) { // // enable ack payload and dynamic payload features @@ -624,7 +631,7 @@ void RF24::enableAckPayload(void) const /******************************************************************/ -void RF24::writeAckPayload(uint8_t pipe, const void* buf, uint8_t len) const +void RF24::writeAckPayload(uint8_t pipe, const void* buf, uint8_t len) { const uint8_t* current = (const uint8_t*)buf; @@ -648,13 +655,13 @@ boolean RF24::isAckPayloadAvailable(void) /******************************************************************/ -boolean RF24::isPVariant(void) const { +boolean RF24::isPVariant(void) { return p_variant ; } /******************************************************************/ -void RF24::setAutoAck(bool enable) const +void RF24::setAutoAck(bool enable) { if ( enable ) write_register(EN_AA, B111111); @@ -664,7 +671,7 @@ void RF24::setAutoAck(bool enable) const /******************************************************************/ -void RF24::setAutoAck( uint8_t pipe, bool enable ) const +void RF24::setAutoAck( uint8_t pipe, bool enable ) { uint8_t en_aa = read_register( EN_AA ) ; if( enable ) { @@ -677,21 +684,21 @@ void RF24::setAutoAck( uint8_t pipe, bool enable ) const /******************************************************************/ -boolean RF24::testCarrier(void) const +boolean RF24::testCarrier(void) { return ( read_register(CD) & 1 ); } /******************************************************************/ -boolean RF24::testRPD(void) const +boolean RF24::testRPD(void) { return ( read_register(RPD) & 1 ) ; } /******************************************************************/ -void RF24::setPALevel(rf24_pa_dbm_e level) const +void RF24::setPALevel(rf24_pa_dbm_e level) { uint8_t setup = read_register(RF_SETUP) ; setup &= ~(_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ; @@ -724,7 +731,7 @@ void RF24::setPALevel(rf24_pa_dbm_e level) const /******************************************************************/ -rf24_pa_dbm_e RF24::getPALevel(void) const +rf24_pa_dbm_e RF24::getPALevel(void) { rf24_pa_dbm_e result = RF24_PA_ERROR ; uint8_t power = read_register(RF_SETUP) & (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ; @@ -794,7 +801,7 @@ boolean RF24::setDataRate(rf24_datarate_e speed) /******************************************************************/ -rf24_datarate_e RF24::getDataRate( void ) const { +rf24_datarate_e RF24::getDataRate( void ) { rf24_datarate_e result ; uint8_t setup = read_register(RF_SETUP) ; @@ -821,7 +828,7 @@ rf24_datarate_e RF24::getDataRate( void ) const { /******************************************************************/ -void RF24::setCRCLength(rf24_crclength_e length) const +void RF24::setCRCLength(rf24_crclength_e length) { uint8_t config = read_register(CONFIG) & ~_BV(CRCO) ; @@ -839,7 +846,7 @@ void RF24::setCRCLength(rf24_crclength_e length) const /******************************************************************/ -void RF24::disableCRC( void ) const +void RF24::disableCRC( void ) { uint8_t disable = read_register(CONFIG) & ~_BV(EN_CRC) ; write_register( CONFIG, disable ) ; diff --git a/RF24.h b/RF24.h index e4cf87c..81f10ba 100644 --- a/RF24.h +++ b/RF24.h @@ -50,7 +50,7 @@ protected: * * @param mode HIGH to take this unit off the SPI bus, LOW to put it on */ - void csn(int mode) const ; + void csn(int mode) ; /** * Set chip enable @@ -58,7 +58,7 @@ protected: * @param level HIGH to actively begin transmission or LOW to put in standby. Please see data sheet * for a much more detailed description of this pin. */ - void ce(int level) const ; + void ce(int level) ; /** * Read a chunk of data in from a register @@ -68,7 +68,7 @@ protected: * @param len How many bytes of data to transfer * @return Current value of status register */ - uint8_t read_register(uint8_t reg, uint8_t* buf, uint8_t len) const ; + uint8_t read_register(uint8_t reg, uint8_t* buf, uint8_t len) ; /** * Read single byte from a register @@ -76,7 +76,7 @@ protected: * @param reg Which register. Use constants from nRF24L01.h * @return Current value of register @p reg */ - uint8_t read_register(uint8_t reg) const ; + uint8_t read_register(uint8_t reg) ; /** * Write a chunk of data to a register @@ -86,7 +86,7 @@ protected: * @param len How many bytes of data to transfer * @return Current value of status register */ - uint8_t write_register(uint8_t reg, const uint8_t* buf, uint8_t len) const ; + uint8_t write_register(uint8_t reg, const uint8_t* buf, uint8_t len) ; /** * Write a single byte to a register @@ -95,7 +95,7 @@ protected: * @param value The new value to write * @return Current value of status register */ - uint8_t write_register(uint8_t reg, uint8_t value) const ; + uint8_t write_register(uint8_t reg, uint8_t value) ; /** * Write the transmit payload @@ -134,21 +134,21 @@ protected: * * @return Current value of status register */ - uint8_t flush_rx(void) const ; + uint8_t flush_rx(void) ; /** * Empty the transmit buffer * * @return Current value of status register */ - uint8_t flush_tx(void) const ; + uint8_t flush_tx(void) ; /** * Retrieve the current status of the chip * * @return Current value of status register */ - uint8_t get_status(void) const ; + uint8_t get_status(void) ; /** * Decode and print the given status to stdout @@ -157,7 +157,7 @@ protected: * * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h */ - void print_status(uint8_t status) const ; + void print_status(uint8_t status) ; /** * Decode and print the given 'observe_tx' value to stdout @@ -166,7 +166,7 @@ protected: * * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h */ - void print_observe_tx(uint8_t value) const ; + void print_observe_tx(uint8_t value) ; /** * Turn on or off the special features of the chip @@ -174,7 +174,7 @@ protected: * The chip has certain 'features' which are only available when the 'features' * are enabled. See the datasheet for details. */ - void toggle_features(void) const ; + void toggle_features(void) ; /**@}*/ public: @@ -211,14 +211,14 @@ public: * in this mode, without first calling stopListening(). Call * isAvailable() to check for incoming traffic, and read() to get it. */ - void startListening(void) const ; + void startListening(void) ; /** * Stop listening for incoming messages * * Do this before calling write(). */ - void stopListening(void) const ; + void stopListening(void) ; /** * Write to the open writing pipe @@ -245,7 +245,7 @@ public: * * @return True if there is a payload available, false if none is */ - boolean available(void) const ; + boolean available(void) ; /** * Read the payload @@ -351,15 +351,22 @@ public: * * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h */ - void printDetails(void) const ; + void printDetails(void) ; /** * Enter low-power mode * - * To return to normal power mode, either write() some data or - * startListening(). + * To return to normal power mode, either write() some data, + * startListening(), or powerUp(). */ - void powerDown(void) const ; + void powerDown(void) ; + + /** + * Leave low-power mode - making radio more responsive + * + * To return to low power mode, call powerDown(). + */ + void powerUp(void) ; /** * Test whether there are bytes available to be read @@ -370,7 +377,7 @@ public: * @param[out] pipe_num Which pipe has the payload available * @return True if there is a payload available, false if none is */ - boolean available(uint8_t* pipe_num) const ; + boolean available(uint8_t* pipe_num) ; /** * Enable custom payloads on the acknowledge packets @@ -380,7 +387,7 @@ public: * * @see examples/pingpair_pl/pingpair_pl.pde */ - void enableAckPayload(void) const; + void enableAckPayload(void) ; /** * Write an ack payload for the specified pipe @@ -396,7 +403,7 @@ public: * @param len Length of the data to send, up to 32 bytes max. Not affected * by the static payload set by setPayloadSize(). */ - void writeAckPayload(uint8_t pipe, const void* buf, uint8_t len) const ; + void writeAckPayload(uint8_t pipe, const void* buf, uint8_t len) ; /** * Determine if an ack payload was received in the most recent call to @@ -417,7 +424,7 @@ public: * @return Returns true if the hardware is RF24L01P (or compatible) and false * if its not. */ - boolean isPVariant(void) const ; + boolean isPVariant(void) ; /** * Enable or disable auto-acknowlede packets @@ -427,7 +434,7 @@ public: * * @param enable Whether to enable (true) or disable (false) auto-acks */ - void setAutoAck(bool enable) const ; + void setAutoAck(bool enable) ; /** * Enable or disable auto-acknowlede packets on a per pipeline basis. @@ -438,7 +445,7 @@ public: * @param which pipeline to modify * @param enable Whether to enable (true) or disable (false) auto-acks */ - void setAutoAck( uint8_t pipe, bool enable ) const ; + void setAutoAck( uint8_t pipe, bool enable ) ; /** * Test whether there was a carrier on the line for the @@ -448,7 +455,7 @@ public: * * @return true if was carrier, false if not */ - boolean testCarrier(void) const ; + boolean testCarrier(void) ; /** * Test whether a signal (carrier or otherwise) greater than @@ -460,7 +467,7 @@ public: * * @return true if signal => -64dBm, false if not */ - boolean testRPD(void) const ; + boolean testRPD(void) ; /** * Set Power Amplifier (PA) level to one of four levels. @@ -471,7 +478,7 @@ public: * * @param Desired PA level. */ - void setPALevel( rf24_pa_dbm_e level ) const ; + void setPALevel( rf24_pa_dbm_e level ) ; /** * Fetches the current PA level. @@ -481,7 +488,7 @@ public: * 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 ) ; /** * Set the transmission data rate @@ -497,20 +504,20 @@ public: * 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 ; + rf24_datarate_e getDataRate( void ) ; /** * Set the CRC length * * @param length RF24_CRC_8 for 8-bit or RF24_CRC_16 for 16-bit */ - void setCRCLength(rf24_crclength_e length) const ; + void setCRCLength(rf24_crclength_e length) ; /** * Disable CRC validation * */ - void disableCRC( void ) const ; + void disableCRC( void ) ; /**@}*/ };