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