Maniacbug's RF24 arduino library ported to mbed. Tested, it works for Nucleo F411

Dependents:   RF24Network_Send RF24Network_Receive WeatherStation maple_chotobot_rf_motores ... more

Committer:
akashvibhute
Date:
Tue Feb 23 00:40:33 2016 +0000
Revision:
5:ee34c2837c4c
Parent:
3:e94be00fd19e
Child:
6:5cc7136648d1
updated typo on line 116, which determined minimum data length...

Who changed what in which revision?

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