Reduce RAM footprint by moving static const data to progmem, and refactoring out switch statements.

This commit is contained in:
maniacbug 2012-01-15 22:05:44 -08:00
parent cb6613d62f
commit eb3b2d800a
1 changed files with 103 additions and 80 deletions

183
RF24.cpp
View File

@ -273,6 +273,39 @@ 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 = "LA_MED";
static const char rf24_pa_dbm_e_str_3[] PROGMEM = "PA_HIGH";
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) void RF24::printDetails(void)
{ {
print_status(get_status()); print_status(get_status());
@ -289,15 +322,10 @@ void RF24::printDetails(void)
print_byte_register(PSTR("CONFIG"),CONFIG); print_byte_register(PSTR("CONFIG"),CONFIG);
print_byte_register(PSTR("DYNPD/FEATURE"),DYNPD,2); print_byte_register(PSTR("DYNPD/FEATURE"),DYNPD,2);
const char * rf24_datarate_e_str[] = { "1MBPS", "2MBPS", "250KBPS" }; printf_P(PSTR("Data Rate\t = %S\r\n"),pgm_read_word(&rf24_datarate_e_str_P[getDataRate()]));
const char * rf24_model_e_str[] = { "nRF24L01", "nRF24L01+" } ; printf_P(PSTR("Model\t\t = %S\r\n"),pgm_read_word(&rf24_model_e_str_P[isPVariant()]));
const char * rf24_crclength_e_str[] = { "Disabled", "8 bits", "16 bits" } ; printf_P(PSTR("CRC Length\t = %S\r\n"),pgm_read_word(&rf24_crclength_e_str_P[getCRCLength()]));
const char * rf24_pa_dbm_e_str[] = { "PA_MIN", "PA_LOW", "LA_MED", "PA_HIGH"} ; printf_P(PSTR("PA Power\t = %S\r\n"),pgm_read_word(&rf24_pa_dbm_e_str_P[getPALevel()]));
printf_P(PSTR("Data Rate\t = %s\r\n"),rf24_datarate_e_str[getDataRate()]);
printf_P(PSTR("Model\t\t = %s\r\n"),rf24_model_e_str[isPVariant()]);
printf_P(PSTR("CRC Length\t = %s\r\n"),rf24_crclength_e_str[getCRCLength()]);
printf_P(PSTR("PA Power\t = %s\r\n"),rf24_pa_dbm_e_str[getPALevel()]);
} }
/****************************************************************************/ /****************************************************************************/
@ -587,21 +615,21 @@ void RF24::openWritingPipe(uint64_t value)
/****************************************************************************/ /****************************************************************************/
static const uint8_t child_pipe[] PROGMEM =
{
RX_ADDR_P0, RX_ADDR_P1, RX_ADDR_P2, RX_ADDR_P3, RX_ADDR_P4, RX_ADDR_P5
};
static const uint8_t child_payload_size[] PROGMEM =
{
RX_PW_P0, RX_PW_P1, RX_PW_P2, RX_PW_P3, RX_PW_P4, RX_PW_P5
};
static const uint8_t child_pipe_enable[] PROGMEM =
{
ERX_P0, ERX_P1, ERX_P2, ERX_P3, ERX_P4, ERX_P5
};
void RF24::openReadingPipe(uint8_t child, uint64_t address) void RF24::openReadingPipe(uint8_t child, uint64_t address)
{ {
const uint8_t child_pipe[] =
{
RX_ADDR_P0, RX_ADDR_P1, RX_ADDR_P2, RX_ADDR_P3, RX_ADDR_P4, RX_ADDR_P5
};
const uint8_t child_payload_size[] =
{
RX_PW_P0, RX_PW_P1, RX_PW_P2, RX_PW_P3, RX_PW_P4, RX_PW_P5
};
const uint8_t child_pipe_enable[] =
{
ERX_P0, ERX_P1, ERX_P2, ERX_P3, ERX_P4, ERX_P5
};
// If this is pipe 0, cache the address. This is needed because // If this is pipe 0, cache the address. This is needed because
// openWritingPipe() will overwrite the pipe 0 address, so // openWritingPipe() will overwrite the pipe 0 address, so
// startListening() will have to restore it. // startListening() will have to restore it.
@ -612,11 +640,11 @@ void RF24::openReadingPipe(uint8_t child, uint64_t address)
{ {
// For pipes 2-5, only write the LSB // For pipes 2-5, only write the LSB
if ( child < 2 ) if ( child < 2 )
write_register(child_pipe[child], reinterpret_cast<const uint8_t*>(&address), 5); write_register(pgm_read_byte(&child_pipe[child]), reinterpret_cast<const uint8_t*>(&address), 5);
else else
write_register(child_pipe[child], reinterpret_cast<const uint8_t*>(&address), 1); write_register(pgm_read_byte(&child_pipe[child]), reinterpret_cast<const uint8_t*>(&address), 1);
write_register(child_payload_size[child],payload_size); write_register(pgm_read_byte(&child_payload_size[child]),payload_size);
// Note it would be more efficient to set all of the bits for all open // Note it would be more efficient to set all of the bits for all open
// pipes at once. However, I thought it would make the calling code // pipes at once. However, I thought it would make the calling code
@ -770,27 +798,27 @@ void RF24::setPALevel(rf24_pa_dbm_e level)
uint8_t setup = read_register(RF_SETUP) ; uint8_t setup = read_register(RF_SETUP) ;
setup &= ~(_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ; setup &= ~(_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ;
switch( level ) // switch uses RAM (evil!)
if ( level == RF24_PA_MAX )
{ {
case RF24_PA_MAX:
setup |= (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ; setup |= (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ;
break ; }
else if ( level == RF24_PA_HIGH )
case RF24_PA_HIGH: {
setup |= _BV(RF_PWR_HIGH) ; setup |= _BV(RF_PWR_HIGH) ;
break ; }
else if ( level == RF24_PA_LOW )
case RF24_PA_LOW: {
setup |= _BV(RF_PWR_LOW) ; setup |= _BV(RF_PWR_LOW);
break ; }
else if ( level == RF24_PA_MIN )
case RF24_PA_MIN: {
break ; // nothing
}
case RF24_PA_ERROR: else if ( level == RF24_PA_ERROR )
{
// On error, go to maximum PA // On error, go to maximum PA
setup |= (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ; setup |= (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ;
break ;
} }
write_register( RF_SETUP, setup ) ; write_register( RF_SETUP, setup ) ;
@ -803,23 +831,22 @@ rf24_pa_dbm_e RF24::getPALevel(void)
rf24_pa_dbm_e result = RF24_PA_ERROR ; rf24_pa_dbm_e result = RF24_PA_ERROR ;
uint8_t power = read_register(RF_SETUP) & (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ; uint8_t power = read_register(RF_SETUP) & (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ;
switch( power ) // switch uses RAM (evil!)
if ( power == (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) )
{ {
case (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)):
result = RF24_PA_MAX ; result = RF24_PA_MAX ;
break ; }
else if ( power == _BV(RF_PWR_HIGH) )
case _BV(RF_PWR_HIGH): {
result = RF24_PA_HIGH ; result = RF24_PA_HIGH ;
break ; }
else if ( power == _BV(RF_PWR_LOW) )
case _BV(RF_PWR_LOW): {
result = RF24_PA_LOW ; result = RF24_PA_LOW ;
break ; }
else
default: {
result = RF24_PA_MIN ; result = RF24_PA_MIN ;
break ;
} }
return result ; return result ;
@ -877,27 +904,25 @@ bool RF24::setDataRate(rf24_datarate_e speed)
rf24_datarate_e RF24::getDataRate( void ) rf24_datarate_e RF24::getDataRate( void )
{ {
rf24_datarate_e result ; rf24_datarate_e result ;
uint8_t setup = read_register(RF_SETUP) ; uint8_t dr = read_register(RF_SETUP) & (_BV(RF_DR_LOW) | _BV(RF_DR_HIGH));
// switch uses RAM (evil!)
// Order matters in our case below // Order matters in our case below
switch( setup & (_BV(RF_DR_LOW) | _BV(RF_DR_HIGH)) ) if ( dr == _BV(RF_DR_LOW) )
{ {
case _BV(RF_DR_LOW):
// '10' = 250KBPS // '10' = 250KBPS
result = RF24_250KBPS ; result = RF24_250KBPS ;
break ; }
else if ( dr == _BV(RF_DR_HIGH) )
case _BV(RF_DR_HIGH): {
// '01' = 2MBPS // '01' = 2MBPS
result = RF24_2MBPS ; result = RF24_2MBPS ;
break ; }
else
default: {
// '00' = 1MBPS // '00' = 1MBPS
result = RF24_1MBPS ; result = RF24_1MBPS ;
break ;
} }
return result ; return result ;
} }
@ -906,23 +931,21 @@ rf24_datarate_e RF24::getDataRate( void )
void RF24::setCRCLength(rf24_crclength_e length) void RF24::setCRCLength(rf24_crclength_e length)
{ {
uint8_t config = read_register(CONFIG) & ~( _BV(CRCO) | _BV(EN_CRC)) ; uint8_t config = read_register(CONFIG) & ~( _BV(CRCO) | _BV(EN_CRC)) ;
switch (length) // switch uses RAM (evil!)
if ( length == RF24_CRC_DISABLED )
{ {
case RF24_CRC_DISABLED: // Do nothing, we turned it off above.
break; }
else if ( length == RF24_CRC_8 )
case RF24_CRC_8: {
config |= _BV(EN_CRC); config |= _BV(EN_CRC);
break; }
else
case RF24_CRC_16: {
default: config |= _BV(EN_CRC);
config |= _BV(EN_CRC); config |= _BV( CRCO );
config |= _BV( CRCO );
break;
} }
write_register( CONFIG, config ) ; write_register( CONFIG, config ) ;
} }