Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of RF24 by
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 | } |