TMRh20 ported to MBED

Fork of TMRh20 by BME SmartLab

Committer:
gume
Date:
Fri Oct 06 20:20:33 2017 +0000
Revision:
6:15a3bbf90fe9
Parent:
5:836f5c6da243
Initial release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gume 0:163155b607df 1 /*
gume 0:163155b607df 2 Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
gume 0:163155b607df 3
gume 0:163155b607df 4 This program is free software; you can redistribute it and/or
gume 0:163155b607df 5 modify it under the terms of the GNU General Public License
gume 0:163155b607df 6 version 2 as published by the Free Software Foundation.
gume 0:163155b607df 7 */
gume 0:163155b607df 8
gume 0:163155b607df 9 #include "nRF24L01.h"
gume 0:163155b607df 10 #include "RF24_config.h"
gume 0:163155b607df 11 #include "RF24.h"
gume 0:163155b607df 12
gume 0:163155b607df 13 /****************************************************************************/
gume 0:163155b607df 14
gume 6:15a3bbf90fe9 15 void RF24::csn(bool mode)
gume 0:163155b607df 16 {
gume 0:163155b607df 17 csn_pin = mode;
gume 6:15a3bbf90fe9 18 wait_us(csDelay);
gume 0:163155b607df 19 }
gume 0:163155b607df 20
gume 0:163155b607df 21 /****************************************************************************/
gume 0:163155b607df 22
gume 6:15a3bbf90fe9 23 void RF24::ce(bool level)
gume 0:163155b607df 24 {
gume 6:15a3bbf90fe9 25 ce_pin = level;
gume 0:163155b607df 26 }
gume 6:15a3bbf90fe9 27
gume 0:163155b607df 28 /****************************************************************************/
gume 0:163155b607df 29
gume 6:15a3bbf90fe9 30 inline void RF24::beginTransaction() {
gume 6:15a3bbf90fe9 31 csn(LOW);
gume 6:15a3bbf90fe9 32 }
gume 3:13e43d3101a5 33
gume 6:15a3bbf90fe9 34 /****************************************************************************/
gume 6:15a3bbf90fe9 35
gume 6:15a3bbf90fe9 36 inline void RF24::endTransaction() {
gume 0:163155b607df 37 csn(HIGH);
gume 6:15a3bbf90fe9 38 }
gume 0:163155b607df 39
gume 0:163155b607df 40 /****************************************************************************/
gume 0:163155b607df 41
gume 0:163155b607df 42 uint8_t RF24::read_register(uint8_t reg, uint8_t* buf, uint8_t len)
gume 0:163155b607df 43 {
gume 6:15a3bbf90fe9 44 uint8_t status;
gume 0:163155b607df 45
gume 6:15a3bbf90fe9 46 beginTransaction();
gume 6:15a3bbf90fe9 47 status = spi->write( R_REGISTER | ( REGISTER_MASK & reg ) );
gume 6:15a3bbf90fe9 48 while ( len-- ){
gume 6:15a3bbf90fe9 49 *buf++ = spi->write(0xff);
gume 6:15a3bbf90fe9 50 }
gume 6:15a3bbf90fe9 51 endTransaction();
gume 0:163155b607df 52
gume 6:15a3bbf90fe9 53 return status;
gume 0:163155b607df 54 }
gume 0:163155b607df 55
gume 0:163155b607df 56 /****************************************************************************/
gume 0:163155b607df 57
gume 0:163155b607df 58 uint8_t RF24::read_register(uint8_t reg)
gume 0:163155b607df 59 {
gume 6:15a3bbf90fe9 60 uint8_t result;
gume 6:15a3bbf90fe9 61
gume 6:15a3bbf90fe9 62 beginTransaction();
gume 6:15a3bbf90fe9 63 spi->write( R_REGISTER | ( REGISTER_MASK & reg ) );
gume 6:15a3bbf90fe9 64 result = spi->write(0xff);
gume 6:15a3bbf90fe9 65 endTransaction();
gume 0:163155b607df 66
gume 6:15a3bbf90fe9 67 return result;
gume 0:163155b607df 68 }
gume 0:163155b607df 69
gume 0:163155b607df 70 /****************************************************************************/
gume 0:163155b607df 71
gume 0:163155b607df 72 uint8_t RF24::write_register(uint8_t reg, const uint8_t* buf, uint8_t len)
gume 0:163155b607df 73 {
gume 6:15a3bbf90fe9 74 uint8_t status;
gume 0:163155b607df 75
gume 6:15a3bbf90fe9 76 beginTransaction();
gume 6:15a3bbf90fe9 77 status = spi->write( W_REGISTER | ( REGISTER_MASK & reg ) );
gume 6:15a3bbf90fe9 78 while ( len-- )
gume 6:15a3bbf90fe9 79 spi->write(*buf++);
gume 6:15a3bbf90fe9 80 endTransaction();
gume 0:163155b607df 81
gume 6:15a3bbf90fe9 82 return status;
gume 0:163155b607df 83 }
gume 0:163155b607df 84
gume 0:163155b607df 85 /****************************************************************************/
gume 0:163155b607df 86
gume 0:163155b607df 87 uint8_t RF24::write_register(uint8_t reg, uint8_t value)
gume 0:163155b607df 88 {
gume 6:15a3bbf90fe9 89 uint8_t status;
gume 0:163155b607df 90
gume 6:15a3bbf90fe9 91 IF_SERIAL_DEBUG(printf_P(PSTR("write_register(%02x,%02x)\r\n"),reg,value));
gume 0:163155b607df 92
gume 6:15a3bbf90fe9 93 beginTransaction();
gume 6:15a3bbf90fe9 94 status = spi->write( W_REGISTER | ( REGISTER_MASK & reg ) );
gume 6:15a3bbf90fe9 95 spi->write(value);
gume 6:15a3bbf90fe9 96 endTransaction();
gume 0:163155b607df 97
gume 6:15a3bbf90fe9 98 return status;
gume 0:163155b607df 99 }
gume 0:163155b607df 100
gume 0:163155b607df 101 /****************************************************************************/
gume 0:163155b607df 102
gume 0:163155b607df 103 uint8_t RF24::write_payload(const void* buf, uint8_t data_len, const uint8_t writeType)
gume 0:163155b607df 104 {
gume 6:15a3bbf90fe9 105 uint8_t status;
gume 6:15a3bbf90fe9 106 const uint8_t* current = reinterpret_cast<const uint8_t*>(buf);
gume 0:163155b607df 107
gume 6:15a3bbf90fe9 108 data_len = rf24_min(data_len, payload_size);
gume 6:15a3bbf90fe9 109 uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len;
gume 6:15a3bbf90fe9 110
gume 6:15a3bbf90fe9 111 //printf("[Writing %u bytes %u blanks]",data_len,blank_len);
gume 6:15a3bbf90fe9 112 IF_SERIAL_DEBUG( printf("[Writing %u bytes %u blanks]\n",data_len,blank_len); );
gume 6:15a3bbf90fe9 113
gume 6:15a3bbf90fe9 114 beginTransaction();
gume 6:15a3bbf90fe9 115 status = spi->write( writeType );
gume 6:15a3bbf90fe9 116 while ( data_len-- ) {
gume 6:15a3bbf90fe9 117 spi->write(*current++);
gume 6:15a3bbf90fe9 118 }
gume 6:15a3bbf90fe9 119 while ( blank_len-- ) {
gume 6:15a3bbf90fe9 120 spi->write(0);
gume 6:15a3bbf90fe9 121 }
gume 6:15a3bbf90fe9 122 endTransaction();
gume 0:163155b607df 123
gume 6:15a3bbf90fe9 124 return status;
gume 0:163155b607df 125 }
gume 0:163155b607df 126
gume 0:163155b607df 127 /****************************************************************************/
gume 0:163155b607df 128
gume 0:163155b607df 129 uint8_t RF24::read_payload(void* buf, uint8_t data_len)
gume 0:163155b607df 130 {
gume 6:15a3bbf90fe9 131 uint8_t status;
gume 6:15a3bbf90fe9 132 uint8_t* current = reinterpret_cast<uint8_t*>(buf);
gume 0:163155b607df 133
gume 6:15a3bbf90fe9 134 if(data_len > payload_size) data_len = payload_size;
gume 6:15a3bbf90fe9 135 uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len;
gume 6:15a3bbf90fe9 136
gume 6:15a3bbf90fe9 137 //printf("[Reading %u bytes %u blanks]",data_len,blank_len);
gume 0:163155b607df 138
gume 6:15a3bbf90fe9 139 IF_SERIAL_DEBUG( printf("[Reading %u bytes %u blanks]\n",data_len,blank_len); );
gume 6:15a3bbf90fe9 140
gume 6:15a3bbf90fe9 141 beginTransaction();
gume 6:15a3bbf90fe9 142 status = spi->write( R_RX_PAYLOAD );
gume 6:15a3bbf90fe9 143 while ( data_len-- ) {
gume 6:15a3bbf90fe9 144 *current++ = spi->write(0xFF);
gume 6:15a3bbf90fe9 145 }
gume 6:15a3bbf90fe9 146 while ( blank_len-- ) {
gume 6:15a3bbf90fe9 147 spi->write(0xff);
gume 6:15a3bbf90fe9 148 }
gume 6:15a3bbf90fe9 149 endTransaction();
gume 0:163155b607df 150
gume 6:15a3bbf90fe9 151 return status;
gume 0:163155b607df 152 }
gume 0:163155b607df 153
gume 0:163155b607df 154 /****************************************************************************/
gume 0:163155b607df 155
gume 0:163155b607df 156 uint8_t RF24::flush_rx(void)
gume 0:163155b607df 157 {
gume 6:15a3bbf90fe9 158 return spiTrans( FLUSH_RX );
gume 0:163155b607df 159 }
gume 0:163155b607df 160
gume 0:163155b607df 161 /****************************************************************************/
gume 0:163155b607df 162
gume 0:163155b607df 163 uint8_t RF24::flush_tx(void)
gume 0:163155b607df 164 {
gume 6:15a3bbf90fe9 165 return spiTrans( FLUSH_TX );
gume 0:163155b607df 166 }
gume 0:163155b607df 167
gume 0:163155b607df 168 /****************************************************************************/
gume 0:163155b607df 169
gume 6:15a3bbf90fe9 170 uint8_t RF24::spiTrans(uint8_t cmd){
gume 0:163155b607df 171
gume 6:15a3bbf90fe9 172 uint8_t status;
gume 6:15a3bbf90fe9 173
gume 6:15a3bbf90fe9 174 beginTransaction();
gume 6:15a3bbf90fe9 175 status = spi->write( cmd );
gume 6:15a3bbf90fe9 176 endTransaction();
gume 6:15a3bbf90fe9 177
gume 6:15a3bbf90fe9 178 return status;
gume 0:163155b607df 179 }
gume 0:163155b607df 180
gume 0:163155b607df 181 /****************************************************************************/
gume 0:163155b607df 182
gume 0:163155b607df 183 uint8_t RF24::get_status(void)
gume 0:163155b607df 184 {
gume 6:15a3bbf90fe9 185 return spiTrans(NOP);
gume 0:163155b607df 186 }
gume 0:163155b607df 187
gume 0:163155b607df 188 /****************************************************************************/
gume 0:163155b607df 189 #if !defined (MINIMAL)
gume 0:163155b607df 190 void RF24::print_status(uint8_t status)
gume 0:163155b607df 191 {
gume 6:15a3bbf90fe9 192 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"),
gume 6:15a3bbf90fe9 193 status,
gume 6:15a3bbf90fe9 194 (status & _BV(RX_DR))?1:0,
gume 6:15a3bbf90fe9 195 (status & _BV(TX_DS))?1:0,
gume 6:15a3bbf90fe9 196 (status & _BV(MAX_RT))?1:0,
gume 6:15a3bbf90fe9 197 ((status >> RX_P_NO) & 0x07),
gume 6:15a3bbf90fe9 198 (status & _BV(TX_FULL))?1:0
gume 6:15a3bbf90fe9 199 );
gume 0:163155b607df 200 }
gume 0:163155b607df 201
gume 0:163155b607df 202 /****************************************************************************/
gume 0:163155b607df 203
gume 0:163155b607df 204 void RF24::print_observe_tx(uint8_t value)
gume 0:163155b607df 205 {
gume 6:15a3bbf90fe9 206 printf_P(PSTR("OBSERVE_TX=%02x: POLS_CNT=%x ARC_CNT=%x\r\n"),
gume 6:15a3bbf90fe9 207 value,
gume 6:15a3bbf90fe9 208 (value >> PLOS_CNT) & 0x0F,
gume 6:15a3bbf90fe9 209 (value >> ARC_CNT) & 0x0F
gume 6:15a3bbf90fe9 210 );
gume 0:163155b607df 211 }
gume 0:163155b607df 212
gume 0:163155b607df 213 /****************************************************************************/
gume 0:163155b607df 214
gume 0:163155b607df 215 void RF24::print_byte_register(const char* name, uint8_t reg, uint8_t qty)
gume 0:163155b607df 216 {
gume 6:15a3bbf90fe9 217 //char extra_tab = strlen_P(name) < 8 ? '\t' : 0;
gume 6:15a3bbf90fe9 218 //printf_P(PSTR(PRIPSTR"\t%c ="),name,extra_tab);
gume 6:15a3bbf90fe9 219 #if defined (RF24_LINUX)
gume 0:163155b607df 220 printf("%s\t =", name);
gume 6:15a3bbf90fe9 221 #else
gume 6:15a3bbf90fe9 222 printf_P(PSTR(PRIPSTR"\t ="),name);
gume 6:15a3bbf90fe9 223 #endif
gume 6:15a3bbf90fe9 224 while (qty--)
gume 6:15a3bbf90fe9 225 printf_P(PSTR(" 0x%02x"),read_register(reg++));
gume 6:15a3bbf90fe9 226 printf_P(PSTR("\r\n"));
gume 0:163155b607df 227 }
gume 0:163155b607df 228
gume 0:163155b607df 229 /****************************************************************************/
gume 0:163155b607df 230
gume 0:163155b607df 231 void RF24::print_address_register(const char* name, uint8_t reg, uint8_t qty)
gume 0:163155b607df 232 {
gume 0:163155b607df 233
gume 6:15a3bbf90fe9 234 printf_P(PSTR(PRIPSTR"\t ="),name);
gume 0:163155b607df 235
gume 6:15a3bbf90fe9 236 while (qty--)
gume 6:15a3bbf90fe9 237 {
gume 6:15a3bbf90fe9 238 uint8_t buffer[addr_width];
gume 6:15a3bbf90fe9 239 read_register(reg++,buffer,sizeof buffer);
gume 0:163155b607df 240
gume 6:15a3bbf90fe9 241 printf_P(PSTR(" 0x"));
gume 6:15a3bbf90fe9 242 uint8_t* bufptr = buffer + sizeof buffer;
gume 6:15a3bbf90fe9 243 while( --bufptr >= buffer )
gume 6:15a3bbf90fe9 244 printf_P(PSTR("%02x"),*bufptr);
gume 6:15a3bbf90fe9 245 }
gume 0:163155b607df 246
gume 6:15a3bbf90fe9 247 printf_P(PSTR("\r\n"));
gume 0:163155b607df 248 }
gume 6:15a3bbf90fe9 249
gume 6:15a3bbf90fe9 250 #endif
gume 0:163155b607df 251
gume 0:163155b607df 252 /****************************************************************************/
gume 0:163155b607df 253
gume 6:15a3bbf90fe9 254 RF24::RF24(SPI *spi, PinName _cepin, PinName _cspin):
gume 6:15a3bbf90fe9 255 ce_pin(_cepin),csn_pin(_cspin),p_variant(false),
gume 6:15a3bbf90fe9 256 payload_size(32), dynamic_payloads_enabled(false),addr_width(5),csDelay(5)//,pipe0_reading_address(0)
gume 0:163155b607df 257 {
gume 6:15a3bbf90fe9 258 this->spi = spi;
gume 6:15a3bbf90fe9 259 pipe0_reading_address[0]=0;
gume 0:163155b607df 260 }
gume 0:163155b607df 261
gume 0:163155b607df 262 /****************************************************************************/
gume 0:163155b607df 263
gume 0:163155b607df 264 void RF24::setChannel(uint8_t channel)
gume 0:163155b607df 265 {
gume 6:15a3bbf90fe9 266 const uint8_t max_channel = 125;
gume 6:15a3bbf90fe9 267 write_register(RF_CH,rf24_min(channel,max_channel));
gume 0:163155b607df 268 }
gume 0:163155b607df 269
gume 0:163155b607df 270 uint8_t RF24::getChannel()
gume 0:163155b607df 271 {
gume 6:15a3bbf90fe9 272
gume 6:15a3bbf90fe9 273 return read_register(RF_CH);
gume 0:163155b607df 274 }
gume 0:163155b607df 275 /****************************************************************************/
gume 0:163155b607df 276
gume 0:163155b607df 277 void RF24::setPayloadSize(uint8_t size)
gume 0:163155b607df 278 {
gume 6:15a3bbf90fe9 279 payload_size = rf24_min(size,32);
gume 0:163155b607df 280 }
gume 0:163155b607df 281
gume 0:163155b607df 282 /****************************************************************************/
gume 0:163155b607df 283
gume 0:163155b607df 284 uint8_t RF24::getPayloadSize(void)
gume 0:163155b607df 285 {
gume 6:15a3bbf90fe9 286 return payload_size;
gume 0:163155b607df 287 }
gume 0:163155b607df 288
gume 0:163155b607df 289 /****************************************************************************/
gume 0:163155b607df 290
gume 0:163155b607df 291 #if !defined (MINIMAL)
gume 0:163155b607df 292
gume 0:163155b607df 293 static const char rf24_datarate_e_str_0[] PROGMEM = "1MBPS";
gume 0:163155b607df 294 static const char rf24_datarate_e_str_1[] PROGMEM = "2MBPS";
gume 0:163155b607df 295 static const char rf24_datarate_e_str_2[] PROGMEM = "250KBPS";
gume 0:163155b607df 296 static const char * const rf24_datarate_e_str_P[] PROGMEM = {
gume 6:15a3bbf90fe9 297 rf24_datarate_e_str_0,
gume 6:15a3bbf90fe9 298 rf24_datarate_e_str_1,
gume 6:15a3bbf90fe9 299 rf24_datarate_e_str_2,
gume 0:163155b607df 300 };
gume 0:163155b607df 301 static const char rf24_model_e_str_0[] PROGMEM = "nRF24L01";
gume 0:163155b607df 302 static const char rf24_model_e_str_1[] PROGMEM = "nRF24L01+";
gume 0:163155b607df 303 static const char * const rf24_model_e_str_P[] PROGMEM = {
gume 6:15a3bbf90fe9 304 rf24_model_e_str_0,
gume 6:15a3bbf90fe9 305 rf24_model_e_str_1,
gume 0:163155b607df 306 };
gume 0:163155b607df 307 static const char rf24_crclength_e_str_0[] PROGMEM = "Disabled";
gume 0:163155b607df 308 static const char rf24_crclength_e_str_1[] PROGMEM = "8 bits";
gume 0:163155b607df 309 static const char rf24_crclength_e_str_2[] PROGMEM = "16 bits" ;
gume 0:163155b607df 310 static const char * const rf24_crclength_e_str_P[] PROGMEM = {
gume 6:15a3bbf90fe9 311 rf24_crclength_e_str_0,
gume 6:15a3bbf90fe9 312 rf24_crclength_e_str_1,
gume 6:15a3bbf90fe9 313 rf24_crclength_e_str_2,
gume 0:163155b607df 314 };
gume 0:163155b607df 315 static const char rf24_pa_dbm_e_str_0[] PROGMEM = "PA_MIN";
gume 0:163155b607df 316 static const char rf24_pa_dbm_e_str_1[] PROGMEM = "PA_LOW";
gume 0:163155b607df 317 static const char rf24_pa_dbm_e_str_2[] PROGMEM = "PA_HIGH";
gume 0:163155b607df 318 static const char rf24_pa_dbm_e_str_3[] PROGMEM = "PA_MAX";
gume 0:163155b607df 319 static const char * const rf24_pa_dbm_e_str_P[] PROGMEM = {
gume 6:15a3bbf90fe9 320 rf24_pa_dbm_e_str_0,
gume 6:15a3bbf90fe9 321 rf24_pa_dbm_e_str_1,
gume 6:15a3bbf90fe9 322 rf24_pa_dbm_e_str_2,
gume 6:15a3bbf90fe9 323 rf24_pa_dbm_e_str_3,
gume 0:163155b607df 324 };
gume 0:163155b607df 325
gume 0:163155b607df 326 void RF24::printDetails(void)
gume 0:163155b607df 327 {
gume 0:163155b607df 328
gume 6:15a3bbf90fe9 329 print_status(get_status());
gume 0:163155b607df 330
gume 6:15a3bbf90fe9 331 print_address_register(PSTR("RX_ADDR_P0-1"),RX_ADDR_P0,2);
gume 6:15a3bbf90fe9 332 print_byte_register(PSTR("RX_ADDR_P2-5"),RX_ADDR_P2,4);
gume 6:15a3bbf90fe9 333 print_address_register(PSTR("TX_ADDR\t"),TX_ADDR);
gume 0:163155b607df 334
gume 6:15a3bbf90fe9 335 print_byte_register(PSTR("RX_PW_P0-6"),RX_PW_P0,6);
gume 6:15a3bbf90fe9 336 print_byte_register(PSTR("EN_AA\t"),EN_AA);
gume 6:15a3bbf90fe9 337 print_byte_register(PSTR("EN_RXADDR"),EN_RXADDR);
gume 6:15a3bbf90fe9 338 print_byte_register(PSTR("RF_CH\t"),RF_CH);
gume 6:15a3bbf90fe9 339 print_byte_register(PSTR("RF_SETUP"),RF_SETUP);
gume 6:15a3bbf90fe9 340 print_byte_register(PSTR("CONFIG\t"),NRF_CONFIG);
gume 6:15a3bbf90fe9 341 print_byte_register(PSTR("DYNPD/FEATURE"),DYNPD,2);
gume 0:163155b607df 342
gume 6:15a3bbf90fe9 343 printf_P(PSTR("Data Rate\t = " PRIPSTR "\r\n"),pgm_read_word(&rf24_datarate_e_str_P[getDataRate()]));
gume 6:15a3bbf90fe9 344 printf_P(PSTR("Model\t\t = " PRIPSTR "\r\n"),pgm_read_word(&rf24_model_e_str_P[isPVariant()]));
gume 6:15a3bbf90fe9 345 printf_P(PSTR("CRC Length\t = " PRIPSTR "\r\n"),pgm_read_word(&rf24_crclength_e_str_P[getCRCLength()]));
gume 6:15a3bbf90fe9 346 printf_P(PSTR("PA Power\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_pa_dbm_e_str_P[getPALevel()]));
gume 0:163155b607df 347
gume 0:163155b607df 348 }
gume 0:163155b607df 349
gume 0:163155b607df 350 #endif
gume 6:15a3bbf90fe9 351
gume 0:163155b607df 352 /****************************************************************************/
gume 0:163155b607df 353
gume 0:163155b607df 354 bool RF24::begin(void)
gume 0:163155b607df 355 {
gume 0:163155b607df 356
gume 6:15a3bbf90fe9 357 uint8_t setup=0;
gume 3:13e43d3101a5 358
gume 3:13e43d3101a5 359 ce(LOW);
gume 3:13e43d3101a5 360 csn(HIGH);
gume 6:15a3bbf90fe9 361 //wait_ms(100);
gume 3:13e43d3101a5 362
gume 3:13e43d3101a5 363 // Must allow the radio time to settle else configuration bits will not necessarily stick.
gume 3:13e43d3101a5 364 // This is actually only required following power up but some settling time also appears to
gume 3:13e43d3101a5 365 // be required after resets too. For full coverage, we'll always assume the worst.
gume 3:13e43d3101a5 366 // Enabling 16b CRC is by far the most obvious case if the wrong timing is used - or skipped.
gume 3:13e43d3101a5 367 // Technically we require 4.5ms + 14us as a worst case. We'll just call it 5ms for good measure.
gume 6:15a3bbf90fe9 368 // WARNING: Delay is based on P-variant whereby non-P *may* require different timing.
gume 3:13e43d3101a5 369 wait_ms( 5 ) ;
gume 3:13e43d3101a5 370
gume 6:15a3bbf90fe9 371 // Reset NRF_CONFIG and enable 16-bit CRC.
gume 6:15a3bbf90fe9 372 write_register( NRF_CONFIG, 0x0C ) ;
gume 6:15a3bbf90fe9 373
gume 3:13e43d3101a5 374 // Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier
gume 3:13e43d3101a5 375 // WARNING: If this is ever lowered, either 250KBS mode with AA is broken or maximum packet
gume 3:13e43d3101a5 376 // sizes must never be used. See documentation for a more complete explanation.
gume 6:15a3bbf90fe9 377 setRetries(5,15);
gume 3:13e43d3101a5 378
gume 6:15a3bbf90fe9 379 // Reset value is MAX
gume 6:15a3bbf90fe9 380 //setPALevel( RF24_PA_MAX ) ;
gume 6:15a3bbf90fe9 381
gume 6:15a3bbf90fe9 382 // check for connected module and if this is a p nRF24l01 variant
gume 6:15a3bbf90fe9 383 //
gume 3:13e43d3101a5 384 if( setDataRate( RF24_250KBPS ) )
gume 3:13e43d3101a5 385 {
gume 3:13e43d3101a5 386 p_variant = true ;
gume 3:13e43d3101a5 387 }
gume 6:15a3bbf90fe9 388 setup = read_register(RF_SETUP);
gume 6:15a3bbf90fe9 389 /*if( setup == 0b00001110 ) // register default for nRF24L01P
gume 6:15a3bbf90fe9 390 {
gume 6:15a3bbf90fe9 391 p_variant = true ;
gume 6:15a3bbf90fe9 392 }*/
gume 3:13e43d3101a5 393
gume 3:13e43d3101a5 394 // Then set the data rate to the slowest (and most reliable) speed supported by all
gume 3:13e43d3101a5 395 // hardware.
gume 3:13e43d3101a5 396 setDataRate( RF24_1MBPS ) ;
gume 3:13e43d3101a5 397
gume 3:13e43d3101a5 398 // Initialize CRC and request 2-byte (16bit) CRC
gume 6:15a3bbf90fe9 399 //setCRCLength( RF24_CRC_16 ) ;
gume 6:15a3bbf90fe9 400
gume 6:15a3bbf90fe9 401 // Disable dynamic payloads, to match dynamic_payloads_enabled setting - Reset value is 0
gume 6:15a3bbf90fe9 402 toggle_features();
gume 6:15a3bbf90fe9 403 write_register(FEATURE,0 );
gume 3:13e43d3101a5 404 write_register(DYNPD,0);
gume 6:15a3bbf90fe9 405 dynamic_payloads_enabled = false;
gume 3:13e43d3101a5 406
gume 3:13e43d3101a5 407 // Reset current status
gume 3:13e43d3101a5 408 // Notice reset and flush is the last thing we do
gume 3:13e43d3101a5 409 write_register(NRF_STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
gume 3:13e43d3101a5 410
gume 3:13e43d3101a5 411 // Set up default configuration. Callers can always change it later.
gume 3:13e43d3101a5 412 // This channel should be universally safe and not bleed over into adjacent
gume 3:13e43d3101a5 413 // spectrum.
gume 3:13e43d3101a5 414 setChannel(76);
gume 3:13e43d3101a5 415
gume 3:13e43d3101a5 416 // Flush buffers
gume 3:13e43d3101a5 417 flush_rx();
gume 3:13e43d3101a5 418 flush_tx();
gume 6:15a3bbf90fe9 419
gume 6:15a3bbf90fe9 420 powerUp(); //Power up by default when begin() is called
gume 6:15a3bbf90fe9 421
gume 6:15a3bbf90fe9 422 // Enable PTX, do not write CE high so radio will remain in standby I mode ( 130us max to transition to RX or TX instead of 1500us from powerUp )
gume 6:15a3bbf90fe9 423 // PTX should use only 22uA of power
gume 6:15a3bbf90fe9 424 write_register(NRF_CONFIG, ( read_register(NRF_CONFIG) ) & ~_BV(PRIM_RX) );
gume 6:15a3bbf90fe9 425
gume 6:15a3bbf90fe9 426 // if setup is 0 or ff then there was no response from module
gume 6:15a3bbf90fe9 427 return ( setup != 0 && setup != 0xff );
gume 3:13e43d3101a5 428 }
gume 3:13e43d3101a5 429
gume 6:15a3bbf90fe9 430 /****************************************************************************/
gume 3:13e43d3101a5 431
gume 6:15a3bbf90fe9 432 bool RF24::isChipConnected()
gume 6:15a3bbf90fe9 433 {
gume 6:15a3bbf90fe9 434 uint8_t setup = read_register(SETUP_AW);
gume 6:15a3bbf90fe9 435 if(setup >= 1 && setup <= 3)
gume 6:15a3bbf90fe9 436 {
gume 6:15a3bbf90fe9 437 return true;
gume 6:15a3bbf90fe9 438 }
gume 6:15a3bbf90fe9 439
gume 6:15a3bbf90fe9 440 return false;
gume 6:15a3bbf90fe9 441 }
gume 1:8f889354678f 442
gume 0:163155b607df 443 /****************************************************************************/
gume 0:163155b607df 444
gume 0:163155b607df 445 void RF24::startListening(void)
gume 0:163155b607df 446 {
gume 6:15a3bbf90fe9 447 #if !defined (RF24_TINY) && ! defined(LITTLEWIRE)
gume 6:15a3bbf90fe9 448 powerUp();
gume 6:15a3bbf90fe9 449 #endif
gume 6:15a3bbf90fe9 450 write_register(NRF_CONFIG, read_register(NRF_CONFIG) | _BV(PRIM_RX));
gume 6:15a3bbf90fe9 451 write_register(NRF_STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
gume 6:15a3bbf90fe9 452 ce(HIGH);
gume 6:15a3bbf90fe9 453 // Restore the pipe0 adddress, if exists
gume 6:15a3bbf90fe9 454 if (pipe0_reading_address[0] > 0){
gume 6:15a3bbf90fe9 455 write_register(RX_ADDR_P0, pipe0_reading_address, addr_width);
gume 6:15a3bbf90fe9 456 }else{
gume 6:15a3bbf90fe9 457 closeReadingPipe(0);
gume 6:15a3bbf90fe9 458 }
gume 0:163155b607df 459
gume 6:15a3bbf90fe9 460 // Flush buffers
gume 6:15a3bbf90fe9 461 //flush_rx();
gume 6:15a3bbf90fe9 462 if(read_register(FEATURE) & _BV(EN_ACK_PAY)){
gume 6:15a3bbf90fe9 463 flush_tx();
gume 6:15a3bbf90fe9 464 }
gume 0:163155b607df 465
gume 6:15a3bbf90fe9 466 // Go!
gume 6:15a3bbf90fe9 467 //delayMicroseconds(100);
gume 0:163155b607df 468 }
gume 0:163155b607df 469
gume 0:163155b607df 470 /****************************************************************************/
gume 6:15a3bbf90fe9 471 static const uint8_t child_pipe_enable[] PROGMEM =
gume 6:15a3bbf90fe9 472 {
gume 6:15a3bbf90fe9 473 ERX_P0, ERX_P1, ERX_P2, ERX_P3, ERX_P4, ERX_P5
gume 0:163155b607df 474 };
gume 0:163155b607df 475
gume 0:163155b607df 476 void RF24::stopListening(void)
gume 6:15a3bbf90fe9 477 {
gume 6:15a3bbf90fe9 478 ce(LOW);
gume 0:163155b607df 479
gume 6:15a3bbf90fe9 480 wait_us(txDelay);
gume 6:15a3bbf90fe9 481
gume 6:15a3bbf90fe9 482 if(read_register(FEATURE) & _BV(EN_ACK_PAY)){
gume 6:15a3bbf90fe9 483 wait_us(txDelay); //200
gume 6:15a3bbf90fe9 484 flush_tx();
gume 6:15a3bbf90fe9 485 }
gume 6:15a3bbf90fe9 486 //flush_rx();
gume 6:15a3bbf90fe9 487 write_register(NRF_CONFIG, ( read_register(NRF_CONFIG) ) & ~_BV(PRIM_RX) );
gume 6:15a3bbf90fe9 488
gume 6:15a3bbf90fe9 489 write_register(EN_RXADDR,read_register(EN_RXADDR) | _BV(pgm_read_byte(&child_pipe_enable[0]))); // Enable RX on pipe0
gume 6:15a3bbf90fe9 490
gume 6:15a3bbf90fe9 491 //delayMicroseconds(100);
gume 0:163155b607df 492
gume 0:163155b607df 493 }
gume 0:163155b607df 494
gume 0:163155b607df 495 /****************************************************************************/
gume 0:163155b607df 496
gume 0:163155b607df 497 void RF24::powerDown(void)
gume 0:163155b607df 498 {
gume 6:15a3bbf90fe9 499 ce(LOW); // Guarantee CE is low on powerDown
gume 6:15a3bbf90fe9 500 write_register(NRF_CONFIG,read_register(NRF_CONFIG) & ~_BV(PWR_UP));
gume 0:163155b607df 501 }
gume 0:163155b607df 502
gume 0:163155b607df 503 /****************************************************************************/
gume 0:163155b607df 504
gume 0:163155b607df 505 //Power up now. Radio will not power down unless instructed by MCU for config changes etc.
gume 0:163155b607df 506 void RF24::powerUp(void)
gume 0:163155b607df 507 {
gume 6:15a3bbf90fe9 508 uint8_t cfg = read_register(NRF_CONFIG);
gume 0:163155b607df 509
gume 6:15a3bbf90fe9 510 // if not powered up then power up and wait for the radio to initialize
gume 6:15a3bbf90fe9 511 if (!(cfg & _BV(PWR_UP))){
gume 6:15a3bbf90fe9 512 write_register(NRF_CONFIG, cfg | _BV(PWR_UP));
gume 0:163155b607df 513
gume 6:15a3bbf90fe9 514 // For nRF24L01+ to go from power down mode to TX or RX mode it must first pass through stand-by mode.
gume 6:15a3bbf90fe9 515 // There must be a delay of Tpd2stby (see Table 16.) after the nRF24L01+ leaves power down mode before
gume 6:15a3bbf90fe9 516 // the CEis set high. - Tpd2stby can be up to 5ms per the 1.0 datasheet
gume 6:15a3bbf90fe9 517 wait_ms(5);
gume 6:15a3bbf90fe9 518 }
gume 0:163155b607df 519 }
gume 0:163155b607df 520
gume 0:163155b607df 521 /******************************************************************/
gume 6:15a3bbf90fe9 522 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
gume 6:15a3bbf90fe9 523 void RF24::errNotify(){
gume 6:15a3bbf90fe9 524 #if defined (SERIAL_DEBUG) || defined (RF24_LINUX)
gume 6:15a3bbf90fe9 525 printf_P(PSTR("RF24 HARDWARE FAIL: Radio not responding, verify pin connections, wiring, etc.\r\n"));
gume 6:15a3bbf90fe9 526 #endif
gume 6:15a3bbf90fe9 527 #if defined (FAILURE_HANDLING)
gume 0:163155b607df 528 failureDetected = 1;
gume 6:15a3bbf90fe9 529 #else
gume 0:163155b607df 530 delay(5000);
gume 6:15a3bbf90fe9 531 #endif
gume 0:163155b607df 532 }
gume 0:163155b607df 533 #endif
gume 0:163155b607df 534 /******************************************************************/
gume 0:163155b607df 535
gume 0:163155b607df 536 //Similar to the previous write, clears the interrupt flags
gume 0:163155b607df 537 bool RF24::write( const void* buf, uint8_t len, const bool multicast )
gume 0:163155b607df 538 {
gume 0:163155b607df 539 //Start Writing
gume 0:163155b607df 540 startFastWrite(buf,len,multicast);
gume 0:163155b607df 541
gume 0:163155b607df 542 //Wait until complete or failed
gume 6:15a3bbf90fe9 543 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
gume 6:15a3bbf90fe9 544 uint32_t timer = millis();
gume 6:15a3bbf90fe9 545 #endif
gume 6:15a3bbf90fe9 546
gume 6:15a3bbf90fe9 547 while( ! ( get_status() & ( _BV(TX_DS) | _BV(MAX_RT) ))) {
gume 6:15a3bbf90fe9 548 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
gume 6:15a3bbf90fe9 549 if(millis() - timer > 95){
gume 6:15a3bbf90fe9 550 errNotify();
gume 6:15a3bbf90fe9 551 #if defined (FAILURE_HANDLING)
gume 6:15a3bbf90fe9 552 return 0;
gume 6:15a3bbf90fe9 553 #else
gume 6:15a3bbf90fe9 554 delay(100);
gume 6:15a3bbf90fe9 555 #endif
gume 6:15a3bbf90fe9 556 }
gume 6:15a3bbf90fe9 557 #endif
gume 0:163155b607df 558 }
gume 6:15a3bbf90fe9 559
gume 0:163155b607df 560 ce(LOW);
gume 0:163155b607df 561
gume 0:163155b607df 562 uint8_t status = write_register(NRF_STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
gume 0:163155b607df 563
gume 6:15a3bbf90fe9 564 //Max retries exceeded
gume 6:15a3bbf90fe9 565 if( status & _BV(MAX_RT)){
gume 6:15a3bbf90fe9 566 flush_tx(); //Only going to be 1 packet int the FIFO at a time using this method, so just flush
gume 6:15a3bbf90fe9 567 return 0;
gume 6:15a3bbf90fe9 568 }
gume 0:163155b607df 569 //TX OK 1 or 0
gume 6:15a3bbf90fe9 570 return 1;
gume 0:163155b607df 571 }
gume 0:163155b607df 572
gume 6:15a3bbf90fe9 573 bool RF24::write( const void* buf, uint8_t len ){
gume 0:163155b607df 574 return write(buf,len,0);
gume 0:163155b607df 575 }
gume 0:163155b607df 576 /****************************************************************************/
gume 0:163155b607df 577
gume 0:163155b607df 578 //For general use, the interrupt flags are not important to clear
gume 0:163155b607df 579 bool RF24::writeBlocking( const void* buf, uint8_t len, uint32_t timeout )
gume 0:163155b607df 580 {
gume 0:163155b607df 581 //Block until the FIFO is NOT full.
gume 0:163155b607df 582 //Keep track of the MAX retries and set auto-retry if seeing failures
gume 0:163155b607df 583 //This way the FIFO will fill up and allow blocking until packets go through
gume 0:163155b607df 584 //The radio will auto-clear everything in the FIFO as long as CE remains high
gume 0:163155b607df 585
gume 6:15a3bbf90fe9 586 uint32_t timer = millis(); //Get the time that the payload transmission started
gume 0:163155b607df 587
gume 0:163155b607df 588 while( ( get_status() & ( _BV(TX_FULL) ))) { //Blocking only if FIFO is full. This will loop and block until TX is successful or timeout
gume 0:163155b607df 589
gume 6:15a3bbf90fe9 590 if( get_status() & _BV(MAX_RT)){ //If MAX Retries have been reached
gume 0:163155b607df 591 reUseTX(); //Set re-transmit and clear the MAX_RT interrupt flag
gume 6:15a3bbf90fe9 592 if(millis() - timer > timeout){ return 0; } //If this payload has exceeded the user-defined timeout, exit and return 0
gume 0:163155b607df 593 }
gume 6:15a3bbf90fe9 594 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
gume 6:15a3bbf90fe9 595 if(millis() - timer > (timeout+95) ){
gume 6:15a3bbf90fe9 596 errNotify();
gume 6:15a3bbf90fe9 597 #if defined (FAILURE_HANDLING)
gume 6:15a3bbf90fe9 598 return 0;
gume 6:15a3bbf90fe9 599 #endif
gume 6:15a3bbf90fe9 600 }
gume 6:15a3bbf90fe9 601 #endif
gume 0:163155b607df 602
gume 0:163155b607df 603 }
gume 0:163155b607df 604
gume 0:163155b607df 605 //Start Writing
gume 0:163155b607df 606 startFastWrite(buf,len,0); //Write the payload if a buffer is clear
gume 0:163155b607df 607
gume 0:163155b607df 608 return 1; //Return 1 to indicate successful transmission
gume 0:163155b607df 609 }
gume 0:163155b607df 610
gume 0:163155b607df 611 /****************************************************************************/
gume 0:163155b607df 612
gume 6:15a3bbf90fe9 613 void RF24::reUseTX(){
gume 0:163155b607df 614 write_register(NRF_STATUS,_BV(MAX_RT) ); //Clear max retry flag
gume 0:163155b607df 615 spiTrans( REUSE_TX_PL );
gume 0:163155b607df 616 ce(LOW); //Re-Transfer packet
gume 0:163155b607df 617 ce(HIGH);
gume 0:163155b607df 618 }
gume 0:163155b607df 619
gume 0:163155b607df 620 /****************************************************************************/
gume 0:163155b607df 621
gume 0:163155b607df 622 bool RF24::writeFast( const void* buf, uint8_t len, const bool multicast )
gume 0:163155b607df 623 {
gume 0:163155b607df 624 //Block until the FIFO is NOT full.
gume 0:163155b607df 625 //Keep track of the MAX retries and set auto-retry if seeing failures
gume 0:163155b607df 626 //Return 0 so the user can control the retrys and set a timer or failure counter if required
gume 0:163155b607df 627 //The radio will auto-clear everything in the FIFO as long as CE remains high
gume 0:163155b607df 628
gume 6:15a3bbf90fe9 629 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
gume 6:15a3bbf90fe9 630 uint32_t timer = millis();
gume 6:15a3bbf90fe9 631 #endif
gume 6:15a3bbf90fe9 632
gume 0:163155b607df 633 while( ( get_status() & ( _BV(TX_FULL) ))) { //Blocking only if FIFO is full. This will loop and block until TX is successful or fail
gume 0:163155b607df 634
gume 6:15a3bbf90fe9 635 if( get_status() & _BV(MAX_RT)){
gume 0:163155b607df 636 //reUseTX(); //Set re-transmit
gume 0:163155b607df 637 write_register(NRF_STATUS,_BV(MAX_RT) ); //Clear max retry flag
gume 0:163155b607df 638 return 0; //Return 0. The previous payload has been retransmitted
gume 6:15a3bbf90fe9 639 //From the user perspective, if you get a 0, just keep trying to send the same payload
gume 0:163155b607df 640 }
gume 6:15a3bbf90fe9 641 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
gume 6:15a3bbf90fe9 642 if(millis() - timer > 95 ){
gume 6:15a3bbf90fe9 643 errNotify();
gume 6:15a3bbf90fe9 644 #if defined (FAILURE_HANDLING)
gume 6:15a3bbf90fe9 645 return 0;
gume 6:15a3bbf90fe9 646 #endif
gume 6:15a3bbf90fe9 647 }
gume 6:15a3bbf90fe9 648 #endif
gume 0:163155b607df 649 }
gume 6:15a3bbf90fe9 650 //Start Writing
gume 0:163155b607df 651 startFastWrite(buf,len,multicast);
gume 0:163155b607df 652
gume 0:163155b607df 653 return 1;
gume 0:163155b607df 654 }
gume 0:163155b607df 655
gume 6:15a3bbf90fe9 656 bool RF24::writeFast( const void* buf, uint8_t len ){
gume 0:163155b607df 657 return writeFast(buf,len,0);
gume 0:163155b607df 658 }
gume 0:163155b607df 659
gume 0:163155b607df 660 /****************************************************************************/
gume 0:163155b607df 661
gume 0:163155b607df 662 //Per the documentation, we want to set PTX Mode when not listening. Then all we do is write data and set CE high
gume 0:163155b607df 663 //In this mode, if we can keep the FIFO buffers loaded, packets will transmit immediately (no 130us delay)
gume 0:163155b607df 664 //Otherwise we enter Standby-II mode, which is still faster than standby mode
gume 0:163155b607df 665 //Also, we remove the need to keep writing the config register over and over and delaying for 150 us each time if sending a stream of data
gume 0:163155b607df 666
gume 6:15a3bbf90fe9 667 void RF24::startFastWrite( const void* buf, uint8_t len, const bool multicast, bool startTx){ //TMRh20
gume 0:163155b607df 668
gume 0:163155b607df 669 //write_payload( buf,len);
gume 0:163155b607df 670 write_payload( buf, len,multicast ? W_TX_PAYLOAD_NO_ACK : W_TX_PAYLOAD ) ;
gume 6:15a3bbf90fe9 671 if(startTx){
gume 0:163155b607df 672 ce(HIGH);
gume 0:163155b607df 673 }
gume 0:163155b607df 674
gume 0:163155b607df 675 }
gume 0:163155b607df 676
gume 0:163155b607df 677 /****************************************************************************/
gume 0:163155b607df 678
gume 0:163155b607df 679 //Added the original startWrite back in so users can still use interrupts, ack payloads, etc
gume 0:163155b607df 680 //Allows the library to pass all tests
gume 6:15a3bbf90fe9 681 void RF24::startWrite( const void* buf, uint8_t len, const bool multicast ){
gume 0:163155b607df 682
gume 6:15a3bbf90fe9 683 // Send the payload
gume 0:163155b607df 684
gume 6:15a3bbf90fe9 685 //write_payload( buf, len );
gume 6:15a3bbf90fe9 686 write_payload( buf, len,multicast? W_TX_PAYLOAD_NO_ACK : W_TX_PAYLOAD ) ;
gume 6:15a3bbf90fe9 687 ce(HIGH);
gume 6:15a3bbf90fe9 688 #if defined(CORE_TEENSY) || !defined(ARDUINO) || defined (RF24_SPIDEV) || defined (RF24_DUE)
gume 6:15a3bbf90fe9 689 delayMicroseconds(10);
gume 6:15a3bbf90fe9 690 #endif
gume 6:15a3bbf90fe9 691 ce(LOW);
gume 0:163155b607df 692
gume 0:163155b607df 693
gume 0:163155b607df 694 }
gume 0:163155b607df 695
gume 0:163155b607df 696 /****************************************************************************/
gume 0:163155b607df 697
gume 6:15a3bbf90fe9 698 bool RF24::rxFifoFull(){
gume 0:163155b607df 699 return read_register(FIFO_STATUS) & _BV(RX_FULL);
gume 0:163155b607df 700 }
gume 0:163155b607df 701 /****************************************************************************/
gume 0:163155b607df 702
gume 6:15a3bbf90fe9 703 bool RF24::txStandBy(){
gume 0:163155b607df 704
gume 6:15a3bbf90fe9 705 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
gume 6:15a3bbf90fe9 706 uint32_t timeout = millis();
gume 6:15a3bbf90fe9 707 #endif
gume 6:15a3bbf90fe9 708 while( ! (read_register(FIFO_STATUS) & _BV(TX_EMPTY)) ){
gume 6:15a3bbf90fe9 709 if( get_status() & _BV(MAX_RT)){
gume 0:163155b607df 710 write_register(NRF_STATUS,_BV(MAX_RT) );
gume 0:163155b607df 711 ce(LOW);
gume 0:163155b607df 712 flush_tx(); //Non blocking, flush the data
gume 0:163155b607df 713 return 0;
gume 0:163155b607df 714 }
gume 6:15a3bbf90fe9 715 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
gume 6:15a3bbf90fe9 716 if( millis() - timeout > 95){
gume 6:15a3bbf90fe9 717 errNotify();
gume 6:15a3bbf90fe9 718 #if defined (FAILURE_HANDLING)
gume 6:15a3bbf90fe9 719 return 0;
gume 6:15a3bbf90fe9 720 #endif
gume 6:15a3bbf90fe9 721 }
gume 6:15a3bbf90fe9 722 #endif
gume 0:163155b607df 723 }
gume 0:163155b607df 724
gume 0:163155b607df 725 ce(LOW); //Set STANDBY-I mode
gume 0:163155b607df 726 return 1;
gume 0:163155b607df 727 }
gume 0:163155b607df 728
gume 0:163155b607df 729 /****************************************************************************/
gume 0:163155b607df 730
gume 6:15a3bbf90fe9 731 bool RF24::txStandBy(uint32_t timeout, bool startTx){
gume 0:163155b607df 732
gume 6:15a3bbf90fe9 733 if(startTx){
gume 6:15a3bbf90fe9 734 stopListening();
gume 6:15a3bbf90fe9 735 ce(HIGH);
gume 0:163155b607df 736 }
gume 6:15a3bbf90fe9 737 uint32_t start = millis();
gume 0:163155b607df 738
gume 6:15a3bbf90fe9 739 while( ! (read_register(FIFO_STATUS) & _BV(TX_EMPTY)) ){
gume 6:15a3bbf90fe9 740 if( get_status() & _BV(MAX_RT)){
gume 0:163155b607df 741 write_register(NRF_STATUS,_BV(MAX_RT) );
gume 6:15a3bbf90fe9 742 ce(LOW); //Set re-transmit
gume 6:15a3bbf90fe9 743 ce(HIGH);
gume 6:15a3bbf90fe9 744 if(millis() - start >= timeout){
gume 6:15a3bbf90fe9 745 ce(LOW); flush_tx(); return 0;
gume 6:15a3bbf90fe9 746 }
gume 0:163155b607df 747 }
gume 6:15a3bbf90fe9 748 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
gume 6:15a3bbf90fe9 749 if( millis() - start > (timeout+95)){
gume 6:15a3bbf90fe9 750 errNotify();
gume 6:15a3bbf90fe9 751 #if defined (FAILURE_HANDLING)
gume 6:15a3bbf90fe9 752 return 0;
gume 6:15a3bbf90fe9 753 #endif
gume 6:15a3bbf90fe9 754 }
gume 6:15a3bbf90fe9 755 #endif
gume 0:163155b607df 756 }
gume 0:163155b607df 757
gume 6:15a3bbf90fe9 758
gume 0:163155b607df 759 ce(LOW); //Set STANDBY-I mode
gume 0:163155b607df 760 return 1;
gume 0:163155b607df 761
gume 0:163155b607df 762 }
gume 0:163155b607df 763
gume 0:163155b607df 764 /****************************************************************************/
gume 0:163155b607df 765
gume 6:15a3bbf90fe9 766 void RF24::maskIRQ(bool tx, bool fail, bool rx){
gume 0:163155b607df 767
gume 6:15a3bbf90fe9 768 uint8_t config = read_register(NRF_CONFIG);
gume 0:163155b607df 769 /* clear the interrupt flags */
gume 0:163155b607df 770 config &= ~(1 << MASK_MAX_RT | 1 << MASK_TX_DS | 1 << MASK_RX_DR);
gume 0:163155b607df 771 /* set the specified interrupt flags */
gume 0:163155b607df 772 config |= fail << MASK_MAX_RT | tx << MASK_TX_DS | rx << MASK_RX_DR;
gume 6:15a3bbf90fe9 773 write_register(NRF_CONFIG, config);
gume 0:163155b607df 774 }
gume 0:163155b607df 775
gume 0:163155b607df 776 /****************************************************************************/
gume 0:163155b607df 777
gume 0:163155b607df 778 uint8_t RF24::getDynamicPayloadSize(void)
gume 0:163155b607df 779 {
gume 6:15a3bbf90fe9 780 uint8_t result = 0;
gume 0:163155b607df 781
gume 6:15a3bbf90fe9 782 beginTransaction();
gume 6:15a3bbf90fe9 783 spi->write( R_RX_PL_WID );
gume 6:15a3bbf90fe9 784 result = spi->write(0xff);
gume 6:15a3bbf90fe9 785 endTransaction();
gume 0:163155b607df 786
gume 6:15a3bbf90fe9 787 if(result > 32) { flush_rx(); delay(2); return 0; }
gume 6:15a3bbf90fe9 788 return result;
gume 0:163155b607df 789 }
gume 0:163155b607df 790
gume 0:163155b607df 791 /****************************************************************************/
gume 0:163155b607df 792
gume 0:163155b607df 793 bool RF24::available(void)
gume 0:163155b607df 794 {
gume 6:15a3bbf90fe9 795 return available(NULL);
gume 0:163155b607df 796 }
gume 0:163155b607df 797
gume 0:163155b607df 798 /****************************************************************************/
gume 0:163155b607df 799
gume 0:163155b607df 800 bool RF24::available(uint8_t* pipe_num)
gume 0:163155b607df 801 {
gume 6:15a3bbf90fe9 802 if (!( read_register(FIFO_STATUS) & _BV(RX_EMPTY) )){
gume 0:163155b607df 803
gume 6:15a3bbf90fe9 804 // If the caller wants the pipe number, include that
gume 6:15a3bbf90fe9 805 if ( pipe_num ){
gume 6:15a3bbf90fe9 806 uint8_t status = get_status();
gume 6:15a3bbf90fe9 807 *pipe_num = ( status >> RX_P_NO ) & 0x07;
gume 0:163155b607df 808 }
gume 6:15a3bbf90fe9 809 return 1;
gume 6:15a3bbf90fe9 810 }
gume 0:163155b607df 811
gume 0:163155b607df 812
gume 6:15a3bbf90fe9 813 return 0;
gume 0:163155b607df 814
gume 0:163155b607df 815
gume 0:163155b607df 816 }
gume 0:163155b607df 817
gume 0:163155b607df 818 /****************************************************************************/
gume 0:163155b607df 819
gume 6:15a3bbf90fe9 820 void RF24::read( void* buf, uint8_t len ){
gume 0:163155b607df 821
gume 6:15a3bbf90fe9 822 // Fetch the payload
gume 6:15a3bbf90fe9 823 read_payload( buf, len );
gume 0:163155b607df 824
gume 6:15a3bbf90fe9 825 //Clear the two possible interrupt flags with one command
gume 6:15a3bbf90fe9 826 write_register(NRF_STATUS,_BV(RX_DR) | _BV(MAX_RT) | _BV(TX_DS) );
gume 0:163155b607df 827
gume 0:163155b607df 828 }
gume 0:163155b607df 829
gume 0:163155b607df 830 /****************************************************************************/
gume 0:163155b607df 831
gume 0:163155b607df 832 void RF24::whatHappened(bool& tx_ok,bool& tx_fail,bool& rx_ready)
gume 0:163155b607df 833 {
gume 6:15a3bbf90fe9 834 // Read the status & reset the status in one easy call
gume 6:15a3bbf90fe9 835 // Or is that such a good idea?
gume 6:15a3bbf90fe9 836 uint8_t status = write_register(NRF_STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
gume 0:163155b607df 837
gume 6:15a3bbf90fe9 838 // Report to the user what happened
gume 6:15a3bbf90fe9 839 tx_ok = status & _BV(TX_DS);
gume 6:15a3bbf90fe9 840 tx_fail = status & _BV(MAX_RT);
gume 6:15a3bbf90fe9 841 rx_ready = status & _BV(RX_DR);
gume 0:163155b607df 842 }
gume 0:163155b607df 843
gume 0:163155b607df 844 /****************************************************************************/
gume 0:163155b607df 845
gume 0:163155b607df 846 void RF24::openWritingPipe(uint64_t value)
gume 0:163155b607df 847 {
gume 6:15a3bbf90fe9 848 // Note that AVR 8-bit uC's store this LSB first, and the NRF24L01(+)
gume 6:15a3bbf90fe9 849 // expects it LSB first too, so we're good.
gume 0:163155b607df 850
gume 6:15a3bbf90fe9 851 write_register(RX_ADDR_P0, reinterpret_cast<uint8_t*>(&value), addr_width);
gume 6:15a3bbf90fe9 852 write_register(TX_ADDR, reinterpret_cast<uint8_t*>(&value), addr_width);
gume 6:15a3bbf90fe9 853
gume 6:15a3bbf90fe9 854
gume 6:15a3bbf90fe9 855 //const uint8_t max_payload_size = 32;
gume 6:15a3bbf90fe9 856 //write_register(RX_PW_P0,rf24_min(payload_size,max_payload_size));
gume 6:15a3bbf90fe9 857 write_register(RX_PW_P0,payload_size);
gume 0:163155b607df 858 }
gume 0:163155b607df 859
gume 0:163155b607df 860 /****************************************************************************/
gume 0:163155b607df 861 void RF24::openWritingPipe(const uint8_t *address)
gume 0:163155b607df 862 {
gume 6:15a3bbf90fe9 863 // Note that AVR 8-bit uC's store this LSB first, and the NRF24L01(+)
gume 6:15a3bbf90fe9 864 // expects it LSB first too, so we're good.
gume 0:163155b607df 865
gume 6:15a3bbf90fe9 866 write_register(RX_ADDR_P0,address, addr_width);
gume 6:15a3bbf90fe9 867 write_register(TX_ADDR, address, addr_width);
gume 0:163155b607df 868
gume 6:15a3bbf90fe9 869 //const uint8_t max_payload_size = 32;
gume 6:15a3bbf90fe9 870 //write_register(RX_PW_P0,rf24_min(payload_size,max_payload_size));
gume 6:15a3bbf90fe9 871 write_register(RX_PW_P0,payload_size);
gume 0:163155b607df 872 }
gume 0:163155b607df 873
gume 0:163155b607df 874 /****************************************************************************/
gume 6:15a3bbf90fe9 875 static const uint8_t child_pipe[] PROGMEM =
gume 6:15a3bbf90fe9 876 {
gume 6:15a3bbf90fe9 877 RX_ADDR_P0, RX_ADDR_P1, RX_ADDR_P2, RX_ADDR_P3, RX_ADDR_P4, RX_ADDR_P5
gume 0:163155b607df 878 };
gume 6:15a3bbf90fe9 879 static const uint8_t child_payload_size[] PROGMEM =
gume 6:15a3bbf90fe9 880 {
gume 6:15a3bbf90fe9 881 RX_PW_P0, RX_PW_P1, RX_PW_P2, RX_PW_P3, RX_PW_P4, RX_PW_P5
gume 0:163155b607df 882 };
gume 0:163155b607df 883
gume 0:163155b607df 884
gume 0:163155b607df 885 void RF24::openReadingPipe(uint8_t child, uint64_t address)
gume 0:163155b607df 886 {
gume 6:15a3bbf90fe9 887 // If this is pipe 0, cache the address. This is needed because
gume 6:15a3bbf90fe9 888 // openWritingPipe() will overwrite the pipe 0 address, so
gume 6:15a3bbf90fe9 889 // startListening() will have to restore it.
gume 6:15a3bbf90fe9 890 if (child == 0){
gume 6:15a3bbf90fe9 891 memcpy(pipe0_reading_address,&address,addr_width);
gume 6:15a3bbf90fe9 892 }
gume 0:163155b607df 893
gume 6:15a3bbf90fe9 894 if (child <= 6)
gume 6:15a3bbf90fe9 895 {
gume 6:15a3bbf90fe9 896 // For pipes 2-5, only write the LSB
gume 6:15a3bbf90fe9 897 if ( child < 2 )
gume 6:15a3bbf90fe9 898 write_register(pgm_read_byte(&child_pipe[child]), reinterpret_cast<const uint8_t*>(&address), addr_width);
gume 6:15a3bbf90fe9 899 else
gume 6:15a3bbf90fe9 900 write_register(pgm_read_byte(&child_pipe[child]), reinterpret_cast<const uint8_t*>(&address), 1);
gume 0:163155b607df 901
gume 6:15a3bbf90fe9 902 write_register(pgm_read_byte(&child_payload_size[child]),payload_size);
gume 0:163155b607df 903
gume 6:15a3bbf90fe9 904 // Note it would be more efficient to set all of the bits for all open
gume 6:15a3bbf90fe9 905 // pipes at once. However, I thought it would make the calling code
gume 6:15a3bbf90fe9 906 // more simple to do it this way.
gume 6:15a3bbf90fe9 907 write_register(EN_RXADDR,read_register(EN_RXADDR) | _BV(pgm_read_byte(&child_pipe_enable[child])));
gume 6:15a3bbf90fe9 908 }
gume 0:163155b607df 909 }
gume 0:163155b607df 910
gume 0:163155b607df 911 /****************************************************************************/
gume 6:15a3bbf90fe9 912 void RF24::setAddressWidth(uint8_t a_width){
gume 0:163155b607df 913
gume 6:15a3bbf90fe9 914 if(a_width -= 2){
gume 0:163155b607df 915 write_register(SETUP_AW,a_width%4);
gume 0:163155b607df 916 addr_width = (a_width%4) + 2;
gume 6:15a3bbf90fe9 917 }else{
gume 6:15a3bbf90fe9 918 write_register(SETUP_AW,0);
gume 6:15a3bbf90fe9 919 addr_width = 2;
gume 0:163155b607df 920 }
gume 0:163155b607df 921
gume 0:163155b607df 922 }
gume 0:163155b607df 923
gume 0:163155b607df 924 /****************************************************************************/
gume 0:163155b607df 925
gume 0:163155b607df 926 void RF24::openReadingPipe(uint8_t child, const uint8_t *address)
gume 0:163155b607df 927 {
gume 6:15a3bbf90fe9 928 // If this is pipe 0, cache the address. This is needed because
gume 6:15a3bbf90fe9 929 // openWritingPipe() will overwrite the pipe 0 address, so
gume 6:15a3bbf90fe9 930 // startListening() will have to restore it.
gume 6:15a3bbf90fe9 931 if (child == 0){
gume 6:15a3bbf90fe9 932 memcpy(pipe0_reading_address,address,addr_width);
gume 6:15a3bbf90fe9 933 }
gume 6:15a3bbf90fe9 934 if (child <= 6)
gume 6:15a3bbf90fe9 935 {
gume 6:15a3bbf90fe9 936 // For pipes 2-5, only write the LSB
gume 6:15a3bbf90fe9 937 if ( child < 2 ){
gume 6:15a3bbf90fe9 938 write_register(pgm_read_byte(&child_pipe[child]), address, addr_width);
gume 6:15a3bbf90fe9 939 }else{
gume 6:15a3bbf90fe9 940 write_register(pgm_read_byte(&child_pipe[child]), address, 1);
gume 0:163155b607df 941 }
gume 6:15a3bbf90fe9 942 write_register(pgm_read_byte(&child_payload_size[child]),payload_size);
gume 0:163155b607df 943
gume 6:15a3bbf90fe9 944 // Note it would be more efficient to set all of the bits for all open
gume 6:15a3bbf90fe9 945 // pipes at once. However, I thought it would make the calling code
gume 6:15a3bbf90fe9 946 // more simple to do it this way.
gume 6:15a3bbf90fe9 947 write_register(EN_RXADDR,read_register(EN_RXADDR) | _BV(pgm_read_byte(&child_pipe_enable[child])));
gume 0:163155b607df 948
gume 6:15a3bbf90fe9 949 }
gume 0:163155b607df 950 }
gume 0:163155b607df 951
gume 0:163155b607df 952 /****************************************************************************/
gume 0:163155b607df 953
gume 0:163155b607df 954 void RF24::closeReadingPipe( uint8_t pipe )
gume 0:163155b607df 955 {
gume 6:15a3bbf90fe9 956 write_register(EN_RXADDR,read_register(EN_RXADDR) & ~_BV(pgm_read_byte(&child_pipe_enable[pipe])));
gume 0:163155b607df 957 }
gume 0:163155b607df 958
gume 0:163155b607df 959 /****************************************************************************/
gume 0:163155b607df 960
gume 0:163155b607df 961 void RF24::toggle_features(void)
gume 0:163155b607df 962 {
gume 0:163155b607df 963 beginTransaction();
gume 6:15a3bbf90fe9 964 spi->write( ACTIVATE );
gume 6:15a3bbf90fe9 965 spi->write( 0x73 );
gume 0:163155b607df 966 endTransaction();
gume 0:163155b607df 967 }
gume 0:163155b607df 968
gume 0:163155b607df 969 /****************************************************************************/
gume 0:163155b607df 970
gume 0:163155b607df 971 void RF24::enableDynamicPayloads(void)
gume 0:163155b607df 972 {
gume 6:15a3bbf90fe9 973 // Enable dynamic payload throughout the system
gume 0:163155b607df 974
gume 0:163155b607df 975 //toggle_features();
gume 0:163155b607df 976 write_register(FEATURE,read_register(FEATURE) | _BV(EN_DPL) );
gume 0:163155b607df 977
gume 6:15a3bbf90fe9 978
gume 6:15a3bbf90fe9 979 IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE)));
gume 6:15a3bbf90fe9 980
gume 6:15a3bbf90fe9 981 // Enable dynamic payload on all pipes
gume 6:15a3bbf90fe9 982 //
gume 6:15a3bbf90fe9 983 // Not sure the use case of only having dynamic payload on certain
gume 6:15a3bbf90fe9 984 // pipes, so the library does not support it.
gume 6:15a3bbf90fe9 985 write_register(DYNPD,read_register(DYNPD) | _BV(DPL_P5) | _BV(DPL_P4) | _BV(DPL_P3) | _BV(DPL_P2) | _BV(DPL_P1) | _BV(DPL_P0));
gume 6:15a3bbf90fe9 986
gume 6:15a3bbf90fe9 987 dynamic_payloads_enabled = true;
gume 6:15a3bbf90fe9 988 }
gume 0:163155b607df 989
gume 6:15a3bbf90fe9 990 /****************************************************************************/
gume 6:15a3bbf90fe9 991 void RF24::disableDynamicPayloads(void)
gume 6:15a3bbf90fe9 992 {
gume 6:15a3bbf90fe9 993 // Disables dynamic payload throughout the system. Also disables Ack Payloads
gume 6:15a3bbf90fe9 994
gume 6:15a3bbf90fe9 995 //toggle_features();
gume 6:15a3bbf90fe9 996 write_register(FEATURE, 0);
gume 6:15a3bbf90fe9 997
gume 0:163155b607df 998
gume 6:15a3bbf90fe9 999 IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE)));
gume 6:15a3bbf90fe9 1000
gume 6:15a3bbf90fe9 1001 // Disable dynamic payload on all pipes
gume 6:15a3bbf90fe9 1002 //
gume 6:15a3bbf90fe9 1003 // Not sure the use case of only having dynamic payload on certain
gume 6:15a3bbf90fe9 1004 // pipes, so the library does not support it.
gume 6:15a3bbf90fe9 1005 write_register(DYNPD, 0);
gume 6:15a3bbf90fe9 1006
gume 6:15a3bbf90fe9 1007 dynamic_payloads_enabled = false;
gume 0:163155b607df 1008 }
gume 0:163155b607df 1009
gume 0:163155b607df 1010 /****************************************************************************/
gume 0:163155b607df 1011
gume 0:163155b607df 1012 void RF24::enableAckPayload(void)
gume 0:163155b607df 1013 {
gume 6:15a3bbf90fe9 1014 //
gume 6:15a3bbf90fe9 1015 // enable ack payload and dynamic payload features
gume 6:15a3bbf90fe9 1016 //
gume 0:163155b607df 1017
gume 0:163155b607df 1018 //toggle_features();
gume 0:163155b607df 1019 write_register(FEATURE,read_register(FEATURE) | _BV(EN_ACK_PAY) | _BV(EN_DPL) );
gume 0:163155b607df 1020
gume 6:15a3bbf90fe9 1021 IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE)));
gume 0:163155b607df 1022
gume 6:15a3bbf90fe9 1023 //
gume 6:15a3bbf90fe9 1024 // Enable dynamic payload on pipes 0 & 1
gume 6:15a3bbf90fe9 1025 //
gume 0:163155b607df 1026
gume 6:15a3bbf90fe9 1027 write_register(DYNPD,read_register(DYNPD) | _BV(DPL_P1) | _BV(DPL_P0));
gume 6:15a3bbf90fe9 1028 dynamic_payloads_enabled = true;
gume 0:163155b607df 1029 }
gume 0:163155b607df 1030
gume 0:163155b607df 1031 /****************************************************************************/
gume 0:163155b607df 1032
gume 6:15a3bbf90fe9 1033 void RF24::enableDynamicAck(void){
gume 6:15a3bbf90fe9 1034 //
gume 6:15a3bbf90fe9 1035 // enable dynamic ack features
gume 6:15a3bbf90fe9 1036 //
gume 0:163155b607df 1037 //toggle_features();
gume 0:163155b607df 1038 write_register(FEATURE,read_register(FEATURE) | _BV(EN_DYN_ACK) );
gume 0:163155b607df 1039
gume 6:15a3bbf90fe9 1040 IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE)));
gume 0:163155b607df 1041
gume 0:163155b607df 1042
gume 0:163155b607df 1043 }
gume 0:163155b607df 1044
gume 0:163155b607df 1045 /****************************************************************************/
gume 0:163155b607df 1046
gume 0:163155b607df 1047 void RF24::writeAckPayload(uint8_t pipe, const void* buf, uint8_t len)
gume 0:163155b607df 1048 {
gume 6:15a3bbf90fe9 1049 const uint8_t* current = reinterpret_cast<const uint8_t*>(buf);
gume 0:163155b607df 1050
gume 6:15a3bbf90fe9 1051 uint8_t data_len = rf24_min(len,32);
gume 0:163155b607df 1052
gume 6:15a3bbf90fe9 1053 beginTransaction();
gume 6:15a3bbf90fe9 1054 spi->write(W_ACK_PAYLOAD | ( pipe & 0x07 ) );
gume 0:163155b607df 1055
gume 6:15a3bbf90fe9 1056 while ( data_len-- )
gume 6:15a3bbf90fe9 1057 spi->write(*current++);
gume 6:15a3bbf90fe9 1058 endTransaction();
gume 6:15a3bbf90fe9 1059
gume 0:163155b607df 1060 }
gume 0:163155b607df 1061
gume 0:163155b607df 1062 /****************************************************************************/
gume 0:163155b607df 1063
gume 0:163155b607df 1064 bool RF24::isAckPayloadAvailable(void)
gume 0:163155b607df 1065 {
gume 6:15a3bbf90fe9 1066 return ! (read_register(FIFO_STATUS) & _BV(RX_EMPTY));
gume 0:163155b607df 1067 }
gume 0:163155b607df 1068
gume 0:163155b607df 1069 /****************************************************************************/
gume 0:163155b607df 1070
gume 0:163155b607df 1071 bool RF24::isPVariant(void)
gume 0:163155b607df 1072 {
gume 6:15a3bbf90fe9 1073 return p_variant ;
gume 0:163155b607df 1074 }
gume 0:163155b607df 1075
gume 0:163155b607df 1076 /****************************************************************************/
gume 0:163155b607df 1077
gume 0:163155b607df 1078 void RF24::setAutoAck(bool enable)
gume 0:163155b607df 1079 {
gume 6:15a3bbf90fe9 1080 if ( enable )
gume 6:15a3bbf90fe9 1081 write_register(EN_AA, 0x3F);
gume 6:15a3bbf90fe9 1082 else
gume 6:15a3bbf90fe9 1083 write_register(EN_AA, 0);
gume 0:163155b607df 1084 }
gume 0:163155b607df 1085
gume 0:163155b607df 1086 /****************************************************************************/
gume 0:163155b607df 1087
gume 0:163155b607df 1088 void RF24::setAutoAck( uint8_t pipe, bool enable )
gume 0:163155b607df 1089 {
gume 6:15a3bbf90fe9 1090 if ( pipe <= 6 )
gume 6:15a3bbf90fe9 1091 {
gume 6:15a3bbf90fe9 1092 uint8_t en_aa = read_register( EN_AA ) ;
gume 6:15a3bbf90fe9 1093 if( enable )
gume 6:15a3bbf90fe9 1094 {
gume 6:15a3bbf90fe9 1095 en_aa |= _BV(pipe) ;
gume 0:163155b607df 1096 }
gume 6:15a3bbf90fe9 1097 else
gume 6:15a3bbf90fe9 1098 {
gume 6:15a3bbf90fe9 1099 en_aa &= ~_BV(pipe) ;
gume 6:15a3bbf90fe9 1100 }
gume 6:15a3bbf90fe9 1101 write_register( EN_AA, en_aa ) ;
gume 6:15a3bbf90fe9 1102 }
gume 0:163155b607df 1103 }
gume 0:163155b607df 1104
gume 0:163155b607df 1105 /****************************************************************************/
gume 0:163155b607df 1106
gume 0:163155b607df 1107 bool RF24::testCarrier(void)
gume 0:163155b607df 1108 {
gume 6:15a3bbf90fe9 1109 return ( read_register(CD) & 1 );
gume 0:163155b607df 1110 }
gume 0:163155b607df 1111
gume 0:163155b607df 1112 /****************************************************************************/
gume 0:163155b607df 1113
gume 0:163155b607df 1114 bool RF24::testRPD(void)
gume 0:163155b607df 1115 {
gume 6:15a3bbf90fe9 1116 return ( read_register(RPD) & 1 ) ;
gume 0:163155b607df 1117 }
gume 0:163155b607df 1118
gume 0:163155b607df 1119 /****************************************************************************/
gume 0:163155b607df 1120
gume 0:163155b607df 1121 void RF24::setPALevel(uint8_t level)
gume 0:163155b607df 1122 {
gume 0:163155b607df 1123
gume 6:15a3bbf90fe9 1124 uint8_t setup = read_register(RF_SETUP) & 0xF8;
gume 0:163155b607df 1125
gume 6:15a3bbf90fe9 1126 if(level > 3){ // If invalid level, go to max PA
gume 6:15a3bbf90fe9 1127 level = (RF24_PA_MAX << 1) + 1; // +1 to support the SI24R1 chip extra bit
gume 6:15a3bbf90fe9 1128 }else{
gume 6:15a3bbf90fe9 1129 level = (level << 1) + 1; // Else set level as requested
gume 6:15a3bbf90fe9 1130 }
gume 0:163155b607df 1131
gume 0:163155b607df 1132
gume 6:15a3bbf90fe9 1133 write_register( RF_SETUP, setup |= level ) ; // Write it to the chip
gume 0:163155b607df 1134 }
gume 0:163155b607df 1135
gume 0:163155b607df 1136 /****************************************************************************/
gume 0:163155b607df 1137
gume 0:163155b607df 1138 uint8_t RF24::getPALevel(void)
gume 0:163155b607df 1139 {
gume 0:163155b607df 1140
gume 6:15a3bbf90fe9 1141 return (read_register(RF_SETUP) & (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH))) >> 1 ;
gume 0:163155b607df 1142 }
gume 0:163155b607df 1143
gume 0:163155b607df 1144 /****************************************************************************/
gume 0:163155b607df 1145
gume 0:163155b607df 1146 bool RF24::setDataRate(rf24_datarate_e speed)
gume 0:163155b607df 1147 {
gume 6:15a3bbf90fe9 1148 bool result = false;
gume 6:15a3bbf90fe9 1149 uint8_t setup = read_register(RF_SETUP) ;
gume 0:163155b607df 1150
gume 6:15a3bbf90fe9 1151 // HIGH and LOW '00' is 1Mbs - our default
gume 6:15a3bbf90fe9 1152 setup &= ~(_BV(RF_DR_LOW) | _BV(RF_DR_HIGH)) ;
gume 6:15a3bbf90fe9 1153
gume 6:15a3bbf90fe9 1154 #if defined(__arm__) || defined (RF24_LINUX) || defined (__ARDUINO_X86__)
gume 6:15a3bbf90fe9 1155 txDelay=250;
gume 6:15a3bbf90fe9 1156 #else //16Mhz Arduino
gume 6:15a3bbf90fe9 1157 txDelay=85;
gume 6:15a3bbf90fe9 1158 #endif
gume 6:15a3bbf90fe9 1159 if( speed == RF24_250KBPS )
gume 6:15a3bbf90fe9 1160 {
gume 6:15a3bbf90fe9 1161 // Must set the RF_DR_LOW to 1; RF_DR_HIGH (used to be RF_DR) is already 0
gume 6:15a3bbf90fe9 1162 // Making it '10'.
gume 6:15a3bbf90fe9 1163 setup |= _BV( RF_DR_LOW ) ;
gume 6:15a3bbf90fe9 1164 #if defined(__arm__) || defined (RF24_LINUX) || defined (__ARDUINO_X86__)
gume 6:15a3bbf90fe9 1165 txDelay=450;
gume 6:15a3bbf90fe9 1166 #else //16Mhz Arduino
gume 6:15a3bbf90fe9 1167 txDelay=155;
gume 6:15a3bbf90fe9 1168 #endif
gume 6:15a3bbf90fe9 1169 }
gume 6:15a3bbf90fe9 1170 else
gume 6:15a3bbf90fe9 1171 {
gume 6:15a3bbf90fe9 1172 // Set 2Mbs, RF_DR (RF_DR_HIGH) is set 1
gume 6:15a3bbf90fe9 1173 // Making it '01'
gume 6:15a3bbf90fe9 1174 if ( speed == RF24_2MBPS )
gume 6:15a3bbf90fe9 1175 {
gume 6:15a3bbf90fe9 1176 setup |= _BV(RF_DR_HIGH);
gume 6:15a3bbf90fe9 1177 #if defined(__arm__) || defined (RF24_LINUX) || defined (__ARDUINO_X86__)
gume 6:15a3bbf90fe9 1178 txDelay=190;
gume 6:15a3bbf90fe9 1179 #else //16Mhz Arduino
gume 6:15a3bbf90fe9 1180 txDelay=65;
gume 6:15a3bbf90fe9 1181 #endif
gume 0:163155b607df 1182 }
gume 6:15a3bbf90fe9 1183 }
gume 6:15a3bbf90fe9 1184 write_register(RF_SETUP,setup);
gume 0:163155b607df 1185
gume 6:15a3bbf90fe9 1186 // Verify our result
gume 6:15a3bbf90fe9 1187 if ( read_register(RF_SETUP) == setup )
gume 6:15a3bbf90fe9 1188 {
gume 6:15a3bbf90fe9 1189 result = true;
gume 6:15a3bbf90fe9 1190 }
gume 6:15a3bbf90fe9 1191 return result;
gume 0:163155b607df 1192 }
gume 0:163155b607df 1193
gume 0:163155b607df 1194 /****************************************************************************/
gume 0:163155b607df 1195
gume 0:163155b607df 1196 rf24_datarate_e RF24::getDataRate( void )
gume 0:163155b607df 1197 {
gume 6:15a3bbf90fe9 1198 rf24_datarate_e result ;
gume 6:15a3bbf90fe9 1199 uint8_t dr = read_register(RF_SETUP) & (_BV(RF_DR_LOW) | _BV(RF_DR_HIGH));
gume 0:163155b607df 1200
gume 6:15a3bbf90fe9 1201 // switch uses RAM (evil!)
gume 6:15a3bbf90fe9 1202 // Order matters in our case below
gume 6:15a3bbf90fe9 1203 if ( dr == _BV(RF_DR_LOW) )
gume 6:15a3bbf90fe9 1204 {
gume 6:15a3bbf90fe9 1205 // '10' = 250KBPS
gume 6:15a3bbf90fe9 1206 result = RF24_250KBPS ;
gume 6:15a3bbf90fe9 1207 }
gume 6:15a3bbf90fe9 1208 else if ( dr == _BV(RF_DR_HIGH) )
gume 6:15a3bbf90fe9 1209 {
gume 6:15a3bbf90fe9 1210 // '01' = 2MBPS
gume 6:15a3bbf90fe9 1211 result = RF24_2MBPS ;
gume 6:15a3bbf90fe9 1212 }
gume 6:15a3bbf90fe9 1213 else
gume 6:15a3bbf90fe9 1214 {
gume 6:15a3bbf90fe9 1215 // '00' = 1MBPS
gume 6:15a3bbf90fe9 1216 result = RF24_1MBPS ;
gume 6:15a3bbf90fe9 1217 }
gume 6:15a3bbf90fe9 1218 return result ;
gume 0:163155b607df 1219 }
gume 0:163155b607df 1220
gume 0:163155b607df 1221 /****************************************************************************/
gume 0:163155b607df 1222
gume 0:163155b607df 1223 void RF24::setCRCLength(rf24_crclength_e length)
gume 0:163155b607df 1224 {
gume 6:15a3bbf90fe9 1225 uint8_t config = read_register(NRF_CONFIG) & ~( _BV(CRCO) | _BV(EN_CRC)) ;
gume 0:163155b607df 1226
gume 6:15a3bbf90fe9 1227 // switch uses RAM (evil!)
gume 6:15a3bbf90fe9 1228 if ( length == RF24_CRC_DISABLED )
gume 6:15a3bbf90fe9 1229 {
gume 6:15a3bbf90fe9 1230 // Do nothing, we turned it off above.
gume 6:15a3bbf90fe9 1231 }
gume 6:15a3bbf90fe9 1232 else if ( length == RF24_CRC_8 )
gume 6:15a3bbf90fe9 1233 {
gume 6:15a3bbf90fe9 1234 config |= _BV(EN_CRC);
gume 6:15a3bbf90fe9 1235 }
gume 6:15a3bbf90fe9 1236 else
gume 6:15a3bbf90fe9 1237 {
gume 6:15a3bbf90fe9 1238 config |= _BV(EN_CRC);
gume 6:15a3bbf90fe9 1239 config |= _BV( CRCO );
gume 6:15a3bbf90fe9 1240 }
gume 6:15a3bbf90fe9 1241 write_register( NRF_CONFIG, config ) ;
gume 0:163155b607df 1242 }
gume 0:163155b607df 1243
gume 0:163155b607df 1244 /****************************************************************************/
gume 0:163155b607df 1245
gume 0:163155b607df 1246 rf24_crclength_e RF24::getCRCLength(void)
gume 0:163155b607df 1247 {
gume 6:15a3bbf90fe9 1248 rf24_crclength_e result = RF24_CRC_DISABLED;
gume 6:15a3bbf90fe9 1249
gume 6:15a3bbf90fe9 1250 uint8_t config = read_register(NRF_CONFIG) & ( _BV(CRCO) | _BV(EN_CRC)) ;
gume 6:15a3bbf90fe9 1251 uint8_t AA = read_register(EN_AA);
gume 6:15a3bbf90fe9 1252
gume 6:15a3bbf90fe9 1253 if ( config & _BV(EN_CRC ) || AA)
gume 6:15a3bbf90fe9 1254 {
gume 6:15a3bbf90fe9 1255 if ( config & _BV(CRCO) )
gume 6:15a3bbf90fe9 1256 result = RF24_CRC_16;
gume 6:15a3bbf90fe9 1257 else
gume 6:15a3bbf90fe9 1258 result = RF24_CRC_8;
gume 6:15a3bbf90fe9 1259 }
gume 0:163155b607df 1260
gume 6:15a3bbf90fe9 1261 return result;
gume 0:163155b607df 1262 }
gume 0:163155b607df 1263
gume 0:163155b607df 1264 /****************************************************************************/
gume 0:163155b607df 1265
gume 0:163155b607df 1266 void RF24::disableCRC( void )
gume 0:163155b607df 1267 {
gume 6:15a3bbf90fe9 1268 uint8_t disable = read_register(NRF_CONFIG) & ~_BV(EN_CRC) ;
gume 6:15a3bbf90fe9 1269 write_register( NRF_CONFIG, disable ) ;
gume 0:163155b607df 1270 }
gume 0:163155b607df 1271
gume 0:163155b607df 1272 /****************************************************************************/
gume 0:163155b607df 1273 void RF24::setRetries(uint8_t delay, uint8_t count)
gume 0:163155b607df 1274 {
gume 6:15a3bbf90fe9 1275 write_register(SETUP_RETR,(delay&0xf)<<ARD | (count&0xf)<<ARC);
gume 0:163155b607df 1276 }