Maniacbug's nRF24L01 arduino library ported to mbed. Functional with minor issues.

Fork of nRF24L01P_Maniacbug by Christiaan M

Committer:
Christilut
Date:
Thu Apr 04 11:49:28 2013 +0000
Revision:
1:d061e50ccc5d
Parent:
nRF24L01P_MANIC.cpp@0:eb5b89f49c35
Child:
2:a483f426d380
Fixed name

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Christilut 0:eb5b89f49c35 1 /*
Christilut 0:eb5b89f49c35 2 Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
Christilut 0:eb5b89f49c35 3
Christilut 0:eb5b89f49c35 4 This program is free software; you can redistribute it and/or
Christilut 0:eb5b89f49c35 5 modify it under the terms of the GNU General Public License
Christilut 0:eb5b89f49c35 6 version 2 as published by the Free Software Foundation.
Christilut 0:eb5b89f49c35 7 */
Christilut 0:eb5b89f49c35 8
Christilut 1:d061e50ccc5d 9 #include "nRF24L01P_Maniacbug.h"
Christilut 0:eb5b89f49c35 10
Christilut 0:eb5b89f49c35 11 /****************************************************************************/
Christilut 0:eb5b89f49c35 12
Christilut 0:eb5b89f49c35 13 void RF24::csn(int mode)
Christilut 0:eb5b89f49c35 14 {
Christilut 0:eb5b89f49c35 15 // // Minimum ideal SPI bus speed is 2x data rate
Christilut 0:eb5b89f49c35 16 // // If we assume 2Mbs data rate and 16Mhz clock, a
Christilut 0:eb5b89f49c35 17 // // divider of 4 is the minimum we want.
Christilut 0:eb5b89f49c35 18 // // CLK:BUS 8Mhz:2Mhz, 16Mhz:4Mhz, or 20Mhz:5Mhz
Christilut 0:eb5b89f49c35 19 ////#ifdef ARDUINO
Christilut 0:eb5b89f49c35 20 //// spi.setBitOrder(MSBFIRST);
Christilut 0:eb5b89f49c35 21 //// spi.setDataMode(SPI_MODE0);
Christilut 0:eb5b89f49c35 22 //// spi.setClockDivider(SPI_CLOCK_DIV4);
Christilut 0:eb5b89f49c35 23 ////#endif
Christilut 0:eb5b89f49c35 24 //// digitalWrite(csn_pin,mode);
Christilut 0:eb5b89f49c35 25 //
Christilut 0:eb5b89f49c35 26 //
Christilut 0:eb5b89f49c35 27 csn_pin = mode;
Christilut 0:eb5b89f49c35 28 }
Christilut 0:eb5b89f49c35 29
Christilut 0:eb5b89f49c35 30 /****************************************************************************/
Christilut 0:eb5b89f49c35 31
Christilut 0:eb5b89f49c35 32 void RF24::ce(int level)
Christilut 0:eb5b89f49c35 33 {
Christilut 0:eb5b89f49c35 34 //digitalWrite(ce_pin,level);
Christilut 0:eb5b89f49c35 35 ce_pin = level;
Christilut 0:eb5b89f49c35 36 wait_us(_NRF24L01P_TIMING_Tpece2csn_us);
Christilut 0:eb5b89f49c35 37 }
Christilut 0:eb5b89f49c35 38
Christilut 0:eb5b89f49c35 39 /****************************************************************************/
Christilut 0:eb5b89f49c35 40
Christilut 0:eb5b89f49c35 41 uint8_t RF24::read_register(uint8_t reg, uint8_t* buf, uint8_t len)
Christilut 0:eb5b89f49c35 42 {
Christilut 0:eb5b89f49c35 43 uint8_t status;
Christilut 0:eb5b89f49c35 44
Christilut 0:eb5b89f49c35 45 csn(LOW);
Christilut 0:eb5b89f49c35 46 status = spi.write( R_REGISTER | ( REGISTER_MASK & reg ) );
Christilut 0:eb5b89f49c35 47 while ( len-- )
Christilut 0:eb5b89f49c35 48 *buf++ = spi.write(0xff);
Christilut 0:eb5b89f49c35 49
Christilut 0:eb5b89f49c35 50 csn(HIGH);
Christilut 0:eb5b89f49c35 51
Christilut 0:eb5b89f49c35 52 return status;
Christilut 0:eb5b89f49c35 53 }
Christilut 0:eb5b89f49c35 54
Christilut 0:eb5b89f49c35 55 /****************************************************************************/
Christilut 0:eb5b89f49c35 56
Christilut 0:eb5b89f49c35 57 uint8_t RF24::read_register(uint8_t reg) //checked
Christilut 0:eb5b89f49c35 58 {
Christilut 0:eb5b89f49c35 59 csn(LOW);
Christilut 0:eb5b89f49c35 60 spi.write( R_REGISTER | ( REGISTER_MASK & reg ) );
Christilut 0:eb5b89f49c35 61 uint8_t result = spi.write(0xff);
Christilut 0:eb5b89f49c35 62
Christilut 0:eb5b89f49c35 63 csn(HIGH);
Christilut 0:eb5b89f49c35 64 return result;
Christilut 0:eb5b89f49c35 65 }
Christilut 0:eb5b89f49c35 66
Christilut 0:eb5b89f49c35 67 /****************************************************************************/
Christilut 0:eb5b89f49c35 68
Christilut 0:eb5b89f49c35 69 uint8_t RF24::write_register(uint8_t reg, const uint8_t* buf, uint8_t len)
Christilut 0:eb5b89f49c35 70 {
Christilut 0:eb5b89f49c35 71 uint8_t status;
Christilut 0:eb5b89f49c35 72 int originalCe = ce_pin;
Christilut 0:eb5b89f49c35 73 ce(LOW);
Christilut 0:eb5b89f49c35 74
Christilut 0:eb5b89f49c35 75 csn(LOW);
Christilut 0:eb5b89f49c35 76 status = spi.write( W_REGISTER | ( REGISTER_MASK & reg ) );
Christilut 0:eb5b89f49c35 77 while ( len-- )
Christilut 0:eb5b89f49c35 78 spi.write(*buf++);
Christilut 0:eb5b89f49c35 79
Christilut 0:eb5b89f49c35 80 csn(HIGH);
Christilut 0:eb5b89f49c35 81
Christilut 0:eb5b89f49c35 82 ce_pin = originalCe;
Christilut 0:eb5b89f49c35 83 wait_us( _NRF24L01P_TIMING_Tpece2csn_us );
Christilut 0:eb5b89f49c35 84
Christilut 0:eb5b89f49c35 85 return status;
Christilut 0:eb5b89f49c35 86 }
Christilut 0:eb5b89f49c35 87
Christilut 0:eb5b89f49c35 88 /****************************************************************************/
Christilut 0:eb5b89f49c35 89
Christilut 0:eb5b89f49c35 90 uint8_t RF24::write_register(uint8_t reg, uint8_t value) //checked
Christilut 0:eb5b89f49c35 91 {
Christilut 0:eb5b89f49c35 92 uint8_t status;
Christilut 0:eb5b89f49c35 93
Christilut 0:eb5b89f49c35 94 // IF_SERIAL_DEBUG(printf(PSTR("write_register(%02x,%02x)\r\n"),reg,value));
Christilut 0:eb5b89f49c35 95 int originalCe = ce_pin;
Christilut 0:eb5b89f49c35 96 ce(LOW);
Christilut 0:eb5b89f49c35 97
Christilut 0:eb5b89f49c35 98
Christilut 0:eb5b89f49c35 99 csn(LOW);
Christilut 0:eb5b89f49c35 100 status = spi.write( W_REGISTER | ( REGISTER_MASK & reg ) );
Christilut 0:eb5b89f49c35 101 spi.write(value);
Christilut 0:eb5b89f49c35 102 csn(HIGH);
Christilut 0:eb5b89f49c35 103
Christilut 0:eb5b89f49c35 104 ce_pin = originalCe;
Christilut 0:eb5b89f49c35 105 wait_us( _NRF24L01P_TIMING_Tpece2csn_us );
Christilut 0:eb5b89f49c35 106
Christilut 0:eb5b89f49c35 107 return status;
Christilut 0:eb5b89f49c35 108 }
Christilut 0:eb5b89f49c35 109
Christilut 0:eb5b89f49c35 110 /****************************************************************************/
Christilut 0:eb5b89f49c35 111
Christilut 0:eb5b89f49c35 112 uint8_t RF24::write_payload(const void* buf, uint8_t len)
Christilut 0:eb5b89f49c35 113 {
Christilut 0:eb5b89f49c35 114 uint8_t status;
Christilut 0:eb5b89f49c35 115
Christilut 0:eb5b89f49c35 116 const uint8_t* current = reinterpret_cast<const uint8_t*>(buf);
Christilut 0:eb5b89f49c35 117
Christilut 0:eb5b89f49c35 118 uint8_t data_len = min(len,payload_size);
Christilut 0:eb5b89f49c35 119 uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len;
Christilut 0:eb5b89f49c35 120
Christilut 0:eb5b89f49c35 121 //printf("[Writing %u bytes %u blanks]",data_len,blank_len);
Christilut 0:eb5b89f49c35 122
Christilut 0:eb5b89f49c35 123 csn(LOW);
Christilut 0:eb5b89f49c35 124 status = spi.write( W_TX_PAYLOAD );
Christilut 0:eb5b89f49c35 125 while ( data_len-- )
Christilut 0:eb5b89f49c35 126 spi.write(*current++);
Christilut 0:eb5b89f49c35 127 while ( blank_len-- )
Christilut 0:eb5b89f49c35 128 spi.write(0);
Christilut 0:eb5b89f49c35 129 csn(HIGH);
Christilut 0:eb5b89f49c35 130
Christilut 0:eb5b89f49c35 131 return status;
Christilut 0:eb5b89f49c35 132 }
Christilut 0:eb5b89f49c35 133
Christilut 0:eb5b89f49c35 134 /****************************************************************************/
Christilut 0:eb5b89f49c35 135
Christilut 0:eb5b89f49c35 136 uint8_t RF24::read_payload(void* buf, uint8_t len)
Christilut 0:eb5b89f49c35 137 {
Christilut 0:eb5b89f49c35 138 uint8_t status;
Christilut 0:eb5b89f49c35 139 uint8_t* current = reinterpret_cast<uint8_t*>(buf);
Christilut 0:eb5b89f49c35 140
Christilut 0:eb5b89f49c35 141 uint8_t data_len = min(len,payload_size);
Christilut 0:eb5b89f49c35 142 uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len;
Christilut 0:eb5b89f49c35 143
Christilut 0:eb5b89f49c35 144 //printf("[Reading %u bytes %u blanks]",data_len,blank_len);
Christilut 0:eb5b89f49c35 145
Christilut 0:eb5b89f49c35 146 csn(LOW);
Christilut 0:eb5b89f49c35 147 status = spi.write( R_RX_PAYLOAD );
Christilut 0:eb5b89f49c35 148 while ( data_len-- )
Christilut 0:eb5b89f49c35 149 *current++ = spi.write(0xff);
Christilut 0:eb5b89f49c35 150 while ( blank_len-- )
Christilut 0:eb5b89f49c35 151 spi.write(0xff);
Christilut 0:eb5b89f49c35 152 csn(HIGH);
Christilut 0:eb5b89f49c35 153
Christilut 0:eb5b89f49c35 154 return status;
Christilut 0:eb5b89f49c35 155 }
Christilut 0:eb5b89f49c35 156
Christilut 0:eb5b89f49c35 157 /****************************************************************************/
Christilut 0:eb5b89f49c35 158
Christilut 0:eb5b89f49c35 159 uint8_t RF24::flush_rx(void)
Christilut 0:eb5b89f49c35 160 {
Christilut 0:eb5b89f49c35 161 uint8_t status;
Christilut 0:eb5b89f49c35 162
Christilut 0:eb5b89f49c35 163 csn(LOW);
Christilut 0:eb5b89f49c35 164 status = spi.write( FLUSH_RX );
Christilut 0:eb5b89f49c35 165 csn(HIGH);
Christilut 0:eb5b89f49c35 166
Christilut 0:eb5b89f49c35 167 return status;
Christilut 0:eb5b89f49c35 168 }
Christilut 0:eb5b89f49c35 169
Christilut 0:eb5b89f49c35 170 /****************************************************************************/
Christilut 0:eb5b89f49c35 171
Christilut 0:eb5b89f49c35 172 uint8_t RF24::flush_tx(void)
Christilut 0:eb5b89f49c35 173 {
Christilut 0:eb5b89f49c35 174 uint8_t status;
Christilut 0:eb5b89f49c35 175
Christilut 0:eb5b89f49c35 176 csn(LOW);
Christilut 0:eb5b89f49c35 177 status = spi.write( FLUSH_TX );
Christilut 0:eb5b89f49c35 178 csn(HIGH);
Christilut 0:eb5b89f49c35 179
Christilut 0:eb5b89f49c35 180 return status;
Christilut 0:eb5b89f49c35 181 }
Christilut 0:eb5b89f49c35 182
Christilut 0:eb5b89f49c35 183 /****************************************************************************/
Christilut 0:eb5b89f49c35 184
Christilut 0:eb5b89f49c35 185 uint8_t RF24::get_status(void)
Christilut 0:eb5b89f49c35 186 {
Christilut 0:eb5b89f49c35 187 uint8_t status;
Christilut 0:eb5b89f49c35 188
Christilut 0:eb5b89f49c35 189 csn(LOW);
Christilut 0:eb5b89f49c35 190 status = spi.write( NOP );
Christilut 0:eb5b89f49c35 191 csn(HIGH);
Christilut 0:eb5b89f49c35 192
Christilut 0:eb5b89f49c35 193 return status;
Christilut 0:eb5b89f49c35 194 }
Christilut 0:eb5b89f49c35 195
Christilut 0:eb5b89f49c35 196 /****************************************************************************/
Christilut 0:eb5b89f49c35 197
Christilut 0:eb5b89f49c35 198 void RF24::print_status(uint8_t status)
Christilut 0:eb5b89f49c35 199 {
Christilut 0:eb5b89f49c35 200 printf("STATUS = 0x%02x RX_DR=%x TX_DS=%x MAX_RT=%x RX_P_NO=%x TX_FULL=%x\r\n",
Christilut 0:eb5b89f49c35 201 status,
Christilut 0:eb5b89f49c35 202 (status & RX_DR)?1:0,
Christilut 0:eb5b89f49c35 203 (status & TX_DS)?1:0,
Christilut 0:eb5b89f49c35 204 (status & MAX_RT)?1:0,
Christilut 0:eb5b89f49c35 205 ((status >> RX_P_NO) & 7),
Christilut 0:eb5b89f49c35 206 (status & TX_FULL)?1:0
Christilut 0:eb5b89f49c35 207 );
Christilut 0:eb5b89f49c35 208 }
Christilut 0:eb5b89f49c35 209
Christilut 0:eb5b89f49c35 210 ///****************************************************************************/
Christilut 0:eb5b89f49c35 211
Christilut 0:eb5b89f49c35 212 void RF24::print_observe_tx(uint8_t value)
Christilut 0:eb5b89f49c35 213 {
Christilut 0:eb5b89f49c35 214 printf("OBSERVE_TX=%02x: POLS_CNT=%x ARC_CNT=%x\r\n",
Christilut 0:eb5b89f49c35 215 value,
Christilut 0:eb5b89f49c35 216 (value >> PLOS_CNT) & 15,
Christilut 0:eb5b89f49c35 217 (value >> ARC_CNT) & 15
Christilut 0:eb5b89f49c35 218 );
Christilut 0:eb5b89f49c35 219 }
Christilut 0:eb5b89f49c35 220
Christilut 0:eb5b89f49c35 221 /****************************************************************************/
Christilut 0:eb5b89f49c35 222
Christilut 0:eb5b89f49c35 223 void RF24::print_byte_register(const char* name, uint8_t reg, uint8_t qty)
Christilut 0:eb5b89f49c35 224 {
Christilut 0:eb5b89f49c35 225 // char extra_tab = strlen(name) < 8 ? '\t' : 0;
Christilut 0:eb5b89f49c35 226 printf("%s =",name);
Christilut 0:eb5b89f49c35 227 while (qty--)
Christilut 0:eb5b89f49c35 228 printf(" 0x%02x",read_register(reg++));
Christilut 0:eb5b89f49c35 229 printf("\r\n");
Christilut 0:eb5b89f49c35 230 }
Christilut 0:eb5b89f49c35 231
Christilut 0:eb5b89f49c35 232 /****************************************************************************/
Christilut 0:eb5b89f49c35 233
Christilut 0:eb5b89f49c35 234 void RF24::print_address_register(const char* name, uint8_t reg, uint8_t qty)
Christilut 0:eb5b89f49c35 235 {
Christilut 0:eb5b89f49c35 236 // char extra_tab = strlen(name) < 8 ? '\t' : 0;
Christilut 0:eb5b89f49c35 237 printf("%s =",name);
Christilut 0:eb5b89f49c35 238
Christilut 0:eb5b89f49c35 239 while (qty--) {
Christilut 0:eb5b89f49c35 240 uint8_t buffer[5];
Christilut 0:eb5b89f49c35 241 read_register(reg++,buffer,sizeof buffer);
Christilut 0:eb5b89f49c35 242
Christilut 0:eb5b89f49c35 243 printf(" 0x");
Christilut 0:eb5b89f49c35 244 uint8_t* bufptr = buffer + sizeof buffer;
Christilut 0:eb5b89f49c35 245 while( --bufptr >= buffer )
Christilut 0:eb5b89f49c35 246 printf("%02x",*bufptr);
Christilut 0:eb5b89f49c35 247 }
Christilut 0:eb5b89f49c35 248
Christilut 0:eb5b89f49c35 249 printf("\r\n");
Christilut 0:eb5b89f49c35 250 }
Christilut 0:eb5b89f49c35 251
Christilut 0:eb5b89f49c35 252 /****************************************************************************/
Christilut 0:eb5b89f49c35 253
Christilut 0:eb5b89f49c35 254 RF24::RF24(PinName mosi, PinName miso, PinName sck, PinName _cspin, PinName _cepin):
Christilut 0:eb5b89f49c35 255 ce_pin(_cepin), csn_pin(_cspin), wide_band(true), p_variant(false),
Christilut 0:eb5b89f49c35 256 payload_size(32), ack_payload_available(false), dynamic_payloads_enabled(false),
Christilut 0:eb5b89f49c35 257 pipe0_reading_address(0), spi(mosi, miso, sck)
Christilut 0:eb5b89f49c35 258 {
Christilut 0:eb5b89f49c35 259 }
Christilut 0:eb5b89f49c35 260
Christilut 0:eb5b89f49c35 261 /****************************************************************************/
Christilut 0:eb5b89f49c35 262
Christilut 0:eb5b89f49c35 263 void RF24::setChannel(uint8_t channel)
Christilut 0:eb5b89f49c35 264 {
Christilut 0:eb5b89f49c35 265 // TODO: This method could take advantage of the 'wide_band' calculation
Christilut 0:eb5b89f49c35 266 // done in setChannel() to require certain channel spacing.
Christilut 0:eb5b89f49c35 267
Christilut 0:eb5b89f49c35 268 const uint8_t max_channel = 127;
Christilut 0:eb5b89f49c35 269 write_register(RF_CH,min(channel,max_channel));
Christilut 0:eb5b89f49c35 270 }
Christilut 0:eb5b89f49c35 271
Christilut 0:eb5b89f49c35 272 /****************************************************************************/
Christilut 0:eb5b89f49c35 273
Christilut 0:eb5b89f49c35 274 void RF24::setPayloadSize(uint8_t size)
Christilut 0:eb5b89f49c35 275 {
Christilut 0:eb5b89f49c35 276 const uint8_t max_payload_size = 32;
Christilut 0:eb5b89f49c35 277 payload_size = min(size,max_payload_size);
Christilut 0:eb5b89f49c35 278 }
Christilut 0:eb5b89f49c35 279
Christilut 0:eb5b89f49c35 280 /****************************************************************************/
Christilut 0:eb5b89f49c35 281
Christilut 0:eb5b89f49c35 282 uint8_t RF24::getPayloadSize(void)
Christilut 0:eb5b89f49c35 283 {
Christilut 0:eb5b89f49c35 284 return payload_size;
Christilut 0:eb5b89f49c35 285 }
Christilut 0:eb5b89f49c35 286
Christilut 0:eb5b89f49c35 287 /****************************************************************************/
Christilut 0:eb5b89f49c35 288
Christilut 0:eb5b89f49c35 289 static const char rf24_datarate_e_str_0[] = "1MBPS";
Christilut 0:eb5b89f49c35 290 static const char rf24_datarate_e_str_1[] = "2MBPS";
Christilut 0:eb5b89f49c35 291 static const char rf24_datarate_e_str_2[] = "250KBPS";
Christilut 0:eb5b89f49c35 292 static const char * const rf24_datarate_e_str_P[] = {
Christilut 0:eb5b89f49c35 293 rf24_datarate_e_str_0,
Christilut 0:eb5b89f49c35 294 rf24_datarate_e_str_1,
Christilut 0:eb5b89f49c35 295 rf24_datarate_e_str_2,
Christilut 0:eb5b89f49c35 296 };
Christilut 0:eb5b89f49c35 297 static const char rf24_model_e_str_0[] = "nRF24L01";
Christilut 0:eb5b89f49c35 298 static const char rf24_model_e_str_1[] = "nRF24L01+";
Christilut 0:eb5b89f49c35 299 static const char * const rf24_model_e_str_P[] = {
Christilut 0:eb5b89f49c35 300 rf24_model_e_str_0,
Christilut 0:eb5b89f49c35 301 rf24_model_e_str_1,
Christilut 0:eb5b89f49c35 302 };
Christilut 0:eb5b89f49c35 303 static const char rf24_crclength_e_str_0[] = "Disabled";
Christilut 0:eb5b89f49c35 304 static const char rf24_crclength_e_str_1[] = "8 bits";
Christilut 0:eb5b89f49c35 305 static const char rf24_crclength_e_str_2[] = "16 bits" ;
Christilut 0:eb5b89f49c35 306 static const char * const rf24_crclength_e_str_P[] = {
Christilut 0:eb5b89f49c35 307 rf24_crclength_e_str_0,
Christilut 0:eb5b89f49c35 308 rf24_crclength_e_str_1,
Christilut 0:eb5b89f49c35 309 rf24_crclength_e_str_2,
Christilut 0:eb5b89f49c35 310 };
Christilut 0:eb5b89f49c35 311 static const char rf24_pa_dbm_e_str_0[] = "PA_MIN";
Christilut 0:eb5b89f49c35 312 static const char rf24_pa_dbm_e_str_1[] = "PA_LOW";
Christilut 0:eb5b89f49c35 313 static const char rf24_pa_dbm_e_str_2[] = "PA_MED";
Christilut 0:eb5b89f49c35 314 static const char rf24_pa_dbm_e_str_3[] = "PA_HIGH";
Christilut 0:eb5b89f49c35 315 static const char * const rf24_pa_dbm_e_str_P[] = {
Christilut 0:eb5b89f49c35 316 rf24_pa_dbm_e_str_0,
Christilut 0:eb5b89f49c35 317 rf24_pa_dbm_e_str_1,
Christilut 0:eb5b89f49c35 318 rf24_pa_dbm_e_str_2,
Christilut 0:eb5b89f49c35 319 rf24_pa_dbm_e_str_3,
Christilut 0:eb5b89f49c35 320 };
Christilut 0:eb5b89f49c35 321
Christilut 0:eb5b89f49c35 322 void RF24::printDetails(void)
Christilut 0:eb5b89f49c35 323 {
Christilut 0:eb5b89f49c35 324 print_status(get_status());
Christilut 0:eb5b89f49c35 325
Christilut 0:eb5b89f49c35 326 print_address_register("RX_ADDR_P0-1",RX_ADDR_P0,2);
Christilut 0:eb5b89f49c35 327 print_byte_register("RX_ADDR_P2-5", RX_ADDR_P2,4);
Christilut 0:eb5b89f49c35 328 print_address_register("TX_ADDR", TX_ADDR);
Christilut 0:eb5b89f49c35 329
Christilut 0:eb5b89f49c35 330 print_byte_register("RX_PW_P0-6", RX_PW_P0,6);
Christilut 0:eb5b89f49c35 331 print_byte_register("EN_AA", EN_AA);
Christilut 0:eb5b89f49c35 332 print_byte_register("EN_RXADDR", EN_RXADDR);
Christilut 0:eb5b89f49c35 333 print_byte_register("RF_CH", RF_CH);
Christilut 0:eb5b89f49c35 334 print_byte_register("RF_SETUP", RF_SETUP);
Christilut 0:eb5b89f49c35 335 print_byte_register("CONFIG", CONFIG);
Christilut 0:eb5b89f49c35 336 print_byte_register("DYNPD/FEATURE",DYNPD,2);
Christilut 0:eb5b89f49c35 337
Christilut 0:eb5b89f49c35 338 printf("Data Rate\t = %s\r\n", rf24_datarate_e_str_P[getDataRate()]);
Christilut 0:eb5b89f49c35 339 printf("Model\t\t = %s\r\n", rf24_model_e_str_P[isPVariant()]);
Christilut 0:eb5b89f49c35 340 printf("CRC Length\t = %s\r\n", rf24_crclength_e_str_P[getCRCLength()]);
Christilut 0:eb5b89f49c35 341 printf("PA Power\t = %s\r\n", rf24_pa_dbm_e_str_P[getPALevel()]);
Christilut 0:eb5b89f49c35 342 }
Christilut 0:eb5b89f49c35 343
Christilut 0:eb5b89f49c35 344 /****************************************************************************/
Christilut 0:eb5b89f49c35 345
Christilut 0:eb5b89f49c35 346 void RF24::begin(void)
Christilut 0:eb5b89f49c35 347 {
Christilut 0:eb5b89f49c35 348 // Initialize pins
Christilut 0:eb5b89f49c35 349 // pinMode(ce_pin,OUTPUT); //ARD
Christilut 0:eb5b89f49c35 350 // pinMode(csn_pin,OUTPUT);
Christilut 0:eb5b89f49c35 351
Christilut 0:eb5b89f49c35 352 mainTimer.start();
Christilut 0:eb5b89f49c35 353
Christilut 0:eb5b89f49c35 354
Christilut 0:eb5b89f49c35 355 spi.frequency(_NRF24L01P_SPI_MAX_DATA_RATE/5); // 2Mbit, 1/5th the maximum transfer rate for the SPI bus
Christilut 0:eb5b89f49c35 356 spi.format(8,0); // 8-bit, ClockPhase = 0, ClockPolarity = 0
Christilut 0:eb5b89f49c35 357
Christilut 0:eb5b89f49c35 358 wait_us(_NRF24L01P_TIMING_Tundef2pd_us); // Wait for Power-on reset //MBED
Christilut 0:eb5b89f49c35 359
Christilut 0:eb5b89f49c35 360 // Initialize SPI bus
Christilut 0:eb5b89f49c35 361 // spi.begin(); //ARD
Christilut 0:eb5b89f49c35 362
Christilut 0:eb5b89f49c35 363 ce(LOW);
Christilut 0:eb5b89f49c35 364 csn(HIGH);
Christilut 0:eb5b89f49c35 365
Christilut 0:eb5b89f49c35 366 // Must allow the radio time to settle else configuration bits will not necessarily stick.
Christilut 0:eb5b89f49c35 367 // This is actually only required following power up but some settling time also appears to
Christilut 0:eb5b89f49c35 368 // be required after resets too. For full coverage, we'll always assume the worst.
Christilut 0:eb5b89f49c35 369 // Enabling 16b CRC is by far the most obvious case if the wrong timing is used - or skipped.
Christilut 0:eb5b89f49c35 370 // Technically we require 4.5ms + 14us as a worst case. We'll just call it 5ms for good measure.
Christilut 0:eb5b89f49c35 371 // WARNING: Delay is based on P-variant whereby non-P *may* require different timing.
Christilut 0:eb5b89f49c35 372 // delay( 5 ) ;
Christilut 0:eb5b89f49c35 373 wait_ms(5);
Christilut 0:eb5b89f49c35 374
Christilut 0:eb5b89f49c35 375 // Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier
Christilut 0:eb5b89f49c35 376 // WARNING: If this is ever lowered, either 250KBS mode with AA is broken or maximum packet
Christilut 0:eb5b89f49c35 377 // sizes must never be used. See documentation for a more complete explanation.
Christilut 0:eb5b89f49c35 378 write_register(SETUP_RETR,(4 << ARD) | (15 << ARC));
Christilut 0:eb5b89f49c35 379
Christilut 0:eb5b89f49c35 380 // Restore our default PA level
Christilut 0:eb5b89f49c35 381 setPALevel( RF24_PA_MAX ) ;
Christilut 0:eb5b89f49c35 382
Christilut 0:eb5b89f49c35 383 // Determine if this is a p or non-p RF24 module and then
Christilut 0:eb5b89f49c35 384 // reset our data rate back to default value. This works
Christilut 0:eb5b89f49c35 385 // because a non-P variant won't allow the data rate to
Christilut 0:eb5b89f49c35 386 // be set to 250Kbps.
Christilut 0:eb5b89f49c35 387 if( setDataRate( RF24_250KBPS ) ) {
Christilut 0:eb5b89f49c35 388 p_variant = true ;
Christilut 0:eb5b89f49c35 389 }
Christilut 0:eb5b89f49c35 390
Christilut 0:eb5b89f49c35 391 // Then set the data rate to the slowest (and most reliable) speed supported by all
Christilut 0:eb5b89f49c35 392 // hardware.
Christilut 0:eb5b89f49c35 393 setDataRate( RF24_1MBPS ) ;
Christilut 0:eb5b89f49c35 394
Christilut 0:eb5b89f49c35 395 // Initialize CRC and request 2-byte (16bit) CRC
Christilut 0:eb5b89f49c35 396 setCRCLength( RF24_CRC_16 ) ;
Christilut 0:eb5b89f49c35 397
Christilut 0:eb5b89f49c35 398 // Disable dynamic payloads, to match dynamic_payloads_enabled setting
Christilut 0:eb5b89f49c35 399 write_register(DYNPD,0);
Christilut 0:eb5b89f49c35 400
Christilut 0:eb5b89f49c35 401 // Reset current status
Christilut 0:eb5b89f49c35 402 // Notice reset and flush is the last thing we do
Christilut 0:eb5b89f49c35 403 write_register(STATUS,RX_DR | TX_DS | MAX_RT );
Christilut 0:eb5b89f49c35 404
Christilut 0:eb5b89f49c35 405 // Set up default configuration. Callers can always change it later.
Christilut 0:eb5b89f49c35 406 // This channel should be universally safe and not bleed over into adjacent
Christilut 0:eb5b89f49c35 407 // spectrum.
Christilut 0:eb5b89f49c35 408 setChannel(76);
Christilut 0:eb5b89f49c35 409
Christilut 0:eb5b89f49c35 410 // Flush buffers
Christilut 0:eb5b89f49c35 411 flush_rx();
Christilut 0:eb5b89f49c35 412 flush_tx();
Christilut 0:eb5b89f49c35 413 }
Christilut 0:eb5b89f49c35 414
Christilut 0:eb5b89f49c35 415 /****************************************************************************/
Christilut 0:eb5b89f49c35 416
Christilut 0:eb5b89f49c35 417 void RF24::startListening(void)
Christilut 0:eb5b89f49c35 418 {
Christilut 0:eb5b89f49c35 419 write_register(CONFIG, read_register(CONFIG) | PWR_UP | PRIM_RX);
Christilut 0:eb5b89f49c35 420 write_register(STATUS, RX_DR | TX_DS | MAX_RT );
Christilut 0:eb5b89f49c35 421
Christilut 0:eb5b89f49c35 422 // Restore the pipe0 adddress, if exists
Christilut 0:eb5b89f49c35 423 if (pipe0_reading_address)
Christilut 0:eb5b89f49c35 424 write_register(RX_ADDR_P0, reinterpret_cast<const uint8_t*>(&pipe0_reading_address), 5);
Christilut 0:eb5b89f49c35 425
Christilut 0:eb5b89f49c35 426 // Flush buffers
Christilut 0:eb5b89f49c35 427 flush_rx();
Christilut 0:eb5b89f49c35 428 flush_tx();
Christilut 0:eb5b89f49c35 429
Christilut 0:eb5b89f49c35 430 // Go!
Christilut 0:eb5b89f49c35 431 ce(HIGH);;
Christilut 0:eb5b89f49c35 432
Christilut 0:eb5b89f49c35 433 // wait for the radio to come up (130us actually only needed)
Christilut 0:eb5b89f49c35 434 // delayMicroseconds(130);
Christilut 0:eb5b89f49c35 435 wait_us(130);
Christilut 0:eb5b89f49c35 436 }
Christilut 0:eb5b89f49c35 437
Christilut 0:eb5b89f49c35 438 /****************************************************************************/
Christilut 0:eb5b89f49c35 439
Christilut 0:eb5b89f49c35 440 void RF24::stopListening(void)
Christilut 0:eb5b89f49c35 441 {
Christilut 0:eb5b89f49c35 442 ce(LOW);
Christilut 0:eb5b89f49c35 443 flush_tx();
Christilut 0:eb5b89f49c35 444 flush_rx();
Christilut 0:eb5b89f49c35 445 }
Christilut 0:eb5b89f49c35 446
Christilut 0:eb5b89f49c35 447 /****************************************************************************/
Christilut 0:eb5b89f49c35 448
Christilut 0:eb5b89f49c35 449 void RF24::powerDown(void)
Christilut 0:eb5b89f49c35 450 {
Christilut 0:eb5b89f49c35 451 write_register(CONFIG,read_register(CONFIG) & ~PWR_UP);
Christilut 0:eb5b89f49c35 452 }
Christilut 0:eb5b89f49c35 453
Christilut 0:eb5b89f49c35 454 /****************************************************************************/
Christilut 0:eb5b89f49c35 455
Christilut 0:eb5b89f49c35 456 void RF24::powerUp(void)
Christilut 0:eb5b89f49c35 457 {
Christilut 0:eb5b89f49c35 458 write_register(CONFIG,read_register(CONFIG) | PWR_UP);
Christilut 0:eb5b89f49c35 459 }
Christilut 0:eb5b89f49c35 460
Christilut 0:eb5b89f49c35 461 /******************************************************************/
Christilut 0:eb5b89f49c35 462
Christilut 0:eb5b89f49c35 463 bool RF24::write( const void* buf, uint8_t len )
Christilut 0:eb5b89f49c35 464 {
Christilut 0:eb5b89f49c35 465 bool result = false;
Christilut 0:eb5b89f49c35 466
Christilut 0:eb5b89f49c35 467 // Begin the write
Christilut 0:eb5b89f49c35 468 startWrite(buf,len);
Christilut 0:eb5b89f49c35 469
Christilut 0:eb5b89f49c35 470 // ------------
Christilut 0:eb5b89f49c35 471 // At this point we could return from a non-blocking write, and then call
Christilut 0:eb5b89f49c35 472 // the rest after an interrupt
Christilut 0:eb5b89f49c35 473
Christilut 0:eb5b89f49c35 474 // Instead, we are going to block here until we get TX_DS (transmission completed and ack'd)
Christilut 0:eb5b89f49c35 475 // or MAX_RT (maximum retries, transmission failed). Also, we'll timeout in case the radio
Christilut 0:eb5b89f49c35 476 // is flaky and we get neither.
Christilut 0:eb5b89f49c35 477
Christilut 0:eb5b89f49c35 478 // IN the end, the send should be blocking. It comes back in 60ms worst case, or much faster
Christilut 0:eb5b89f49c35 479 // if I tighted up the retry logic. (Default settings will be 1500us.
Christilut 0:eb5b89f49c35 480 // Monitor the send
Christilut 0:eb5b89f49c35 481 uint8_t observe_tx;
Christilut 0:eb5b89f49c35 482 uint8_t status;
Christilut 0:eb5b89f49c35 483 uint32_t sent_at = mainTimer.read_ms();
Christilut 0:eb5b89f49c35 484 const uint32_t timeout = 500; //ms to wait for timeout
Christilut 0:eb5b89f49c35 485 do {
Christilut 0:eb5b89f49c35 486 status = read_register(OBSERVE_TX,&observe_tx,1);
Christilut 0:eb5b89f49c35 487 // IF_SERIAL_DEBUG(Serial.print(observe_tx,HEX));
Christilut 0:eb5b89f49c35 488 } while( ! ( status & ( TX_DS | MAX_RT ) ) && ( mainTimer.read_ms() - sent_at < timeout ) );
Christilut 0:eb5b89f49c35 489
Christilut 0:eb5b89f49c35 490 // The part above is what you could recreate with your own interrupt handler,
Christilut 0:eb5b89f49c35 491 // and then call this when you got an interrupt
Christilut 0:eb5b89f49c35 492 // ------------
Christilut 0:eb5b89f49c35 493
Christilut 0:eb5b89f49c35 494 // Call this when you get an interrupt
Christilut 0:eb5b89f49c35 495 // The status tells us three things
Christilut 0:eb5b89f49c35 496 // * The send was successful (TX_DS)
Christilut 0:eb5b89f49c35 497 // * The send failed, too many retries (MAX_RT)
Christilut 0:eb5b89f49c35 498 // * There is an ack packet waiting (RX_DR)
Christilut 0:eb5b89f49c35 499 bool tx_ok, tx_fail;
Christilut 0:eb5b89f49c35 500 whatHappened(tx_ok,tx_fail,ack_payload_available);
Christilut 0:eb5b89f49c35 501
Christilut 0:eb5b89f49c35 502 //printf("%u%u%u\r\n",tx_ok,tx_fail,ack_payload_available);
Christilut 0:eb5b89f49c35 503
Christilut 0:eb5b89f49c35 504 result = tx_ok;
Christilut 0:eb5b89f49c35 505 // IF_SERIAL_DEBUG(Serial.print(result?"...OK.":"...Failed"));
Christilut 0:eb5b89f49c35 506
Christilut 0:eb5b89f49c35 507 // Handle the ack packet
Christilut 0:eb5b89f49c35 508 if ( ack_payload_available ) {
Christilut 0:eb5b89f49c35 509 ack_payload_length = getDynamicPayloadSize();
Christilut 0:eb5b89f49c35 510 // IF_SERIAL_DEBUG(Serial.print("[AckPacket]/"));
Christilut 0:eb5b89f49c35 511 // IF_SERIAL_DEBUG(Serial.println(ack_payload_length,DEC));
Christilut 0:eb5b89f49c35 512 }
Christilut 0:eb5b89f49c35 513
Christilut 0:eb5b89f49c35 514 // Yay, we are done.
Christilut 0:eb5b89f49c35 515
Christilut 0:eb5b89f49c35 516 // Power down
Christilut 0:eb5b89f49c35 517 powerDown();
Christilut 0:eb5b89f49c35 518
Christilut 0:eb5b89f49c35 519 // Flush buffers (Is this a relic of past experimentation, and not needed anymore?
Christilut 0:eb5b89f49c35 520 flush_tx();
Christilut 0:eb5b89f49c35 521
Christilut 0:eb5b89f49c35 522 return result;
Christilut 0:eb5b89f49c35 523 }
Christilut 0:eb5b89f49c35 524 /****************************************************************************/
Christilut 0:eb5b89f49c35 525
Christilut 0:eb5b89f49c35 526 void RF24::startWrite( const void* buf, uint8_t len )
Christilut 0:eb5b89f49c35 527 {
Christilut 0:eb5b89f49c35 528 // Transmitter power-up
Christilut 0:eb5b89f49c35 529 write_register(CONFIG, ( read_register(CONFIG) | PWR_UP ) & ~PRIM_RX );
Christilut 0:eb5b89f49c35 530 //delayMicroseconds(150);
Christilut 0:eb5b89f49c35 531 wait_us(150);
Christilut 0:eb5b89f49c35 532
Christilut 0:eb5b89f49c35 533 // Send the payload
Christilut 0:eb5b89f49c35 534 write_payload( buf, len );
Christilut 0:eb5b89f49c35 535
Christilut 0:eb5b89f49c35 536 // Allons!
Christilut 0:eb5b89f49c35 537 ce(HIGH);;
Christilut 0:eb5b89f49c35 538 // delayMicroseconds(15);
Christilut 0:eb5b89f49c35 539 wait_us(15);
Christilut 0:eb5b89f49c35 540 ce(LOW);
Christilut 0:eb5b89f49c35 541 }
Christilut 0:eb5b89f49c35 542
Christilut 0:eb5b89f49c35 543 /****************************************************************************/
Christilut 0:eb5b89f49c35 544
Christilut 0:eb5b89f49c35 545 uint8_t RF24::getDynamicPayloadSize(void)
Christilut 0:eb5b89f49c35 546 {
Christilut 0:eb5b89f49c35 547 uint8_t result = 0;
Christilut 0:eb5b89f49c35 548
Christilut 0:eb5b89f49c35 549 csn(LOW);
Christilut 0:eb5b89f49c35 550 spi.write( R_RX_PL_WID );
Christilut 0:eb5b89f49c35 551 result = spi.write(0xff);
Christilut 0:eb5b89f49c35 552 csn(HIGH);
Christilut 0:eb5b89f49c35 553
Christilut 0:eb5b89f49c35 554 return result;
Christilut 0:eb5b89f49c35 555 }
Christilut 0:eb5b89f49c35 556
Christilut 0:eb5b89f49c35 557 /****************************************************************************/
Christilut 0:eb5b89f49c35 558
Christilut 0:eb5b89f49c35 559 bool RF24::available(void)
Christilut 0:eb5b89f49c35 560 {
Christilut 0:eb5b89f49c35 561 return available(NULL);
Christilut 0:eb5b89f49c35 562 }
Christilut 0:eb5b89f49c35 563
Christilut 0:eb5b89f49c35 564 /****************************************************************************/
Christilut 0:eb5b89f49c35 565
Christilut 0:eb5b89f49c35 566 bool RF24::available(uint8_t* pipe_num)
Christilut 0:eb5b89f49c35 567 {
Christilut 0:eb5b89f49c35 568 uint8_t status = get_status();
Christilut 0:eb5b89f49c35 569
Christilut 0:eb5b89f49c35 570 // Too noisy, enable if you really want lots o data!!
Christilut 0:eb5b89f49c35 571 //IF_SERIAL_DEBUG(print_status(status));
Christilut 0:eb5b89f49c35 572
Christilut 0:eb5b89f49c35 573 bool result = ( status & RX_DR );
Christilut 0:eb5b89f49c35 574
Christilut 0:eb5b89f49c35 575 if (result) {
Christilut 0:eb5b89f49c35 576 // If the caller wants the pipe number, include that
Christilut 0:eb5b89f49c35 577 if ( pipe_num )
Christilut 0:eb5b89f49c35 578 *pipe_num = ( status >> RX_P_NO ) & 7;
Christilut 0:eb5b89f49c35 579
Christilut 0:eb5b89f49c35 580 // Clear the status bit
Christilut 0:eb5b89f49c35 581
Christilut 0:eb5b89f49c35 582 // ??? Should this REALLY be cleared now? Or wait until we
Christilut 0:eb5b89f49c35 583 // actually READ the payload?
Christilut 0:eb5b89f49c35 584
Christilut 0:eb5b89f49c35 585 write_register(STATUS,RX_DR );
Christilut 0:eb5b89f49c35 586
Christilut 0:eb5b89f49c35 587 // Handle ack payload receipt
Christilut 0:eb5b89f49c35 588 if ( status & TX_DS ) {
Christilut 0:eb5b89f49c35 589 write_register(STATUS,TX_DS);
Christilut 0:eb5b89f49c35 590 }
Christilut 0:eb5b89f49c35 591 }
Christilut 0:eb5b89f49c35 592
Christilut 0:eb5b89f49c35 593 return result;
Christilut 0:eb5b89f49c35 594 }
Christilut 0:eb5b89f49c35 595
Christilut 0:eb5b89f49c35 596 /****************************************************************************/
Christilut 0:eb5b89f49c35 597
Christilut 0:eb5b89f49c35 598 bool RF24::read( void* buf, uint8_t len )
Christilut 0:eb5b89f49c35 599 {
Christilut 0:eb5b89f49c35 600 // Fetch the payload
Christilut 0:eb5b89f49c35 601 read_payload( buf, len );
Christilut 0:eb5b89f49c35 602
Christilut 0:eb5b89f49c35 603 // was this the last of the data available?
Christilut 0:eb5b89f49c35 604 return read_register(FIFO_STATUS) & RX_EMPTY;
Christilut 0:eb5b89f49c35 605 }
Christilut 0:eb5b89f49c35 606
Christilut 0:eb5b89f49c35 607 /****************************************************************************/
Christilut 0:eb5b89f49c35 608
Christilut 0:eb5b89f49c35 609 void RF24::whatHappened(bool& tx_ok,bool& tx_fail,bool& rx_ready)
Christilut 0:eb5b89f49c35 610 {
Christilut 0:eb5b89f49c35 611 // Read the status & reset the status in one easy call
Christilut 0:eb5b89f49c35 612 // Or is that such a good idea?
Christilut 0:eb5b89f49c35 613 uint8_t status = write_register(STATUS,RX_DR | TX_DS | MAX_RT );
Christilut 0:eb5b89f49c35 614
Christilut 0:eb5b89f49c35 615 // Report to the user what happened
Christilut 0:eb5b89f49c35 616 tx_ok = status & TX_DS;
Christilut 0:eb5b89f49c35 617 tx_fail = status & MAX_RT;
Christilut 0:eb5b89f49c35 618 rx_ready = status & RX_DR;
Christilut 0:eb5b89f49c35 619 }
Christilut 0:eb5b89f49c35 620
Christilut 0:eb5b89f49c35 621 /****************************************************************************/
Christilut 0:eb5b89f49c35 622
Christilut 0:eb5b89f49c35 623 void RF24::openWritingPipe(uint64_t value)
Christilut 0:eb5b89f49c35 624 {
Christilut 0:eb5b89f49c35 625 // Note that AVR 8-bit uC's store this LSB first, and the NRF24L01(+)
Christilut 0:eb5b89f49c35 626 // expects it LSB first too, so we're good.
Christilut 0:eb5b89f49c35 627
Christilut 0:eb5b89f49c35 628 write_register(RX_ADDR_P0, reinterpret_cast<uint8_t*>(&value), 5);
Christilut 0:eb5b89f49c35 629 write_register(TX_ADDR, reinterpret_cast<uint8_t*>(&value), 5);
Christilut 0:eb5b89f49c35 630
Christilut 0:eb5b89f49c35 631 const uint8_t max_payload_size = 32;
Christilut 0:eb5b89f49c35 632 write_register(RX_PW_P0,min(payload_size,max_payload_size));
Christilut 0:eb5b89f49c35 633 }
Christilut 0:eb5b89f49c35 634
Christilut 0:eb5b89f49c35 635 /****************************************************************************/
Christilut 0:eb5b89f49c35 636
Christilut 0:eb5b89f49c35 637 static const uint8_t child_pipe[] = {
Christilut 0:eb5b89f49c35 638 RX_ADDR_P0, RX_ADDR_P1, RX_ADDR_P2, RX_ADDR_P3, RX_ADDR_P4, RX_ADDR_P5
Christilut 0:eb5b89f49c35 639 };
Christilut 0:eb5b89f49c35 640 static const uint8_t child_payload_size[] = {
Christilut 0:eb5b89f49c35 641 RX_PW_P0, RX_PW_P1, RX_PW_P2, RX_PW_P3, RX_PW_P4, RX_PW_P5
Christilut 0:eb5b89f49c35 642 };
Christilut 0:eb5b89f49c35 643 static const uint8_t child_pipe_enable[] = {
Christilut 0:eb5b89f49c35 644 ERX_P0, ERX_P1, ERX_P2, ERX_P3, ERX_P4, ERX_P5
Christilut 0:eb5b89f49c35 645 };
Christilut 0:eb5b89f49c35 646
Christilut 0:eb5b89f49c35 647 void RF24::openReadingPipe(uint8_t child, uint64_t address)
Christilut 0:eb5b89f49c35 648 {
Christilut 0:eb5b89f49c35 649 // If this is pipe 0, cache the address. This is needed because
Christilut 0:eb5b89f49c35 650 // openWritingPipe() will overwrite the pipe 0 address, so
Christilut 0:eb5b89f49c35 651 // startListening() will have to restore it.
Christilut 0:eb5b89f49c35 652 if (child == 0)
Christilut 0:eb5b89f49c35 653 pipe0_reading_address = address;
Christilut 0:eb5b89f49c35 654
Christilut 0:eb5b89f49c35 655 if (child <= 6) {
Christilut 0:eb5b89f49c35 656 // For pipes 2-5, only write the LSB
Christilut 0:eb5b89f49c35 657 if ( child < 2 )
Christilut 0:eb5b89f49c35 658 write_register(child_pipe[child], reinterpret_cast<const uint8_t*>(&address), 5);
Christilut 0:eb5b89f49c35 659 else
Christilut 0:eb5b89f49c35 660 write_register(child_pipe[child], reinterpret_cast<const uint8_t*>(&address), 1);
Christilut 0:eb5b89f49c35 661
Christilut 0:eb5b89f49c35 662 write_register(child_payload_size[child],payload_size);
Christilut 0:eb5b89f49c35 663
Christilut 0:eb5b89f49c35 664 // Note it would be more efficient to set all of the bits for all open
Christilut 0:eb5b89f49c35 665 // pipes at once. However, I thought it would make the calling code
Christilut 0:eb5b89f49c35 666 // more simple to do it this way.
Christilut 0:eb5b89f49c35 667 write_register(EN_RXADDR,read_register(EN_RXADDR) | child_pipe_enable[child]);
Christilut 0:eb5b89f49c35 668 }
Christilut 0:eb5b89f49c35 669 }
Christilut 0:eb5b89f49c35 670
Christilut 0:eb5b89f49c35 671 /****************************************************************************/
Christilut 0:eb5b89f49c35 672
Christilut 0:eb5b89f49c35 673 void RF24::toggle_features(void)
Christilut 0:eb5b89f49c35 674 {
Christilut 0:eb5b89f49c35 675 csn(LOW);
Christilut 0:eb5b89f49c35 676 spi.write( ACTIVATE );
Christilut 0:eb5b89f49c35 677 spi.write( 0x73 );
Christilut 0:eb5b89f49c35 678 csn(HIGH);
Christilut 0:eb5b89f49c35 679 }
Christilut 0:eb5b89f49c35 680
Christilut 0:eb5b89f49c35 681 /****************************************************************************/
Christilut 0:eb5b89f49c35 682
Christilut 0:eb5b89f49c35 683 void RF24::enableDynamicPayloads(void)
Christilut 0:eb5b89f49c35 684 {
Christilut 0:eb5b89f49c35 685 // Enable dynamic payload throughout the system
Christilut 0:eb5b89f49c35 686 write_register(FEATURE,read_register(FEATURE) | EN_DPL );
Christilut 0:eb5b89f49c35 687
Christilut 0:eb5b89f49c35 688 // If it didn't work, the features are not enabled
Christilut 0:eb5b89f49c35 689 if ( ! read_register(FEATURE) ) {
Christilut 0:eb5b89f49c35 690 // So enable them and try again
Christilut 0:eb5b89f49c35 691 toggle_features();
Christilut 0:eb5b89f49c35 692 write_register(FEATURE,read_register(FEATURE) | EN_DPL );
Christilut 0:eb5b89f49c35 693 }
Christilut 0:eb5b89f49c35 694
Christilut 0:eb5b89f49c35 695 // IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE)));
Christilut 0:eb5b89f49c35 696
Christilut 0:eb5b89f49c35 697 // Enable dynamic payload on all pipes
Christilut 0:eb5b89f49c35 698 //
Christilut 0:eb5b89f49c35 699 // Not sure the use case of only having dynamic payload on certain
Christilut 0:eb5b89f49c35 700 // pipes, so the library does not support it.
Christilut 0:eb5b89f49c35 701 write_register(DYNPD,read_register(DYNPD) | DPL_P5 | DPL_P4 | DPL_P3 | DPL_P2 | DPL_P1 | DPL_P0);
Christilut 0:eb5b89f49c35 702
Christilut 0:eb5b89f49c35 703 dynamic_payloads_enabled = true;
Christilut 0:eb5b89f49c35 704 }
Christilut 0:eb5b89f49c35 705
Christilut 0:eb5b89f49c35 706 /****************************************************************************/
Christilut 0:eb5b89f49c35 707
Christilut 0:eb5b89f49c35 708 void RF24::enableAckPayload(void)
Christilut 0:eb5b89f49c35 709 {
Christilut 0:eb5b89f49c35 710 //
Christilut 0:eb5b89f49c35 711 // enable ack payload and dynamic payload features
Christilut 0:eb5b89f49c35 712 //
Christilut 0:eb5b89f49c35 713
Christilut 0:eb5b89f49c35 714 write_register(FEATURE,read_register(FEATURE) | EN_ACK_PAY | EN_DPL );
Christilut 0:eb5b89f49c35 715
Christilut 0:eb5b89f49c35 716 // If it didn't work, the features are not enabled
Christilut 0:eb5b89f49c35 717 if ( ! read_register(FEATURE) ) {
Christilut 0:eb5b89f49c35 718 // So enable them and try again
Christilut 0:eb5b89f49c35 719 toggle_features();
Christilut 0:eb5b89f49c35 720 write_register(FEATURE,read_register(FEATURE) | EN_ACK_PAY | EN_DPL );
Christilut 0:eb5b89f49c35 721 }
Christilut 0:eb5b89f49c35 722
Christilut 0:eb5b89f49c35 723 // IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE)));
Christilut 0:eb5b89f49c35 724
Christilut 0:eb5b89f49c35 725 //
Christilut 0:eb5b89f49c35 726 // Enable dynamic payload on pipes 0 & 1
Christilut 0:eb5b89f49c35 727 //
Christilut 0:eb5b89f49c35 728
Christilut 0:eb5b89f49c35 729 write_register(DYNPD,read_register(DYNPD) | DPL_P1 | DPL_P0);
Christilut 0:eb5b89f49c35 730 }
Christilut 0:eb5b89f49c35 731
Christilut 0:eb5b89f49c35 732 /****************************************************************************/
Christilut 0:eb5b89f49c35 733
Christilut 0:eb5b89f49c35 734 void RF24::writeAckPayload(uint8_t pipe, const void* buf, uint8_t len)
Christilut 0:eb5b89f49c35 735 {
Christilut 0:eb5b89f49c35 736 const uint8_t* current = reinterpret_cast<const uint8_t*>(buf);
Christilut 0:eb5b89f49c35 737
Christilut 0:eb5b89f49c35 738 csn(LOW);
Christilut 0:eb5b89f49c35 739 spi.write( W_ACK_PAYLOAD | ( pipe & 7 ) );
Christilut 0:eb5b89f49c35 740 const uint8_t max_payload_size = 32;
Christilut 0:eb5b89f49c35 741 uint8_t data_len = min(len,max_payload_size);
Christilut 0:eb5b89f49c35 742 while ( data_len-- )
Christilut 0:eb5b89f49c35 743 spi.write(*current++);
Christilut 0:eb5b89f49c35 744
Christilut 0:eb5b89f49c35 745 csn(HIGH);
Christilut 0:eb5b89f49c35 746 }
Christilut 0:eb5b89f49c35 747
Christilut 0:eb5b89f49c35 748 /****************************************************************************/
Christilut 0:eb5b89f49c35 749
Christilut 0:eb5b89f49c35 750 bool RF24::isAckPayloadAvailable(void)
Christilut 0:eb5b89f49c35 751 {
Christilut 0:eb5b89f49c35 752 bool result = ack_payload_available;
Christilut 0:eb5b89f49c35 753 ack_payload_available = false;
Christilut 0:eb5b89f49c35 754 return result;
Christilut 0:eb5b89f49c35 755 }
Christilut 0:eb5b89f49c35 756
Christilut 0:eb5b89f49c35 757 /****************************************************************************/
Christilut 0:eb5b89f49c35 758
Christilut 0:eb5b89f49c35 759 bool RF24::isPVariant(void)
Christilut 0:eb5b89f49c35 760 {
Christilut 0:eb5b89f49c35 761 return p_variant ;
Christilut 0:eb5b89f49c35 762 }
Christilut 0:eb5b89f49c35 763
Christilut 0:eb5b89f49c35 764 /****************************************************************************/
Christilut 0:eb5b89f49c35 765
Christilut 0:eb5b89f49c35 766 void RF24::setAutoAck(bool enable)
Christilut 0:eb5b89f49c35 767 {
Christilut 0:eb5b89f49c35 768 if ( enable )
Christilut 0:eb5b89f49c35 769 write_register(EN_AA, 63);
Christilut 0:eb5b89f49c35 770 else
Christilut 0:eb5b89f49c35 771 write_register(EN_AA, 0);
Christilut 0:eb5b89f49c35 772 }
Christilut 0:eb5b89f49c35 773
Christilut 0:eb5b89f49c35 774 /****************************************************************************/
Christilut 0:eb5b89f49c35 775
Christilut 0:eb5b89f49c35 776 void RF24::setAutoAck( uint8_t pipe, bool enable )
Christilut 0:eb5b89f49c35 777 {
Christilut 0:eb5b89f49c35 778 if ( pipe <= 6 ) {
Christilut 0:eb5b89f49c35 779 uint8_t en_aa = read_register( EN_AA ) ;
Christilut 0:eb5b89f49c35 780 if( enable ) {
Christilut 0:eb5b89f49c35 781 en_aa |= pipe ;
Christilut 0:eb5b89f49c35 782 } else {
Christilut 0:eb5b89f49c35 783 en_aa &= ~pipe ;
Christilut 0:eb5b89f49c35 784 }
Christilut 0:eb5b89f49c35 785 write_register( EN_AA, en_aa ) ;
Christilut 0:eb5b89f49c35 786 }
Christilut 0:eb5b89f49c35 787 }
Christilut 0:eb5b89f49c35 788
Christilut 0:eb5b89f49c35 789 /****************************************************************************/
Christilut 0:eb5b89f49c35 790
Christilut 0:eb5b89f49c35 791 bool RF24::testCarrier(void)
Christilut 0:eb5b89f49c35 792 {
Christilut 0:eb5b89f49c35 793 return ( read_register(CD) & 1 );
Christilut 0:eb5b89f49c35 794 }
Christilut 0:eb5b89f49c35 795
Christilut 0:eb5b89f49c35 796 /****************************************************************************/
Christilut 0:eb5b89f49c35 797
Christilut 0:eb5b89f49c35 798 bool RF24::testRPD(void)
Christilut 0:eb5b89f49c35 799 {
Christilut 0:eb5b89f49c35 800 return ( read_register(RPD) & 1 ) ;
Christilut 0:eb5b89f49c35 801 }
Christilut 0:eb5b89f49c35 802
Christilut 0:eb5b89f49c35 803 /****************************************************************************/
Christilut 0:eb5b89f49c35 804
Christilut 0:eb5b89f49c35 805 void RF24::setPALevel(rf24_pa_dbm_e level)
Christilut 0:eb5b89f49c35 806 {
Christilut 0:eb5b89f49c35 807 uint8_t setup = read_register(RF_SETUP) ;
Christilut 0:eb5b89f49c35 808 setup &= ~(RF_PWR_LOW | RF_PWR_HIGH) ;
Christilut 0:eb5b89f49c35 809
Christilut 0:eb5b89f49c35 810 // switch uses RAM (evil!)
Christilut 0:eb5b89f49c35 811 if ( level == RF24_PA_MAX ) {
Christilut 0:eb5b89f49c35 812 setup |= (RF_PWR_LOW | RF_PWR_HIGH) ;
Christilut 0:eb5b89f49c35 813 } else if ( level == RF24_PA_HIGH ) {
Christilut 0:eb5b89f49c35 814 setup |= RF_PWR_HIGH ;
Christilut 0:eb5b89f49c35 815 } else if ( level == RF24_PA_LOW ) {
Christilut 0:eb5b89f49c35 816 setup |= RF_PWR_LOW;
Christilut 0:eb5b89f49c35 817 } else if ( level == RF24_PA_MIN ) {
Christilut 0:eb5b89f49c35 818 // nothing
Christilut 0:eb5b89f49c35 819 } else if ( level == RF24_PA_ERROR ) {
Christilut 0:eb5b89f49c35 820 // On error, go to maximum PA
Christilut 0:eb5b89f49c35 821 setup |= (RF_PWR_LOW | RF_PWR_HIGH) ;
Christilut 0:eb5b89f49c35 822 }
Christilut 0:eb5b89f49c35 823
Christilut 0:eb5b89f49c35 824 write_register( RF_SETUP, setup ) ;
Christilut 0:eb5b89f49c35 825 }
Christilut 0:eb5b89f49c35 826
Christilut 0:eb5b89f49c35 827 /****************************************************************************/
Christilut 0:eb5b89f49c35 828
Christilut 0:eb5b89f49c35 829 rf24_pa_dbm_e RF24::getPALevel(void)
Christilut 0:eb5b89f49c35 830 {
Christilut 0:eb5b89f49c35 831 rf24_pa_dbm_e result = RF24_PA_ERROR ;
Christilut 0:eb5b89f49c35 832 uint8_t power = read_register(RF_SETUP) & (RF_PWR_LOW | RF_PWR_HIGH) ;
Christilut 0:eb5b89f49c35 833
Christilut 0:eb5b89f49c35 834 // switch uses RAM (evil!)
Christilut 0:eb5b89f49c35 835 if ( power == (RF_PWR_LOW | RF_PWR_HIGH) ) {
Christilut 0:eb5b89f49c35 836 result = RF24_PA_MAX ;
Christilut 0:eb5b89f49c35 837 } else if ( power == RF_PWR_HIGH) {
Christilut 0:eb5b89f49c35 838 result = RF24_PA_HIGH ;
Christilut 0:eb5b89f49c35 839 } else if ( power == RF_PWR_LOW) {
Christilut 0:eb5b89f49c35 840 result = RF24_PA_LOW ;
Christilut 0:eb5b89f49c35 841 } else {
Christilut 0:eb5b89f49c35 842 result = RF24_PA_MIN ;
Christilut 0:eb5b89f49c35 843 }
Christilut 0:eb5b89f49c35 844
Christilut 0:eb5b89f49c35 845 return result ;
Christilut 0:eb5b89f49c35 846 }
Christilut 0:eb5b89f49c35 847
Christilut 0:eb5b89f49c35 848 /****************************************************************************/
Christilut 0:eb5b89f49c35 849
Christilut 0:eb5b89f49c35 850 bool RF24::setDataRate(rf24_datarate_e speed)
Christilut 0:eb5b89f49c35 851 {
Christilut 0:eb5b89f49c35 852 bool result = false;
Christilut 0:eb5b89f49c35 853 uint8_t setup = read_register(RF_SETUP) ;
Christilut 0:eb5b89f49c35 854
Christilut 0:eb5b89f49c35 855 // HIGH and LOW '00' is 1Mbs - our default
Christilut 0:eb5b89f49c35 856 wide_band = false ;
Christilut 0:eb5b89f49c35 857 setup &= ~(RF_DR_LOW | RF_DR_HIGH) ;
Christilut 0:eb5b89f49c35 858 if( speed == RF24_250KBPS ) {
Christilut 0:eb5b89f49c35 859 // Must set the RF_DR_LOW to 1; RF_DR_HIGH (used to be RF_DR) is already 0
Christilut 0:eb5b89f49c35 860 // Making it '10'.
Christilut 0:eb5b89f49c35 861 wide_band = false ;
Christilut 0:eb5b89f49c35 862 setup |= RF_DR_LOW ;
Christilut 0:eb5b89f49c35 863 } else {
Christilut 0:eb5b89f49c35 864 // Set 2Mbs, RF_DR (RF_DR_HIGH) is set 1
Christilut 0:eb5b89f49c35 865 // Making it '01'
Christilut 0:eb5b89f49c35 866 if ( speed == RF24_2MBPS ) {
Christilut 0:eb5b89f49c35 867 wide_band = true ;
Christilut 0:eb5b89f49c35 868 setup |= RF_DR_HIGH;
Christilut 0:eb5b89f49c35 869 } else {
Christilut 0:eb5b89f49c35 870 // 1Mbs
Christilut 0:eb5b89f49c35 871 wide_band = false ;
Christilut 0:eb5b89f49c35 872 }
Christilut 0:eb5b89f49c35 873 }
Christilut 0:eb5b89f49c35 874 write_register(RF_SETUP,setup);
Christilut 0:eb5b89f49c35 875
Christilut 0:eb5b89f49c35 876 // Verify our result
Christilut 0:eb5b89f49c35 877 if ( read_register(RF_SETUP) == setup ) {
Christilut 0:eb5b89f49c35 878 result = true;
Christilut 0:eb5b89f49c35 879 } else {
Christilut 0:eb5b89f49c35 880 wide_band = false;
Christilut 0:eb5b89f49c35 881 }
Christilut 0:eb5b89f49c35 882
Christilut 0:eb5b89f49c35 883 return result;
Christilut 0:eb5b89f49c35 884 }
Christilut 0:eb5b89f49c35 885
Christilut 0:eb5b89f49c35 886 /****************************************************************************/
Christilut 0:eb5b89f49c35 887
Christilut 0:eb5b89f49c35 888 rf24_datarate_e RF24::getDataRate( void )
Christilut 0:eb5b89f49c35 889 {
Christilut 0:eb5b89f49c35 890 rf24_datarate_e result ;
Christilut 0:eb5b89f49c35 891 uint8_t dr = read_register(RF_SETUP) & (RF_DR_LOW | RF_DR_HIGH);
Christilut 0:eb5b89f49c35 892
Christilut 0:eb5b89f49c35 893 // switch uses RAM (evil!)
Christilut 0:eb5b89f49c35 894 // Order matters in our case below
Christilut 0:eb5b89f49c35 895 if ( dr == RF_DR_LOW) {
Christilut 0:eb5b89f49c35 896 // '10' = 250KBPS
Christilut 0:eb5b89f49c35 897 result = RF24_250KBPS ;
Christilut 0:eb5b89f49c35 898 } else if ( dr == RF_DR_HIGH) {
Christilut 0:eb5b89f49c35 899 // '01' = 2MBPS
Christilut 0:eb5b89f49c35 900 result = RF24_2MBPS ;
Christilut 0:eb5b89f49c35 901 } else {
Christilut 0:eb5b89f49c35 902 // '00' = 1MBPS
Christilut 0:eb5b89f49c35 903 result = RF24_1MBPS ;
Christilut 0:eb5b89f49c35 904 }
Christilut 0:eb5b89f49c35 905 return result ;
Christilut 0:eb5b89f49c35 906 }
Christilut 0:eb5b89f49c35 907
Christilut 0:eb5b89f49c35 908 /****************************************************************************/
Christilut 0:eb5b89f49c35 909
Christilut 0:eb5b89f49c35 910 void RF24::setCRCLength(rf24_crclength_e length)
Christilut 0:eb5b89f49c35 911 {
Christilut 0:eb5b89f49c35 912 uint8_t config = read_register(CONFIG) & ~( CRCO | EN_CRC) ;
Christilut 0:eb5b89f49c35 913
Christilut 0:eb5b89f49c35 914 if ( length == RF24_CRC_DISABLED ) {
Christilut 0:eb5b89f49c35 915 // Do nothing, we turned it off above.
Christilut 0:eb5b89f49c35 916 } else if ( length == RF24_CRC_8 ) {
Christilut 0:eb5b89f49c35 917 config |= EN_CRC;
Christilut 0:eb5b89f49c35 918 } else {
Christilut 0:eb5b89f49c35 919 config |= EN_CRC;
Christilut 0:eb5b89f49c35 920 config |= CRCO;
Christilut 0:eb5b89f49c35 921 }
Christilut 0:eb5b89f49c35 922 write_register( CONFIG, config ) ;
Christilut 0:eb5b89f49c35 923
Christilut 0:eb5b89f49c35 924 printf("CRC SET: %u\n\r", config);
Christilut 0:eb5b89f49c35 925 }
Christilut 0:eb5b89f49c35 926
Christilut 0:eb5b89f49c35 927 /****************************************************************************/
Christilut 0:eb5b89f49c35 928
Christilut 0:eb5b89f49c35 929 rf24_crclength_e RF24::getCRCLength(void)
Christilut 0:eb5b89f49c35 930 {
Christilut 0:eb5b89f49c35 931 rf24_crclength_e result = RF24_CRC_DISABLED;
Christilut 0:eb5b89f49c35 932 uint8_t config = read_register(CONFIG) & ( CRCO | EN_CRC) ;
Christilut 0:eb5b89f49c35 933
Christilut 0:eb5b89f49c35 934 if ( config & EN_CRC) {
Christilut 0:eb5b89f49c35 935 if ( config & CRCO )
Christilut 0:eb5b89f49c35 936 result = RF24_CRC_16;
Christilut 0:eb5b89f49c35 937 else
Christilut 0:eb5b89f49c35 938 result = RF24_CRC_8;
Christilut 0:eb5b89f49c35 939 }
Christilut 0:eb5b89f49c35 940
Christilut 0:eb5b89f49c35 941 return result;
Christilut 0:eb5b89f49c35 942 }
Christilut 0:eb5b89f49c35 943
Christilut 0:eb5b89f49c35 944 /****************************************************************************/
Christilut 0:eb5b89f49c35 945
Christilut 0:eb5b89f49c35 946 void RF24::disableCRC( void )
Christilut 0:eb5b89f49c35 947 {
Christilut 0:eb5b89f49c35 948 uint8_t disable = read_register(CONFIG) & ~EN_CRC ;
Christilut 0:eb5b89f49c35 949 write_register( CONFIG, disable ) ;
Christilut 0:eb5b89f49c35 950 }
Christilut 0:eb5b89f49c35 951
Christilut 0:eb5b89f49c35 952 /****************************************************************************/
Christilut 0:eb5b89f49c35 953 void RF24::setRetries(uint8_t delay, uint8_t count)
Christilut 0:eb5b89f49c35 954 {
Christilut 0:eb5b89f49c35 955 write_register(SETUP_RETR,(delay&0xf)<<ARD | (count&0xf)<<ARC);
Christilut 0:eb5b89f49c35 956 }
Christilut 0:eb5b89f49c35 957
Christilut 0:eb5b89f49c35 958 int RF24::min(int a, int b)
Christilut 0:eb5b89f49c35 959 {
Christilut 0:eb5b89f49c35 960 if(a < b)
Christilut 0:eb5b89f49c35 961 return a;
Christilut 0:eb5b89f49c35 962 else
Christilut 0:eb5b89f49c35 963 return b;
Christilut 0:eb5b89f49c35 964 }