TMRh20 ported to MBED

Fork of TMRh20 by BME SmartLab

Committer:
gume
Date:
Thu Mar 17 07:19:37 2016 +0000
Revision:
3:13e43d3101a5
Parent:
2:3332510eebba
Child:
5:836f5c6da243
- Fixed SPI problems. The problems was the initilaztion order. SPI has to be initialized after its CE/CS pins

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