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

Fork of nRF24L01P_Maniacbug by Christiaan M

Committer:
kenno
Date:
Thu Jan 01 11:56:44 2015 +0000
Revision:
8:ea2d2e86df4f
Parent:
7:8858f26d373f
Fix conflicted variable names with K64F board.

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