From ad38f3a477657c3ef5719751f061cc310e76d619 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 30 Aug 2013 08:12:59 +0100 Subject: [PATCH 01/26] reduce code size on ATtiny --- RF24_config.h | 1 + 1 file changed, 1 insertion(+) diff --git a/RF24_config.h b/RF24_config.h index fc7397fb..488e1b79 100644 --- a/RF24_config.h +++ b/RF24_config.h @@ -34,6 +34,7 @@ extern HardwareSPI SPI; #define IF_SERIAL_DEBUG(x) ({x;}) #else #define IF_SERIAL_DEBUG(x) +#define printf_P(...) #endif // Avoid spurious warnings From 01e9840fef42a1cd15055fc923dfc82684b36170 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 5 Sep 2013 14:45:12 +0100 Subject: [PATCH 02/26] #ifdefs for attiny --- RF24_config.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RF24_config.h b/RF24_config.h index 488e1b79..18e2e85c 100644 --- a/RF24_config.h +++ b/RF24_config.h @@ -34,8 +34,10 @@ extern HardwareSPI SPI; #define IF_SERIAL_DEBUG(x) ({x;}) #else #define IF_SERIAL_DEBUG(x) +#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny85__) #define printf_P(...) #endif +#endif // Avoid spurious warnings #if 1 From d98a6f93277f37c4038d50760c880a5e9a8b629d Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 19 Nov 2013 17:52:32 +0000 Subject: [PATCH 03/26] merge ebcd0d1d0b3061fcb57444e1dbe5829ef25705cd --- RF24.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/RF24.h b/RF24.h index b7d3c7a9..8459dafa 100644 --- a/RF24.h +++ b/RF24.h @@ -682,6 +682,15 @@ class RF24 */ uint16_t getMaxTimeout(void) ; + /** + * Test whether this is a real radio, or a mock shim for + * debugging. Setting either pin to 0xff is the way to + * indicate that this is not a real radio. + * + * @return true if this is a legitimate radio + */ + bool isValid() { return ce_pin != 0xff && csn_pin != 0xff; } + /**@}*/ }; From edf7af8e303aa87c89e798153c890fdf857ad039 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Sat, 7 Jun 2014 13:08:02 +0100 Subject: [PATCH 04/26] energia --- RF24_config.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/RF24_config.h b/RF24_config.h index 18e2e85c..6c1a5da0 100644 --- a/RF24_config.h +++ b/RF24_config.h @@ -34,7 +34,7 @@ extern HardwareSPI SPI; #define IF_SERIAL_DEBUG(x) ({x;}) #else #define IF_SERIAL_DEBUG(x) -#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny85__) +#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny85__) || defined(__MSP430__) #define printf_P(...) #endif #endif @@ -49,10 +49,18 @@ extern HardwareSPI SPI; #endif #endif +#if defined(ENERGIA) +#define strlen_P strlen +#define pgm_read_byte(p) (*(p)) +#define pgm_read_word(p) (*(p)) +#define PRIPSTR "%s" +#define _BV(x) (1 << (x)) + +#elif defined(ARDUINO) // Progmem is Arduino-specific -#ifdef ARDUINO #include #define PRIPSTR "%S" + #else typedef char const char; typedef uint16_t prog_uint16_t; From f06cb9a27c418988cc0161a2df91ddec82135204 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Sat, 7 Jun 2014 13:35:26 +0100 Subject: [PATCH 05/26] fixup for msp430 --- examples/pingpair/printf.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/examples/pingpair/printf.h b/examples/pingpair/printf.h index 05dd0888..b1d901f4 100644 --- a/examples/pingpair/printf.h +++ b/examples/pingpair/printf.h @@ -18,7 +18,19 @@ #include -int serial_putc( char c, FILE * ) +#ifdef ENERGIA +int putchar(int c) +{ + Serial.write( c ); + return c; +} + +void printf_begin(void) +{ +} + +#else +int serial_putc( char c, struct FILE * ) { Serial.write( c ); @@ -27,7 +39,8 @@ int serial_putc( char c, FILE * ) void printf_begin(void) { - fdevopen( &serial_putc, 0 ); + fdevopen( &serial_putc, 0 ); } +#endif #endif // __PRINTF_H__ From 541262dc2346c7aacb5297d4cfc11ba1ab852a3a Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 23 Jul 2014 14:11:53 +0100 Subject: [PATCH 06/26] replacing printf() with printf_P() everywhere --- RF24.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/RF24.cpp b/RF24.cpp index 5f6c41d9..d33acf84 100644 --- a/RF24.cpp +++ b/RF24.cpp @@ -104,7 +104,7 @@ uint8_t RF24::write_payload(const void* buf, uint8_t len, const uint8_t writeTyp uint8_t data_len = min(len,payload_size); uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len; - //printf("[Writing %u bytes %u blanks]",data_len,blank_len); + //printf_P("[Writing %u bytes %u blanks]",data_len,blank_len); csn(LOW); status = SPI.transfer( writeType ); @@ -127,7 +127,7 @@ uint8_t RF24::read_payload(void* buf, uint8_t len) uint8_t data_len = min(len,payload_size); uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len; - //printf("[Reading %u bytes %u blanks]",data_len,blank_len); + //printf_P("[Reading %u bytes %u blanks]",data_len,blank_len); csn(LOW); status = SPI.transfer( R_RX_PAYLOAD ); @@ -490,7 +490,7 @@ bool RF24::write( const void* buf, uint8_t len, const bool multicast ) bool tx_ok, tx_fail; whatHappened(tx_ok,tx_fail,ack_payload_available); - //printf("%u%u%u\r\n",tx_ok,tx_fail,ack_payload_available); + //printf_P("%u%u%u\r\n",tx_ok,tx_fail,ack_payload_available); result = tx_ok; IF_SERIAL_DEBUG(Serial.print(result?"...OK.":"...Failed")); @@ -688,7 +688,7 @@ void RF24::enableDynamicPayloads(void) write_register(FEATURE,read_register(FEATURE) | _BV(EN_DPL) ); } - IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE))); + IF_SERIAL_DEBUG(printf_P("FEATURE=%i\r\n",read_register(FEATURE))); // Enable dynamic payload on all pipes // @@ -717,7 +717,7 @@ void RF24::enableAckPayload(void) write_register(FEATURE,read_register(FEATURE) | _BV(EN_DYN_ACK) | _BV(EN_ACK_PAY) | _BV(EN_DPL) ); } - IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE))); + IF_SERIAL_DEBUG(printf_P("FEATURE=%i\r\n",read_register(FEATURE))); // // Enable dynamic payload on pipes 0 & 1 From 82fe1035fbd044a61752b30b8ce066058a8d2c61 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 23 Jul 2014 15:27:19 +0100 Subject: [PATCH 07/26] separate debugging from RF24 class --- RF24.cpp | 141 ++++------------------------------------ RF24.h | 68 +++++--------------- RF24SerialDebug.cpp | 153 ++++++++++++++++++++++++++++++++++++++++++++ RF24SerialDebug.h | 74 +++++++++++++++++++++ RF24_config.h | 10 --- 5 files changed, 257 insertions(+), 189 deletions(-) create mode 100644 RF24SerialDebug.cpp create mode 100644 RF24SerialDebug.h diff --git a/RF24.cpp b/RF24.cpp index d33acf84..83debc8e 100644 --- a/RF24.cpp +++ b/RF24.cpp @@ -83,7 +83,8 @@ uint8_t RF24::write_register(uint8_t reg, uint8_t value) { uint8_t status; - IF_SERIAL_DEBUG(printf_P(PSTR("write_register(%02x,%02x)\r\n"),reg,value)); + if (dbg) + dbg->on_write_register(reg, value); csn(LOW); status = SPI.transfer( W_REGISTER | ( REGISTER_MASK & reg ) ); @@ -104,7 +105,8 @@ uint8_t RF24::write_payload(const void* buf, uint8_t len, const uint8_t writeTyp uint8_t data_len = min(len,payload_size); uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len; - //printf_P("[Writing %u bytes %u blanks]",data_len,blank_len); + if (dbg) + dbg->on_write_payload(data_len, blank_len); csn(LOW); status = SPI.transfer( writeType ); @@ -127,7 +129,8 @@ uint8_t RF24::read_payload(void* buf, uint8_t len) uint8_t data_len = min(len,payload_size); uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len; - //printf_P("[Reading %u bytes %u blanks]",data_len,blank_len); + if (dbg) + dbg->on_read_payload(data_len, blank_len); csn(LOW); status = SPI.transfer( R_RX_PAYLOAD ); @@ -181,63 +184,6 @@ uint8_t RF24::get_status(void) /****************************************************************************/ -void RF24::print_status(uint8_t status) -{ - printf_P(PSTR("STATUS\t\t = 0x%02x RX_DR=%x TX_DS=%x MAX_RT=%x RX_P_NO=%x TX_FULL=%x\r\n"), - status, - (status & _BV(RX_DR))?1:0, - (status & _BV(TX_DS))?1:0, - (status & _BV(MAX_RT))?1:0, - ((status >> RX_P_NO) & B111), - (status & _BV(TX_FULL))?1:0 - ); -} - -/****************************************************************************/ - -void RF24::print_observe_tx(uint8_t value) -{ - printf_P(PSTR("OBSERVE_TX=%02x: POLS_CNT=%x ARC_CNT=%x\r\n"), - value, - (value >> PLOS_CNT) & B1111, - (value >> ARC_CNT) & B1111 - ); -} - -/****************************************************************************/ - -void RF24::print_byte_register(const char* name, uint8_t reg, uint8_t qty) -{ - char extra_tab = strlen_P(name) < 8 ? '\t' : 0; - printf_P(PSTR(PRIPSTR"\t%c ="),name,extra_tab); - while (qty--) - printf_P(PSTR(" 0x%02x"),read_register(reg++)); - printf_P(PSTR("\r\n")); -} - -/****************************************************************************/ - -void RF24::print_address_register(const char* name, uint8_t reg, uint8_t qty) -{ - char extra_tab = strlen_P(name) < 8 ? '\t' : 0; - printf_P(PSTR(PRIPSTR"\t%c ="),name,extra_tab); - - while (qty--) - { - uint8_t buffer[5]; - read_register(reg++,buffer,sizeof buffer); - - printf_P(PSTR(" 0x")); - uint8_t* bufptr = buffer + sizeof buffer; - while( --bufptr >= buffer ) - printf_P(PSTR("%02x"),*bufptr); - } - - printf_P(PSTR("\r\n")); -} - -/****************************************************************************/ - RF24::RF24(uint8_t _cepin, uint8_t _cspin): ce_pin(_cepin), csn_pin(_cspin), wide_band(false), p_variant(false), payload_size(32), ack_payload_available(false), dynamic_payloads_enabled(false), @@ -280,63 +226,6 @@ uint8_t RF24::getPayloadSize(void) /****************************************************************************/ -static const char rf24_datarate_e_str_0[] PROGMEM = "1MBPS"; -static const char rf24_datarate_e_str_1[] PROGMEM = "2MBPS"; -static const char rf24_datarate_e_str_2[] PROGMEM = "250KBPS"; -static const char * const rf24_datarate_e_str_P[] PROGMEM = { - rf24_datarate_e_str_0, - rf24_datarate_e_str_1, - rf24_datarate_e_str_2, -}; -static const char rf24_model_e_str_0[] PROGMEM = "nRF24L01"; -static const char rf24_model_e_str_1[] PROGMEM = "nRF24L01+"; -static const char * const rf24_model_e_str_P[] PROGMEM = { - rf24_model_e_str_0, - rf24_model_e_str_1, -}; -static const char rf24_crclength_e_str_0[] PROGMEM = "Disabled"; -static const char rf24_crclength_e_str_1[] PROGMEM = "8 bits"; -static const char rf24_crclength_e_str_2[] PROGMEM = "16 bits" ; -static const char * const rf24_crclength_e_str_P[] PROGMEM = { - rf24_crclength_e_str_0, - rf24_crclength_e_str_1, - rf24_crclength_e_str_2, -}; -static const char rf24_pa_dbm_e_str_0[] PROGMEM = "PA_MIN"; -static const char rf24_pa_dbm_e_str_1[] PROGMEM = "PA_LOW"; -static const char rf24_pa_dbm_e_str_2[] PROGMEM = "PA_HIGH"; -static const char rf24_pa_dbm_e_str_3[] PROGMEM = "PA_MAX"; -static const char * const rf24_pa_dbm_e_str_P[] PROGMEM = { - rf24_pa_dbm_e_str_0, - rf24_pa_dbm_e_str_1, - rf24_pa_dbm_e_str_2, - rf24_pa_dbm_e_str_3, -}; - -void RF24::printDetails(void) -{ - print_status(get_status()); - - print_address_register(PSTR("RX_ADDR_P0-1"),RX_ADDR_P0,2); - print_byte_register(PSTR("RX_ADDR_P2-5"),RX_ADDR_P2,4); - print_address_register(PSTR("TX_ADDR"),TX_ADDR); - - print_byte_register(PSTR("RX_PW_P0-6"),RX_PW_P0,6); - print_byte_register(PSTR("EN_AA"),EN_AA); - print_byte_register(PSTR("EN_RXADDR"),EN_RXADDR); - print_byte_register(PSTR("RF_CH"),RF_CH); - print_byte_register(PSTR("RF_SETUP"),RF_SETUP); - print_byte_register(PSTR("CONFIG"),CONFIG); - print_byte_register(PSTR("DYNPD/FEATURE"),DYNPD,2); - - printf_P(PSTR("Data Rate\t = %S\r\n"),pgm_read_word(&rf24_datarate_e_str_P[getDataRate()])); - printf_P(PSTR("Model\t\t = %S\r\n"),pgm_read_word(&rf24_model_e_str_P[isPVariant()])); - printf_P(PSTR("CRC Length\t = %S\r\n"),pgm_read_word(&rf24_crclength_e_str_P[getCRCLength()])); - printf_P(PSTR("PA Power\t = %S\r\n"),pgm_read_word(&rf24_pa_dbm_e_str_P[getPALevel()])); -} - -/****************************************************************************/ - void RF24::begin(void) { // Initialize pins @@ -474,7 +363,8 @@ bool RF24::write( const void* buf, uint8_t len, const bool multicast ) do { status = read_register(OBSERVE_TX,&observe_tx,1); - IF_SERIAL_DEBUG(Serial.print(observe_tx,HEX)); + if (dbg) + dbg->observe_tx(observe_tx); } while( ! ( status & ( _BV(TX_DS) | _BV(MAX_RT) ) ) && ( micros() - sent_at < timeout ) ); @@ -493,14 +383,13 @@ bool RF24::write( const void* buf, uint8_t len, const bool multicast ) //printf_P("%u%u%u\r\n",tx_ok,tx_fail,ack_payload_available); result = tx_ok; - IF_SERIAL_DEBUG(Serial.print(result?"...OK.":"...Failed")); // Handle the ack packet if ( ack_payload_available ) { ack_payload_length = getDynamicPayloadSize(); - IF_SERIAL_DEBUG(Serial.print("[AckPacket]/")); - IF_SERIAL_DEBUG(Serial.println(ack_payload_length,DEC)); + if (dbg) + dbg->on_ack(ack_payload_length); } return result; @@ -549,9 +438,6 @@ bool RF24::available(uint8_t* pipe_num) { uint8_t status = get_status(); - // Too noisy, enable if you really want lots o data!! - //IF_SERIAL_DEBUG(print_status(status)); - bool result = ( status & _BV(RX_DR) ); if (result) @@ -596,6 +482,9 @@ void RF24::whatHappened(bool& tx_ok,bool& tx_fail,bool& rx_ready) // Or is that such a good idea? uint8_t status = write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); + if (dbg) + dbg->on_status(status); + // Report to the user what happened tx_ok = status & _BV(TX_DS); tx_fail = status & _BV(MAX_RT); @@ -688,8 +577,6 @@ void RF24::enableDynamicPayloads(void) write_register(FEATURE,read_register(FEATURE) | _BV(EN_DPL) ); } - IF_SERIAL_DEBUG(printf_P("FEATURE=%i\r\n",read_register(FEATURE))); - // Enable dynamic payload on all pipes // // Not sure the use case of only having dynamic payload on certain @@ -717,8 +604,6 @@ void RF24::enableAckPayload(void) write_register(FEATURE,read_register(FEATURE) | _BV(EN_DYN_ACK) | _BV(EN_ACK_PAY) | _BV(EN_DPL) ); } - IF_SERIAL_DEBUG(printf_P("FEATURE=%i\r\n",read_register(FEATURE))); - // // Enable dynamic payload on pipes 0 & 1 // diff --git a/RF24.h b/RF24.h index 8459dafa..da618f58 100644 --- a/RF24.h +++ b/RF24.h @@ -40,6 +40,20 @@ typedef enum { RF24_1MBPS = 0, RF24_2MBPS, RF24_250KBPS } rf24_datarate_e; */ typedef enum { RF24_CRC_DISABLED = 0, RF24_CRC_8, RF24_CRC_16 } rf24_crclength_e; +class RF24Debug +{ +public: + /** + * Callbacks from RF24 + */ + virtual void on_write_register(uint8_t reg, uint8_t value) {} + virtual void observe_tx(uint8_t tx) {} + virtual void on_ack(uint8_t ack_len) {} + virtual void on_status(uint8_t status) {} + virtual void on_write_payload(uint8_t data_len, uint8_t blank_len) {} + virtual void on_read_payload(uint8_t data_len, uint8_t blank_len) {} +}; + /** * Driver for nRF24L01(+) 2.4GHz Wireless Transceiver */ @@ -56,8 +70,11 @@ class RF24 bool dynamic_payloads_enabled; /**< Whether dynamic payloads are enabled. */ uint8_t ack_payload_length; /**< Dynamic size of pending ack payload. */ uint64_t pipe0_reading_address; /**< Last address set on pipe 0 for reading. */ + friend class SerialDebug; + RF24Debug *dbg; protected: + /** * @name Low-level internal interface. * @@ -167,50 +184,6 @@ class RF24 */ uint8_t get_status(void); - /** - * Decode and print the given status to stdout - * - * @param status Status value to print - * - * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h - */ - void print_status(uint8_t status); - - /** - * Decode and print the given 'observe_tx' value to stdout - * - * @param value The observe_tx value to print - * - * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h - */ - void print_observe_tx(uint8_t value); - - /** - * Print the name and value of an 8-bit register to stdout - * - * Optionally it can print some quantity of successive - * registers on the same line. This is useful for printing a group - * of related registers on one line. - * - * @param name Name of the register - * @param reg Which register. Use constants from nRF24L01.h - * @param qty How many successive registers to print - */ - void print_byte_register(const char* name, uint8_t reg, uint8_t qty = 1); - - /** - * Print the name and value of a 40-bit address register to stdout - * - * Optionally it can print some quantity of successive - * registers on the same line. This is useful for printing a group - * of related registers on one line. - * - * @param name Name of the register - * @param reg Which register. Use constants from nRF24L01.h - * @param qty How many successive registers to print - */ - void print_address_register(const char* name, uint8_t reg, uint8_t qty = 1); - /** * Turn on or off the special features of the chip * @@ -558,13 +531,6 @@ class RF24 */ /**@{*/ - /** - * Print a giant block of debugging information to stdout - * - * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h - */ - void printDetails(void); - /** * Enter low-power mode * diff --git a/RF24SerialDebug.cpp b/RF24SerialDebug.cpp new file mode 100644 index 00000000..4f55e8df --- /dev/null +++ b/RF24SerialDebug.cpp @@ -0,0 +1,153 @@ +#include "RF24.h" +#include "RF24SerialDebug.h" + +/****************************************************************************/ + +void SerialDebug::print_observe_tx(uint8_t value) +{ + printf_P(PSTR("OBSERVE_TX=%02x: POLS_CNT=%x ARC_CNT=%x\r\n"), + value, + (value >> PLOS_CNT) & B1111, + (value >> ARC_CNT) & B1111 + ); +} + +/****************************************************************************/ + +void SerialDebug::print_byte_register(const char* name, uint8_t reg, uint8_t qty) +{ + char extra_tab = strlen_P(name) < 8 ? '\t' : 0; + printf_P(PSTR(PRIPSTR"\t%c ="),name,extra_tab); + while (qty--) + printf_P(PSTR(" 0x%02x"), r.read_register(reg++)); + printf_P(PSTR("\r\n")); +} + +/****************************************************************************/ + +void SerialDebug::print_address_register(const char* name, uint8_t reg, uint8_t qty) +{ + char extra_tab = strlen_P(name) < 8 ? '\t' : 0; + printf_P(PSTR(PRIPSTR"\t%c ="),name,extra_tab); + + while (qty--) + { + uint8_t buffer[5]; + r.read_register(reg++,buffer,sizeof buffer); + + printf_P(PSTR(" 0x")); + uint8_t* bufptr = buffer + sizeof buffer; + while( --bufptr >= buffer ) + printf_P(PSTR("%02x"),*bufptr); + } + + printf_P(PSTR("\r\n")); +} + +/****************************************************************************/ + +void SerialDebug::print_status(uint8_t status) +{ + printf_P(PSTR("STATUS\t\t = 0x%02x RX_DR=%x TX_DS=%x MAX_RT=%x RX_P_NO=%x TX_FULL=%x\r\n"), + status, + (status & _BV(RX_DR))?1:0, + (status & _BV(TX_DS))?1:0, + (status & _BV(MAX_RT))?1:0, + ((status >> RX_P_NO) & B111), + (status & _BV(TX_FULL))?1:0 + ); +} + +/****************************************************************************/ + +static const char rf24_datarate_e_str_0[] PROGMEM = "1MBPS"; +static const char rf24_datarate_e_str_1[] PROGMEM = "2MBPS"; +static const char rf24_datarate_e_str_2[] PROGMEM = "250KBPS"; +static const char * const rf24_datarate_e_str_P[] PROGMEM = { + rf24_datarate_e_str_0, + rf24_datarate_e_str_1, + rf24_datarate_e_str_2, +}; +static const char rf24_model_e_str_0[] PROGMEM = "nRF24L01"; +static const char rf24_model_e_str_1[] PROGMEM = "nRF24L01+"; +static const char * const rf24_model_e_str_P[] PROGMEM = { + rf24_model_e_str_0, + rf24_model_e_str_1, +}; +static const char rf24_crclength_e_str_0[] PROGMEM = "Disabled"; +static const char rf24_crclength_e_str_1[] PROGMEM = "8 bits"; +static const char rf24_crclength_e_str_2[] PROGMEM = "16 bits" ; +static const char * const rf24_crclength_e_str_P[] PROGMEM = { + rf24_crclength_e_str_0, + rf24_crclength_e_str_1, + rf24_crclength_e_str_2, +}; +static const char rf24_pa_dbm_e_str_0[] PROGMEM = "PA_MIN"; +static const char rf24_pa_dbm_e_str_1[] PROGMEM = "PA_LOW"; +static const char rf24_pa_dbm_e_str_2[] PROGMEM = "PA_HIGH"; +static const char rf24_pa_dbm_e_str_3[] PROGMEM = "PA_MAX"; +static const char * const rf24_pa_dbm_e_str_P[] PROGMEM = { + rf24_pa_dbm_e_str_0, + rf24_pa_dbm_e_str_1, + rf24_pa_dbm_e_str_2, + rf24_pa_dbm_e_str_3, +}; + +void SerialDebug::printDetails(void) +{ + print_status(r.get_status()); + + print_address_register(PSTR("RX_ADDR_P0-1"),RX_ADDR_P0,2); + print_byte_register(PSTR("RX_ADDR_P2-5"),RX_ADDR_P2,4); + print_address_register(PSTR("TX_ADDR"),TX_ADDR); + + print_byte_register(PSTR("RX_PW_P0-6"),RX_PW_P0,6); + print_byte_register(PSTR("EN_AA"),EN_AA); + print_byte_register(PSTR("EN_RXADDR"),EN_RXADDR); + print_byte_register(PSTR("RF_CH"),RF_CH); + print_byte_register(PSTR("RF_SETUP"),RF_SETUP); + print_byte_register(PSTR("CONFIG"),CONFIG); + print_byte_register(PSTR("DYNPD/FEATURE"),DYNPD,2); + + printf_P(PSTR("Data Rate\t = %S\r\n"),pgm_read_word(&rf24_datarate_e_str_P[r.getDataRate()])); + printf_P(PSTR("Model\t\t = %S\r\n"),pgm_read_word(&rf24_model_e_str_P[r.isPVariant()])); + printf_P(PSTR("CRC Length\t = %S\r\n"),pgm_read_word(&rf24_crclength_e_str_P[r.getCRCLength()])); + printf_P(PSTR("PA Power\t = %S\r\n"),pgm_read_word(&rf24_pa_dbm_e_str_P[r.getPALevel()])); +} + +void SerialDebug::on_write_register(uint8_t reg, uint8_t value) +{ + printf_P(PSTR("write_register(%02x,%02x)\r\n"),reg,value); +} + +void SerialDebug::observe_tx(uint8_t observe_tx) +{ + Serial.print(observe_tx,HEX); +} + +void SerialDebug::on_status(uint8_t status) +{ + uint8_t result = status & _BV(TX_DS); + Serial.println(result?"...OK.":"...Failed"); +} + +void SerialDebug::on_ack(uint8_t ack_payload_length) +{ + Serial.print("[AckPacket]/"); + Serial.println(ack_payload_length,DEC); +} + +void SerialDebug::on_write_payload(uint8_t data_len, uint8_t blank_len) +{ + printf_P(PSTR("[Writing %u bytes %u blanks]"),data_len,blank_len); +} + +void SerialDebug::on_read_payload(uint8_t data_len, uint8_t blank_len) +{ + printf_P(PSTR("[Reading %u bytes %u blanks]"),data_len,blank_len); +} + +SerialDebug::SerialDebug(RF24 &radio): r(radio) +{ + r.dbg = this; +} diff --git a/RF24SerialDebug.h b/RF24SerialDebug.h new file mode 100644 index 00000000..a66a6c7b --- /dev/null +++ b/RF24SerialDebug.h @@ -0,0 +1,74 @@ +#ifndef __RF24_SERIAL_DEBUG_H +#define __RF24_SERIAL_DEBUG_H + +class SerialDebug: public RF24Debug +{ +protected: + /** + * Decode and print the given status to stdout + * + * @param status Status value to print + * + * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h + */ + void print_status(uint8_t status); + + /** + * Decode and print the given 'observe_tx' value to stdout + * + * @param value The observe_tx value to print + * + * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h + */ + void print_observe_tx(uint8_t value); + + /** + * Print the name and value of an 8-bit register to stdout + * + * Optionally it can print some quantity of successive + * registers on the same line. This is useful for printing a group + * of related registers on one line. + * + * @param name Name of the register + * @param reg Which register. Use constants from nRF24L01.h + * @param qty How many successive registers to print + */ + void print_byte_register(const char* name, uint8_t reg, uint8_t qty = 1); + + /** + * Print the name and value of a 40-bit address register to stdout + * + * Optionally it can print some quantity of successive + * registers on the same line. This is useful for printing a group + * of related registers on one line. + * + * @param name Name of the register + * @param reg Which register. Use constants from nRF24L01.h + * @param qty How many successive registers to print + */ + void print_address_register(const char* name, uint8_t reg, uint8_t qty = 1); + + RF24 &r; + +public: + /** + * Print a giant block of debugging information to stdout + * + * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h + */ + void printDetails(void); + + SerialDebug(RF24 &radio); + + /** + * Callbacks from RF24 + */ + void on_write_register(uint8_t reg, uint8_t value); + void observe_tx(uint8_t tx); + void on_ack(uint8_t ack_len); + void on_status(uint8_t status); + void on_write_payload(uint8_t data_len, uint8_t blank_len); + void on_read_payload(uint8_t data_len, uint8_t blank_len); +}; + +#endif diff --git a/RF24_config.h b/RF24_config.h index 6c1a5da0..a662446a 100644 --- a/RF24_config.h +++ b/RF24_config.h @@ -29,16 +29,6 @@ extern HardwareSPI SPI; #define _BV(x) (1<<(x)) #endif -#undef SERIAL_DEBUG -#ifdef SERIAL_DEBUG -#define IF_SERIAL_DEBUG(x) ({x;}) -#else -#define IF_SERIAL_DEBUG(x) -#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny85__) || defined(__MSP430__) -#define printf_P(...) -#endif -#endif - // Avoid spurious warnings #if 1 #if ! defined( NATIVE ) && defined( ARDUINO ) From 5d7893b107d01a06655b84576e2f5e0fcdae485f Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 23 Jul 2014 15:35:06 +0100 Subject: [PATCH 08/26] inline print_observe_tx --- RF24SerialDebug.cpp | 18 +++++------------- RF24SerialDebug.h | 9 --------- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/RF24SerialDebug.cpp b/RF24SerialDebug.cpp index 4f55e8df..7ff331ef 100644 --- a/RF24SerialDebug.cpp +++ b/RF24SerialDebug.cpp @@ -3,17 +3,6 @@ /****************************************************************************/ -void SerialDebug::print_observe_tx(uint8_t value) -{ - printf_P(PSTR("OBSERVE_TX=%02x: POLS_CNT=%x ARC_CNT=%x\r\n"), - value, - (value >> PLOS_CNT) & B1111, - (value >> ARC_CNT) & B1111 - ); -} - -/****************************************************************************/ - void SerialDebug::print_byte_register(const char* name, uint8_t reg, uint8_t qty) { char extra_tab = strlen_P(name) < 8 ? '\t' : 0; @@ -120,9 +109,12 @@ void SerialDebug::on_write_register(uint8_t reg, uint8_t value) printf_P(PSTR("write_register(%02x,%02x)\r\n"),reg,value); } -void SerialDebug::observe_tx(uint8_t observe_tx) +void SerialDebug::observe_tx(uint8_t value) { - Serial.print(observe_tx,HEX); + printf_P(PSTR("OBSERVE_TX=%02x: POLS_CNT=%x ARC_CNT=%x\r\n"), + value, + (value >> PLOS_CNT) & B1111, + (value >> ARC_CNT) & B1111); } void SerialDebug::on_status(uint8_t status) diff --git a/RF24SerialDebug.h b/RF24SerialDebug.h index a66a6c7b..8d30cce7 100644 --- a/RF24SerialDebug.h +++ b/RF24SerialDebug.h @@ -13,15 +13,6 @@ class SerialDebug: public RF24Debug */ void print_status(uint8_t status); - /** - * Decode and print the given 'observe_tx' value to stdout - * - * @param value The observe_tx value to print - * - * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h - */ - void print_observe_tx(uint8_t value); - /** * Print the name and value of an 8-bit register to stdout * From d87354e332e92affbdb624af85888c5567a70b3f Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 24 Jul 2014 17:04:48 +0100 Subject: [PATCH 09/26] fixes for msp430 --- RF24SerialDebug.cpp | 11 ++++++----- RF24_config.h | 4 +++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/RF24SerialDebug.cpp b/RF24SerialDebug.cpp index 7ff331ef..6c79ad3a 100644 --- a/RF24SerialDebug.cpp +++ b/RF24SerialDebug.cpp @@ -1,3 +1,4 @@ +#include "RF24_config.h" #include "RF24.h" #include "RF24SerialDebug.h" @@ -98,10 +99,10 @@ void SerialDebug::printDetails(void) print_byte_register(PSTR("CONFIG"),CONFIG); print_byte_register(PSTR("DYNPD/FEATURE"),DYNPD,2); - printf_P(PSTR("Data Rate\t = %S\r\n"),pgm_read_word(&rf24_datarate_e_str_P[r.getDataRate()])); - printf_P(PSTR("Model\t\t = %S\r\n"),pgm_read_word(&rf24_model_e_str_P[r.isPVariant()])); - printf_P(PSTR("CRC Length\t = %S\r\n"),pgm_read_word(&rf24_crclength_e_str_P[r.getCRCLength()])); - printf_P(PSTR("PA Power\t = %S\r\n"),pgm_read_word(&rf24_pa_dbm_e_str_P[r.getPALevel()])); + printf_P(PSTR("Data Rate\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_datarate_e_str_P[r.getDataRate()])); + printf_P(PSTR("Model\t\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_model_e_str_P[r.isPVariant()])); + printf_P(PSTR("CRC Length\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_crclength_e_str_P[r.getCRCLength()])); + printf_P(PSTR("PA Power\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_pa_dbm_e_str_P[r.getPALevel()])); } void SerialDebug::on_write_register(uint8_t reg, uint8_t value) @@ -111,7 +112,7 @@ void SerialDebug::on_write_register(uint8_t reg, uint8_t value) void SerialDebug::observe_tx(uint8_t value) { - printf_P(PSTR("OBSERVE_TX=%02x: POLS_CNT=%x ARC_CNT=%x\r\n"), + printf_P(PSTR("OBSERVE_TX=%02x: PLOS_CNT=%x ARC_CNT=%x\r\n"), value, (value >> PLOS_CNT) & B1111, (value >> ARC_CNT) & B1111); diff --git a/RF24_config.h b/RF24_config.h index a662446a..604aaf9f 100644 --- a/RF24_config.h +++ b/RF24_config.h @@ -33,7 +33,8 @@ extern HardwareSPI SPI; #if 1 #if ! defined( NATIVE ) && defined( ARDUINO ) #undef PROGMEM -#define PROGMEM __attribute__(( section(".progmem.data") )) +//#define PROGMEM __attribute__(( section(".progmem.data") )) +#define PROGMEM #undef PSTR #define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];})) #endif @@ -41,6 +42,7 @@ extern HardwareSPI SPI; #if defined(ENERGIA) #define strlen_P strlen +#define printf_P printf #define pgm_read_byte(p) (*(p)) #define pgm_read_word(p) (*(p)) #define PRIPSTR "%s" From a3a5799422976d71afbefb06d5e0c435ad32610d Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 24 Jul 2014 17:15:20 +0100 Subject: [PATCH 10/26] msp430 update --- RF24_config.h | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/RF24_config.h b/RF24_config.h index 604aaf9f..25177356 100644 --- a/RF24_config.h +++ b/RF24_config.h @@ -29,17 +29,6 @@ extern HardwareSPI SPI; #define _BV(x) (1<<(x)) #endif -// Avoid spurious warnings -#if 1 -#if ! defined( NATIVE ) && defined( ARDUINO ) -#undef PROGMEM -//#define PROGMEM __attribute__(( section(".progmem.data") )) -#define PROGMEM -#undef PSTR -#define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];})) -#endif -#endif - #if defined(ENERGIA) #define strlen_P strlen #define printf_P printf @@ -47,6 +36,8 @@ extern HardwareSPI SPI; #define pgm_read_word(p) (*(p)) #define PRIPSTR "%s" #define _BV(x) (1 << (x)) +#define PROGMEM +#define PSTR(s) (s) #elif defined(ARDUINO) // Progmem is Arduino-specific From f9f049582bae5228fd88be341ebd4399d20d47dc Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 25 Jul 2014 09:49:02 +0100 Subject: [PATCH 11/26] - add back printDetails() on RF24 for backwards compatibility - add msp430 version of pingpair --- RF24.h | 14 ++ examples/pingpair_msp430/pingpair.ino | 219 ++++++++++++++++++++++++++ examples/pingpair_msp430/printf.h | 48 ++++++ 3 files changed, 281 insertions(+) create mode 100644 examples/pingpair_msp430/pingpair.ino create mode 100644 examples/pingpair_msp430/printf.h diff --git a/RF24.h b/RF24.h index da618f58..7dd13ec7 100644 --- a/RF24.h +++ b/RF24.h @@ -52,6 +52,11 @@ class RF24Debug virtual void on_status(uint8_t status) {} virtual void on_write_payload(uint8_t data_len, uint8_t blank_len) {} virtual void on_read_payload(uint8_t data_len, uint8_t blank_len) {} + + /** + * Backwards-compatibility + */ + virtual void printDetails(void) {} }; /** @@ -531,6 +536,15 @@ class RF24 */ /**@{*/ + /** + * Print a giant block of debugging information to stdout + * + * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h + * @warning Also does nothing if a real RF24Debug isn't configured. See + * RF24SerialDebug.h + */ + void printDetails(void) { if (dbg) dbg->printDetails(); } + /** * Enter low-power mode * diff --git a/examples/pingpair_msp430/pingpair.ino b/examples/pingpair_msp430/pingpair.ino new file mode 100644 index 00000000..276544c9 --- /dev/null +++ b/examples/pingpair_msp430/pingpair.ino @@ -0,0 +1,219 @@ +/* + Copyright (C) 2011 James Coliz, Jr. + + 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. + */ + +/** + * Example RF Radio Ping Pair + * + * This is an example of how to use the RF24 class. Write this sketch to two different nodes, + * connect the role_pin to ground on one. The ping node sends the current time to the pong node, + * which responds by sending the value back. The ping node can then see how long the whole cycle + * took. + */ + +#include +#include +#include +#include "printf.h" + +// +// Hardware configuration +// + +// Set up nRF24L01 radio on SPI bus plus pins 8 & 9 +RF24 radio(P2_1,P2_0); +//SerialDebug dbg(radio); + +// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver +// Leave open to be the 'ping' transmitter +const int role_pin = P2_2; + +// +// Topology +// + +// Radio pipe addresses for the 2 nodes to communicate. +const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; + +// +// Role management +// +// Set up role. This sketch uses the same software for all the nodes +// in this system. Doing so greatly simplifies testing. The hardware itself specifies +// which node it is. +// +// This is done through the role_pin +// + +// The various roles supported by this sketch +typedef enum { role_ping_out = 1, role_pong_back } role_e; + +// The debug-friendly names of those roles +const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"}; + +// The role of the current running sketch +role_e role; + +void setup(void) +{ + // + // Role + // + + // set up the role pin + pinMode(role_pin, INPUT); + digitalWrite(role_pin,HIGH); + delay(20); // Just to get a solid reading on the role pin + + // read the address pin, establish our role + if ( digitalRead(role_pin) ) + role = role_ping_out; + else + role = role_pong_back; + + // + // Print preamble + // + + Serial.begin(9600); + printf_begin(); + printf("\n\rRF24/examples/pingpair/\n\r"); + printf("ROLE: %s\n\r",role_friendly_name[role]); + + // + // Setup and configure rf radio + // + + radio.begin(); + + // optionally, increase the delay between retries & # of retries + // radio.setRetries(15,15); + + // optionally, reduce the payload size. seems to + // improve reliability + // radio.setPayloadSize(8); + + // + // Open pipes to other nodes for communication + // + + // This simple sketch opens two pipes for these two nodes to communicate + // back and forth. + // Open 'our' pipe for writing + // Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading) + + if ( role == role_ping_out ) + { + radio.openWritingPipe(pipes[0]); + radio.openReadingPipe(1,pipes[1]); + } + else + { + radio.openWritingPipe(pipes[1]); + radio.openReadingPipe(1,pipes[0]); + } + + // + // Start listening + // + // if( radio.setDataRate( RF24_250KBPS ) ) { + // printf( "Data rate 250KBPS set!\n\r" ) ; + // } else { + // printf( "Data rate 250KBPS set FAILED!!\n\r" ) ; + // } + // radio.setDataRate( RF24_2MBPS ) ; + // radio.setPALevel( RF24_PA_MAX ) ; + radio.enableDynamicPayloads() ; + radio.setAutoAck( true ) ; + radio.powerUp() ; + radio.startListening(); + + // + // Dump the configuration of the rf unit for debugging + // + radio.printDetails(); +} + +void loop(void) +{ + // + // Ping out role. Repeatedly send the current time + // + + if (role == role_ping_out) + { + // First, stop listening so we can talk. + radio.stopListening(); + + // Take the time, and send it. This will block until complete + unsigned long time = millis(); + printf("Now sending %lx...",time); + radio.write( &time, sizeof(unsigned long) ); + + // Now, continue listening + radio.startListening(); + + // Wait here until we get a response, or timeout (250ms) + unsigned long started_waiting_at = millis(); + bool timeout = false; + while ( ! radio.available() && ! timeout ) +// if (millis() - started_waiting_at > 1+(radio.getMaxTimeout()/1000) ) + if (millis() - started_waiting_at > 250 ) + timeout = true; + + // Describe the results + if ( timeout ) + { + printf("Failed, response timed out.\n\r"); + printf("Timeout duration: %d\n\r", (1+radio.getMaxTimeout()/1000) ) ; + } + else + { + // Grab the response, compare, and send to debugging spew + unsigned long got_time; + radio.read( &got_time, sizeof(unsigned long) ); + + // Spew it + printf("Got response %lx, round-trip delay: %lx\n\r",got_time,millis()-got_time); + } + + // Try again 1s later + delay(5000); + } + + // + // Pong back role. Receive each packet, dump it out, and send it back + // + + if ( role == role_pong_back ) + { + // if there is data ready + if ( radio.available() ) + { + // Dump the payloads until we've gotten everything + unsigned long got_time; + bool done = false; + while (!done) + { + // Fetch the payload, and see if this was the last one. + done = radio.read( &got_time, sizeof(unsigned long) ); + } + + // First, stop listening so we can talk + radio.stopListening(); + + // Send the final one back. This way, we don't delay + // the reply while we wait on serial i/o. + radio.write( &got_time, sizeof(unsigned long) ); + printf("Sent response %lx\n\r", got_time); + + // Now, resume listening so we catch the next packets. + radio.startListening(); + } + } +} +// vim:cin:ai:sts=2 sw=2 ft=cpp diff --git a/examples/pingpair_msp430/printf.h b/examples/pingpair_msp430/printf.h new file mode 100644 index 00000000..efb9113f --- /dev/null +++ b/examples/pingpair_msp430/printf.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2011 James Coliz, Jr. + + 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. + */ + +/** + * @file printf.h + * + * Setup necessary to direct stdout to the Arduino Serial library, which + * enables 'printf' + */ + +#ifndef __PRINTF_H__ +#define __PRINTF_H__ + +#include + +#ifdef ENERGIA +extern "C" { + int putchar(int c) + { + Serial.write((uint8_t)c); + return c; + } +} + +void printf_begin(void) +{ +} + +#else +int serial_putc( char c, struct FILE * ) +{ + Serial.write( c ); + + return c; +} + +void printf_begin(void) +{ + fdevopen( &serial_putc, 0 ); +} +#endif + +#endif // __PRINTF_H__ From 3b0dd05da74bb4265c0f4714799137ef670857ac Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 25 Jul 2014 09:52:48 +0100 Subject: [PATCH 12/26] update for new debugging --- .../pingpair/{pingpair.pde => pingpair.ino} | 6 ++++-- examples/pingpair/printf.h | 17 ++--------------- 2 files changed, 6 insertions(+), 17 deletions(-) rename examples/pingpair/{pingpair.pde => pingpair.ino} (98%) diff --git a/examples/pingpair/pingpair.pde b/examples/pingpair/pingpair.ino similarity index 98% rename from examples/pingpair/pingpair.pde rename to examples/pingpair/pingpair.ino index 449f5377..a5596c2f 100644 --- a/examples/pingpair/pingpair.pde +++ b/examples/pingpair/pingpair.ino @@ -17,6 +17,7 @@ #include #include +#include #include "printf.h" // @@ -25,7 +26,8 @@ // Set up nRF24L01 radio on SPI bus plus pins 8 & 9 -RF24 radio(8,9); +RF24 radio(9,10); +SerialDebug dbg(radio); // sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver // Leave open to be the 'ping' transmitter @@ -135,7 +137,7 @@ void setup(void) // Dump the configuration of the rf unit for debugging // - radio.printDetails(); + dbg.printDetails(); } void loop(void) diff --git a/examples/pingpair/printf.h b/examples/pingpair/printf.h index b1d901f4..05dd0888 100644 --- a/examples/pingpair/printf.h +++ b/examples/pingpair/printf.h @@ -18,19 +18,7 @@ #include -#ifdef ENERGIA -int putchar(int c) -{ - Serial.write( c ); - return c; -} - -void printf_begin(void) -{ -} - -#else -int serial_putc( char c, struct FILE * ) +int serial_putc( char c, FILE * ) { Serial.write( c ); @@ -39,8 +27,7 @@ int serial_putc( char c, struct FILE * ) void printf_begin(void) { - fdevopen( &serial_putc, 0 ); + fdevopen( &serial_putc, 0 ); } -#endif #endif // __PRINTF_H__ From 904b959f63edc052b648c8ec2106fbdff820e27b Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 25 Jul 2014 11:54:02 +0100 Subject: [PATCH 13/26] debug --- examples/pingpair/pingpair.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/pingpair/pingpair.ino b/examples/pingpair/pingpair.ino index a5596c2f..aa2cfe1a 100644 --- a/examples/pingpair/pingpair.ino +++ b/examples/pingpair/pingpair.ino @@ -137,7 +137,7 @@ void setup(void) // Dump the configuration of the rf unit for debugging // - dbg.printDetails(); + radio.printDetails(); } void loop(void) From d1c927a4cb69ef39b095dbd954de97b195431b57 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 29 Jul 2014 12:00:59 +0100 Subject: [PATCH 14/26] add setter for debug --- RF24.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/RF24.h b/RF24.h index 7dd13ec7..c4da3ebf 100644 --- a/RF24.h +++ b/RF24.h @@ -75,11 +75,12 @@ class RF24 bool dynamic_payloads_enabled; /**< Whether dynamic payloads are enabled. */ uint8_t ack_payload_length; /**< Dynamic size of pending ack payload. */ uint64_t pipe0_reading_address; /**< Last address set on pipe 0 for reading. */ - friend class SerialDebug; RF24Debug *dbg; protected: +friend class SerialDebug; + /** * @name Low-level internal interface. * @@ -217,6 +218,8 @@ class RF24 */ RF24(uint8_t _cepin, uint8_t _cspin); + void setDebug(RF24Debug *dbg) { this->dbg = dbg; } + /** * Begin operation of the chip * From 9840064abc41f4263e82304c4118c41609123005 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 29 Jul 2014 16:58:35 +0100 Subject: [PATCH 15/26] bodge for stellaris --- examples/pingpair_msp430/printf.h | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/pingpair_msp430/printf.h b/examples/pingpair_msp430/printf.h index efb9113f..094e08f4 100644 --- a/examples/pingpair_msp430/printf.h +++ b/examples/pingpair_msp430/printf.h @@ -19,6 +19,7 @@ #include #ifdef ENERGIA +#undef putchar extern "C" { int putchar(int c) { From ac0c78a1c92e080519274d85c3469596d332a4c9 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 30 Jul 2014 09:19:47 +0100 Subject: [PATCH 16/26] merge msp430 + arduino pingpair examples --- examples/pingpair/pingpair.ino | 49 +++--- examples/pingpair/printf.h | 20 ++- examples/pingpair_msp430/pingpair.ino | 219 -------------------------- examples/pingpair_msp430/printf.h | 49 ------ 4 files changed, 48 insertions(+), 289 deletions(-) delete mode 100644 examples/pingpair_msp430/pingpair.ino delete mode 100644 examples/pingpair_msp430/printf.h diff --git a/examples/pingpair/pingpair.ino b/examples/pingpair/pingpair.ino index aa2cfe1a..85b47f08 100644 --- a/examples/pingpair/pingpair.ino +++ b/examples/pingpair/pingpair.ino @@ -21,17 +21,27 @@ #include "printf.h" // -// Hardware configuration +// Hardware configuration: first MSP430, then ATMega // -// Set up nRF24L01 radio on SPI bus plus pins 8 & 9 - -RF24 radio(9,10); +#if defined(ENERGIA) +# define CE P2_1 +# define CS P2_0 +# define ROLE P2_2 +# define BAUD 9600 +#else +# define CE 9 +# define CS 10 +# define ROLE 7 +# define BAUD 57600 +#endif + +RF24 radio(CE, CS); SerialDebug dbg(radio); // sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver // Leave open to be the 'ping' transmitter -const int role_pin = 7; +const int role_pin = ROLE; // // Topology @@ -67,7 +77,7 @@ void setup(void) // set up the role pin pinMode(role_pin, INPUT); - digitalWrite(role_pin,HIGH); + digitalWrite(role_pin, HIGH); delay(20); // Just to get a solid reading on the role pin // read the address pin, establish our role @@ -80,10 +90,10 @@ void setup(void) // Print preamble // - Serial.begin(57600); + Serial.begin(BAUD); printf_begin(); - printf("\n\rRF24/examples/pingpair/\n\r"); - printf("ROLE: %s\n\r",role_friendly_name[role]); + printf_P("RF24/examples/pingpair/\n\r"); + printf_P("ROLE: %s\n\r",role_friendly_name[role]); // // Setup and configure rf radio @@ -122,9 +132,9 @@ void setup(void) // Start listening // // if( radio.setDataRate( RF24_250KBPS ) ) { - // printf( "Data rate 250KBPS set!\n\r" ) ; + // printf_P( "Data rate 250KBPS set!\n\r" ) ; // } else { - // printf( "Data rate 250KBPS set FAILED!!\n\r" ) ; + // printf_P( "Data rate 250KBPS set FAILED!!\n\r" ) ; // } // radio.setDataRate( RF24_2MBPS ) ; // radio.setPALevel( RF24_PA_MAX ) ; @@ -153,7 +163,7 @@ void loop(void) // Take the time, and send it. This will block until complete unsigned long time = millis(); - printf("Now sending %lu...",time); + printf_P("Now sending %lu...",time); radio.write( &time, sizeof(unsigned long) ); // Now, continue listening @@ -163,14 +173,15 @@ void loop(void) unsigned long started_waiting_at = millis(); bool timeout = false; while ( ! radio.available() && ! timeout ) - if (millis() - started_waiting_at > 1+(radio.getMaxTimeout()/1000) ) +// if (millis() - started_waiting_at > 1+(radio.getMaxTimeout()/1000) ) + if (millis() - started_waiting_at > 250 ) timeout = true; // Describe the results if ( timeout ) { - printf("Failed, response timed out.\n\r"); - printf("Timeout duration: %d\n\r", (1+radio.getMaxTimeout()/1000) ) ; + printf_P("Failed, response timed out.\n\r"); + printf_P("Timeout duration: %d\n\r", (1+radio.getMaxTimeout()/1000) ) ; } else { @@ -179,11 +190,11 @@ void loop(void) radio.read( &got_time, sizeof(unsigned long) ); // Spew it - printf("Got response %lu, round-trip delay: %lu\n\r",got_time,millis()-got_time); + printf_P("Got response %lu, round-trip delay: %lu\n\r",got_time,millis()-got_time); } - // Try again 1s later - delay(1000); + // Try again 5s later + delay(5000); } // @@ -210,7 +221,7 @@ void loop(void) // Send the final one back. This way, we don't delay // the reply while we wait on serial i/o. radio.write( &got_time, sizeof(unsigned long) ); - printf("Sent response %lu\n\r", got_time); + printf_P("Sent response %lu\n\r", got_time); // Now, resume listening so we catch the next packets. radio.startListening(); diff --git a/examples/pingpair/printf.h b/examples/pingpair/printf.h index 05dd0888..094e08f4 100644 --- a/examples/pingpair/printf.h +++ b/examples/pingpair/printf.h @@ -18,7 +18,22 @@ #include -int serial_putc( char c, FILE * ) +#ifdef ENERGIA +#undef putchar +extern "C" { + int putchar(int c) + { + Serial.write((uint8_t)c); + return c; + } +} + +void printf_begin(void) +{ +} + +#else +int serial_putc( char c, struct FILE * ) { Serial.write( c ); @@ -27,7 +42,8 @@ int serial_putc( char c, FILE * ) void printf_begin(void) { - fdevopen( &serial_putc, 0 ); + fdevopen( &serial_putc, 0 ); } +#endif #endif // __PRINTF_H__ diff --git a/examples/pingpair_msp430/pingpair.ino b/examples/pingpair_msp430/pingpair.ino deleted file mode 100644 index 276544c9..00000000 --- a/examples/pingpair_msp430/pingpair.ino +++ /dev/null @@ -1,219 +0,0 @@ -/* - Copyright (C) 2011 James Coliz, Jr. - - 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. - */ - -/** - * Example RF Radio Ping Pair - * - * This is an example of how to use the RF24 class. Write this sketch to two different nodes, - * connect the role_pin to ground on one. The ping node sends the current time to the pong node, - * which responds by sending the value back. The ping node can then see how long the whole cycle - * took. - */ - -#include -#include -#include -#include "printf.h" - -// -// Hardware configuration -// - -// Set up nRF24L01 radio on SPI bus plus pins 8 & 9 -RF24 radio(P2_1,P2_0); -//SerialDebug dbg(radio); - -// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver -// Leave open to be the 'ping' transmitter -const int role_pin = P2_2; - -// -// Topology -// - -// Radio pipe addresses for the 2 nodes to communicate. -const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; - -// -// Role management -// -// Set up role. This sketch uses the same software for all the nodes -// in this system. Doing so greatly simplifies testing. The hardware itself specifies -// which node it is. -// -// This is done through the role_pin -// - -// The various roles supported by this sketch -typedef enum { role_ping_out = 1, role_pong_back } role_e; - -// The debug-friendly names of those roles -const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"}; - -// The role of the current running sketch -role_e role; - -void setup(void) -{ - // - // Role - // - - // set up the role pin - pinMode(role_pin, INPUT); - digitalWrite(role_pin,HIGH); - delay(20); // Just to get a solid reading on the role pin - - // read the address pin, establish our role - if ( digitalRead(role_pin) ) - role = role_ping_out; - else - role = role_pong_back; - - // - // Print preamble - // - - Serial.begin(9600); - printf_begin(); - printf("\n\rRF24/examples/pingpair/\n\r"); - printf("ROLE: %s\n\r",role_friendly_name[role]); - - // - // Setup and configure rf radio - // - - radio.begin(); - - // optionally, increase the delay between retries & # of retries - // radio.setRetries(15,15); - - // optionally, reduce the payload size. seems to - // improve reliability - // radio.setPayloadSize(8); - - // - // Open pipes to other nodes for communication - // - - // This simple sketch opens two pipes for these two nodes to communicate - // back and forth. - // Open 'our' pipe for writing - // Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading) - - if ( role == role_ping_out ) - { - radio.openWritingPipe(pipes[0]); - radio.openReadingPipe(1,pipes[1]); - } - else - { - radio.openWritingPipe(pipes[1]); - radio.openReadingPipe(1,pipes[0]); - } - - // - // Start listening - // - // if( radio.setDataRate( RF24_250KBPS ) ) { - // printf( "Data rate 250KBPS set!\n\r" ) ; - // } else { - // printf( "Data rate 250KBPS set FAILED!!\n\r" ) ; - // } - // radio.setDataRate( RF24_2MBPS ) ; - // radio.setPALevel( RF24_PA_MAX ) ; - radio.enableDynamicPayloads() ; - radio.setAutoAck( true ) ; - radio.powerUp() ; - radio.startListening(); - - // - // Dump the configuration of the rf unit for debugging - // - radio.printDetails(); -} - -void loop(void) -{ - // - // Ping out role. Repeatedly send the current time - // - - if (role == role_ping_out) - { - // First, stop listening so we can talk. - radio.stopListening(); - - // Take the time, and send it. This will block until complete - unsigned long time = millis(); - printf("Now sending %lx...",time); - radio.write( &time, sizeof(unsigned long) ); - - // Now, continue listening - radio.startListening(); - - // Wait here until we get a response, or timeout (250ms) - unsigned long started_waiting_at = millis(); - bool timeout = false; - while ( ! radio.available() && ! timeout ) -// if (millis() - started_waiting_at > 1+(radio.getMaxTimeout()/1000) ) - if (millis() - started_waiting_at > 250 ) - timeout = true; - - // Describe the results - if ( timeout ) - { - printf("Failed, response timed out.\n\r"); - printf("Timeout duration: %d\n\r", (1+radio.getMaxTimeout()/1000) ) ; - } - else - { - // Grab the response, compare, and send to debugging spew - unsigned long got_time; - radio.read( &got_time, sizeof(unsigned long) ); - - // Spew it - printf("Got response %lx, round-trip delay: %lx\n\r",got_time,millis()-got_time); - } - - // Try again 1s later - delay(5000); - } - - // - // Pong back role. Receive each packet, dump it out, and send it back - // - - if ( role == role_pong_back ) - { - // if there is data ready - if ( radio.available() ) - { - // Dump the payloads until we've gotten everything - unsigned long got_time; - bool done = false; - while (!done) - { - // Fetch the payload, and see if this was the last one. - done = radio.read( &got_time, sizeof(unsigned long) ); - } - - // First, stop listening so we can talk - radio.stopListening(); - - // Send the final one back. This way, we don't delay - // the reply while we wait on serial i/o. - radio.write( &got_time, sizeof(unsigned long) ); - printf("Sent response %lx\n\r", got_time); - - // Now, resume listening so we catch the next packets. - radio.startListening(); - } - } -} -// vim:cin:ai:sts=2 sw=2 ft=cpp diff --git a/examples/pingpair_msp430/printf.h b/examples/pingpair_msp430/printf.h deleted file mode 100644 index 094e08f4..00000000 --- a/examples/pingpair_msp430/printf.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright (C) 2011 James Coliz, Jr. - - 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. - */ - -/** - * @file printf.h - * - * Setup necessary to direct stdout to the Arduino Serial library, which - * enables 'printf' - */ - -#ifndef __PRINTF_H__ -#define __PRINTF_H__ - -#include - -#ifdef ENERGIA -#undef putchar -extern "C" { - int putchar(int c) - { - Serial.write((uint8_t)c); - return c; - } -} - -void printf_begin(void) -{ -} - -#else -int serial_putc( char c, struct FILE * ) -{ - Serial.write( c ); - - return c; -} - -void printf_begin(void) -{ - fdevopen( &serial_putc, 0 ); -} -#endif - -#endif // __PRINTF_H__ From 1e6b222b8001f5d472d69300efa1ad6372e3e3f1 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 30 Jul 2014 09:23:11 +0100 Subject: [PATCH 17/26] bugfix --- examples/pingpair/printf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/pingpair/printf.h b/examples/pingpair/printf.h index 094e08f4..6336f855 100644 --- a/examples/pingpair/printf.h +++ b/examples/pingpair/printf.h @@ -33,7 +33,7 @@ void printf_begin(void) } #else -int serial_putc( char c, struct FILE * ) +int serial_putc( char c, FILE * ) { Serial.write( c ); From d11cf6970c002f6037e56bc627eff0408a3226ce Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 31 Jul 2014 08:39:43 +0100 Subject: [PATCH 18/26] improve debugging --- RF24.cpp | 22 +++++-------- RF24.h | 38 +++++---------------- RF24SerialDebug.cpp => RF24Debug.cpp | 49 ++++++++++------------------ RF24SerialDebug.h => RF24Debug.h | 30 ++++++++--------- examples/pingpair/pingpair.ino | 46 ++++++++++---------------- 5 files changed, 67 insertions(+), 118 deletions(-) rename RF24SerialDebug.cpp => RF24Debug.cpp (72%) rename RF24SerialDebug.h => RF24Debug.h (90%) diff --git a/RF24.cpp b/RF24.cpp index 83debc8e..86b809b0 100644 --- a/RF24.cpp +++ b/RF24.cpp @@ -83,8 +83,7 @@ uint8_t RF24::write_register(uint8_t reg, uint8_t value) { uint8_t status; - if (dbg) - dbg->on_write_register(reg, value); + on_write_register(reg, value); csn(LOW); status = SPI.transfer( W_REGISTER | ( REGISTER_MASK & reg ) ); @@ -105,8 +104,7 @@ uint8_t RF24::write_payload(const void* buf, uint8_t len, const uint8_t writeTyp uint8_t data_len = min(len,payload_size); uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len; - if (dbg) - dbg->on_write_payload(data_len, blank_len); + on_write_payload(data_len, blank_len); csn(LOW); status = SPI.transfer( writeType ); @@ -129,8 +127,7 @@ uint8_t RF24::read_payload(void* buf, uint8_t len) uint8_t data_len = min(len,payload_size); uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len; - if (dbg) - dbg->on_read_payload(data_len, blank_len); + on_read_payload(data_len, blank_len); csn(LOW); status = SPI.transfer( R_RX_PAYLOAD ); @@ -354,7 +351,7 @@ bool RF24::write( const void* buf, uint8_t len, const bool multicast ) // IN the end, the send should be blocking. It comes back in 60ms worst case. // Generally much faster. - uint8_t observe_tx; + uint8_t obs; uint8_t status; uint32_t sent_at = micros(); const uint16_t timeout = getMaxTimeout() ; //us to wait for timeout @@ -362,9 +359,8 @@ bool RF24::write( const void* buf, uint8_t len, const bool multicast ) // Monitor the send do { - status = read_register(OBSERVE_TX,&observe_tx,1); - if (dbg) - dbg->observe_tx(observe_tx); + status = read_register(OBSERVE_TX, &obs, 1); + observe_tx(obs); } while( ! ( status & ( _BV(TX_DS) | _BV(MAX_RT) ) ) && ( micros() - sent_at < timeout ) ); @@ -388,8 +384,7 @@ bool RF24::write( const void* buf, uint8_t len, const bool multicast ) if ( ack_payload_available ) { ack_payload_length = getDynamicPayloadSize(); - if (dbg) - dbg->on_ack(ack_payload_length); + on_ack(ack_payload_length); } return result; @@ -482,8 +477,7 @@ void RF24::whatHappened(bool& tx_ok,bool& tx_fail,bool& rx_ready) // Or is that such a good idea? uint8_t status = write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); - if (dbg) - dbg->on_status(status); + on_status(status); // Report to the user what happened tx_ok = status & _BV(TX_DS); diff --git a/RF24.h b/RF24.h index c4da3ebf..c56264e3 100644 --- a/RF24.h +++ b/RF24.h @@ -40,25 +40,6 @@ typedef enum { RF24_1MBPS = 0, RF24_2MBPS, RF24_250KBPS } rf24_datarate_e; */ typedef enum { RF24_CRC_DISABLED = 0, RF24_CRC_8, RF24_CRC_16 } rf24_crclength_e; -class RF24Debug -{ -public: - /** - * Callbacks from RF24 - */ - virtual void on_write_register(uint8_t reg, uint8_t value) {} - virtual void observe_tx(uint8_t tx) {} - virtual void on_ack(uint8_t ack_len) {} - virtual void on_status(uint8_t status) {} - virtual void on_write_payload(uint8_t data_len, uint8_t blank_len) {} - virtual void on_read_payload(uint8_t data_len, uint8_t blank_len) {} - - /** - * Backwards-compatibility - */ - virtual void printDetails(void) {} -}; - /** * Driver for nRF24L01(+) 2.4GHz Wireless Transceiver */ @@ -75,11 +56,14 @@ class RF24 bool dynamic_payloads_enabled; /**< Whether dynamic payloads are enabled. */ uint8_t ack_payload_length; /**< Dynamic size of pending ack payload. */ uint64_t pipe0_reading_address; /**< Last address set on pipe 0 for reading. */ - RF24Debug *dbg; - protected: - -friend class SerialDebug; + /* debugging interface: does nothing by default */ + virtual void on_write_register(uint8_t reg, uint8_t value) {} + virtual void observe_tx(uint8_t tx) {} + virtual void on_ack(uint8_t ack_len) {} + virtual void on_status(uint8_t status) {} + virtual void on_write_payload(uint8_t data_len, uint8_t blank_len) {} + virtual void on_read_payload(uint8_t data_len, uint8_t blank_len) {} /** * @name Low-level internal interface. @@ -218,8 +202,6 @@ friend class SerialDebug; */ RF24(uint8_t _cepin, uint8_t _cspin); - void setDebug(RF24Debug *dbg) { this->dbg = dbg; } - /** * Begin operation of the chip * @@ -542,11 +524,9 @@ friend class SerialDebug; /** * Print a giant block of debugging information to stdout * - * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h - * @warning Also does nothing if a real RF24Debug isn't configured. See - * RF24SerialDebug.h + * @warning Does nothing by default */ - void printDetails(void) { if (dbg) dbg->printDetails(); } + virtual void printDetails(void) {} /** * Enter low-power mode diff --git a/RF24SerialDebug.cpp b/RF24Debug.cpp similarity index 72% rename from RF24SerialDebug.cpp rename to RF24Debug.cpp index 6c79ad3a..d1f3823d 100644 --- a/RF24SerialDebug.cpp +++ b/RF24Debug.cpp @@ -1,21 +1,17 @@ #include "RF24_config.h" #include "RF24.h" -#include "RF24SerialDebug.h" +#include "RF24Debug.h" -/****************************************************************************/ - -void SerialDebug::print_byte_register(const char* name, uint8_t reg, uint8_t qty) +void RF24Debug::print_byte_register(const char* name, uint8_t reg, uint8_t qty) { char extra_tab = strlen_P(name) < 8 ? '\t' : 0; printf_P(PSTR(PRIPSTR"\t%c ="),name,extra_tab); while (qty--) - printf_P(PSTR(" 0x%02x"), r.read_register(reg++)); + printf_P(PSTR(" 0x%02x"), read_register(reg++)); printf_P(PSTR("\r\n")); } -/****************************************************************************/ - -void SerialDebug::print_address_register(const char* name, uint8_t reg, uint8_t qty) +void RF24Debug::print_address_register(const char* name, uint8_t reg, uint8_t qty) { char extra_tab = strlen_P(name) < 8 ? '\t' : 0; printf_P(PSTR(PRIPSTR"\t%c ="),name,extra_tab); @@ -23,7 +19,7 @@ void SerialDebug::print_address_register(const char* name, uint8_t reg, uint8_t while (qty--) { uint8_t buffer[5]; - r.read_register(reg++,buffer,sizeof buffer); + read_register(reg++,buffer,sizeof buffer); printf_P(PSTR(" 0x")); uint8_t* bufptr = buffer + sizeof buffer; @@ -34,9 +30,7 @@ void SerialDebug::print_address_register(const char* name, uint8_t reg, uint8_t printf_P(PSTR("\r\n")); } -/****************************************************************************/ - -void SerialDebug::print_status(uint8_t status) +void RF24Debug::print_status(uint8_t status) { printf_P(PSTR("STATUS\t\t = 0x%02x RX_DR=%x TX_DS=%x MAX_RT=%x RX_P_NO=%x TX_FULL=%x\r\n"), status, @@ -48,8 +42,6 @@ void SerialDebug::print_status(uint8_t status) ); } -/****************************************************************************/ - static const char rf24_datarate_e_str_0[] PROGMEM = "1MBPS"; static const char rf24_datarate_e_str_1[] PROGMEM = "2MBPS"; static const char rf24_datarate_e_str_2[] PROGMEM = "250KBPS"; @@ -83,9 +75,9 @@ static const char * const rf24_pa_dbm_e_str_P[] PROGMEM = { rf24_pa_dbm_e_str_3, }; -void SerialDebug::printDetails(void) +void RF24Debug::printDetails(void) { - print_status(r.get_status()); + print_status(get_status()); print_address_register(PSTR("RX_ADDR_P0-1"),RX_ADDR_P0,2); print_byte_register(PSTR("RX_ADDR_P2-5"),RX_ADDR_P2,4); @@ -99,18 +91,18 @@ void SerialDebug::printDetails(void) print_byte_register(PSTR("CONFIG"),CONFIG); print_byte_register(PSTR("DYNPD/FEATURE"),DYNPD,2); - printf_P(PSTR("Data Rate\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_datarate_e_str_P[r.getDataRate()])); - printf_P(PSTR("Model\t\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_model_e_str_P[r.isPVariant()])); - printf_P(PSTR("CRC Length\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_crclength_e_str_P[r.getCRCLength()])); - printf_P(PSTR("PA Power\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_pa_dbm_e_str_P[r.getPALevel()])); + printf_P(PSTR("Data Rate\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_datarate_e_str_P[getDataRate()])); + printf_P(PSTR("Model\t\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_model_e_str_P[isPVariant()])); + printf_P(PSTR("CRC Length\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_crclength_e_str_P[getCRCLength()])); + printf_P(PSTR("PA Power\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_pa_dbm_e_str_P[getPALevel()])); } -void SerialDebug::on_write_register(uint8_t reg, uint8_t value) +void RF24Debug::on_write_register(uint8_t reg, uint8_t value) { printf_P(PSTR("write_register(%02x,%02x)\r\n"),reg,value); } -void SerialDebug::observe_tx(uint8_t value) +void RF24Debug::observe_tx(uint8_t value) { printf_P(PSTR("OBSERVE_TX=%02x: PLOS_CNT=%x ARC_CNT=%x\r\n"), value, @@ -118,29 +110,24 @@ void SerialDebug::observe_tx(uint8_t value) (value >> ARC_CNT) & B1111); } -void SerialDebug::on_status(uint8_t status) +void RF24Debug::on_status(uint8_t status) { uint8_t result = status & _BV(TX_DS); Serial.println(result?"...OK.":"...Failed"); } -void SerialDebug::on_ack(uint8_t ack_payload_length) +void RF24Debug::on_ack(uint8_t ack_payload_length) { Serial.print("[AckPacket]/"); Serial.println(ack_payload_length,DEC); } -void SerialDebug::on_write_payload(uint8_t data_len, uint8_t blank_len) +void RF24Debug::on_write_payload(uint8_t data_len, uint8_t blank_len) { printf_P(PSTR("[Writing %u bytes %u blanks]"),data_len,blank_len); } -void SerialDebug::on_read_payload(uint8_t data_len, uint8_t blank_len) +void RF24Debug::on_read_payload(uint8_t data_len, uint8_t blank_len) { printf_P(PSTR("[Reading %u bytes %u blanks]"),data_len,blank_len); } - -SerialDebug::SerialDebug(RF24 &radio): r(radio) -{ - r.dbg = this; -} diff --git a/RF24SerialDebug.h b/RF24Debug.h similarity index 90% rename from RF24SerialDebug.h rename to RF24Debug.h index 8d30cce7..10eea078 100644 --- a/RF24SerialDebug.h +++ b/RF24Debug.h @@ -1,9 +1,11 @@ -#ifndef __RF24_SERIAL_DEBUG_H -#define __RF24_SERIAL_DEBUG_H +#ifndef __RF24_DEBUG_H +#define __RF24_DEBUG_H -class SerialDebug: public RF24Debug +#include + +class RF24Debug: public RF24 { -protected: +private: /** * Decode and print the given status to stdout * @@ -39,7 +41,13 @@ class SerialDebug: public RF24Debug */ void print_address_register(const char* name, uint8_t reg, uint8_t qty = 1); - RF24 &r; +protected: + void on_write_register(uint8_t reg, uint8_t value); + void observe_tx(uint8_t tx); + void on_ack(uint8_t ack_len); + void on_status(uint8_t status); + void on_write_payload(uint8_t data_len, uint8_t blank_len); + void on_read_payload(uint8_t data_len, uint8_t blank_len); public: /** @@ -49,17 +57,7 @@ class SerialDebug: public RF24Debug */ void printDetails(void); - SerialDebug(RF24 &radio); - - /** - * Callbacks from RF24 - */ - void on_write_register(uint8_t reg, uint8_t value); - void observe_tx(uint8_t tx); - void on_ack(uint8_t ack_len); - void on_status(uint8_t status); - void on_write_payload(uint8_t data_len, uint8_t blank_len); - void on_read_payload(uint8_t data_len, uint8_t blank_len); + RF24Debug(uint8_t _cepin, uint8_t _cspin): RF24(_cepin, _cspin) {} }; #endif diff --git a/examples/pingpair/pingpair.ino b/examples/pingpair/pingpair.ino index 85b47f08..25f7b75e 100644 --- a/examples/pingpair/pingpair.ino +++ b/examples/pingpair/pingpair.ino @@ -21,27 +21,17 @@ #include "printf.h" // -// Hardware configuration: first MSP430, then ATMega +// Hardware configuration // -#if defined(ENERGIA) -# define CE P2_1 -# define CS P2_0 -# define ROLE P2_2 -# define BAUD 9600 -#else -# define CE 9 -# define CS 10 -# define ROLE 7 -# define BAUD 57600 -#endif - -RF24 radio(CE, CS); +// Set up nRF24L01 radio on SPI bus plus pins 8 & 9 + +RF24 radio(9,10); SerialDebug dbg(radio); // sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver // Leave open to be the 'ping' transmitter -const int role_pin = ROLE; +const int role_pin = 7; // // Topology @@ -77,7 +67,7 @@ void setup(void) // set up the role pin pinMode(role_pin, INPUT); - digitalWrite(role_pin, HIGH); + digitalWrite(role_pin,HIGH); delay(20); // Just to get a solid reading on the role pin // read the address pin, establish our role @@ -90,10 +80,10 @@ void setup(void) // Print preamble // - Serial.begin(BAUD); + Serial.begin(57600); printf_begin(); - printf_P("RF24/examples/pingpair/\n\r"); - printf_P("ROLE: %s\n\r",role_friendly_name[role]); + printf("\n\rRF24/examples/pingpair/\n\r"); + printf("ROLE: %s\n\r",role_friendly_name[role]); // // Setup and configure rf radio @@ -132,9 +122,9 @@ void setup(void) // Start listening // // if( radio.setDataRate( RF24_250KBPS ) ) { - // printf_P( "Data rate 250KBPS set!\n\r" ) ; + // printf( "Data rate 250KBPS set!\n\r" ) ; // } else { - // printf_P( "Data rate 250KBPS set FAILED!!\n\r" ) ; + // printf( "Data rate 250KBPS set FAILED!!\n\r" ) ; // } // radio.setDataRate( RF24_2MBPS ) ; // radio.setPALevel( RF24_PA_MAX ) ; @@ -147,7 +137,7 @@ void setup(void) // Dump the configuration of the rf unit for debugging // - radio.printDetails(); + dbg.printDetails(); } void loop(void) @@ -163,7 +153,7 @@ void loop(void) // Take the time, and send it. This will block until complete unsigned long time = millis(); - printf_P("Now sending %lu...",time); + printf("Now sending %lx...",time); radio.write( &time, sizeof(unsigned long) ); // Now, continue listening @@ -180,8 +170,8 @@ void loop(void) // Describe the results if ( timeout ) { - printf_P("Failed, response timed out.\n\r"); - printf_P("Timeout duration: %d\n\r", (1+radio.getMaxTimeout()/1000) ) ; + printf("Failed, response timed out.\n\r"); + printf("Timeout duration: %d\n\r", (1+radio.getMaxTimeout()/1000) ) ; } else { @@ -190,10 +180,10 @@ void loop(void) radio.read( &got_time, sizeof(unsigned long) ); // Spew it - printf_P("Got response %lu, round-trip delay: %lu\n\r",got_time,millis()-got_time); + printf("Got response %lx, round-trip delay: %lx\n\r",got_time,millis()-got_time); } - // Try again 5s later + // Try again 1s later delay(5000); } @@ -221,7 +211,7 @@ void loop(void) // Send the final one back. This way, we don't delay // the reply while we wait on serial i/o. radio.write( &got_time, sizeof(unsigned long) ); - printf_P("Sent response %lu\n\r", got_time); + printf("Sent response %lx\n\r", got_time); // Now, resume listening so we catch the next packets. radio.startListening(); From 3def073c5f32bf26659f472abfbad63e7b811534 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 31 Jul 2014 08:45:42 +0100 Subject: [PATCH 19/26] grrr --- examples/pingpair/pingpair.ino | 38 ++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/examples/pingpair/pingpair.ino b/examples/pingpair/pingpair.ino index 25f7b75e..b1a75670 100644 --- a/examples/pingpair/pingpair.ino +++ b/examples/pingpair/pingpair.ino @@ -16,22 +16,30 @@ */ #include -#include -#include +#include #include "printf.h" // -// Hardware configuration +// Hardware configuration: first MSP430, then ATMega // -// Set up nRF24L01 radio on SPI bus plus pins 8 & 9 +#if defined(ENERGIA) +# define CE P2_1 +# define CS P2_0 +# define ROLE P2_2 +# define BAUD 9600 +#else +# define CE 9 +# define CS 10 +# define ROLE 7 +# define BAUD 57600 +#endif -RF24 radio(9,10); -SerialDebug dbg(radio); +RF24Debug radio(CE, CS); // sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver // Leave open to be the 'ping' transmitter -const int role_pin = 7; +const int role_pin = ROLE; // // Topology @@ -67,7 +75,7 @@ void setup(void) // set up the role pin pinMode(role_pin, INPUT); - digitalWrite(role_pin,HIGH); + digitalWrite(role_pin, HIGH); delay(20); // Just to get a solid reading on the role pin // read the address pin, establish our role @@ -80,9 +88,9 @@ void setup(void) // Print preamble // - Serial.begin(57600); + Serial.begin(BAUD); printf_begin(); - printf("\n\rRF24/examples/pingpair/\n\r"); + printf("RF24/examples/pingpair/\n\r"); printf("ROLE: %s\n\r",role_friendly_name[role]); // @@ -137,7 +145,7 @@ void setup(void) // Dump the configuration of the rf unit for debugging // - dbg.printDetails(); + radio.printDetails(); } void loop(void) @@ -153,7 +161,7 @@ void loop(void) // Take the time, and send it. This will block until complete unsigned long time = millis(); - printf("Now sending %lx...",time); + printf("Now sending %lu...",time); radio.write( &time, sizeof(unsigned long) ); // Now, continue listening @@ -180,10 +188,10 @@ void loop(void) radio.read( &got_time, sizeof(unsigned long) ); // Spew it - printf("Got response %lx, round-trip delay: %lx\n\r",got_time,millis()-got_time); + printf("Got response %lu, round-trip delay: %lu\n\r",got_time,millis()-got_time); } - // Try again 1s later + // Try again 5s later delay(5000); } @@ -211,7 +219,7 @@ void loop(void) // Send the final one back. This way, we don't delay // the reply while we wait on serial i/o. radio.write( &got_time, sizeof(unsigned long) ); - printf("Sent response %lx\n\r", got_time); + printf("Sent response %lu\n\r", got_time); // Now, resume listening so we catch the next packets. radio.startListening(); From 418e41dad2b2bb312df402bf8a8b8a52d8b313e8 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 31 Jul 2014 11:27:22 +0100 Subject: [PATCH 20/26] - remove printf from debugging, replace with Print - output defaults to Serial --- RF24.cpp | 2 - RF24Debug.cpp | 111 +++++++++++++++++++++++++++++++++----------------- RF24Debug.h | 12 ++++-- RF24_config.h | 5 +-- 4 files changed, 84 insertions(+), 46 deletions(-) diff --git a/RF24.cpp b/RF24.cpp index 86b809b0..a2ff46de 100644 --- a/RF24.cpp +++ b/RF24.cpp @@ -376,8 +376,6 @@ bool RF24::write( const void* buf, uint8_t len, const bool multicast ) bool tx_ok, tx_fail; whatHappened(tx_ok,tx_fail,ack_payload_available); - //printf_P("%u%u%u\r\n",tx_ok,tx_fail,ack_payload_available); - result = tx_ok; // Handle the ack packet diff --git a/RF24Debug.cpp b/RF24Debug.cpp index d1f3823d..4a72ecb8 100644 --- a/RF24Debug.cpp +++ b/RF24Debug.cpp @@ -2,44 +2,65 @@ #include "RF24.h" #include "RF24Debug.h" -void RF24Debug::print_byte_register(const char* name, uint8_t reg, uint8_t qty) +void RF24Debug::print_name(const prog_char *name) { - char extra_tab = strlen_P(name) < 8 ? '\t' : 0; - printf_P(PSTR(PRIPSTR"\t%c ="),name,extra_tab); + _out.print((const __FlashStringHelper *)name); + if (strlen_P(name) < 8) + _out.print('\t'); + _out.print(F("\t =")); +} + +void RF24Debug::print_hex_byte(uint8_t b) +{ + _out.print(F(" 0x")); + if (b < 16) + _out.print('0'); + _out.print(b, HEX); +} + +void RF24Debug::print_byte_register(const prog_char *name, uint8_t reg, uint8_t qty) +{ + print_name(name); while (qty--) - printf_P(PSTR(" 0x%02x"), read_register(reg++)); - printf_P(PSTR("\r\n")); + print_hex_byte(read_register(reg++)); + _out.println(); } -void RF24Debug::print_address_register(const char* name, uint8_t reg, uint8_t qty) +void RF24Debug::print_address_register(const prog_char *name, uint8_t reg, uint8_t qty) { - char extra_tab = strlen_P(name) < 8 ? '\t' : 0; - printf_P(PSTR(PRIPSTR"\t%c ="),name,extra_tab); + print_name(name); while (qty--) { uint8_t buffer[5]; read_register(reg++,buffer,sizeof buffer); - printf_P(PSTR(" 0x")); + _out.print(F(" 0x")); uint8_t* bufptr = buffer + sizeof buffer; - while( --bufptr >= buffer ) - printf_P(PSTR("%02x"),*bufptr); + while( --bufptr >= buffer ) { + uint8_t b = *bufptr; + if (b < 10) + _out.print('0'); + _out.print(b, HEX); + } } - - printf_P(PSTR("\r\n")); + _out.println(); } void RF24Debug::print_status(uint8_t status) { - printf_P(PSTR("STATUS\t\t = 0x%02x RX_DR=%x TX_DS=%x MAX_RT=%x RX_P_NO=%x TX_FULL=%x\r\n"), - status, - (status & _BV(RX_DR))?1:0, - (status & _BV(TX_DS))?1:0, - (status & _BV(MAX_RT))?1:0, - ((status >> RX_P_NO) & B111), - (status & _BV(TX_FULL))?1:0 - ); + print_name(PSTR("STATUS")); + print_hex_byte(status); + _out.print(F(" RX_DR=")); + _out.print((status & _BV(RX_DR))? 1: 0); + _out.print(F(" TX_DS=")); + _out.print((status & _BV(TX_DS))? 1: 0); + _out.print(F(" MAX_RT=")); + _out.print((status & _BV(MAX_RT))? 1: 0); + _out.print(F(" RX_P_NO=")); + _out.print((status >> RX_P_NO) & B111); + _out.print(F(" TX_FULL=")); + _out.println((status & _BV(TX_FULL))? 1: 0); } static const char rf24_datarate_e_str_0[] PROGMEM = "1MBPS"; @@ -91,43 +112,59 @@ void RF24Debug::printDetails(void) print_byte_register(PSTR("CONFIG"),CONFIG); print_byte_register(PSTR("DYNPD/FEATURE"),DYNPD,2); - printf_P(PSTR("Data Rate\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_datarate_e_str_P[getDataRate()])); - printf_P(PSTR("Model\t\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_model_e_str_P[isPVariant()])); - printf_P(PSTR("CRC Length\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_crclength_e_str_P[getCRCLength()])); - printf_P(PSTR("PA Power\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_pa_dbm_e_str_P[getPALevel()])); + _out.print(F("Data Rate\t = ")); + _out.println((const __FlashStringHelper *)pgm_read_word(&rf24_datarate_e_str_P[getDataRate()])); + _out.print(F("Model\t\t = ")); + _out.println((const __FlashStringHelper *)pgm_read_word(&rf24_model_e_str_P[isPVariant()])); + _out.print(F("CRC Length\t = ")); + _out.println((const __FlashStringHelper *)pgm_read_word(&rf24_crclength_e_str_P[getCRCLength()])); + _out.print(F("PA Power\t = ")); + _out.println((const __FlashStringHelper *)pgm_read_word(&rf24_pa_dbm_e_str_P[getPALevel()])); } void RF24Debug::on_write_register(uint8_t reg, uint8_t value) { - printf_P(PSTR("write_register(%02x,%02x)\r\n"),reg,value); + _out.print(F("write_register(")); + print_hex_byte(reg); + _out.print(','); + print_hex_byte(value); + _out.println(')'); } void RF24Debug::observe_tx(uint8_t value) { - printf_P(PSTR("OBSERVE_TX=%02x: PLOS_CNT=%x ARC_CNT=%x\r\n"), - value, - (value >> PLOS_CNT) & B1111, - (value >> ARC_CNT) & B1111); + _out.print(F("OBSERVE_TX")); + print_hex_byte(value); + _out.print(F(": PLOS_CNT=")); + _out.print((value >> PLOS_CNT) & B1111, HEX); + _out.print(F(" ARC_CNT=")); + _out.println((value >> ARC_CNT) & B1111, HEX); } void RF24Debug::on_status(uint8_t status) { - uint8_t result = status & _BV(TX_DS); - Serial.println(result?"...OK.":"...Failed"); + print_status(status); + _out.println(status & _BV(TX_DS)? F("...OK."): F("...Failed")); } -void RF24Debug::on_ack(uint8_t ack_payload_length) +void RF24Debug::on_ack(uint8_t ack_len) { - Serial.print("[AckPacket]/"); - Serial.println(ack_payload_length,DEC); + _out.print(F("got ack ")); + _out.println(ack_len); } void RF24Debug::on_write_payload(uint8_t data_len, uint8_t blank_len) { - printf_P(PSTR("[Writing %u bytes %u blanks]"),data_len,blank_len); + _out.print(F("Writing ")); + _out.print(data_len); + _out.print(F(" bytes ")); + _out.println(blank_len); } void RF24Debug::on_read_payload(uint8_t data_len, uint8_t blank_len) { - printf_P(PSTR("[Reading %u bytes %u blanks]"),data_len,blank_len); + _out.print(F("Reading ")); + _out.print(data_len); + _out.print(F(" bytes ")); + _out.println(blank_len); } diff --git a/RF24Debug.h b/RF24Debug.h index 10eea078..000063ce 100644 --- a/RF24Debug.h +++ b/RF24Debug.h @@ -6,6 +6,12 @@ class RF24Debug: public RF24 { private: + Print &_out; + + void print_name(const prog_char *name); + + void print_hex_byte(uint8_t b); + /** * Decode and print the given status to stdout * @@ -26,7 +32,7 @@ class RF24Debug: public RF24 * @param reg Which register. Use constants from nRF24L01.h * @param qty How many successive registers to print */ - void print_byte_register(const char* name, uint8_t reg, uint8_t qty = 1); + void print_byte_register(const prog_char *name, uint8_t reg, uint8_t qty = 1); /** * Print the name and value of a 40-bit address register to stdout @@ -39,7 +45,7 @@ class RF24Debug: public RF24 * @param reg Which register. Use constants from nRF24L01.h * @param qty How many successive registers to print */ - void print_address_register(const char* name, uint8_t reg, uint8_t qty = 1); + void print_address_register(const prog_char *name, uint8_t reg, uint8_t qty = 1); protected: void on_write_register(uint8_t reg, uint8_t value); @@ -57,7 +63,7 @@ class RF24Debug: public RF24 */ void printDetails(void); - RF24Debug(uint8_t _cepin, uint8_t _cspin): RF24(_cepin, _cspin) {} + RF24Debug(uint8_t _cepin, uint8_t _cspin, Print &out = Serial): RF24(_cepin, _cspin), _out(out) {} }; #endif diff --git a/RF24_config.h b/RF24_config.h index 25177356..b00ca5f6 100644 --- a/RF24_config.h +++ b/RF24_config.h @@ -31,18 +31,16 @@ extern HardwareSPI SPI; #if defined(ENERGIA) #define strlen_P strlen -#define printf_P printf #define pgm_read_byte(p) (*(p)) #define pgm_read_word(p) (*(p)) -#define PRIPSTR "%s" #define _BV(x) (1 << (x)) #define PROGMEM #define PSTR(s) (s) +#define prog_char char #elif defined(ARDUINO) // Progmem is Arduino-specific #include -#define PRIPSTR "%S" #else typedef char const char; @@ -52,7 +50,6 @@ typedef uint16_t prog_uint16_t; #define strlen_P strlen #define PROGMEM #define pgm_read_word(p) (*(p)) -#define PRIPSTR "%s" #endif #endif // __RF24_CONFIG_H__ From 6621fad27df98c735f35534b63cffd0a83dd734b Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 31 Jul 2014 11:32:06 +0100 Subject: [PATCH 21/26] fix for msp430 --- RF24_config.h | 1 + 1 file changed, 1 insertion(+) diff --git a/RF24_config.h b/RF24_config.h index b00ca5f6..3f95ea01 100644 --- a/RF24_config.h +++ b/RF24_config.h @@ -37,6 +37,7 @@ extern HardwareSPI SPI; #define PROGMEM #define PSTR(s) (s) #define prog_char char +#define __FlashStringHelper char #elif defined(ARDUINO) // Progmem is Arduino-specific From adb9019f758490d66a32bcd1a1340e18e6185d59 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 31 Jul 2014 12:13:11 +0100 Subject: [PATCH 22/26] - merge RF24Debug.h into RF24.h - add tinypingpair example --- RF24.h | 63 +++++++ RF24Debug.cpp | 21 ++- RF24Debug.h | 69 -------- RF24_config.h | 1 + examples/pingpair/pingpair.ino | 2 +- examples/tinypingpair/tinypingpair.ino | 233 +++++++++++++++++++++++++ 6 files changed, 311 insertions(+), 78 deletions(-) delete mode 100644 RF24Debug.h create mode 100644 examples/tinypingpair/tinypingpair.ino diff --git a/RF24.h b/RF24.h index c56264e3..bf60326d 100644 --- a/RF24.h +++ b/RF24.h @@ -657,6 +657,69 @@ class RF24 /**@}*/ }; +class RF24Debug: public RF24 +{ +private: + Print &_out; + + void print_name(const prog_char *name); + + void print_hex_byte(uint8_t b); + + /** + * Decode and print the given status to stdout + * + * @param status Status value to print + * + * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h + */ + void print_status(uint8_t status); + + /** + * Print the name and value of an 8-bit register to stdout + * + * Optionally it can print some quantity of successive + * registers on the same line. This is useful for printing a group + * of related registers on one line. + * + * @param name Name of the register + * @param reg Which register. Use constants from nRF24L01.h + * @param qty How many successive registers to print + */ + void print_byte_register(const prog_char *name, uint8_t reg, uint8_t qty = 1); + + /** + * Print the name and value of a 40-bit address register to stdout + * + * Optionally it can print some quantity of successive + * registers on the same line. This is useful for printing a group + * of related registers on one line. + * + * @param name Name of the register + * @param reg Which register. Use constants from nRF24L01.h + * @param qty How many successive registers to print + */ + void print_address_register(const prog_char *name, uint8_t reg, uint8_t qty = 1); + +protected: + void on_write_register(uint8_t reg, uint8_t value); + void observe_tx(uint8_t tx); + void on_ack(uint8_t ack_len); + void on_status(uint8_t status); + void on_write_payload(uint8_t data_len, uint8_t blank_len); + void on_read_payload(uint8_t data_len, uint8_t blank_len); + +public: + /** + * Print a giant block of debugging information to stdout + * + * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h + */ + void printDetails(void); + + RF24Debug(uint8_t _cepin, uint8_t _cspin, Print &out = Serial): RF24(_cepin, _cspin), _out(out) {} +}; + /** * @example GettingStarted.pde * diff --git a/RF24Debug.cpp b/RF24Debug.cpp index 4a72ecb8..b52021d9 100644 --- a/RF24Debug.cpp +++ b/RF24Debug.cpp @@ -1,10 +1,15 @@ #include "RF24_config.h" #include "RF24.h" -#include "RF24Debug.h" + +#if defined(__AVR_ATtinyX4__) || defined(__AVR_ATtinyX5__) +# define FLASH_PTR(x) ((fstr_t *)x) +#else +# define FLASH_PTR(x) ((const __FlashStringHelper *)x) +#endif void RF24Debug::print_name(const prog_char *name) { - _out.print((const __FlashStringHelper *)name); + _out.print(FLASH_PTR(name)); if (strlen_P(name) < 8) _out.print('\t'); _out.print(F("\t =")); @@ -113,13 +118,13 @@ void RF24Debug::printDetails(void) print_byte_register(PSTR("DYNPD/FEATURE"),DYNPD,2); _out.print(F("Data Rate\t = ")); - _out.println((const __FlashStringHelper *)pgm_read_word(&rf24_datarate_e_str_P[getDataRate()])); + _out.println(FLASH_PTR(pgm_read_word(&rf24_datarate_e_str_P[getDataRate()]))); _out.print(F("Model\t\t = ")); - _out.println((const __FlashStringHelper *)pgm_read_word(&rf24_model_e_str_P[isPVariant()])); + _out.println(FLASH_PTR(pgm_read_word(&rf24_model_e_str_P[isPVariant()]))); _out.print(F("CRC Length\t = ")); - _out.println((const __FlashStringHelper *)pgm_read_word(&rf24_crclength_e_str_P[getCRCLength()])); + _out.println(FLASH_PTR(pgm_read_word(&rf24_crclength_e_str_P[getCRCLength()]))); _out.print(F("PA Power\t = ")); - _out.println((const __FlashStringHelper *)pgm_read_word(&rf24_pa_dbm_e_str_P[getPALevel()])); + _out.println(FLASH_PTR(pgm_read_word(&rf24_pa_dbm_e_str_P[getPALevel()]))); } void RF24Debug::on_write_register(uint8_t reg, uint8_t value) @@ -156,9 +161,9 @@ void RF24Debug::on_ack(uint8_t ack_len) void RF24Debug::on_write_payload(uint8_t data_len, uint8_t blank_len) { _out.print(F("Writing ")); - _out.print(data_len); + _out.print(data_len, DEC); _out.print(F(" bytes ")); - _out.println(blank_len); + _out.println(blank_len, DEC); } void RF24Debug::on_read_payload(uint8_t data_len, uint8_t blank_len) diff --git a/RF24Debug.h b/RF24Debug.h deleted file mode 100644 index 000063ce..00000000 --- a/RF24Debug.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef __RF24_DEBUG_H -#define __RF24_DEBUG_H - -#include - -class RF24Debug: public RF24 -{ -private: - Print &_out; - - void print_name(const prog_char *name); - - void print_hex_byte(uint8_t b); - - /** - * Decode and print the given status to stdout - * - * @param status Status value to print - * - * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h - */ - void print_status(uint8_t status); - - /** - * Print the name and value of an 8-bit register to stdout - * - * Optionally it can print some quantity of successive - * registers on the same line. This is useful for printing a group - * of related registers on one line. - * - * @param name Name of the register - * @param reg Which register. Use constants from nRF24L01.h - * @param qty How many successive registers to print - */ - void print_byte_register(const prog_char *name, uint8_t reg, uint8_t qty = 1); - - /** - * Print the name and value of a 40-bit address register to stdout - * - * Optionally it can print some quantity of successive - * registers on the same line. This is useful for printing a group - * of related registers on one line. - * - * @param name Name of the register - * @param reg Which register. Use constants from nRF24L01.h - * @param qty How many successive registers to print - */ - void print_address_register(const prog_char *name, uint8_t reg, uint8_t qty = 1); - -protected: - void on_write_register(uint8_t reg, uint8_t value); - void observe_tx(uint8_t tx); - void on_ack(uint8_t ack_len); - void on_status(uint8_t status); - void on_write_payload(uint8_t data_len, uint8_t blank_len); - void on_read_payload(uint8_t data_len, uint8_t blank_len); - -public: - /** - * Print a giant block of debugging information to stdout - * - * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h - */ - void printDetails(void); - - RF24Debug(uint8_t _cepin, uint8_t _cspin, Print &out = Serial): RF24(_cepin, _cspin), _out(out) {} -}; - -#endif diff --git a/RF24_config.h b/RF24_config.h index b00ca5f6..32c1e901 100644 --- a/RF24_config.h +++ b/RF24_config.h @@ -43,6 +43,7 @@ extern HardwareSPI SPI; #include #else +// RPi maybe? typedef char const char; typedef uint16_t prog_uint16_t; #define PSTR(x) (x) diff --git a/examples/pingpair/pingpair.ino b/examples/pingpair/pingpair.ino index b1a75670..cbaeea8e 100644 --- a/examples/pingpair/pingpair.ino +++ b/examples/pingpair/pingpair.ino @@ -16,7 +16,7 @@ */ #include -#include +#include #include "printf.h" // diff --git a/examples/tinypingpair/tinypingpair.ino b/examples/tinypingpair/tinypingpair.ino new file mode 100644 index 00000000..1160230c --- /dev/null +++ b/examples/tinypingpair/tinypingpair.ino @@ -0,0 +1,233 @@ +/* + Copyright (C) 2011 J. Coliz + + 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. + */ + +/** + * Example RF Radio Ping Pair + * + * This is an example of how to use the RF24 class. Write this sketch to two different nodes, + * connect the role_pin to ground on one. The ping node sends the current time to the pong node, + * which responds by sending the value back. The ping node can then see how long the whole cycle + * took. + */ +#include +#include "nRF24L01.h" +#include "RF24.h" + +// +// Hardware configuration +// + +// Set up nRF24L01 radio on SPI bus plus pins 9 & 10 + +RF24Debug radio(2,3); + +// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver +// Leave open to be the 'ping' transmitter +const int role_pin = 7; + +// +// Topology +// + +// Radio pipe addresses for the 2 nodes to communicate. +const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; + +// +// Role management +// +// Set up role. This sketch uses the same software for all the nodes +// in this system. Doing so greatly simplifies testing. The hardware itself specifies +// which node it is. +// +// This is done through the role_pin +// + +// The various roles supported by this sketch +typedef enum { role_ping_out = 1, role_pong_back } role_e; + +// The debug-friendly names of those roles +const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"}; + +// The role of the current running sketch +role_e role; + +void setup(void) +{ + // + // Role + // + Serial.begin(9600); + Serial.println("hello world"); + + // set up the role pin + pinMode(role_pin, INPUT); + digitalWrite(role_pin,HIGH); + delay(20); // Just to get a solid reading on the role pin + + role = role_ping_out; + +/* + // read the address pin, establish our role + if ( ! digitalRead(role_pin) ) { + role = role_ping_out; + Serial.println("ping out"); + } else { + role = role_pong_back; + Serial.println("pong back"); + } +*/ + + // + // Print preamble + // + + + // + // Setup and configure rf radio + // + + radio.begin(); + + // optionally, increase the delay between retries & # of retries +// radio.setRetries(15,15); + + // optionally, reduce the payload size. seems to + // improve reliability +// radio.setPayloadSize(8); + + // + // Open pipes to other nodes for communication + // + + // This simple sketch opens two pipes for these two nodes to communicate + // back and forth. + // Open 'our' pipe for writing + // Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading) + + if ( role == role_ping_out ) + { + radio.openWritingPipe(pipes[0]); + radio.openReadingPipe(1,pipes[1]); + } + else + { + radio.openWritingPipe(pipes[1]); + radio.openReadingPipe(1,pipes[0]); + } + + // + // Start listening + // + radio.enableDynamicPayloads() ; + radio.setAutoAck( true ) ; + radio.powerUp() ; + + radio.startListening(); + + // + // Dump the configuration of the rf unit for debugging + // + + radio.printDetails(); +} + +void loop(void) +{ + // + // Ping out role. Repeatedly send the current time + // + + if (role == role_ping_out) + { + // First, stop listening so we can talk. + radio.stopListening(); + + // Take the time, and send it. This will block until complete + unsigned long time = millis(); + Serial.print("Sending "); + Serial.println(time); + bool ok = radio.write( &time, sizeof(unsigned long) ); + + if (ok) { + Serial.println("ok"); + } else { + Serial.println("failed"); + } + + // Now, continue listening + radio.startListening(); + + // Wait here until we get a response, or timeout (250ms) + unsigned long started_waiting_at = millis(); + bool timeout = false; + while ( ! radio.available() && ! timeout ) + if (millis() - started_waiting_at > 200 ) + timeout = true; + + // Describe the results + if ( timeout ) + { + Serial.println("Failed, response timed out"); + } + else + { + // Grab the response, compare, and send to debugging spew + unsigned long got_time; + radio.read( &got_time, sizeof(unsigned long) ); + + // Spew it + Serial.print("Got response "); + Serial.print(got_time); + Serial.print(", round-trip delay: "); + Serial.println(millis() - got_time); + } + + // Try again 1s later + delay(1000); + } + + // + // Pong back role. Receive each packet, dump it out, and send it back + // + + if ( role == role_pong_back ) + { + // if there is data ready + + if ( radio.available() ) + { + // Dump the payloads until we've gotten everything + unsigned long got_time; + bool done = false; + while (!done) + { + // Fetch the payload, and see if this was the last one. + done = radio.read( &got_time, sizeof(unsigned long) ); + + // Spew it + Serial.print("Got payload "); + Serial.println(got_time); + + // Delay just a little bit to let the other unit + // make the transition to receiver + delay(20); + } + + // First, stop listening so we can talk + radio.stopListening(); + + // Send the final one back. + radio.write( &got_time, sizeof(unsigned long) ); + Serial.println("Sent response"); + + // Now, resume listening so we catch the next packets. + radio.startListening(); + } + } +} +// vim:cin:ai:sts=2 sw=2 ft=cpp From 8b7da7f67b9c7a403462d7ddc118ac0113d76b50 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 1 Aug 2014 11:39:30 +0100 Subject: [PATCH 23/26] update for fraunchpad --- examples/pingpair/pingpair.ino | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/examples/pingpair/pingpair.ino b/examples/pingpair/pingpair.ino index cbaeea8e..4f25dd33 100644 --- a/examples/pingpair/pingpair.ino +++ b/examples/pingpair/pingpair.ino @@ -24,9 +24,19 @@ // #if defined(ENERGIA) +#if defined(__MSP430FR5739__) +# define CE P1_2 +# define CS P1_3 +# define ROLE P2_5 +#elif defined(__MSP430G2553__) # define CE P2_1 # define CS P2_0 # define ROLE P2_2 +//#elif defined(__LM4F120H5QR__) +//# define CE PA_6 +//# define CS PB_5 +//# define ROLE PA_5 +#endif # define BAUD 9600 #else # define CE 9 @@ -35,7 +45,7 @@ # define BAUD 57600 #endif -RF24Debug radio(CE, CS); +RF24 radio(CE, CS); // sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver // Leave open to be the 'ping' transmitter From 2835a819efd9b0b690779e46eecf9bb9b182236d Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 25 Mar 2015 10:19:27 +0000 Subject: [PATCH 24/26] update for new avr toolchain --- RF24.h | 6 +++--- RF24Debug.cpp | 6 +++--- RF24_config.h | 1 - 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/RF24.h b/RF24.h index bf60326d..a67f3c78 100644 --- a/RF24.h +++ b/RF24.h @@ -662,7 +662,7 @@ class RF24Debug: public RF24 private: Print &_out; - void print_name(const prog_char *name); + void print_name(const char *name); void print_hex_byte(uint8_t b); @@ -686,7 +686,7 @@ class RF24Debug: public RF24 * @param reg Which register. Use constants from nRF24L01.h * @param qty How many successive registers to print */ - void print_byte_register(const prog_char *name, uint8_t reg, uint8_t qty = 1); + void print_byte_register(const char *name, uint8_t reg, uint8_t qty = 1); /** * Print the name and value of a 40-bit address register to stdout @@ -699,7 +699,7 @@ class RF24Debug: public RF24 * @param reg Which register. Use constants from nRF24L01.h * @param qty How many successive registers to print */ - void print_address_register(const prog_char *name, uint8_t reg, uint8_t qty = 1); + void print_address_register(const char *name, uint8_t reg, uint8_t qty = 1); protected: void on_write_register(uint8_t reg, uint8_t value); diff --git a/RF24Debug.cpp b/RF24Debug.cpp index b52021d9..9bc9a00f 100644 --- a/RF24Debug.cpp +++ b/RF24Debug.cpp @@ -7,7 +7,7 @@ # define FLASH_PTR(x) ((const __FlashStringHelper *)x) #endif -void RF24Debug::print_name(const prog_char *name) +void RF24Debug::print_name(const char *name) { _out.print(FLASH_PTR(name)); if (strlen_P(name) < 8) @@ -23,7 +23,7 @@ void RF24Debug::print_hex_byte(uint8_t b) _out.print(b, HEX); } -void RF24Debug::print_byte_register(const prog_char *name, uint8_t reg, uint8_t qty) +void RF24Debug::print_byte_register(const char *name, uint8_t reg, uint8_t qty) { print_name(name); while (qty--) @@ -31,7 +31,7 @@ void RF24Debug::print_byte_register(const prog_char *name, uint8_t reg, uint8_t _out.println(); } -void RF24Debug::print_address_register(const prog_char *name, uint8_t reg, uint8_t qty) +void RF24Debug::print_address_register(const char *name, uint8_t reg, uint8_t qty) { print_name(name); diff --git a/RF24_config.h b/RF24_config.h index 64fe9bf0..d997fd88 100644 --- a/RF24_config.h +++ b/RF24_config.h @@ -36,7 +36,6 @@ extern HardwareSPI SPI; #define _BV(x) (1 << (x)) #define PROGMEM #define PSTR(s) (s) -#define prog_char char #define __FlashStringHelper char #elif defined(ARDUINO) From 5a49ec8993713f7f521cbce488e7cbd10ca41e29 Mon Sep 17 00:00:00 2001 From: Prasad Pandit Date: Thu, 16 Jul 2015 15:03:29 +0530 Subject: [PATCH 25/26] A simple project from Original RF24 library to just check transmit and receive of data. Tested and works with MSP430G2553 and Arduino Mega 2560, with nrf24l01+ module --- examples/GettingStarted/GettingStarted.pde | 227 +++++++++++++++++++++ examples/GettingStarted/Jamfile | 210 +++++++++++++++++++ examples/GettingStarted/printf.h | 49 +++++ 3 files changed, 486 insertions(+) create mode 100644 examples/GettingStarted/GettingStarted.pde create mode 100644 examples/GettingStarted/Jamfile create mode 100644 examples/GettingStarted/printf.h diff --git a/examples/GettingStarted/GettingStarted.pde b/examples/GettingStarted/GettingStarted.pde new file mode 100644 index 00000000..bf1851ac --- /dev/null +++ b/examples/GettingStarted/GettingStarted.pde @@ -0,0 +1,227 @@ +/* + Copyright (C) 2011 J. Coliz + + 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. + */ + +/** + * Example for Getting Started with nRF24L01+ radios. + * + * This is an example of how to use the RF24 class. Write this sketch to two + * different nodes. Put one of the nodes into 'transmit' mode by connecting + * with the serial monitor and sending a 'T'. The ping node sends the current + * time to the pong node, which responds by sending the value back. The ping + * node can then see how long the whole cycle took. + */ + +#include +#include "nRF24L01.h" +#include "RF24.h" +#include "printf.h" + +// +// Hardware configuration +// + +// Set up nRF24L01 radio on SPI bus plus pins 9 & 10 + +RF24 radio(9,10); + +// +// Topology +// + +// Radio pipe addresses for the 2 nodes to communicate. +const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; + +// +// Role management +// +// Set up role. This sketch uses the same software for all the nodes +// in this system. Doing so greatly simplifies testing. +// + +// The various roles supported by this sketch +typedef enum { role_ping_out = 1, role_pong_back } role_e; + +// The debug-friendly names of those roles +const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"}; + +// The role of the current running sketch +role_e role = role_pong_back; + +void setup(void) +{ + // + // Print preamble + // + + Serial.begin(57600); + printf_begin(); + printf("\n\rRF24/examples/GettingStarted/\n\r"); + printf("ROLE: %s\n\r",role_friendly_name[role]); + printf("*** PRESS 'T' to begin transmitting to the other node\n\r"); + + // + // Setup and configure rf radio + // + + radio.begin(); + + // optionally, increase the delay between retries & # of retries + radio.setRetries(15,15); + + // optionally, reduce the payload size. seems to + // improve reliability + //radio.setPayloadSize(8); + + // + // Open pipes to other nodes for communication + // + + // This simple sketch opens two pipes for these two nodes to communicate + // back and forth. + // Open 'our' pipe for writing + // Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading) + + //if ( role == role_ping_out ) + { + //radio.openWritingPipe(pipes[0]); + radio.openReadingPipe(1,pipes[1]); + } + //else + { + //radio.openWritingPipe(pipes[1]); + //radio.openReadingPipe(1,pipes[0]); + } + + // + // Start listening + // + + radio.startListening(); + + // + // Dump the configuration of the rf unit for debugging + // + + radio.printDetails(); +} + +void loop(void) +{ + // + // Ping out role. Repeatedly send the current time + // + + if (role == role_ping_out) + { + // First, stop listening so we can talk. + radio.stopListening(); + + // Take the time, and send it. This will block until complete + unsigned long time = millis(); + printf("Now sending %lu...",time); + bool ok = radio.write( &time, sizeof(unsigned long) ); + + if (ok) + printf("ok..."); + else + printf("failed.\n\r"); + + // Now, continue listening + radio.startListening(); + + // Wait here until we get a response, or timeout (250ms) + unsigned long started_waiting_at = millis(); + bool timeout = false; + while ( ! radio.available() && ! timeout ) + if (millis() - started_waiting_at > 200 ) + timeout = true; + + // Describe the results + if ( timeout ) + { + printf("Failed, response timed out.\n\r"); + } + else + { + // Grab the response, compare, and send to debugging spew + unsigned long got_time; + radio.read( &got_time, sizeof(unsigned long) ); + + // Spew it + printf("Got response %lu, round-trip delay: %lu\n\r",got_time,millis()-got_time); + } + + // Try again 1s later + delay(1000); + } + + // + // Pong back role. Receive each packet, dump it out, and send it back + // + + if ( role == role_pong_back ) + { + // if there is data ready + if ( radio.available() ) + { + // Dump the payloads until we've gotten everything + unsigned long got_time; + bool done = false; + while (!done) + { + // Fetch the payload, and see if this was the last one. + done = radio.read( &got_time, sizeof(unsigned long) ); + + // Spew it + printf("Got payload %lu...",got_time); + + // Delay just a little bit to let the other unit + // make the transition to receiver + delay(20); + } + + // First, stop listening so we can talk + radio.stopListening(); + + // Send the final one back. + radio.write( &got_time, sizeof(unsigned long) ); + printf("Sent response.\n\r"); + + // Now, resume listening so we catch the next packets. + radio.startListening(); + } + } + + // + // Change roles + // + + if ( Serial.available() ) + { + char c = toupper(Serial.read()); + if ( c == 'T' && role == role_pong_back ) + { + printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r"); + + // Become the primary transmitter (ping out) + role = role_ping_out; + radio.openWritingPipe(pipes[0]); + radio.openReadingPipe(1,pipes[1]); + } + else if ( c == 'R' && role == role_ping_out ) + { + printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r"); + + // Become the primary receiver (pong back) + role = role_pong_back; + radio.openWritingPipe(pipes[1]); + radio.openReadingPipe(1,pipes[0]); + } + } +} +// vim:cin:ai:sts=2 sw=2 ft=cpp diff --git a/examples/GettingStarted/Jamfile b/examples/GettingStarted/Jamfile new file mode 100644 index 00000000..9a5f2c47 --- /dev/null +++ b/examples/GettingStarted/Jamfile @@ -0,0 +1,210 @@ +# (1) Project Information + +PROJECT_LIBS = SPI RF24 ; + +# (2) Board Information + +UPLOAD_PROTOCOL ?= arduino ; +UPLOAD_SPEED ?= 57600 ; +MCU ?= atmega328p ; +F_CPU ?= 16000000 ; +CORE ?= arduino ; +VARIANT ?= standard ; +ARDUINO_VERSION ?= 100 ; + +# (3) USB Ports + +PORTS = p4 p6 p9 u0 u1 u2 ; +PORT_p6 = /dev/tty.usbserial-A600eHIs ; +PORT_p4 = /dev/tty.usbserial-A40081RP ; +PORT_p9 = /dev/tty.usbserial-A9007LmI ; +PORT_u0 = /dev/ttyUSB0 ; +PORT_u1 = /dev/ttyUSB1 ; +PORT_u2 = /dev/ttyUSB2 ; + +# (4) Location of AVR tools +# +# This configuration assumes using avr-tools that were obtained separate from the Arduino +# distribution. + +if $(OS) = MACOSX +{ + AVR_BIN = /usr/local/avrtools/bin ; + AVR_ETC = /usr/local/avrtools/etc ; + AVR_INCLUDE = /usr/local/avrtools/include ; +} +else +{ + AVR_BIN ?= /usr/bin ; + AVR_INCLUDE ?= /usr/lib/avr/include ; + AVR_ETC = /etc ; +} + +# (5) Directories where Arduino core and libraries are located + +ARDUINO_DIR ?= /opt/Arduino ; +ARDUINO_CORE = $(ARDUINO_DIR)/hardware/arduino/cores/$(CORE) $(ARDUINO_DIR)/hardware/arduino/variants/$(VARIANT) ; +ARDUINO_LIB = $(ARDUINO_DIR)/libraries ; +SKETCH_LIB = $(HOME)/Source/Arduino/libraries ; + +# +# -------------------------------------------------- +# Below this line usually never needs to be modified +# + +# Tool locations + +CC = $(AVR_BIN)/avr-gcc ; +C++ = $(AVR_BIN)/avr-g++ ; +LINK = $(AVR_BIN)/avr-gcc ; +OBJCOPY = $(AVR_BIN)/avr-objcopy ; +AVRDUDE = $(AVR_BIN)/avrdude ; + +# Flags + +DEFINES += F_CPU=$(F_CPU)L ARDUINO=$(ARDUINO_VERSION) VERSION_H ; +OPTIM = -Os ; +CCFLAGS = -Wall -Wextra -mmcu=$(MCU) -ffunction-sections -fdata-sections ; +C++FLAGS = $(CCFLAGS) -fno-exceptions -fno-strict-aliasing ; +LINKFLAGS = $(OPTIM) -lm -Wl,--gc-sections -mmcu=$(MCU) ; +AVRDUDEFLAGS = -V -F -D -C $(AVR_ETC)/avrdude.conf -p $(MCU) -c $(UPLOAD_PROTOCOL) -b $(UPLOAD_SPEED) ; + +# Search everywhere for headers + +HDRS = $(PWD) $(AVR_INCLUDE) $(ARDUINO_CORE) $(ARDUINO_LIB)/$(PROJECT_LIBS) $(ARDUINO_LIB)/$(PROJECT_LIBS)/utility $(SKETCH_LIB)/$(PROJECT_LIBS) ; + +# Output locations + +LOCATE_TARGET = $(F_CPU) ; +LOCATE_SOURCE = $(F_CPU) ; + +# +# Custom rules +# + +rule GitVersion +{ + Always $(<) ; + Depends all : $(<) ; +} + +actions GitVersion +{ + echo "const char program_version[] = \"\\" > $(<) + git log -1 --pretty=format:%h >> $(<) + echo "\";" >> $(<) +} + +GitVersion version.h ; + +rule Pde +{ + Depends $(<) : $(>) ; + MakeLocate $(<) : $(LOCATE_SOURCE) ; + Clean clean : $(<) ; +} + +if ( $(ARDUINO_VERSION) < 100 ) +{ + ARDUINO_H = WProgram.h ; +} +else +{ + ARDUINO_H = Arduino.h ; +} + +actions Pde +{ + echo "#include <$(ARDUINO_H)>" > $(<) + echo "#line 1 \"$(>)\"" >> $(<) + cat $(>) >> $(<) +} + +rule C++Pde +{ + local _CPP = $(>:B).cpp ; + Pde $(_CPP) : $(>) ; + C++ $(<) : $(_CPP) ; +} + +rule UserObject +{ + switch $(>:S) + { + case .ino : C++Pde $(<) : $(>) ; + case .pde : C++Pde $(<) : $(>) ; + } +} + +rule Objects +{ + local _i ; + + for _i in [ FGristFiles $(<) ] + { + local _b = $(_i:B)$(SUFOBJ) ; + local _o = $(_b:G=$(SOURCE_GRIST:E)) ; + Object $(_o) : $(_i) ; + Depends obj : $(_o) ; + } +} + +rule Main +{ + MainFromObjects $(<) : $(>:B)$(SUFOBJ) ; + Objects $(>) ; +} + +rule Hex +{ + Depends $(<) : $(>) ; + MakeLocate $(<) : $(LOCATE_TARGET) ; + Depends hex : $(<) ; + Clean clean : $(<) ; +} + +actions Hex +{ + $(OBJCOPY) -O ihex -R .eeprom $(>) $(<) +} + +rule Upload +{ + Depends $(1) : $(2) ; + Depends $(2) : $(3) ; + NotFile $(1) ; + Always $(1) ; + Always $(2) ; + UploadAction $(2) : $(3) ; +} + +actions UploadAction +{ + $(AVRDUDE) $(AVRDUDEFLAGS) -P $(<) $(AVRDUDE_WRITE_FLASH) -U flash:w:$(>):i +} + +# +# Targets +# + +# Grab everything from the core directory +CORE_MODULES = [ GLOB $(ARDUINO_CORE) : *.c *.cpp ] ; + +# Grab everything from libraries. To avoid this "grab everything" behaviour, you +# can specify specific modules to pick up in PROJECT_MODULES +LIB_MODULES = [ GLOB $(ARDUINO_LIB)/$(PROJECT_LIBS) $(ARDUINO_LIB)/$(PROJECT_LIBS)/utility $(SKETCH_LIB)/$(PROJECT_LIBS) : *.cpp *.c ] ; + +# Grab everything from the current dir +PROJECT_MODULES += [ GLOB $(PWD) : *.c *.cpp *.pde *.ino ] ; + +# Main output executable +MAIN = $(PWD:B).elf ; + +Main $(MAIN) : $(CORE_MODULES) $(LIB_MODULES) $(PROJECT_MODULES) ; +Hex $(MAIN:B).hex : $(MAIN) ; + +# Upload targets +for _p in $(PORTS) +{ + Upload $(_p) : $(PORT_$(_p)) : $(MAIN:B).hex ; +} diff --git a/examples/GettingStarted/printf.h b/examples/GettingStarted/printf.h new file mode 100644 index 00000000..6336f855 --- /dev/null +++ b/examples/GettingStarted/printf.h @@ -0,0 +1,49 @@ +/* + Copyright (C) 2011 James Coliz, Jr. + + 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. + */ + +/** + * @file printf.h + * + * Setup necessary to direct stdout to the Arduino Serial library, which + * enables 'printf' + */ + +#ifndef __PRINTF_H__ +#define __PRINTF_H__ + +#include + +#ifdef ENERGIA +#undef putchar +extern "C" { + int putchar(int c) + { + Serial.write((uint8_t)c); + return c; + } +} + +void printf_begin(void) +{ +} + +#else +int serial_putc( char c, FILE * ) +{ + Serial.write( c ); + + return c; +} + +void printf_begin(void) +{ + fdevopen( &serial_putc, 0 ); +} +#endif + +#endif // __PRINTF_H__ From 10156104352b6daf487a6353d1ff11752afb89d0 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 31 Jan 2020 14:23:03 +0000 Subject: [PATCH 26/26] changes for esp8266 --- RF24.cpp | 10 +++++----- RF24Debug.cpp | 11 +++++++++++ nRF24L01.h | 2 +- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/RF24.cpp b/RF24.cpp index a2ff46de..6d1e224d 100644 --- a/RF24.cpp +++ b/RF24.cpp @@ -272,7 +272,7 @@ void RF24::begin(void) // 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) ); + write_register(STATUS_,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); // Set up default configuration. Callers can always change it later. // This channel should be universally safe and not bleed over into adjacent @@ -289,7 +289,7 @@ void RF24::begin(void) 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) ); + write_register(STATUS_, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); // Restore the pipe0 adddress, if exists if (pipe0_reading_address) @@ -444,12 +444,12 @@ bool RF24::available(uint8_t* pipe_num) // ??? Should this REALLY be cleared now? Or wait until we // actually READ the payload? - write_register(STATUS,_BV(RX_DR) ); + write_register(STATUS_,_BV(RX_DR) ); // Handle ack payload receipt if ( status & _BV(TX_DS) ) { - write_register(STATUS,_BV(TX_DS)); + write_register(STATUS_,_BV(TX_DS)); } } @@ -473,7 +473,7 @@ void RF24::whatHappened(bool& tx_ok,bool& tx_fail,bool& rx_ready) { // Read the status & reset the status in one easy call // Or is that such a good idea? - uint8_t status = write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); + uint8_t status = write_register(STATUS_,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); on_status(status); diff --git a/RF24Debug.cpp b/RF24Debug.cpp index 9bc9a00f..8ff91667 100644 --- a/RF24Debug.cpp +++ b/RF24Debug.cpp @@ -117,6 +117,16 @@ void RF24Debug::printDetails(void) print_byte_register(PSTR("CONFIG"),CONFIG); print_byte_register(PSTR("DYNPD/FEATURE"),DYNPD,2); +#if defined(ESP8266) + _out.print(F("Data Rate\t = ")); + _out.println(FLASH_PTR(pgm_read_dword(&rf24_datarate_e_str_P[getDataRate()]))); + _out.print(F("Model\t\t = ")); + _out.println(FLASH_PTR(pgm_read_dword(&rf24_model_e_str_P[isPVariant()]))); + _out.print(F("CRC Length\t = ")); + _out.println(FLASH_PTR(pgm_read_dword(&rf24_crclength_e_str_P[getCRCLength()]))); + _out.print(F("PA Power\t = ")); + _out.println(FLASH_PTR(pgm_read_dword(&rf24_pa_dbm_e_str_P[getPALevel()]))); +#else _out.print(F("Data Rate\t = ")); _out.println(FLASH_PTR(pgm_read_word(&rf24_datarate_e_str_P[getDataRate()]))); _out.print(F("Model\t\t = ")); @@ -125,6 +135,7 @@ void RF24Debug::printDetails(void) _out.println(FLASH_PTR(pgm_read_word(&rf24_crclength_e_str_P[getCRCLength()]))); _out.print(F("PA Power\t = ")); _out.println(FLASH_PTR(pgm_read_word(&rf24_pa_dbm_e_str_P[getPALevel()]))); +#endif } void RF24Debug::on_write_register(uint8_t reg, uint8_t value) diff --git a/nRF24L01.h b/nRF24L01.h index 9943c3af..9247fa91 100644 --- a/nRF24L01.h +++ b/nRF24L01.h @@ -31,7 +31,7 @@ #define SETUP_RETR 0x04 #define RF_CH 0x05 #define RF_SETUP 0x06 -#define STATUS 0x07 +#define STATUS_ 0x07 #define OBSERVE_TX 0x08 #define CD 0x09 #define RX_ADDR_P0 0x0A