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: JNP3_IOT_6_RADIO_ECHO_FIXED2
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 // Wait until the nRF24L01+ powers down 00195 wait_us( _NRF24L01P_TIMING_Tpd2stby_us ); // This *may* not be necessary (no timing is shown in the Datasheet), but just to be safe 00196 00197 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_MAX_RT|_NRF24L01P_STATUS_TX_DS|_NRF24L01P_STATUS_RX_DR); // Clear any pending interrupts 00198 00199 //flush FIFO 00200 nCS_ = 0; 00201 spi_.write(_NRF24L01P_SPI_CMD_FLUSH_TX); 00202 nCS_ = 1; 00203 wait_us( _NRF24L01P_TIMING_Tpece2csn_us ); 00204 nCS_ = 0; 00205 spi_.write(_NRF24L01P_SPI_CMD_FLUSH_RX); 00206 nCS_ = 1; 00207 wait_us( _NRF24L01P_TIMING_Tpece2csn_us ); 00208 00209 00210 // 00211 // Setup default configuration 00212 // 00213 disableAllRxPipes(); 00214 setRfFrequency(); 00215 setRfOutputPower(); 00216 setAirDataRate(); 00217 setCrcWidth(); 00218 setTxAddress(); 00219 setRxAddress(); 00220 disableAutoAcknowledge(); 00221 disableAutoRetransmit(); 00222 setTransferSize(); 00223 00224 a_retr_enabled = true; 00225 00226 mode = _NRF24L01P_MODE_POWER_DOWN; 00227 00228 } 00229 00230 00231 void nRF24L01P::powerUp(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 up 00240 wait_us( _NRF24L01P_TIMING_Tpd2stby_us ); 00241 00242 mode = _NRF24L01P_MODE_STANDBY; 00243 00244 } 00245 00246 00247 void nRF24L01P::powerDown(void) { 00248 00249 int config = getRegister(_NRF24L01P_REG_CONFIG); 00250 00251 config &= ~_NRF24L01P_CONFIG_PWR_UP; 00252 00253 setRegister(_NRF24L01P_REG_CONFIG, config); 00254 00255 // Wait until the nRF24L01+ powers down 00256 wait_us( _NRF24L01P_TIMING_Tpd2stby_us ); // This *may* not be necessary (no timing is shown in the Datasheet), but just to be safe 00257 00258 mode = _NRF24L01P_MODE_POWER_DOWN; 00259 00260 } 00261 00262 00263 void nRF24L01P::setReceiveMode(void) { 00264 00265 if ( _NRF24L01P_MODE_POWER_DOWN == mode ) powerUp(); 00266 00267 int config = getRegister(_NRF24L01P_REG_CONFIG); 00268 00269 config |= _NRF24L01P_CONFIG_PRIM_RX; 00270 00271 setRegister(_NRF24L01P_REG_CONFIG, config); 00272 00273 mode = _NRF24L01P_MODE_RX; 00274 00275 } 00276 00277 00278 void nRF24L01P::setTransmitMode(void) { 00279 00280 if ( _NRF24L01P_MODE_POWER_DOWN == mode ) powerUp(); 00281 00282 int config = getRegister(_NRF24L01P_REG_CONFIG); 00283 00284 config &= ~_NRF24L01P_CONFIG_PRIM_RX; 00285 00286 setRegister(_NRF24L01P_REG_CONFIG, config); 00287 00288 mode = _NRF24L01P_MODE_TX; 00289 00290 } 00291 00292 00293 void nRF24L01P::enable(void) { 00294 00295 ce_ = 1; 00296 wait_us( _NRF24L01P_TIMING_Tpece2csn_us ); 00297 00298 } 00299 00300 00301 void nRF24L01P::disable(void) { 00302 00303 ce_ = 0; 00304 00305 } 00306 00307 void nRF24L01P::setRfFrequency(int frequency) { 00308 00309 if ( ( frequency < NRF24L01P_MIN_RF_FREQUENCY ) || ( frequency > NRF24L01P_MAX_RF_FREQUENCY ) ) { 00310 00311 error( "nRF24L01P: Invalid RF Frequency setting %d\r\n", frequency ); 00312 return; 00313 00314 } 00315 00316 int channel = ( frequency - NRF24L01P_MIN_RF_FREQUENCY ) & 0x7F; 00317 00318 setRegister(_NRF24L01P_REG_RF_CH, channel); 00319 00320 } 00321 00322 00323 int nRF24L01P::getRfFrequency(void) { 00324 00325 int channel = getRegister(_NRF24L01P_REG_RF_CH) & 0x7F; 00326 00327 return ( channel + NRF24L01P_MIN_RF_FREQUENCY ); 00328 00329 } 00330 00331 00332 void nRF24L01P::setRfOutputPower(int power) { 00333 00334 int rfSetup = getRegister(_NRF24L01P_REG_RF_SETUP) & ~_NRF24L01P_RF_SETUP_RF_PWR_MASK; 00335 00336 switch ( power ) { 00337 00338 case NRF24L01P_TX_PWR_ZERO_DB: 00339 rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_0DBM; 00340 break; 00341 00342 case NRF24L01P_TX_PWR_MINUS_6_DB: 00343 rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_MINUS_6DBM; 00344 break; 00345 00346 case NRF24L01P_TX_PWR_MINUS_12_DB: 00347 rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_MINUS_12DBM; 00348 break; 00349 00350 case NRF24L01P_TX_PWR_MINUS_18_DB: 00351 rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_MINUS_18DBM; 00352 break; 00353 00354 default: 00355 error( "nRF24L01P: Invalid RF Output Power setting %d\r\n", power ); 00356 return; 00357 00358 } 00359 00360 setRegister(_NRF24L01P_REG_RF_SETUP, rfSetup); 00361 00362 } 00363 00364 00365 int nRF24L01P::getRfOutputPower(void) { 00366 00367 int rfPwr = getRegister(_NRF24L01P_REG_RF_SETUP) & _NRF24L01P_RF_SETUP_RF_PWR_MASK; 00368 00369 switch ( rfPwr ) { 00370 00371 case _NRF24L01P_RF_SETUP_RF_PWR_0DBM: 00372 return NRF24L01P_TX_PWR_ZERO_DB; 00373 00374 case _NRF24L01P_RF_SETUP_RF_PWR_MINUS_6DBM: 00375 return NRF24L01P_TX_PWR_MINUS_6_DB; 00376 00377 case _NRF24L01P_RF_SETUP_RF_PWR_MINUS_12DBM: 00378 return NRF24L01P_TX_PWR_MINUS_12_DB; 00379 00380 case _NRF24L01P_RF_SETUP_RF_PWR_MINUS_18DBM: 00381 return NRF24L01P_TX_PWR_MINUS_18_DB; 00382 00383 default: 00384 error( "nRF24L01P: Unknown RF Output Power value %d\r\n", rfPwr ); 00385 return 0; 00386 00387 } 00388 } 00389 00390 00391 void nRF24L01P::setAirDataRate(int rate) { 00392 00393 int rfSetup = getRegister(_NRF24L01P_REG_RF_SETUP) & ~_NRF24L01P_RF_SETUP_RF_DR_MASK; 00394 00395 switch ( rate ) { 00396 00397 case NRF24L01P_DATARATE_250_KBPS: 00398 rfSetup |= _NRF24L01P_RF_SETUP_RF_DR_250KBPS; 00399 break; 00400 00401 case NRF24L01P_DATARATE_1_MBPS: 00402 rfSetup |= _NRF24L01P_RF_SETUP_RF_DR_1MBPS; 00403 break; 00404 00405 case NRF24L01P_DATARATE_2_MBPS: 00406 rfSetup |= _NRF24L01P_RF_SETUP_RF_DR_2MBPS; 00407 break; 00408 00409 default: 00410 error( "nRF24L01P: Invalid Air Data Rate setting %d\r\n", rate ); 00411 return; 00412 00413 } 00414 00415 setRegister(_NRF24L01P_REG_RF_SETUP, rfSetup); 00416 00417 } 00418 00419 00420 int nRF24L01P::getAirDataRate(void) { 00421 00422 int rfDataRate = getRegister(_NRF24L01P_REG_RF_SETUP) & _NRF24L01P_RF_SETUP_RF_DR_MASK; 00423 00424 switch ( rfDataRate ) { 00425 00426 case _NRF24L01P_RF_SETUP_RF_DR_250KBPS: 00427 return NRF24L01P_DATARATE_250_KBPS; 00428 00429 case _NRF24L01P_RF_SETUP_RF_DR_1MBPS: 00430 return NRF24L01P_DATARATE_1_MBPS; 00431 00432 case _NRF24L01P_RF_SETUP_RF_DR_2MBPS: 00433 return NRF24L01P_DATARATE_2_MBPS; 00434 00435 default: 00436 error( "nRF24L01P: Unknown Air Data Rate value %d\r\n", rfDataRate ); 00437 return 0; 00438 00439 } 00440 } 00441 00442 00443 void nRF24L01P::setCrcWidth(int width) { 00444 00445 int config = getRegister(_NRF24L01P_REG_CONFIG) & ~_NRF24L01P_CONFIG_CRC_MASK; 00446 00447 switch ( width ) { 00448 00449 case NRF24L01P_CRC_NONE: 00450 config |= _NRF24L01P_CONFIG_CRC_NONE; 00451 break; 00452 00453 case NRF24L01P_CRC_8_BIT: 00454 config |= _NRF24L01P_CONFIG_CRC_8BIT; 00455 break; 00456 00457 case NRF24L01P_CRC_16_BIT: 00458 config |= _NRF24L01P_CONFIG_CRC_16BIT; 00459 break; 00460 00461 default: 00462 error( "nRF24L01P: Invalid CRC Width setting %d\r\n", width ); 00463 return; 00464 00465 } 00466 00467 setRegister(_NRF24L01P_REG_CONFIG, config); 00468 00469 } 00470 00471 00472 int nRF24L01P::getCrcWidth(void) { 00473 00474 int crcWidth = getRegister(_NRF24L01P_REG_CONFIG) & _NRF24L01P_CONFIG_CRC_MASK; 00475 00476 switch ( crcWidth ) { 00477 00478 case _NRF24L01P_CONFIG_CRC_NONE: 00479 return NRF24L01P_CRC_NONE; 00480 00481 case _NRF24L01P_CONFIG_CRC_8BIT: 00482 return NRF24L01P_CRC_8_BIT; 00483 00484 case _NRF24L01P_CONFIG_CRC_16BIT: 00485 return NRF24L01P_CRC_16_BIT; 00486 00487 default: 00488 error( "nRF24L01P: Unknown CRC Width value %d\r\n", crcWidth ); 00489 return 0; 00490 00491 } 00492 } 00493 00494 00495 void nRF24L01P::setTransferSize(int size, int pipe) { 00496 00497 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00498 00499 error( "nRF24L01P: Invalid Transfer Size pipe number %d\r\n", pipe ); 00500 return; 00501 00502 } 00503 00504 if ( ( size < 0 ) || ( size > _NRF24L01P_RX_FIFO_SIZE ) ) { 00505 00506 error( "nRF24L01P: Invalid Transfer Size setting %d\r\n", size ); 00507 return; 00508 00509 } 00510 00511 int rxPwPxRegister = _NRF24L01P_REG_RX_PW_P0 + ( pipe - NRF24L01P_PIPE_P0 ); 00512 00513 setRegister(rxPwPxRegister, ( size & _NRF24L01P_RX_PW_Px_MASK ) ); 00514 00515 } 00516 00517 00518 int nRF24L01P::getTransferSize(int pipe) { 00519 00520 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00521 00522 error( "nRF24L01P: Invalid Transfer Size pipe number %d\r\n", pipe ); 00523 return 0; 00524 00525 } 00526 00527 int rxPwPxRegister = _NRF24L01P_REG_RX_PW_P0 + ( pipe - NRF24L01P_PIPE_P0 ); 00528 00529 int size = getRegister(rxPwPxRegister); 00530 00531 return ( size & _NRF24L01P_RX_PW_Px_MASK ); 00532 00533 } 00534 00535 00536 void nRF24L01P::disableAllRxPipes(void) { 00537 00538 setRegister(_NRF24L01P_REG_EN_RXADDR, _NRF24L01P_EN_RXADDR_NONE); 00539 00540 } 00541 00542 00543 void nRF24L01P::disableAutoAcknowledge(void) { 00544 00545 setRegister(_NRF24L01P_REG_EN_AA, _NRF24L01P_EN_AA_NONE); 00546 00547 } 00548 00549 00550 void nRF24L01P::enableAutoAcknowledge(int pipe) { 00551 00552 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00553 00554 error( "nRF24L01P: Invalid Enable AutoAcknowledge pipe number %d\r\n", pipe ); 00555 return; 00556 00557 } 00558 00559 int enAA = getRegister(_NRF24L01P_REG_EN_AA); 00560 00561 enAA |= ( 1 << (pipe - NRF24L01P_PIPE_P0) ); 00562 00563 setRegister(_NRF24L01P_REG_EN_AA, enAA); 00564 00565 } 00566 00567 00568 void nRF24L01P::enableDynamicPayload(int pipe) { 00569 00570 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00571 00572 error( "nRF24L01P: Invalid Enable AutoAcknowledge pipe number %d\r\n", pipe ); 00573 return; 00574 00575 } 00576 00577 int feature = getRegister(_NRF24L01P_REG_FEATURE); 00578 feature |= ( 1 << 2 ); 00579 setRegister(_NRF24L01P_REG_FEATURE, feature); 00580 00581 int dynpd = getRegister(_NRF24L01P_REG_DYNPD); 00582 dynpd |= ( 1 << (pipe - NRF24L01P_PIPE_P0) ); 00583 setRegister(_NRF24L01P_REG_DYNPD, dynpd); 00584 00585 } 00586 00587 00588 void nRF24L01P::disableDynamicPayload(void) { 00589 00590 int feature = getRegister(_NRF24L01P_REG_FEATURE); 00591 feature &= !( 1 << 2 ); 00592 setRegister(_NRF24L01P_REG_FEATURE, feature); 00593 } 00594 00595 00596 void nRF24L01P::disableAutoRetransmit(void) { 00597 00598 setRegister(_NRF24L01P_REG_SETUP_RETR, _NRF24L01P_SETUP_RETR_NONE); 00599 a_retr_enabled = false; 00600 00601 } 00602 00603 void nRF24L01P::enableAutoRetransmit(int delay, int count) { 00604 delay = (0x00F0 & (delay << 4)); 00605 count = (0x000F & count); 00606 00607 setRegister(_NRF24L01P_REG_SETUP_RETR, delay|count); 00608 a_retr_enabled = true; 00609 00610 } 00611 00612 int nRF24L01P::getRetrCount(){ 00613 return getRegister(_NRF24L01P_REG_OBSERVE_TX) & 0x0F; 00614 } 00615 00616 void nRF24L01P::setRxAddress(unsigned long long address, int width, int pipe) { 00617 00618 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00619 00620 error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe ); 00621 return; 00622 00623 } 00624 00625 if ( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) { 00626 00627 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & ~_NRF24L01P_SETUP_AW_AW_MASK; 00628 00629 switch ( width ) { 00630 00631 case 3: 00632 setupAw |= _NRF24L01P_SETUP_AW_AW_3BYTE; 00633 break; 00634 00635 case 4: 00636 setupAw |= _NRF24L01P_SETUP_AW_AW_4BYTE; 00637 break; 00638 00639 case 5: 00640 setupAw |= _NRF24L01P_SETUP_AW_AW_5BYTE; 00641 break; 00642 00643 default: 00644 error( "nRF24L01P: Invalid setRxAddress width setting %d\r\n", width ); 00645 return; 00646 00647 } 00648 00649 setRegister(_NRF24L01P_REG_SETUP_AW, setupAw); 00650 00651 } else { 00652 00653 width = 1; 00654 00655 } 00656 00657 int rxAddrPxRegister = _NRF24L01P_REG_RX_ADDR_P0 + ( pipe - NRF24L01P_PIPE_P0 ); 00658 00659 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (rxAddrPxRegister & _NRF24L01P_REG_ADDRESS_MASK)); 00660 00661 nCS_ = 0; 00662 00663 int status = spi_.write(cn); 00664 00665 while ( width-- > 0 ) { 00666 00667 // 00668 // LSByte first 00669 // 00670 spi_.write((int) (address & 0xFF)); 00671 address >>= 8; 00672 00673 } 00674 00675 nCS_ = 1; 00676 00677 int enRxAddr = getRegister(_NRF24L01P_REG_EN_RXADDR); 00678 00679 enRxAddr |= (1 << ( pipe - NRF24L01P_PIPE_P0 ) ); 00680 00681 setRegister(_NRF24L01P_REG_EN_RXADDR, enRxAddr); 00682 } 00683 00684 void nRF24L01P::disablePipeRX(int pipe) { 00685 00686 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00687 error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe ); 00688 return; 00689 } 00690 00691 int enRxAddr = getRegister(_NRF24L01P_REG_EN_RXADDR); 00692 00693 enRxAddr &= ~(1 << ( pipe - NRF24L01P_PIPE_P0 ) ); 00694 00695 setRegister(_NRF24L01P_REG_EN_RXADDR, enRxAddr); 00696 00697 } 00698 00699 void nRF24L01P::enablePipeRX(int pipe) { 00700 00701 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00702 error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe ); 00703 return; 00704 } 00705 00706 int enRxAddr = getRegister(_NRF24L01P_REG_EN_RXADDR); 00707 00708 enRxAddr |= (1 << ( pipe - NRF24L01P_PIPE_P0 ) ); 00709 00710 setRegister(_NRF24L01P_REG_EN_RXADDR, enRxAddr); 00711 00712 } 00713 00714 /* 00715 * This version of setRxAddress is just a wrapper for the version that takes 'long long's, 00716 * in case the main code doesn't want to deal with long long's. 00717 */ 00718 void nRF24L01P::setRxAddress(unsigned long msb_address, unsigned long lsb_address, int width, int pipe) { 00719 00720 unsigned long long address = ( ( (unsigned long long) msb_address ) << 32 ) | ( ( (unsigned long long) lsb_address ) << 0 ); 00721 00722 setRxAddress(address, width, pipe); 00723 00724 } 00725 00726 00727 /* 00728 * This version of setTxAddress is just a wrapper for the version that takes 'long long's, 00729 * in case the main code doesn't want to deal with long long's. 00730 */ 00731 void nRF24L01P::setTxAddress(unsigned long msb_address, unsigned long lsb_address, int width) { 00732 00733 unsigned long long address = ( ( (unsigned long long) msb_address ) << 32 ) | ( ( (unsigned long long) lsb_address ) << 0 ); 00734 00735 setTxAddress(address, width); 00736 00737 } 00738 00739 00740 void nRF24L01P::setTxAddress(unsigned long long address, int width) { 00741 00742 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & ~_NRF24L01P_SETUP_AW_AW_MASK; 00743 00744 switch ( width ) { 00745 00746 case 3: 00747 setupAw |= _NRF24L01P_SETUP_AW_AW_3BYTE; 00748 break; 00749 00750 case 4: 00751 setupAw |= _NRF24L01P_SETUP_AW_AW_4BYTE; 00752 break; 00753 00754 case 5: 00755 setupAw |= _NRF24L01P_SETUP_AW_AW_5BYTE; 00756 break; 00757 00758 default: 00759 error( "nRF24L01P: Invalid setTxAddress width setting %d\r\n", width ); 00760 return; 00761 00762 } 00763 00764 setRegister(_NRF24L01P_REG_SETUP_AW, setupAw); 00765 00766 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (_NRF24L01P_REG_TX_ADDR & _NRF24L01P_REG_ADDRESS_MASK)); 00767 00768 nCS_ = 0; 00769 00770 int status = spi_.write(cn); 00771 00772 while ( width-- > 0 ) { 00773 00774 // 00775 // LSByte first 00776 // 00777 spi_.write((int) (address & 0xFF)); 00778 address >>= 8; 00779 00780 } 00781 00782 nCS_ = 1; 00783 00784 } 00785 00786 00787 unsigned long long nRF24L01P::getRxAddress(int pipe) { 00788 00789 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00790 00791 error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe ); 00792 return 0; 00793 00794 } 00795 00796 int width; 00797 00798 if ( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) { 00799 00800 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & _NRF24L01P_SETUP_AW_AW_MASK; 00801 00802 switch ( setupAw ) { 00803 00804 case _NRF24L01P_SETUP_AW_AW_3BYTE: 00805 width = 3; 00806 break; 00807 00808 case _NRF24L01P_SETUP_AW_AW_4BYTE: 00809 width = 4; 00810 break; 00811 00812 case _NRF24L01P_SETUP_AW_AW_5BYTE: 00813 width = 5; 00814 break; 00815 00816 default: 00817 error( "nRF24L01P: Unknown getRxAddress width value %d\r\n", setupAw ); 00818 return 0; 00819 00820 } 00821 00822 } else { 00823 00824 width = 1; 00825 00826 } 00827 00828 int rxAddrPxRegister = _NRF24L01P_REG_RX_ADDR_P0 + ( pipe - NRF24L01P_PIPE_P0 ); 00829 00830 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (rxAddrPxRegister & _NRF24L01P_REG_ADDRESS_MASK)); 00831 00832 unsigned long long address = 0; 00833 00834 nCS_ = 0; 00835 00836 int status = spi_.write(cn); 00837 00838 for ( int i=0; i<width; i++ ) { 00839 00840 // 00841 // LSByte first 00842 // 00843 address |= ( ( (unsigned long long)( spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF ) ) << (i*8) ); 00844 00845 } 00846 00847 nCS_ = 1; 00848 00849 if ( !( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) ) { 00850 00851 address |= ( getRxAddress(NRF24L01P_PIPE_P1) & ~((unsigned long long) 0xFF) ); 00852 00853 } 00854 00855 return address; 00856 00857 } 00858 00859 00860 unsigned long long nRF24L01P::getTxAddress(void) { 00861 00862 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & _NRF24L01P_SETUP_AW_AW_MASK; 00863 00864 int width; 00865 00866 switch ( setupAw ) { 00867 00868 case _NRF24L01P_SETUP_AW_AW_3BYTE: 00869 width = 3; 00870 break; 00871 00872 case _NRF24L01P_SETUP_AW_AW_4BYTE: 00873 width = 4; 00874 break; 00875 00876 case _NRF24L01P_SETUP_AW_AW_5BYTE: 00877 width = 5; 00878 break; 00879 00880 default: 00881 error( "nRF24L01P: Unknown getTxAddress width value %d\r\n", setupAw ); 00882 return 0; 00883 00884 } 00885 00886 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (_NRF24L01P_REG_TX_ADDR & _NRF24L01P_REG_ADDRESS_MASK)); 00887 00888 unsigned long long address = 0; 00889 00890 nCS_ = 0; 00891 00892 int status = spi_.write(cn); 00893 00894 for ( int i=0; i<width; i++ ) { 00895 00896 // 00897 // LSByte first 00898 // 00899 address |= ( ( (unsigned long long)( spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF ) ) << (i*8) ); 00900 00901 } 00902 00903 nCS_ = 1; 00904 00905 return address; 00906 } 00907 00908 00909 bool nRF24L01P::readable(int pipe) { 00910 00911 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00912 00913 error( "nRF24L01P: Invalid readable pipe number %d\r\n", pipe ); 00914 return false; 00915 00916 } 00917 00918 int status = getStatusRegister(); 00919 00920 return ( ( status & _NRF24L01P_STATUS_RX_DR ) && ( ( ( status & _NRF24L01P_STATUS_RX_P_NO ) >> 1 ) == ( pipe & 0x7 ) ) ); 00921 00922 } 00923 00924 00925 int nRF24L01P::write(int pipe, char *data, int count) { 00926 00927 // Note: the pipe number is ignored in a Transmit / write 00928 00929 // 00930 // Save the CE state 00931 // 00932 int originalCe = ce_; 00933 disable(); 00934 00935 if ( count <= 0 ) return 0; 00936 00937 if ( count > _NRF24L01P_TX_FIFO_SIZE ) count = _NRF24L01P_TX_FIFO_SIZE; 00938 00939 // Clear the Status bit 00940 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_TX_DS); 00941 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_MAX_RT); 00942 00943 nCS_ = 0; 00944 00945 int status = spi_.write(_NRF24L01P_SPI_CMD_WR_TX_PAYLOAD); 00946 00947 for ( int i = 0; i < count; i++ ) { 00948 00949 spi_.write(*data++); 00950 00951 } 00952 00953 nCS_ = 1; 00954 00955 int originalMode = mode; 00956 setTransmitMode(); 00957 00958 enable(); 00959 wait_us(_NRF24L01P_TIMING_Thce_us); 00960 disable(); 00961 00962 while ( !( getStatusRegister() & (_NRF24L01P_STATUS_TX_DS | _NRF24L01P_STATUS_MAX_RT) ) ) { 00963 } 00964 00965 int s = getStatusRegister(); 00966 00967 if (s & _NRF24L01P_STATUS_MAX_RT){ 00968 //max retransmissions 00969 flushTx(); 00970 count = -1; 00971 } 00972 00973 // Clear the Status bit 00974 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_TX_DS); 00975 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_MAX_RT); 00976 00977 if ( originalMode == _NRF24L01P_MODE_RX ) { 00978 00979 setReceiveMode(); 00980 00981 } 00982 00983 ce_ = originalCe; 00984 wait_us( _NRF24L01P_TIMING_Tpece2csn_us ); 00985 00986 return count; 00987 00988 } 00989 00990 00991 int nRF24L01P::read(int pipe, char *data, int count) { 00992 00993 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00994 00995 error( "nRF24L01P: Invalid read pipe number %d\r\n", pipe ); 00996 return -1; 00997 00998 } 00999 01000 if ( count <= 0 ) return 0; 01001 01002 if ( count > _NRF24L01P_RX_FIFO_SIZE ) count = _NRF24L01P_RX_FIFO_SIZE; 01003 01004 if ( readable(pipe) ) { 01005 01006 nCS_ = 0; 01007 01008 int status = spi_.write(_NRF24L01P_SPI_CMD_R_RX_PL_WID); 01009 01010 int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF; 01011 01012 nCS_ = 1; 01013 01014 if ( ( rxPayloadWidth < 0 ) || ( rxPayloadWidth > _NRF24L01P_RX_FIFO_SIZE ) ) { 01015 01016 // Received payload error: need to flush the FIFO 01017 01018 nCS_ = 0; 01019 01020 int status = spi_.write(_NRF24L01P_SPI_CMD_FLUSH_RX); 01021 01022 int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP); 01023 01024 nCS_ = 1; 01025 01026 // 01027 // At this point, we should retry the reception, 01028 // but for now we'll just fall through... 01029 // 01030 01031 } else { 01032 01033 if ( rxPayloadWidth < count ) count = rxPayloadWidth; 01034 01035 nCS_ = 0; 01036 01037 int status = spi_.write(_NRF24L01P_SPI_CMD_RD_RX_PAYLOAD); 01038 01039 for ( int i = 0; i < count; i++ ) { 01040 01041 *data++ = spi_.write(_NRF24L01P_SPI_CMD_NOP); 01042 01043 } 01044 01045 nCS_ = 1; 01046 01047 // Clear the Status bit 01048 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_RX_DR); 01049 01050 return count; 01051 01052 } 01053 01054 } else { 01055 01056 // 01057 // What should we do if there is no 'readable' data? 01058 // We could wait for data to arrive, but for now, we'll 01059 // just return with no data. 01060 // 01061 return 0; 01062 01063 } 01064 01065 // 01066 // We get here because an error condition occured; 01067 // We could wait for data to arrive, but for now, we'll 01068 // just return with no data. 01069 // 01070 return -1; 01071 01072 } 01073 01074 bool nRF24L01P::getRPD(){ 01075 uint8_t rpd = getRegister(_NRF24L01P_REG_RPD); 01076 return (rpd>0); 01077 } 01078 01079 uint8_t nRF24L01P::getRSSI(){ 01080 uint8_t rssi =0; 01081 for(int i=0; i<256; i++){ 01082 rssi += getRPD(); 01083 wait_us(50); 01084 flushRx(); 01085 } 01086 return rssi; 01087 } 01088 01089 void nRF24L01P::flushRx(void) 01090 { 01091 nCS_ = 0; 01092 spi_.write(_NRF24L01P_SPI_CMD_FLUSH_RX); 01093 nCS_ = 1; 01094 } 01095 01096 void nRF24L01P::flushTx(void) 01097 { 01098 nCS_ = 0; 01099 spi_.write(_NRF24L01P_SPI_CMD_FLUSH_TX); 01100 nCS_ = 1; 01101 } 01102 01103 01104 void nRF24L01P::setRegister(int regAddress, int regData) { 01105 01106 // 01107 // Save the CE state 01108 // 01109 int originalCe = ce_; 01110 disable(); 01111 01112 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (regAddress & _NRF24L01P_REG_ADDRESS_MASK)); 01113 01114 nCS_ = 0; 01115 01116 int status = spi_.write(cn); 01117 01118 spi_.write(regData & 0xFF); 01119 01120 nCS_ = 1; 01121 01122 ce_ = originalCe; 01123 wait_us( _NRF24L01P_TIMING_Tpece2csn_us ); 01124 01125 } 01126 01127 01128 int nRF24L01P::getRegister(int regAddress) { 01129 01130 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (regAddress & _NRF24L01P_REG_ADDRESS_MASK)); 01131 01132 nCS_ = 0; 01133 01134 int status = spi_.write(cn); 01135 01136 int dn = spi_.write(_NRF24L01P_SPI_CMD_NOP); 01137 01138 nCS_ = 1; 01139 01140 return dn; 01141 01142 } 01143 01144 int nRF24L01P::getStatusRegister(void) { 01145 01146 nCS_ = 0; 01147 01148 int status = spi_.write(_NRF24L01P_SPI_CMD_NOP); 01149 01150 nCS_ = 1; 01151 01152 return status; 01153 01154 }
Generated on Mon Aug 8 2022 06:17:48 by
