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