Fix printDetails() & debugging for ESP8266

Switched from printf_P to Serial.print to prevent all kinds of nasty
PROGMEM troubles.
Distinguish between 32- and 16-bit architectures when reading ptrs from
flash.
Ditched #defines MINIMAL & SERIAL_DEBUG.
Debugging code is now only included when DEBUG is defined.
If your target (e.g. ATTiny) cannot handle the extra code, then don't
enable DEBUG.
#defining DEBUG will now also output a register-dump on calling begin()
of NRF24 driver to aid in (connection) problems.
This commit is contained in:
Yveaux
2015-10-03 16:48:02 +02:00
parent f11223c88c
commit afe6d62368
3 changed files with 116 additions and 113 deletions
+100 -90
View File
@@ -132,19 +132,19 @@ uint8_t RF24::write_register(uint8_t reg, uint8_t value)
{ {
uint8_t status; uint8_t status;
IF_SERIAL_DEBUG(printf_P(PSTR("write_register(%02x,%02x)\r\n"),reg,value)); #ifdef DEBUG
Serial.print(F("write_register(")); print_hex(reg, true); Serial.print(F(",")); print_hex(value, true); Serial.println(F(")"));
#endif
#if defined (__arm__) && !defined ( CORE_TEENSY ) #if defined (__arm__) && !defined ( CORE_TEENSY )
status = _SPI.transfer(csn_pin, W_REGISTER | ( REGISTER_MASK & reg ), SPI_CONTINUE); status = _SPI.transfer(csn_pin, W_REGISTER | ( REGISTER_MASK & reg ), SPI_CONTINUE);
_SPI.transfer(csn_pin,value); _SPI.transfer(csn_pin,value);
#else #else
csn(LOW); csn(LOW);
status = _SPI.transfer( W_REGISTER | ( REGISTER_MASK & reg ) ); status = _SPI.transfer( W_REGISTER | ( REGISTER_MASK & reg ) );
_SPI.transfer(value); _SPI.transfer(value);
csn(HIGH); csn(HIGH);
#endif
#endif
return status; return status;
} }
@@ -286,60 +286,67 @@ uint8_t RF24::get_status(void)
} }
/****************************************************************************/ /****************************************************************************/
#if !defined (MINIMAL) #ifdef DEBUG
void RF24::print_hex( uint8_t v, const bool prefix0x )
{
if (prefix0x)
Serial.print(F("0x"));
Serial.print(v >> 4, HEX);
Serial.print(v & 0x0F, HEX);
}
void RF24::print_status(uint8_t status) 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"), print_hex(status, true);
status, Serial.print(F(" RX_DR=")); Serial.print((status & _BV(RX_DR))?uint8_t(1):uint8_t(0));
(status & _BV(RX_DR))?1:0, Serial.print(F(" TX_DS=")); Serial.print((status & _BV(TX_DS))?uint8_t(1):uint8_t(0));
(status & _BV(TX_DS))?1:0, Serial.print(F(" MAX_RT=")); Serial.print((status & _BV(MAX_RT))?uint8_t(1):uint8_t(0));
(status & _BV(MAX_RT))?1:0, Serial.print(F(" RX_P_NO=")); Serial.print((status >> RX_P_NO) & uint8_t(B111));
((status >> RX_P_NO) & B111), Serial.print(F(" TX_FULL=")); Serial.println((status & _BV(TX_FULL))?uint8_t(1):uint8_t(0));
(status & _BV(TX_FULL))?1:0
);
} }
/****************************************************************************/ /****************************************************************************/
void RF24::print_observe_tx(uint8_t value) void RF24::print_observe_tx(uint8_t value)
{ {
printf_P(PSTR("OBSERVE_TX=%02x: POLS_CNT=%x ARC_CNT=%x\r\n"), print_hex(value, true);
value, Serial.print(F(": POLS_CNT=")); Serial.print((value >> PLOS_CNT) & uint8_t(B1111));
(value >> PLOS_CNT) & B1111, Serial.print(F(" ARC_CNT=")); Serial.println((value >> ARC_CNT) & uint8_t(B1111));
(value >> ARC_CNT) & B1111
);
} }
/****************************************************************************/ /****************************************************************************/
void RF24::print_byte_register(const char* name, uint8_t reg, uint8_t qty) void RF24::print_byte_register(uint8_t reg, uint8_t qty)
{ {
char extra_tab = strlen_P(name) < 8 ? '\t' : 0; bool prefix0x = true;
printf_P(PSTR(PRIPSTR"\t%c ="),name,extra_tab);
while (qty--) while (qty--)
printf_P(PSTR(" 0x%02x"),read_register(reg++)); {
printf_P(PSTR("\r\n")); print_hex(read_register(reg++), prefix0x);
Serial.print(F(" "));
prefix0x = false;
}
Serial.println(F(""));
} }
/****************************************************************************/ /****************************************************************************/
void RF24::print_address_register(uint8_t reg, uint8_t qty)
void RF24::print_address_register(const char* name, uint8_t reg, uint8_t qty)
{ {
char extra_tab = strlen_P(name) < 8 ? '\t' : 0; bool prefix0x = true;
printf_P(PSTR(PRIPSTR"\t%c ="),name,extra_tab);
while (qty--) while (qty--)
{ {
uint8_t buffer[addr_width]; uint8_t buffer[addr_width];
read_register(reg++,buffer,sizeof buffer); read_register(reg++,buffer,sizeof buffer);
printf_P(PSTR(" 0x"));
uint8_t* bufptr = buffer + sizeof buffer; uint8_t* bufptr = buffer + sizeof buffer;
while( --bufptr >= buffer ) while( --bufptr >= buffer )
printf_P(PSTR("%02x"),*bufptr); {
print_hex(read_register(*bufptr), prefix0x);
prefix0x = false;
}
Serial.print(F(" "));
} }
Serial.println(F(""));
printf_P(PSTR("\r\n"));
} }
#endif #endif
/****************************************************************************/ /****************************************************************************/
@@ -374,8 +381,7 @@ uint8_t RF24::getPayloadSize(void)
/****************************************************************************/ /****************************************************************************/
#if !defined (MINIMAL) #ifdef DEBUG
static const char rf24_datarate_e_str_0[] PROGMEM = "1MBPS"; 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_1[] PROGMEM = "2MBPS";
static const char rf24_datarate_e_str_2[] PROGMEM = "250KBPS"; static const char rf24_datarate_e_str_2[] PROGMEM = "250KBPS";
@@ -409,36 +415,36 @@ static const char * const rf24_pa_dbm_e_str_P[] PROGMEM = {
rf24_pa_dbm_e_str_3, rf24_pa_dbm_e_str_3,
}; };
void RF24::printDetails(void) #if (INTPTR_MAX == INT16_MAX)
{ // 16-bit architecture -> read word from flash and cast to ptr
print_status(get_status()); #define PGM_READ_PTR(adr) (reinterpret_cast<__FlashStringHelper*>(pgm_read_word(adr)))
#elif (INTPTR_MAX == INT32_MAX)
print_address_register(PSTR("RX_ADDR_P0-1"),RX_ADDR_P0,2); // 32-bit architecture -> read double-word from flash and cast to ptr
print_byte_register(PSTR("RX_ADDR_P2-5"),RX_ADDR_P2,4); #define PGM_READ_PTR(adr) (reinterpret_cast<__FlashStringHelper*>(pgm_read_dword(adr)))
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"),NRF_CONFIG);
print_byte_register(PSTR("DYNPD/FEATURE"),DYNPD,2);
#if defined(__arm__)
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()]));
#else #else
printf_P(PSTR("Data Rate\t = %S\r\n"),pgm_read_word(&rf24_datarate_e_str_P[getDataRate()])); #error Unsupported processor architecture!
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()]));
#endif #endif
} void RF24::printDetails(void)
{
Serial.print(F("STATUS\t\t")); print_status(get_status());
Serial.print(F("RX_ADDR_P0-1\t")); print_address_register(RX_ADDR_P0,2);
Serial.print(F("RX_ADDR_P2-5\t")); print_byte_register(RX_ADDR_P2,4);
Serial.print(F("TX_ADDR\t\t")); print_address_register(TX_ADDR);
Serial.print(F("RX_PW_P0-6\t")); print_byte_register(RX_PW_P0,6);
Serial.print(F("EN_AA\t\t")); print_byte_register(EN_AA);
Serial.print(F("EN_RXADDR\t")); print_byte_register(EN_RXADDR);
Serial.print(F("RF_CH\t\t")); print_byte_register(RF_CH);
Serial.print(F("RF_SETUP\t")); print_byte_register(RF_SETUP);
Serial.print(F("CONFIG\t\t")); print_byte_register(CONFIG);
Serial.print(F("DYNPD/FEATURE\t")); print_byte_register(DYNPD,2);
Serial.print(F("Data Rate\t")); Serial.println(PGM_READ_PTR(&rf24_datarate_e_str_P[getDataRate()]));
Serial.print(F("Model\t\t")); Serial.println(PGM_READ_PTR(&rf24_model_e_str_P[isPVariant()]));
Serial.print(F("CRC Length\t")); Serial.println(PGM_READ_PTR(&rf24_crclength_e_str_P[getCRCLength()]));
Serial.print(F("PA Power\t")); Serial.println(PGM_READ_PTR(&rf24_pa_dbm_e_str_P[getPALevel()]));
}
#endif #endif
/****************************************************************************/ /****************************************************************************/
@@ -515,6 +521,10 @@ void RF24::begin(void)
// PTX should use only 22uA of power // PTX should use only 22uA of power
write_register(NRF_CONFIG, ( read_register(NRF_CONFIG) ) & ~_BV(PRIM_RX) ); write_register(NRF_CONFIG, ( read_register(NRF_CONFIG) ) & ~_BV(PRIM_RX) );
#ifdef DEBUG
// Dump register values
printDetails();
#endif
} }
/****************************************************************************/ /****************************************************************************/
@@ -528,21 +538,20 @@ void RF24::startListening(void)
write_register(RF24_STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); write_register(RF24_STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
// Restore the pipe0 adddress, if exists // Restore the pipe0 adddress, if exists
if (pipe0_reading_address[0] > 0){ if (pipe0_reading_address[0] > 0) {
write_register(RX_ADDR_P0, pipe0_reading_address, addr_width); write_register(RX_ADDR_P0, pipe0_reading_address, addr_width);
}else{ } else {
closeReadingPipe(0); closeReadingPipe(0);
} }
// Flush buffers // Flush buffers
//flush_rx(); //flush_rx();
if(read_register(FEATURE) & _BV(EN_ACK_PAY)){ if(read_register(FEATURE) & _BV(EN_ACK_PAY)) {
flush_tx(); flush_tx();
} }
// Go! // Go!
ce(HIGH); ce(HIGH);
} }
/****************************************************************************/ /****************************************************************************/
@@ -566,13 +575,13 @@ static uint8_t get_child_pipe_mask(const uint8_t idx)
void RF24::stopListening(void) void RF24::stopListening(void)
{ {
ce(LOW); ce(LOW);
#if defined(__arm__) #if defined(__arm__)
delayMicroseconds(300); delayMicroseconds(300);
#endif #endif
delayMicroseconds(130); delayMicroseconds(130);
if(read_register(FEATURE) & _BV(EN_ACK_PAY)){ if(read_register(FEATURE) & _BV(EN_ACK_PAY)) {
flush_tx(); flush_tx();
} }
//flush_rx(); //flush_rx();
@@ -621,8 +630,10 @@ void RF24::powerUp(void)
/******************************************************************/ /******************************************************************/
#if defined (FAILURE_HANDLING) #if defined (FAILURE_HANDLING)
void RF24::errNotify(){ void RF24::errNotify(){
IF_SERIAL_DEBUG(printf_P(PSTR("HARDWARE FAIL\r\n"))); #ifdef DEBUG
failureDetected = 1; Serial.println(F("HARDWARE FAIL"));
#endif
failureDetected = 1;
} }
#endif #endif
/******************************************************************/ /******************************************************************/
@@ -1058,13 +1069,12 @@ void RF24::toggle_features(void)
void RF24::enableDynamicPayloads(void) void RF24::enableDynamicPayloads(void)
{ {
// Enable dynamic payload throughout the system // Enable dynamic payload throughout the system
toggle_features();
write_register(FEATURE,read_register(FEATURE) | _BV(EN_DPL) );
toggle_features(); #ifdef DEBUG
write_register(FEATURE,read_register(FEATURE) | _BV(EN_DPL) ); Serial.print(F("FEATURE=")); print_hex(read_register(FEATURE), true); Serial.println(F(""));
#endif
IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE)));
// Enable dynamic payload on all pipes // Enable dynamic payload on all pipes
// //
// Not sure the use case of only having dynamic payload on certain // Not sure the use case of only having dynamic payload on certain
@@ -1081,12 +1091,12 @@ void RF24::enableAckPayload(void)
// //
// enable ack payload and dynamic payload features // enable ack payload and dynamic payload features
// //
toggle_features();
write_register(FEATURE,read_register(FEATURE) | _BV(EN_ACK_PAY) | _BV(EN_DPL) );
toggle_features(); #ifdef DEBUG
write_register(FEATURE,read_register(FEATURE) | _BV(EN_ACK_PAY) | _BV(EN_DPL) ); Serial.print(F("FEATURE=")); print_hex(read_register(FEATURE), true); Serial.println(F(""));
#endif
IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE)));
// //
// Enable dynamic payload on pipes 0 & 1 // Enable dynamic payload on pipes 0 & 1
// //
@@ -1104,9 +1114,9 @@ void RF24::enableDynamicAck(void){
toggle_features(); toggle_features();
write_register(FEATURE,read_register(FEATURE) | _BV(EN_DYN_ACK) ); write_register(FEATURE,read_register(FEATURE) | _BV(EN_DYN_ACK) );
IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE))); #ifdef DEBUG
Serial.print(F("FEATURE=")); print_hex(read_register(FEATURE), true); Serial.println(F(""));
#endif
} }
/****************************************************************************/ /****************************************************************************/
+15 -7
View File
@@ -923,7 +923,7 @@ private:
*/ */
uint8_t get_status(void); uint8_t get_status(void);
#if !defined (MINIMAL) #ifdef DEBUG
/** /**
* Decode and print the given status to stdout * Decode and print the given status to stdout
* *
@@ -943,30 +943,38 @@ private:
void print_observe_tx(uint8_t value); void print_observe_tx(uint8_t value);
/** /**
* Print the name and value of an 8-bit register to stdout * Print the value of an 8-bit register to stdout
* *
* Optionally it can print some quantity of successive * Optionally it can print some quantity of successive
* registers on the same line. This is useful for printing a group * registers on the same line. This is useful for printing a group
* of related registers on one line. * of related registers on one line.
* *
* @param name Name of the register
* @param reg Which register. Use constants from nRF24L01.h * @param reg Which register. Use constants from nRF24L01.h
* @param qty How many successive registers to print * @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(uint8_t reg, uint8_t qty = 1);
/** /**
* Print the name and value of a 40-bit address register to stdout * Print the value of a 40-bit address register to stdout
* *
* Optionally it can print some quantity of successive * Optionally it can print some quantity of successive
* registers on the same line. This is useful for printing a group * registers on the same line. This is useful for printing a group
* of related registers on one line. * of related registers on one line.
* *
* @param name Name of the register
* @param reg Which register. Use constants from nRF24L01.h * @param reg Which register. Use constants from nRF24L01.h
* @param qty How many successive registers to print * @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(uint8_t reg, uint8_t qty = 1);
/**
* Print a value in hex to serial output.
*
* For values < 16 a leading 0 will be printed.
*
* @param v Value to print in hex.
*/
void print_hex( uint8_t v, const bool prefix0x = false );
#endif #endif
/** /**
* Turn on or off the special features of the chip * Turn on or off the special features of the chip
+1 -16
View File
@@ -23,8 +23,6 @@
/*** USER DEFINES: ***/ /*** USER DEFINES: ***/
//#define FAILURE_HANDLING //#define FAILURE_HANDLING
//#define SERIAL_DEBUG
#define MINIMAL
//#define SPI_UART // Requires library from https://github.com/TMRh20/Sketches/tree/master/SPI_UART //#define SPI_UART // Requires library from https://github.com/TMRh20/Sketches/tree/master/SPI_UART
//#define MY_SOFTSPI // Requires library from https://github.com/greiman/DigitalIO //#define MY_SOFTSPI // Requires library from https://github.com/greiman/DigitalIO
/**********************/ /**********************/
@@ -76,16 +74,7 @@
#define _SPI SPI #define _SPI SPI
#endif #endif
#ifdef SERIAL_DEBUG
#define IF_SERIAL_DEBUG(x) ({x;})
#else
#define IF_SERIAL_DEBUG(x)
#if defined(RF24_TINY)
#define printf_P(...)
#endif
#endif
// Avoid spurious warnings // Avoid spurious warnings
// Arduino DUE is arm and uses traditional PROGMEM constructs // Arduino DUE is arm and uses traditional PROGMEM constructs
#if 1 #if 1
@@ -101,7 +90,6 @@
// Arduino DUE is arm and does not include avr/pgmspace // Arduino DUE is arm and does not include avr/pgmspace
#if defined(__AVR__) #if defined(__AVR__)
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#define PRIPSTR "%S"
#else #else
#if defined(ESP8266) #if defined(ESP8266)
#include <pgmspace.h> #include <pgmspace.h>
@@ -121,9 +109,6 @@
#define PROGMEM #define PROGMEM
#define pgm_read_word(p) (*(p)) #define pgm_read_word(p) (*(p))
#endif #endif
#define PRIPSTR "%s"
#endif #endif