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.
Dependents: nRF24L01P_Hello_World
nRF24L01P.cpp
00001 /** 00002 * @file nRF24L01P.cpp 00003 * 00004 * @author Owen Edwards 00005 * 00006 * @section LICENSE 00007 * 00008 * Copyright (c) 2010 Owen Edwards 00009 * 00010 * This program is free software: you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation, either version 3 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU General Public License 00021 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00022 * 00023 * The above copyright notice and this permission notice shall be included in 00024 * all copies or substantial portions of the Software. 00025 * 00026 * @section DESCRIPTION 00027 * 00028 * nRF24L01+ Single Chip 2.4GHz Transceiver from Nordic Semiconductor. 00029 * 00030 * Datasheet: 00031 * 00032 * http://www.nordicsemi.no/files/Product/data_sheet/nRF24L01P_Product_Specification_1_0.pdf 00033 */ 00034 00035 /** 00036 * Includes 00037 */ 00038 #include "nRF24L01P.h " 00039 00040 /** 00041 * Defines 00042 * 00043 * (Note that all defines here start with an underscore, e.g. '_NRF24L01P_MODE_UNKNOWN', 00044 * and are local to this library. The defines in the nRF24L01P.h file do not start 00045 * with the underscore, and can be used by code to access this library.) 00046 */ 00047 00048 typedef enum { 00049 _NRF24L01P_MODE_UNKNOWN, 00050 _NRF24L01P_MODE_POWER_DOWN, 00051 _NRF24L01P_MODE_STANDBY, 00052 _NRF24L01P_MODE_RX, 00053 _NRF24L01P_MODE_TX, 00054 } nRF24L01P_Mode_Type; 00055 00056 /* 00057 * The following FIFOs are present in nRF24L01+: 00058 * TX three level, 32 byte FIFO 00059 * RX three level, 32 byte FIFO 00060 */ 00061 #define _NRF24L01P_TX_FIFO_COUNT 3 00062 #define _NRF24L01P_RX_FIFO_COUNT 3 00063 00064 #define _NRF24L01P_TX_FIFO_SIZE 32 00065 #define _NRF24L01P_RX_FIFO_SIZE 32 00066 00067 #define _NRF24L01P_SPI_MAX_DATA_RATE 10000000 00068 00069 #define _NRF24L01P_SPI_CMD_RD_REG 0x00 00070 #define _NRF24L01P_SPI_CMD_WR_REG 0x20 00071 #define _NRF24L01P_SPI_CMD_RD_RX_PAYLOAD 0x61 00072 #define _NRF24L01P_SPI_CMD_WR_TX_PAYLOAD 0xa0 00073 #define _NRF24L01P_SPI_CMD_FLUSH_TX 0xe1 00074 #define _NRF24L01P_SPI_CMD_FLUSH_RX 0xe2 00075 #define _NRF24L01P_SPI_CMD_REUSE_TX_PL 0xe3 00076 #define _NRF24L01P_SPI_CMD_R_RX_PL_WID 0x60 00077 #define _NRF24L01P_SPI_CMD_W_ACK_PAYLOAD 0xa8 00078 #define _NRF24L01P_SPI_CMD_W_TX_PYLD_NO_ACK 0xb0 00079 #define _NRF24L01P_SPI_CMD_NOP 0xff 00080 00081 00082 #define _NRF24L01P_REG_CONFIG 0x00 00083 #define _NRF24L01P_REG_EN_AA 0x01 00084 #define _NRF24L01P_REG_EN_RXADDR 0x02 00085 #define _NRF24L01P_REG_SETUP_AW 0x03 00086 #define _NRF24L01P_REG_SETUP_RETR 0x04 00087 #define _NRF24L01P_REG_RF_CH 0x05 00088 #define _NRF24L01P_REG_RF_SETUP 0x06 00089 #define _NRF24L01P_REG_STATUS 0x07 00090 #define _NRF24L01P_REG_OBSERVE_TX 0x08 00091 #define _NRF24L01P_REG_RPD 0x09 00092 #define _NRF24L01P_REG_RX_ADDR_P0 0x0a 00093 #define _NRF24L01P_REG_RX_ADDR_P1 0x0b 00094 #define _NRF24L01P_REG_RX_ADDR_P2 0x0c 00095 #define _NRF24L01P_REG_RX_ADDR_P3 0x0d 00096 #define _NRF24L01P_REG_RX_ADDR_P4 0x0e 00097 #define _NRF24L01P_REG_RX_ADDR_P5 0x0f 00098 #define _NRF24L01P_REG_TX_ADDR 0x10 00099 #define _NRF24L01P_REG_RX_PW_P0 0x11 00100 #define _NRF24L01P_REG_RX_PW_P1 0x12 00101 #define _NRF24L01P_REG_RX_PW_P2 0x13 00102 #define _NRF24L01P_REG_RX_PW_P3 0x14 00103 #define _NRF24L01P_REG_RX_PW_P4 0x15 00104 #define _NRF24L01P_REG_RX_PW_P5 0x16 00105 #define _NRF24L01P_REG_FIFO_STATUS 0x17 00106 #define _NRF24L01P_REG_DYNPD 0x1c 00107 #define _NRF24L01P_REG_FEATURE 0x1d 00108 00109 #define _NRF24L01P_REG_ADDRESS_MASK 0x1f 00110 00111 // CONFIG register: 00112 #define _NRF24L01P_CONFIG_PRIM_RX (1<<0) 00113 #define _NRF24L01P_CONFIG_PWR_UP (1<<1) 00114 #define _NRF24L01P_CONFIG_CRC0 (1<<2) 00115 #define _NRF24L01P_CONFIG_EN_CRC (1<<3) 00116 #define _NRF24L01P_CONFIG_MASK_MAX_RT (1<<4) 00117 #define _NRF24L01P_CONFIG_MASK_TX_DS (1<<5) 00118 #define _NRF24L01P_CONFIG_MASK_RX_DR (1<<6) 00119 00120 #define _NRF24L01P_CONFIG_CRC_MASK (_NRF24L01P_CONFIG_EN_CRC|_NRF24L01P_CONFIG_CRC0) 00121 #define _NRF24L01P_CONFIG_CRC_NONE (0) 00122 #define _NRF24L01P_CONFIG_CRC_8BIT (_NRF24L01P_CONFIG_EN_CRC) 00123 #define _NRF24L01P_CONFIG_CRC_16BIT (_NRF24L01P_CONFIG_EN_CRC|_NRF24L01P_CONFIG_CRC0) 00124 00125 // EN_AA register: 00126 #define _NRF24L01P_EN_AA_NONE 0 00127 00128 // EN_RXADDR register: 00129 #define _NRF24L01P_EN_RXADDR_NONE 0 00130 00131 // SETUP_AW register: 00132 #define _NRF24L01P_SETUP_AW_AW_MASK (0x3<<0) 00133 #define _NRF24L01P_SETUP_AW_AW_3BYTE (0x1<<0) 00134 #define _NRF24L01P_SETUP_AW_AW_4BYTE (0x2<<0) 00135 #define _NRF24L01P_SETUP_AW_AW_5BYTE (0x3<<0) 00136 00137 // SETUP_RETR register: 00138 #define _NRF24L01P_SETUP_RETR_NONE 0 00139 00140 // RF_SETUP register: 00141 #define _NRF24L01P_RF_SETUP_RF_PWR_MASK (0x3<<1) 00142 #define _NRF24L01P_RF_SETUP_RF_PWR_0DBM (0x3<<1) 00143 #define _NRF24L01P_RF_SETUP_RF_PWR_MINUS_6DBM (0x2<<1) 00144 #define _NRF24L01P_RF_SETUP_RF_PWR_MINUS_12DBM (0x1<<1) 00145 #define _NRF24L01P_RF_SETUP_RF_PWR_MINUS_18DBM (0x0<<1) 00146 00147 #define _NRF24L01P_RF_SETUP_RF_DR_HIGH_BIT (1 << 3) 00148 #define _NRF24L01P_RF_SETUP_RF_DR_LOW_BIT (1 << 5) 00149 #define _NRF24L01P_RF_SETUP_RF_DR_MASK (_NRF24L01P_RF_SETUP_RF_DR_LOW_BIT|_NRF24L01P_RF_SETUP_RF_DR_HIGH_BIT) 00150 #define _NRF24L01P_RF_SETUP_RF_DR_250KBPS (_NRF24L01P_RF_SETUP_RF_DR_LOW_BIT) 00151 #define _NRF24L01P_RF_SETUP_RF_DR_1MBPS (0) 00152 #define _NRF24L01P_RF_SETUP_RF_DR_2MBPS (_NRF24L01P_RF_SETUP_RF_DR_HIGH_BIT) 00153 00154 // STATUS register: 00155 #define _NRF24L01P_STATUS_TX_FULL (1<<0) 00156 #define _NRF24L01P_STATUS_RX_P_NO (0x7<<1) 00157 #define _NRF24L01P_STATUS_MAX_RT (1<<4) 00158 #define _NRF24L01P_STATUS_TX_DS (1<<5) 00159 #define _NRF24L01P_STATUS_RX_DR (1<<6) 00160 00161 // RX_PW_P0..RX_PW_P5 registers: 00162 #define _NRF24L01P_RX_PW_Px_MASK 0x3F 00163 00164 #define _NRF24L01P_TIMING_Tundef2pd_us 100000 // 100mS 00165 #define _NRF24L01P_TIMING_Tstby2a_us 130 // 130uS 00166 #define _NRF24L01P_TIMING_Thce_us 10 // 10uS 00167 #define _NRF24L01P_TIMING_Tpd2stby_us 4500 // 4.5mS worst case 00168 #define _NRF24L01P_TIMING_Tpece2csn_us 4 // 4uS 00169 00170 /** 00171 * Methods 00172 */ 00173 00174 nRF24L01P::nRF24L01P(PinName mosi, 00175 PinName miso, 00176 PinName sck, 00177 PinName csn, 00178 PinName ce, 00179 PinName irq) : spi_(mosi, miso, sck), nCS_(csn), ce_(ce), nIRQ_(irq) { 00180 00181 mode = _NRF24L01P_MODE_UNKNOWN; 00182 00183 disable(); 00184 00185 nCS_ = 1; 00186 00187 spi_.frequency(_NRF24L01P_SPI_MAX_DATA_RATE/5); // 2Mbit, 1/5th the maximum transfer rate for the SPI bus 00188 spi_.format(8,0); // 8-bit, ClockPhase = 0, ClockPolarity = 0 00189 00190 wait_us(_NRF24L01P_TIMING_Tundef2pd_us); // Wait for Power-on reset 00191 00192 setRegister(_NRF24L01P_REG_CONFIG, 0); // Power Down 00193 00194 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_MAX_RT|_NRF24L01P_STATUS_TX_DS|_NRF24L01P_STATUS_RX_DR); // Clear any pending interrupts 00195 00196 // 00197 // Setup default configuration 00198 // 00199 disableAllRxPipes(); 00200 setRfFrequency(); 00201 setRfOutputPower(); 00202 setAirDataRate(); 00203 setCrcWidth(); 00204 setTxAddress(); 00205 setRxAddress(); 00206 disableAutoAcknowledge(); 00207 disableAutoRetransmit(); 00208 setTransferSize(); 00209 00210 mode = _NRF24L01P_MODE_POWER_DOWN; 00211 00212 } 00213 00214 00215 void nRF24L01P::powerUp(void) { 00216 00217 int config = getRegister(_NRF24L01P_REG_CONFIG); 00218 00219 config |= _NRF24L01P_CONFIG_PWR_UP; 00220 00221 setRegister(_NRF24L01P_REG_CONFIG, config); 00222 00223 // Wait until the nRF24L01+ powers up 00224 wait_us( _NRF24L01P_TIMING_Tpd2stby_us ); 00225 00226 mode = _NRF24L01P_MODE_STANDBY; 00227 00228 } 00229 00230 00231 void nRF24L01P::powerDown(void) { 00232 00233 int config = getRegister(_NRF24L01P_REG_CONFIG); 00234 00235 config &= ~_NRF24L01P_CONFIG_PWR_UP; 00236 00237 setRegister(_NRF24L01P_REG_CONFIG, config); 00238 00239 // Wait until the nRF24L01+ powers down 00240 wait_us( _NRF24L01P_TIMING_Tpd2stby_us ); // This *may* not be necessary (no timing is shown in the Datasheet), but just to be safe 00241 00242 mode = _NRF24L01P_MODE_POWER_DOWN; 00243 00244 } 00245 00246 00247 void nRF24L01P::setReceiveMode(void) { 00248 00249 if ( _NRF24L01P_MODE_POWER_DOWN == mode ) powerUp(); 00250 00251 int config = getRegister(_NRF24L01P_REG_CONFIG); 00252 00253 config |= _NRF24L01P_CONFIG_PRIM_RX; 00254 00255 setRegister(_NRF24L01P_REG_CONFIG, config); 00256 00257 mode = _NRF24L01P_MODE_RX; 00258 00259 } 00260 00261 00262 void nRF24L01P::setTransmitMode(void) { 00263 00264 if ( _NRF24L01P_MODE_POWER_DOWN == mode ) powerUp(); 00265 00266 int config = getRegister(_NRF24L01P_REG_CONFIG); 00267 00268 config &= ~_NRF24L01P_CONFIG_PRIM_RX; 00269 00270 setRegister(_NRF24L01P_REG_CONFIG, config); 00271 00272 mode = _NRF24L01P_MODE_TX; 00273 00274 } 00275 00276 00277 void nRF24L01P::enable(void) { 00278 00279 ce_ = 1; 00280 wait_us( _NRF24L01P_TIMING_Tpece2csn_us ); 00281 00282 } 00283 00284 00285 void nRF24L01P::disable(void) { 00286 00287 ce_ = 0; 00288 00289 } 00290 00291 void nRF24L01P::setRfFrequency(int frequency) { 00292 00293 if ( ( frequency < NRF24L01P_MIN_RF_FREQUENCY ) || ( frequency > NRF24L01P_MAX_RF_FREQUENCY ) ) { 00294 00295 error( "nRF24L01P: Invalid RF Frequency setting %d\r\n", frequency ); 00296 return; 00297 00298 } 00299 00300 int channel = ( frequency - NRF24L01P_MIN_RF_FREQUENCY ) & 0x7F; 00301 00302 setRegister(_NRF24L01P_REG_RF_CH, channel); 00303 00304 } 00305 00306 00307 int nRF24L01P::getRfFrequency(void) { 00308 00309 int channel = getRegister(_NRF24L01P_REG_RF_CH) & 0x7F; 00310 00311 return ( channel + NRF24L01P_MIN_RF_FREQUENCY ); 00312 00313 } 00314 00315 00316 void nRF24L01P::setRfOutputPower(int power) { 00317 00318 int rfSetup = getRegister(_NRF24L01P_REG_RF_SETUP) & ~_NRF24L01P_RF_SETUP_RF_PWR_MASK; 00319 00320 switch ( power ) { 00321 00322 case NRF24L01P_TX_PWR_ZERO_DB: 00323 rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_0DBM; 00324 break; 00325 00326 case NRF24L01P_TX_PWR_MINUS_6_DB: 00327 rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_MINUS_6DBM; 00328 break; 00329 00330 case NRF24L01P_TX_PWR_MINUS_12_DB: 00331 rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_MINUS_12DBM; 00332 break; 00333 00334 case NRF24L01P_TX_PWR_MINUS_18_DB: 00335 rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_MINUS_18DBM; 00336 break; 00337 00338 default: 00339 error( "nRF24L01P: Invalid RF Output Power setting %d\r\n", power ); 00340 return; 00341 00342 } 00343 00344 setRegister(_NRF24L01P_REG_RF_SETUP, rfSetup); 00345 00346 } 00347 00348 00349 int nRF24L01P::getRfOutputPower(void) { 00350 00351 int rfPwr = getRegister(_NRF24L01P_REG_RF_SETUP) & _NRF24L01P_RF_SETUP_RF_PWR_MASK; 00352 00353 switch ( rfPwr ) { 00354 00355 case _NRF24L01P_RF_SETUP_RF_PWR_0DBM: 00356 return NRF24L01P_TX_PWR_ZERO_DB; 00357 00358 case _NRF24L01P_RF_SETUP_RF_PWR_MINUS_6DBM: 00359 return NRF24L01P_TX_PWR_MINUS_6_DB; 00360 00361 case _NRF24L01P_RF_SETUP_RF_PWR_MINUS_12DBM: 00362 return NRF24L01P_TX_PWR_MINUS_12_DB; 00363 00364 case _NRF24L01P_RF_SETUP_RF_PWR_MINUS_18DBM: 00365 return NRF24L01P_TX_PWR_MINUS_18_DB; 00366 00367 default: 00368 error( "nRF24L01P: Unknown RF Output Power value %d\r\n", rfPwr ); 00369 return 0; 00370 00371 } 00372 } 00373 00374 00375 void nRF24L01P::setAirDataRate(int rate) { 00376 00377 int rfSetup = getRegister(_NRF24L01P_REG_RF_SETUP) & ~_NRF24L01P_RF_SETUP_RF_DR_MASK; 00378 00379 switch ( rate ) { 00380 00381 case NRF24L01P_DATARATE_250_KBPS: 00382 rfSetup |= _NRF24L01P_RF_SETUP_RF_DR_250KBPS; 00383 break; 00384 00385 case NRF24L01P_DATARATE_1_MBPS: 00386 rfSetup |= _NRF24L01P_RF_SETUP_RF_DR_1MBPS; 00387 break; 00388 00389 case NRF24L01P_DATARATE_2_MBPS: 00390 rfSetup |= _NRF24L01P_RF_SETUP_RF_DR_2MBPS; 00391 break; 00392 00393 default: 00394 error( "nRF24L01P: Invalid Air Data Rate setting %d\r\n", rate ); 00395 return; 00396 00397 } 00398 00399 setRegister(_NRF24L01P_REG_RF_SETUP, rfSetup); 00400 00401 } 00402 00403 00404 int nRF24L01P::getAirDataRate(void) { 00405 00406 int rfDataRate = getRegister(_NRF24L01P_REG_RF_SETUP) & _NRF24L01P_RF_SETUP_RF_DR_MASK; 00407 00408 switch ( rfDataRate ) { 00409 00410 case _NRF24L01P_RF_SETUP_RF_DR_250KBPS: 00411 return NRF24L01P_DATARATE_250_KBPS; 00412 00413 case _NRF24L01P_RF_SETUP_RF_DR_1MBPS: 00414 return NRF24L01P_DATARATE_1_MBPS; 00415 00416 case _NRF24L01P_RF_SETUP_RF_DR_2MBPS: 00417 return NRF24L01P_DATARATE_2_MBPS; 00418 00419 default: 00420 error( "nRF24L01P: Unknown Air Data Rate value %d\r\n", rfDataRate ); 00421 return 0; 00422 00423 } 00424 } 00425 00426 00427 void nRF24L01P::setCrcWidth(int width) { 00428 00429 int config = getRegister(_NRF24L01P_REG_CONFIG) & ~_NRF24L01P_CONFIG_CRC_MASK; 00430 00431 switch ( width ) { 00432 00433 case NRF24L01P_CRC_NONE: 00434 config |= _NRF24L01P_CONFIG_CRC_NONE; 00435 break; 00436 00437 case NRF24L01P_CRC_8_BIT: 00438 config |= _NRF24L01P_CONFIG_CRC_8BIT; 00439 break; 00440 00441 case NRF24L01P_CRC_16_BIT: 00442 config |= _NRF24L01P_CONFIG_CRC_16BIT; 00443 break; 00444 00445 default: 00446 error( "nRF24L01P: Invalid CRC Width setting %d\r\n", width ); 00447 return; 00448 00449 } 00450 00451 setRegister(_NRF24L01P_REG_CONFIG, config); 00452 00453 } 00454 00455 00456 int nRF24L01P::getCrcWidth(void) { 00457 00458 int crcWidth = getRegister(_NRF24L01P_REG_CONFIG) & _NRF24L01P_CONFIG_CRC_MASK; 00459 00460 switch ( crcWidth ) { 00461 00462 case _NRF24L01P_CONFIG_CRC_NONE: 00463 return NRF24L01P_CRC_NONE; 00464 00465 case _NRF24L01P_CONFIG_CRC_8BIT: 00466 return NRF24L01P_CRC_8_BIT; 00467 00468 case _NRF24L01P_CONFIG_CRC_16BIT: 00469 return NRF24L01P_CRC_16_BIT; 00470 00471 default: 00472 error( "nRF24L01P: Unknown CRC Width value %d\r\n", crcWidth ); 00473 return 0; 00474 00475 } 00476 } 00477 00478 00479 void nRF24L01P::setTransferSize(int size, int pipe) { 00480 00481 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00482 00483 error( "nRF24L01P: Invalid Transfer Size pipe number %d\r\n", pipe ); 00484 return; 00485 00486 } 00487 00488 if ( ( size < 0 ) || ( size > _NRF24L01P_RX_FIFO_SIZE ) ) { 00489 00490 error( "nRF24L01P: Invalid Transfer Size setting %d\r\n", size ); 00491 return; 00492 00493 } 00494 00495 int rxPwPxRegister = _NRF24L01P_REG_RX_PW_P0 + ( pipe - NRF24L01P_PIPE_P0 ); 00496 00497 setRegister(rxPwPxRegister, ( size & _NRF24L01P_RX_PW_Px_MASK ) ); 00498 00499 } 00500 00501 00502 int nRF24L01P::getTransferSize(int pipe) { 00503 00504 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00505 00506 error( "nRF24L01P: Invalid Transfer Size pipe number %d\r\n", pipe ); 00507 return 0; 00508 00509 } 00510 00511 int rxPwPxRegister = _NRF24L01P_REG_RX_PW_P0 + ( pipe - NRF24L01P_PIPE_P0 ); 00512 00513 int size = getRegister(rxPwPxRegister); 00514 00515 return ( size & _NRF24L01P_RX_PW_Px_MASK ); 00516 00517 } 00518 00519 00520 void nRF24L01P::disableAllRxPipes(void) { 00521 00522 setRegister(_NRF24L01P_REG_EN_RXADDR, _NRF24L01P_EN_RXADDR_NONE); 00523 00524 } 00525 00526 00527 void nRF24L01P::disableAutoAcknowledge(void) { 00528 00529 setRegister(_NRF24L01P_REG_EN_AA, _NRF24L01P_EN_AA_NONE); 00530 00531 } 00532 00533 00534 void nRF24L01P::enableAutoAcknowledge(int pipe) { 00535 00536 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00537 00538 error( "nRF24L01P: Invalid Enable AutoAcknowledge pipe number %d\r\n", pipe ); 00539 return; 00540 00541 } 00542 00543 int enAA = getRegister(_NRF24L01P_REG_EN_AA); 00544 00545 enAA |= ( 1 << (pipe - NRF24L01P_PIPE_P0) ); 00546 00547 setRegister(_NRF24L01P_REG_EN_AA, enAA); 00548 00549 } 00550 00551 void nRF24L01P::enableAutoRetransmit(int delay, int count) { 00552 uint32_t value = count; 00553 value <<= 4; 00554 value += delay; 00555 setRegister(_NRF24L01P_REG_SETUP_RETR, value); 00556 } 00557 00558 void nRF24L01P::disableAutoRetransmit(void) { 00559 00560 setRegister(_NRF24L01P_REG_SETUP_RETR, _NRF24L01P_SETUP_RETR_NONE); 00561 00562 } 00563 00564 void nRF24L01P::setRxAddress(unsigned long long address, int width, int pipe) { 00565 00566 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00567 00568 error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe ); 00569 return; 00570 00571 } 00572 00573 if ( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) { 00574 00575 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & ~_NRF24L01P_SETUP_AW_AW_MASK; 00576 00577 switch ( width ) { 00578 00579 case 3: 00580 setupAw |= _NRF24L01P_SETUP_AW_AW_3BYTE; 00581 break; 00582 00583 case 4: 00584 setupAw |= _NRF24L01P_SETUP_AW_AW_4BYTE; 00585 break; 00586 00587 case 5: 00588 setupAw |= _NRF24L01P_SETUP_AW_AW_5BYTE; 00589 break; 00590 00591 default: 00592 error( "nRF24L01P: Invalid setRxAddress width setting %d\r\n", width ); 00593 return; 00594 00595 } 00596 00597 setRegister(_NRF24L01P_REG_SETUP_AW, setupAw); 00598 00599 } else { 00600 00601 width = 1; 00602 00603 } 00604 00605 int rxAddrPxRegister = _NRF24L01P_REG_RX_ADDR_P0 + ( pipe - NRF24L01P_PIPE_P0 ); 00606 00607 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (rxAddrPxRegister & _NRF24L01P_REG_ADDRESS_MASK)); 00608 00609 nCS_ = 0; 00610 00611 int status = spi_.write(cn); 00612 00613 while ( width-- > 0 ) { 00614 00615 // 00616 // LSByte first 00617 // 00618 spi_.write((int) (address & 0xFF)); 00619 address >>= 8; 00620 00621 } 00622 00623 nCS_ = 1; 00624 00625 int enRxAddr = getRegister(_NRF24L01P_REG_EN_RXADDR); 00626 00627 enRxAddr |= (1 << ( pipe - NRF24L01P_PIPE_P0 ) ); 00628 00629 setRegister(_NRF24L01P_REG_EN_RXADDR, enRxAddr); 00630 } 00631 00632 /* 00633 * This version of setRxAddress is just a wrapper for the version that takes 'long long's, 00634 * in case the main code doesn't want to deal with long long's. 00635 */ 00636 void nRF24L01P::setRxAddress(unsigned long msb_address, unsigned long lsb_address, int width, int pipe) { 00637 00638 unsigned long long address = ( ( (unsigned long long) msb_address ) << 32 ) | ( ( (unsigned long long) lsb_address ) << 0 ); 00639 00640 setRxAddress(address, width, pipe); 00641 00642 } 00643 00644 00645 /* 00646 * This version of setTxAddress is just a wrapper for the version that takes 'long long's, 00647 * in case the main code doesn't want to deal with long long's. 00648 */ 00649 void nRF24L01P::setTxAddress(unsigned long msb_address, unsigned long lsb_address, int width) { 00650 00651 unsigned long long address = ( ( (unsigned long long) msb_address ) << 32 ) | ( ( (unsigned long long) lsb_address ) << 0 ); 00652 00653 setTxAddress(address, width); 00654 00655 } 00656 00657 00658 void nRF24L01P::setTxAddress(unsigned long long address, int width) { 00659 00660 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & ~_NRF24L01P_SETUP_AW_AW_MASK; 00661 00662 switch ( width ) { 00663 00664 case 3: 00665 setupAw |= _NRF24L01P_SETUP_AW_AW_3BYTE; 00666 break; 00667 00668 case 4: 00669 setupAw |= _NRF24L01P_SETUP_AW_AW_4BYTE; 00670 break; 00671 00672 case 5: 00673 setupAw |= _NRF24L01P_SETUP_AW_AW_5BYTE; 00674 break; 00675 00676 default: 00677 error( "nRF24L01P: Invalid setTxAddress width setting %d\r\n", width ); 00678 return; 00679 00680 } 00681 00682 setRegister(_NRF24L01P_REG_SETUP_AW, setupAw); 00683 00684 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (_NRF24L01P_REG_TX_ADDR & _NRF24L01P_REG_ADDRESS_MASK)); 00685 00686 nCS_ = 0; 00687 00688 int status = spi_.write(cn); 00689 00690 while ( width-- > 0 ) { 00691 00692 // 00693 // LSByte first 00694 // 00695 spi_.write((int) (address & 0xFF)); 00696 address >>= 8; 00697 00698 } 00699 00700 nCS_ = 1; 00701 00702 } 00703 00704 00705 unsigned long long nRF24L01P::getRxAddress(int pipe) { 00706 00707 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00708 00709 error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe ); 00710 return 0; 00711 00712 } 00713 00714 int width; 00715 00716 if ( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) { 00717 00718 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & _NRF24L01P_SETUP_AW_AW_MASK; 00719 00720 switch ( setupAw ) { 00721 00722 case _NRF24L01P_SETUP_AW_AW_3BYTE: 00723 width = 3; 00724 break; 00725 00726 case _NRF24L01P_SETUP_AW_AW_4BYTE: 00727 width = 4; 00728 break; 00729 00730 case _NRF24L01P_SETUP_AW_AW_5BYTE: 00731 width = 5; 00732 break; 00733 00734 default: 00735 error( "nRF24L01P: Unknown getRxAddress width value %d\r\n", setupAw ); 00736 return 0; 00737 00738 } 00739 00740 } else { 00741 00742 width = 1; 00743 00744 } 00745 00746 int rxAddrPxRegister = _NRF24L01P_REG_RX_ADDR_P0 + ( pipe - NRF24L01P_PIPE_P0 ); 00747 00748 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (rxAddrPxRegister & _NRF24L01P_REG_ADDRESS_MASK)); 00749 00750 unsigned long long address = 0; 00751 00752 nCS_ = 0; 00753 00754 int status = spi_.write(cn); 00755 00756 for ( int i=0; i<width; i++ ) { 00757 00758 // 00759 // LSByte first 00760 // 00761 address |= ( ( (unsigned long long)( spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF ) ) << (i*8) ); 00762 00763 } 00764 00765 nCS_ = 1; 00766 00767 if ( !( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) ) { 00768 00769 address |= ( getRxAddress(NRF24L01P_PIPE_P1) & ~((unsigned long long) 0xFF) ); 00770 00771 } 00772 00773 return address; 00774 00775 } 00776 00777 00778 unsigned long long nRF24L01P::getTxAddress(void) { 00779 00780 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & _NRF24L01P_SETUP_AW_AW_MASK; 00781 00782 int width; 00783 00784 switch ( setupAw ) { 00785 00786 case _NRF24L01P_SETUP_AW_AW_3BYTE: 00787 width = 3; 00788 break; 00789 00790 case _NRF24L01P_SETUP_AW_AW_4BYTE: 00791 width = 4; 00792 break; 00793 00794 case _NRF24L01P_SETUP_AW_AW_5BYTE: 00795 width = 5; 00796 break; 00797 00798 default: 00799 error( "nRF24L01P: Unknown getTxAddress width value %d\r\n", setupAw ); 00800 return 0; 00801 00802 } 00803 00804 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (_NRF24L01P_REG_TX_ADDR & _NRF24L01P_REG_ADDRESS_MASK)); 00805 00806 unsigned long long address = 0; 00807 00808 nCS_ = 0; 00809 00810 int status = spi_.write(cn); 00811 00812 for ( int i=0; i<width; i++ ) { 00813 00814 // 00815 // LSByte first 00816 // 00817 address |= ( ( (unsigned long long)( spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF ) ) << (i*8) ); 00818 00819 } 00820 00821 nCS_ = 1; 00822 00823 return address; 00824 } 00825 00826 00827 bool nRF24L01P::readable(int pipe) { 00828 00829 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00830 00831 error( "nRF24L01P: Invalid readable pipe number %d\r\n", pipe ); 00832 return false; 00833 00834 } 00835 00836 int status = getStatusRegister(); 00837 00838 return ( ( status & _NRF24L01P_STATUS_RX_DR ) && ( ( ( status & _NRF24L01P_STATUS_RX_P_NO ) >> 1 ) == ( pipe & 0x7 ) ) ); 00839 00840 } 00841 00842 00843 int nRF24L01P::write(int pipe, char *data, int count) { 00844 00845 // Note: the pipe number is ignored in a Transmit / write 00846 00847 // 00848 // Save the CE state 00849 // 00850 int originalCe = ce_; 00851 disable(); 00852 00853 if ( count <= 0 ) return 0; 00854 00855 if ( count > _NRF24L01P_TX_FIFO_SIZE ) count = _NRF24L01P_TX_FIFO_SIZE; 00856 00857 // Clear the Status bit 00858 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_TX_DS); 00859 00860 nCS_ = 0; 00861 00862 int status = spi_.write(_NRF24L01P_SPI_CMD_WR_TX_PAYLOAD); 00863 00864 for ( int i = 0; i < count; i++ ) { 00865 00866 spi_.write(*data++); 00867 00868 } 00869 00870 nCS_ = 1; 00871 00872 int originalMode = mode; 00873 setTransmitMode(); 00874 00875 enable(); 00876 wait_us(_NRF24L01P_TIMING_Thce_us); 00877 disable(); 00878 00879 while ( !( getStatusRegister() & _NRF24L01P_STATUS_TX_DS ) ) { 00880 00881 // Wait for the transfer to complete 00882 00883 } 00884 00885 // Clear the Status bit 00886 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_TX_DS); 00887 00888 if ( originalMode == _NRF24L01P_MODE_RX ) { 00889 00890 setReceiveMode(); 00891 00892 } 00893 00894 ce_ = originalCe; 00895 wait_us( _NRF24L01P_TIMING_Tpece2csn_us ); 00896 00897 return count; 00898 00899 } 00900 00901 00902 int nRF24L01P::read(int pipe, char *data, int count) { 00903 00904 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00905 00906 error( "nRF24L01P: Invalid read pipe number %d\r\n", pipe ); 00907 return -1; 00908 00909 } 00910 00911 if ( count <= 0 ) return 0; 00912 00913 if ( count > _NRF24L01P_RX_FIFO_SIZE ) count = _NRF24L01P_RX_FIFO_SIZE; 00914 00915 if ( readable(pipe) ) { 00916 00917 nCS_ = 0; 00918 00919 int status = spi_.write(_NRF24L01P_SPI_CMD_R_RX_PL_WID); 00920 00921 int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP); 00922 00923 nCS_ = 1; 00924 00925 if ( ( rxPayloadWidth < 0 ) || ( rxPayloadWidth > _NRF24L01P_RX_FIFO_SIZE ) ) { 00926 00927 // Received payload error: need to flush the FIFO 00928 00929 nCS_ = 0; 00930 00931 int status = spi_.write(_NRF24L01P_SPI_CMD_FLUSH_RX); 00932 00933 int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP); 00934 00935 nCS_ = 1; 00936 00937 // 00938 // At this point, we should retry the reception, 00939 // but for now we'll just fall through... 00940 // 00941 00942 } else { 00943 00944 if ( rxPayloadWidth < count ) count = rxPayloadWidth; 00945 00946 nCS_ = 0; 00947 00948 int status = spi_.write(_NRF24L01P_SPI_CMD_RD_RX_PAYLOAD); 00949 00950 for ( int i = 0; i < count; i++ ) { 00951 00952 *data++ = spi_.write(_NRF24L01P_SPI_CMD_NOP); 00953 00954 } 00955 00956 nCS_ = 1; 00957 00958 // Clear the Status bit 00959 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_RX_DR); 00960 00961 return count; 00962 00963 } 00964 00965 } else { 00966 00967 // 00968 // What should we do if there is no 'readable' data? 00969 // We could wait for data to arrive, but for now, we'll 00970 // just return with no data. 00971 // 00972 return 0; 00973 00974 } 00975 00976 // 00977 // We get here because an error condition occured; 00978 // We could wait for data to arrive, but for now, we'll 00979 // just return with no data. 00980 // 00981 return -1; 00982 00983 } 00984 00985 void nRF24L01P::setRegister(int regAddress, int regData) { 00986 00987 // 00988 // Save the CE state 00989 // 00990 int originalCe = ce_; 00991 disable(); 00992 00993 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (regAddress & _NRF24L01P_REG_ADDRESS_MASK)); 00994 00995 nCS_ = 0; 00996 00997 int status = spi_.write(cn); 00998 00999 spi_.write(regData & 0xFF); 01000 01001 nCS_ = 1; 01002 01003 ce_ = originalCe; 01004 wait_us( _NRF24L01P_TIMING_Tpece2csn_us ); 01005 01006 } 01007 01008 01009 int nRF24L01P::getRegister(int regAddress) { 01010 01011 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (regAddress & _NRF24L01P_REG_ADDRESS_MASK)); 01012 01013 nCS_ = 0; 01014 01015 int status = spi_.write(cn); 01016 01017 int dn = spi_.write(_NRF24L01P_SPI_CMD_NOP); 01018 01019 nCS_ = 1; 01020 01021 return dn; 01022 01023 } 01024 01025 int nRF24L01P::getStatusRegister(void) { 01026 01027 nCS_ = 0; 01028 01029 int status = spi_.write(_NRF24L01P_SPI_CMD_NOP); 01030 01031 nCS_ = 1; 01032 01033 return status; 01034 01035 }
Generated on Mon Jul 25 2022 19:06:01 by
1.7.2