Interface library for the nRF24L01+ chip (specifically the Transceiver nRF24L01+ Module with Chip Antenna from SparkFun, talking to their Nordic Serial Interface Board, but should work with any nRF24L01+).
Dependents: nRF24L01P_Hello_World NerfGun_nRF24L01P_RX NerfGun_nRF24L01P_TX idd_hw3_AngieWangAntonioDeLimaFernandesDanielLim_BladeSymphony ... more
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 00552 void nRF24L01P::disableAutoRetransmit(void) { 00553 00554 setRegister(_NRF24L01P_REG_SETUP_RETR, _NRF24L01P_SETUP_RETR_NONE); 00555 00556 } 00557 00558 void nRF24L01P::setRxAddress(unsigned long long address, int width, int pipe) { 00559 00560 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00561 00562 error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe ); 00563 return; 00564 00565 } 00566 00567 if ( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) { 00568 00569 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & ~_NRF24L01P_SETUP_AW_AW_MASK; 00570 00571 switch ( width ) { 00572 00573 case 3: 00574 setupAw |= _NRF24L01P_SETUP_AW_AW_3BYTE; 00575 break; 00576 00577 case 4: 00578 setupAw |= _NRF24L01P_SETUP_AW_AW_4BYTE; 00579 break; 00580 00581 case 5: 00582 setupAw |= _NRF24L01P_SETUP_AW_AW_5BYTE; 00583 break; 00584 00585 default: 00586 error( "nRF24L01P: Invalid setRxAddress width setting %d\r\n", width ); 00587 return; 00588 00589 } 00590 00591 setRegister(_NRF24L01P_REG_SETUP_AW, setupAw); 00592 00593 } else { 00594 00595 width = 1; 00596 00597 } 00598 00599 int rxAddrPxRegister = _NRF24L01P_REG_RX_ADDR_P0 + ( pipe - NRF24L01P_PIPE_P0 ); 00600 00601 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (rxAddrPxRegister & _NRF24L01P_REG_ADDRESS_MASK)); 00602 00603 nCS_ = 0; 00604 00605 int status = spi_.write(cn); 00606 00607 while ( width-- > 0 ) { 00608 00609 // 00610 // LSByte first 00611 // 00612 spi_.write((int) (address & 0xFF)); 00613 address >>= 8; 00614 00615 } 00616 00617 nCS_ = 1; 00618 00619 int enRxAddr = getRegister(_NRF24L01P_REG_EN_RXADDR); 00620 00621 enRxAddr |= (1 << ( pipe - NRF24L01P_PIPE_P0 ) ); 00622 00623 setRegister(_NRF24L01P_REG_EN_RXADDR, enRxAddr); 00624 } 00625 00626 /* 00627 * This version of setRxAddress is just a wrapper for the version that takes 'long long's, 00628 * in case the main code doesn't want to deal with long long's. 00629 */ 00630 void nRF24L01P::setRxAddress(unsigned long msb_address, unsigned long lsb_address, int width, int pipe) { 00631 00632 unsigned long long address = ( ( (unsigned long long) msb_address ) << 32 ) | ( ( (unsigned long long) lsb_address ) << 0 ); 00633 00634 setRxAddress(address, width, pipe); 00635 00636 } 00637 00638 00639 /* 00640 * This version of setTxAddress is just a wrapper for the version that takes 'long long's, 00641 * in case the main code doesn't want to deal with long long's. 00642 */ 00643 void nRF24L01P::setTxAddress(unsigned long msb_address, unsigned long lsb_address, int width) { 00644 00645 unsigned long long address = ( ( (unsigned long long) msb_address ) << 32 ) | ( ( (unsigned long long) lsb_address ) << 0 ); 00646 00647 setTxAddress(address, width); 00648 00649 } 00650 00651 00652 void nRF24L01P::setTxAddress(unsigned long long address, int width) { 00653 00654 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & ~_NRF24L01P_SETUP_AW_AW_MASK; 00655 00656 switch ( width ) { 00657 00658 case 3: 00659 setupAw |= _NRF24L01P_SETUP_AW_AW_3BYTE; 00660 break; 00661 00662 case 4: 00663 setupAw |= _NRF24L01P_SETUP_AW_AW_4BYTE; 00664 break; 00665 00666 case 5: 00667 setupAw |= _NRF24L01P_SETUP_AW_AW_5BYTE; 00668 break; 00669 00670 default: 00671 error( "nRF24L01P: Invalid setTxAddress width setting %d\r\n", width ); 00672 return; 00673 00674 } 00675 00676 setRegister(_NRF24L01P_REG_SETUP_AW, setupAw); 00677 00678 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (_NRF24L01P_REG_TX_ADDR & _NRF24L01P_REG_ADDRESS_MASK)); 00679 00680 nCS_ = 0; 00681 00682 int status = spi_.write(cn); 00683 00684 while ( width-- > 0 ) { 00685 00686 // 00687 // LSByte first 00688 // 00689 spi_.write((int) (address & 0xFF)); 00690 address >>= 8; 00691 00692 } 00693 00694 nCS_ = 1; 00695 00696 } 00697 00698 00699 unsigned long long nRF24L01P::getRxAddress(int pipe) { 00700 00701 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00702 00703 error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe ); 00704 return 0; 00705 00706 } 00707 00708 int width; 00709 00710 if ( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) { 00711 00712 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & _NRF24L01P_SETUP_AW_AW_MASK; 00713 00714 switch ( setupAw ) { 00715 00716 case _NRF24L01P_SETUP_AW_AW_3BYTE: 00717 width = 3; 00718 break; 00719 00720 case _NRF24L01P_SETUP_AW_AW_4BYTE: 00721 width = 4; 00722 break; 00723 00724 case _NRF24L01P_SETUP_AW_AW_5BYTE: 00725 width = 5; 00726 break; 00727 00728 default: 00729 error( "nRF24L01P: Unknown getRxAddress width value %d\r\n", setupAw ); 00730 return 0; 00731 00732 } 00733 00734 } else { 00735 00736 width = 1; 00737 00738 } 00739 00740 int rxAddrPxRegister = _NRF24L01P_REG_RX_ADDR_P0 + ( pipe - NRF24L01P_PIPE_P0 ); 00741 00742 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (rxAddrPxRegister & _NRF24L01P_REG_ADDRESS_MASK)); 00743 00744 unsigned long long address = 0; 00745 00746 nCS_ = 0; 00747 00748 int status = spi_.write(cn); 00749 00750 for ( int i=0; i<width; i++ ) { 00751 00752 // 00753 // LSByte first 00754 // 00755 address |= ( ( (unsigned long long)( spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF ) ) << (i*8) ); 00756 00757 } 00758 00759 nCS_ = 1; 00760 00761 if ( !( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) ) { 00762 00763 address |= ( getRxAddress(NRF24L01P_PIPE_P1) & ~((unsigned long long) 0xFF) ); 00764 00765 } 00766 00767 return address; 00768 00769 } 00770 00771 00772 unsigned long long nRF24L01P::getTxAddress(void) { 00773 00774 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & _NRF24L01P_SETUP_AW_AW_MASK; 00775 00776 int width; 00777 00778 switch ( setupAw ) { 00779 00780 case _NRF24L01P_SETUP_AW_AW_3BYTE: 00781 width = 3; 00782 break; 00783 00784 case _NRF24L01P_SETUP_AW_AW_4BYTE: 00785 width = 4; 00786 break; 00787 00788 case _NRF24L01P_SETUP_AW_AW_5BYTE: 00789 width = 5; 00790 break; 00791 00792 default: 00793 error( "nRF24L01P: Unknown getTxAddress width value %d\r\n", setupAw ); 00794 return 0; 00795 00796 } 00797 00798 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (_NRF24L01P_REG_TX_ADDR & _NRF24L01P_REG_ADDRESS_MASK)); 00799 00800 unsigned long long address = 0; 00801 00802 nCS_ = 0; 00803 00804 int status = spi_.write(cn); 00805 00806 for ( int i=0; i<width; i++ ) { 00807 00808 // 00809 // LSByte first 00810 // 00811 address |= ( ( (unsigned long long)( spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF ) ) << (i*8) ); 00812 00813 } 00814 00815 nCS_ = 1; 00816 00817 return address; 00818 } 00819 00820 00821 bool nRF24L01P::readable(int pipe) { 00822 00823 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00824 00825 error( "nRF24L01P: Invalid readable pipe number %d\r\n", pipe ); 00826 return false; 00827 00828 } 00829 00830 int status = getStatusRegister(); 00831 00832 return ( ( status & _NRF24L01P_STATUS_RX_DR ) && ( ( ( status & _NRF24L01P_STATUS_RX_P_NO ) >> 1 ) == ( pipe & 0x7 ) ) ); 00833 00834 } 00835 00836 00837 int nRF24L01P::write(int pipe, char *data, int count) { 00838 00839 // Note: the pipe number is ignored in a Transmit / write 00840 00841 // 00842 // Save the CE state 00843 // 00844 int originalCe = ce_; 00845 disable(); 00846 00847 if ( count <= 0 ) return 0; 00848 00849 if ( count > _NRF24L01P_TX_FIFO_SIZE ) count = _NRF24L01P_TX_FIFO_SIZE; 00850 00851 // Clear the Status bit 00852 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_TX_DS); 00853 00854 nCS_ = 0; 00855 00856 int status = spi_.write(_NRF24L01P_SPI_CMD_WR_TX_PAYLOAD); 00857 00858 for ( int i = 0; i < count; i++ ) { 00859 00860 spi_.write(*data++); 00861 00862 } 00863 00864 nCS_ = 1; 00865 00866 int originalMode = mode; 00867 setTransmitMode(); 00868 00869 enable(); 00870 wait_us(_NRF24L01P_TIMING_Thce_us); 00871 disable(); 00872 00873 while ( !( getStatusRegister() & _NRF24L01P_STATUS_TX_DS ) ) { 00874 00875 // Wait for the transfer to complete 00876 00877 } 00878 00879 // Clear the Status bit 00880 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_TX_DS); 00881 00882 if ( originalMode == _NRF24L01P_MODE_RX ) { 00883 00884 setReceiveMode(); 00885 00886 } 00887 00888 ce_ = originalCe; 00889 wait_us( _NRF24L01P_TIMING_Tpece2csn_us ); 00890 00891 return count; 00892 00893 } 00894 00895 00896 int nRF24L01P::read(int pipe, char *data, int count) { 00897 00898 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00899 00900 error( "nRF24L01P: Invalid read pipe number %d\r\n", pipe ); 00901 return -1; 00902 00903 } 00904 00905 if ( count <= 0 ) return 0; 00906 00907 if ( count > _NRF24L01P_RX_FIFO_SIZE ) count = _NRF24L01P_RX_FIFO_SIZE; 00908 00909 if ( readable(pipe) ) { 00910 00911 nCS_ = 0; 00912 00913 int status = spi_.write(_NRF24L01P_SPI_CMD_R_RX_PL_WID); 00914 00915 int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP); 00916 00917 nCS_ = 1; 00918 00919 if ( ( rxPayloadWidth < 0 ) || ( rxPayloadWidth > _NRF24L01P_RX_FIFO_SIZE ) ) { 00920 00921 // Received payload error: need to flush the FIFO 00922 00923 nCS_ = 0; 00924 00925 int status = spi_.write(_NRF24L01P_SPI_CMD_FLUSH_RX); 00926 00927 int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP); 00928 00929 nCS_ = 1; 00930 00931 // 00932 // At this point, we should retry the reception, 00933 // but for now we'll just fall through... 00934 // 00935 00936 } else { 00937 00938 if ( rxPayloadWidth < count ) count = rxPayloadWidth; 00939 00940 nCS_ = 0; 00941 00942 int status = spi_.write(_NRF24L01P_SPI_CMD_RD_RX_PAYLOAD); 00943 00944 for ( int i = 0; i < count; i++ ) { 00945 00946 *data++ = spi_.write(_NRF24L01P_SPI_CMD_NOP); 00947 00948 } 00949 00950 nCS_ = 1; 00951 00952 // Clear the Status bit 00953 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_RX_DR); 00954 00955 return count; 00956 00957 } 00958 00959 } else { 00960 00961 // 00962 // What should we do if there is no 'readable' data? 00963 // We could wait for data to arrive, but for now, we'll 00964 // just return with no data. 00965 // 00966 return 0; 00967 00968 } 00969 00970 // 00971 // We get here because an error condition occured; 00972 // We could wait for data to arrive, but for now, we'll 00973 // just return with no data. 00974 // 00975 return -1; 00976 00977 } 00978 00979 void nRF24L01P::setRegister(int regAddress, int regData) { 00980 00981 // 00982 // Save the CE state 00983 // 00984 int originalCe = ce_; 00985 disable(); 00986 00987 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (regAddress & _NRF24L01P_REG_ADDRESS_MASK)); 00988 00989 nCS_ = 0; 00990 00991 int status = spi_.write(cn); 00992 00993 spi_.write(regData & 0xFF); 00994 00995 nCS_ = 1; 00996 00997 ce_ = originalCe; 00998 wait_us( _NRF24L01P_TIMING_Tpece2csn_us ); 00999 01000 } 01001 01002 01003 int nRF24L01P::getRegister(int regAddress) { 01004 01005 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (regAddress & _NRF24L01P_REG_ADDRESS_MASK)); 01006 01007 nCS_ = 0; 01008 01009 int status = spi_.write(cn); 01010 01011 int dn = spi_.write(_NRF24L01P_SPI_CMD_NOP); 01012 01013 nCS_ = 1; 01014 01015 return dn; 01016 01017 } 01018 01019 int nRF24L01P::getStatusRegister(void) { 01020 01021 nCS_ = 0; 01022 01023 int status = spi_.write(_NRF24L01P_SPI_CMD_NOP); 01024 01025 nCS_ = 1; 01026 01027 return status; 01028 01029 }
Generated on Tue Jul 12 2022 17:37:08 by 1.7.2