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_FIXED nRF24L01P_NET_GW nRF24L01P_NET_SENSOR Kubus ... more
Fork of nRF24L01P by
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 void nRF24L01P::enableDynamicPayload(int pipe) { 00568 00569 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00570 00571 error( "nRF24L01P: Invalid Enable AutoAcknowledge pipe number %d\r\n", pipe ); 00572 return; 00573 00574 } 00575 00576 int feature = getRegister(_NRF24L01P_REG_FEATURE); 00577 feature |= ( 1 << 2 ); 00578 setRegister(_NRF24L01P_REG_FEATURE, feature); 00579 00580 int dynpd = getRegister(_NRF24L01P_REG_DYNPD); 00581 dynpd |= ( 1 << (pipe - NRF24L01P_PIPE_P0) ); 00582 setRegister(_NRF24L01P_REG_DYNPD, dynpd); 00583 00584 } 00585 00586 00587 void nRF24L01P::disableDynamicPayload(void) { 00588 00589 int feature = getRegister(_NRF24L01P_REG_FEATURE); 00590 feature &= !( 1 << 2 ); 00591 setRegister(_NRF24L01P_REG_FEATURE, feature); 00592 } 00593 00594 00595 void nRF24L01P::disableAutoRetransmit(void) { 00596 00597 setRegister(_NRF24L01P_REG_SETUP_RETR, _NRF24L01P_SETUP_RETR_NONE); 00598 a_retr_enabled = false; 00599 00600 } 00601 00602 void nRF24L01P::enableAutoRetransmit(int delay, int count) { 00603 delay = (0x00F0 & (delay << 4)); 00604 count = (0x000F & count); 00605 00606 setRegister(_NRF24L01P_REG_SETUP_RETR, delay|count); 00607 a_retr_enabled = true; 00608 00609 } 00610 00611 int nRF24L01P::getRetrCount(){ 00612 return getRegister(_NRF24L01P_REG_OBSERVE_TX) & 0x0F; 00613 } 00614 00615 void nRF24L01P::setRxAddress(unsigned long long address, int width, int pipe) { 00616 00617 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00618 00619 error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe ); 00620 return; 00621 00622 } 00623 00624 if ( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) { 00625 00626 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & ~_NRF24L01P_SETUP_AW_AW_MASK; 00627 00628 switch ( width ) { 00629 00630 case 3: 00631 setupAw |= _NRF24L01P_SETUP_AW_AW_3BYTE; 00632 break; 00633 00634 case 4: 00635 setupAw |= _NRF24L01P_SETUP_AW_AW_4BYTE; 00636 break; 00637 00638 case 5: 00639 setupAw |= _NRF24L01P_SETUP_AW_AW_5BYTE; 00640 break; 00641 00642 default: 00643 error( "nRF24L01P: Invalid setRxAddress width setting %d\r\n", width ); 00644 return; 00645 00646 } 00647 00648 setRegister(_NRF24L01P_REG_SETUP_AW, setupAw); 00649 00650 } else { 00651 00652 width = 1; 00653 00654 } 00655 00656 int rxAddrPxRegister = _NRF24L01P_REG_RX_ADDR_P0 + ( pipe - NRF24L01P_PIPE_P0 ); 00657 00658 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (rxAddrPxRegister & _NRF24L01P_REG_ADDRESS_MASK)); 00659 00660 nCS_ = 0; 00661 00662 int status = spi_.write(cn); 00663 00664 while ( width-- > 0 ) { 00665 00666 // 00667 // LSByte first 00668 // 00669 spi_.write((int) (address & 0xFF)); 00670 address >>= 8; 00671 00672 } 00673 00674 nCS_ = 1; 00675 00676 int enRxAddr = getRegister(_NRF24L01P_REG_EN_RXADDR); 00677 00678 enRxAddr |= (1 << ( pipe - NRF24L01P_PIPE_P0 ) ); 00679 00680 setRegister(_NRF24L01P_REG_EN_RXADDR, enRxAddr); 00681 } 00682 00683 void nRF24L01P::disablePipeRX(int pipe) { 00684 00685 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00686 error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe ); 00687 return; 00688 } 00689 00690 int enRxAddr = getRegister(_NRF24L01P_REG_EN_RXADDR); 00691 00692 enRxAddr &= ~(1 << ( pipe - NRF24L01P_PIPE_P0 ) ); 00693 00694 setRegister(_NRF24L01P_REG_EN_RXADDR, enRxAddr); 00695 00696 } 00697 00698 void nRF24L01P::enablePipeRX(int pipe) { 00699 00700 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00701 error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe ); 00702 return; 00703 } 00704 00705 int enRxAddr = getRegister(_NRF24L01P_REG_EN_RXADDR); 00706 00707 enRxAddr |= (1 << ( pipe - NRF24L01P_PIPE_P0 ) ); 00708 00709 setRegister(_NRF24L01P_REG_EN_RXADDR, enRxAddr); 00710 00711 } 00712 00713 /* 00714 * This version of setRxAddress is just a wrapper for the version that takes 'long long's, 00715 * in case the main code doesn't want to deal with long long's. 00716 */ 00717 void nRF24L01P::setRxAddress(unsigned long msb_address, unsigned long lsb_address, int width, int pipe) { 00718 00719 unsigned long long address = ( ( (unsigned long long) msb_address ) << 32 ) | ( ( (unsigned long long) lsb_address ) << 0 ); 00720 00721 setRxAddress(address, width, pipe); 00722 00723 } 00724 00725 00726 /* 00727 * This version of setTxAddress is just a wrapper for the version that takes 'long long's, 00728 * in case the main code doesn't want to deal with long long's. 00729 */ 00730 void nRF24L01P::setTxAddress(unsigned long msb_address, unsigned long lsb_address, int width) { 00731 00732 unsigned long long address = ( ( (unsigned long long) msb_address ) << 32 ) | ( ( (unsigned long long) lsb_address ) << 0 ); 00733 00734 setTxAddress(address, width); 00735 00736 } 00737 00738 00739 void nRF24L01P::setTxAddress(unsigned long long address, int width) { 00740 00741 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & ~_NRF24L01P_SETUP_AW_AW_MASK; 00742 00743 switch ( width ) { 00744 00745 case 3: 00746 setupAw |= _NRF24L01P_SETUP_AW_AW_3BYTE; 00747 break; 00748 00749 case 4: 00750 setupAw |= _NRF24L01P_SETUP_AW_AW_4BYTE; 00751 break; 00752 00753 case 5: 00754 setupAw |= _NRF24L01P_SETUP_AW_AW_5BYTE; 00755 break; 00756 00757 default: 00758 error( "nRF24L01P: Invalid setTxAddress width setting %d\r\n", width ); 00759 return; 00760 00761 } 00762 00763 setRegister(_NRF24L01P_REG_SETUP_AW, setupAw); 00764 00765 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (_NRF24L01P_REG_TX_ADDR & _NRF24L01P_REG_ADDRESS_MASK)); 00766 00767 nCS_ = 0; 00768 00769 int status = spi_.write(cn); 00770 00771 while ( width-- > 0 ) { 00772 00773 // 00774 // LSByte first 00775 // 00776 spi_.write((int) (address & 0xFF)); 00777 address >>= 8; 00778 00779 } 00780 00781 nCS_ = 1; 00782 00783 } 00784 00785 00786 unsigned long long nRF24L01P::getRxAddress(int pipe) { 00787 00788 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00789 00790 error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe ); 00791 return 0; 00792 00793 } 00794 00795 int width; 00796 00797 if ( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) { 00798 00799 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & _NRF24L01P_SETUP_AW_AW_MASK; 00800 00801 switch ( setupAw ) { 00802 00803 case _NRF24L01P_SETUP_AW_AW_3BYTE: 00804 width = 3; 00805 break; 00806 00807 case _NRF24L01P_SETUP_AW_AW_4BYTE: 00808 width = 4; 00809 break; 00810 00811 case _NRF24L01P_SETUP_AW_AW_5BYTE: 00812 width = 5; 00813 break; 00814 00815 default: 00816 error( "nRF24L01P: Unknown getRxAddress width value %d\r\n", setupAw ); 00817 return 0; 00818 00819 } 00820 00821 } else { 00822 00823 width = 1; 00824 00825 } 00826 00827 int rxAddrPxRegister = _NRF24L01P_REG_RX_ADDR_P0 + ( pipe - NRF24L01P_PIPE_P0 ); 00828 00829 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (rxAddrPxRegister & _NRF24L01P_REG_ADDRESS_MASK)); 00830 00831 unsigned long long address = 0; 00832 00833 nCS_ = 0; 00834 00835 int status = spi_.write(cn); 00836 00837 for ( int i=0; i<width; i++ ) { 00838 00839 // 00840 // LSByte first 00841 // 00842 address |= ( ( (unsigned long long)( spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF ) ) << (i*8) ); 00843 00844 } 00845 00846 nCS_ = 1; 00847 00848 if ( !( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) ) { 00849 00850 address |= ( getRxAddress(NRF24L01P_PIPE_P1) & ~((unsigned long long) 0xFF) ); 00851 00852 } 00853 00854 return address; 00855 00856 } 00857 00858 00859 unsigned long long nRF24L01P::getTxAddress(void) { 00860 00861 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & _NRF24L01P_SETUP_AW_AW_MASK; 00862 00863 int width; 00864 00865 switch ( setupAw ) { 00866 00867 case _NRF24L01P_SETUP_AW_AW_3BYTE: 00868 width = 3; 00869 break; 00870 00871 case _NRF24L01P_SETUP_AW_AW_4BYTE: 00872 width = 4; 00873 break; 00874 00875 case _NRF24L01P_SETUP_AW_AW_5BYTE: 00876 width = 5; 00877 break; 00878 00879 default: 00880 error( "nRF24L01P: Unknown getTxAddress width value %d\r\n", setupAw ); 00881 return 0; 00882 00883 } 00884 00885 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (_NRF24L01P_REG_TX_ADDR & _NRF24L01P_REG_ADDRESS_MASK)); 00886 00887 unsigned long long address = 0; 00888 00889 nCS_ = 0; 00890 00891 int status = spi_.write(cn); 00892 00893 for ( int i=0; i<width; i++ ) { 00894 00895 // 00896 // LSByte first 00897 // 00898 address |= ( ( (unsigned long long)( spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF ) ) << (i*8) ); 00899 00900 } 00901 00902 nCS_ = 1; 00903 00904 return address; 00905 } 00906 00907 00908 bool nRF24L01P::readable(int pipe) { 00909 00910 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00911 00912 error( "nRF24L01P: Invalid readable pipe number %d\r\n", pipe ); 00913 return false; 00914 00915 } 00916 00917 int status = getStatusRegister(); 00918 00919 return ( ( status & _NRF24L01P_STATUS_RX_DR ) && ( ( ( status & _NRF24L01P_STATUS_RX_P_NO ) >> 1 ) == ( pipe & 0x7 ) ) ); 00920 00921 } 00922 00923 00924 int nRF24L01P::write(int pipe, char *data, int count) { 00925 00926 // Note: the pipe number is ignored in a Transmit / write 00927 00928 // 00929 // Save the CE state 00930 // 00931 int originalCe = ce_; 00932 disable(); 00933 00934 if ( count <= 0 ) return 0; 00935 00936 if ( count > _NRF24L01P_TX_FIFO_SIZE ) count = _NRF24L01P_TX_FIFO_SIZE; 00937 00938 // Clear the Status bit 00939 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_TX_DS); 00940 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_MAX_RT); 00941 00942 nCS_ = 0; 00943 00944 int status = spi_.write(_NRF24L01P_SPI_CMD_WR_TX_PAYLOAD); 00945 00946 for ( int i = 0; i < count; i++ ) { 00947 00948 spi_.write(*data++); 00949 00950 } 00951 00952 nCS_ = 1; 00953 00954 int originalMode = mode; 00955 setTransmitMode(); 00956 00957 enable(); 00958 wait_us(_NRF24L01P_TIMING_Thce_us); 00959 disable(); 00960 00961 while ( !( getStatusRegister() & (_NRF24L01P_STATUS_TX_DS | _NRF24L01P_STATUS_MAX_RT) ) ) { 00962 } 00963 00964 int s = getStatusRegister(); 00965 00966 if (s & _NRF24L01P_STATUS_MAX_RT){ 00967 //max retransmissions 00968 flushTx(); 00969 count = -1; 00970 } 00971 00972 // Clear the Status bit 00973 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_TX_DS); 00974 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_MAX_RT); 00975 00976 if ( originalMode == _NRF24L01P_MODE_RX ) { 00977 00978 setReceiveMode(); 00979 00980 } 00981 00982 ce_ = originalCe; 00983 wait_us( _NRF24L01P_TIMING_Tpece2csn_us ); 00984 00985 return count; 00986 00987 } 00988 00989 00990 int nRF24L01P::read(int pipe, char *data, int count) { 00991 00992 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00993 00994 error( "nRF24L01P: Invalid read pipe number %d\r\n", pipe ); 00995 return -1; 00996 00997 } 00998 00999 if ( count <= 0 ) return 0; 01000 01001 if ( count > _NRF24L01P_RX_FIFO_SIZE ) count = _NRF24L01P_RX_FIFO_SIZE; 01002 01003 if ( readable(pipe) ) { 01004 01005 nCS_ = 0; 01006 01007 int status = spi_.write(_NRF24L01P_SPI_CMD_R_RX_PL_WID); 01008 01009 int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF; 01010 01011 nCS_ = 1; 01012 01013 if ( ( rxPayloadWidth < 0 ) || ( rxPayloadWidth > _NRF24L01P_RX_FIFO_SIZE ) ) { 01014 01015 // Received payload error: need to flush the FIFO 01016 01017 nCS_ = 0; 01018 01019 int status = spi_.write(_NRF24L01P_SPI_CMD_FLUSH_RX); 01020 01021 int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP); 01022 01023 nCS_ = 1; 01024 01025 // 01026 // At this point, we should retry the reception, 01027 // but for now we'll just fall through... 01028 // 01029 01030 } else { 01031 01032 if ( rxPayloadWidth < count ) count = rxPayloadWidth; 01033 01034 nCS_ = 0; 01035 01036 int status = spi_.write(_NRF24L01P_SPI_CMD_RD_RX_PAYLOAD); 01037 01038 for ( int i = 0; i < count; i++ ) { 01039 01040 *data++ = spi_.write(_NRF24L01P_SPI_CMD_NOP); 01041 01042 } 01043 01044 nCS_ = 1; 01045 01046 // Clear the Status bit 01047 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_RX_DR); 01048 01049 return count; 01050 01051 } 01052 01053 } else { 01054 01055 // 01056 // What should we do if there is no 'readable' data? 01057 // We could wait for data to arrive, but for now, we'll 01058 // just return with no data. 01059 // 01060 return 0; 01061 01062 } 01063 01064 // 01065 // We get here because an error condition occured; 01066 // We could wait for data to arrive, but for now, we'll 01067 // just return with no data. 01068 // 01069 return -1; 01070 01071 } 01072 01073 bool nRF24L01P::getRPD(){ 01074 uint8_t rpd = getRegister(_NRF24L01P_REG_RPD); 01075 return (rpd>0); 01076 } 01077 01078 uint8_t nRF24L01P::getRSSI(){ 01079 uint8_t rssi =0; 01080 for(int i=0; i<256; i++){ 01081 rssi += getRPD(); 01082 wait_us(50); 01083 flushRx(); 01084 } 01085 return rssi; 01086 } 01087 01088 void nRF24L01P::flushRx(void) 01089 { 01090 nCS_ = 0; 01091 spi_.write(_NRF24L01P_SPI_CMD_FLUSH_RX); 01092 nCS_ = 1; 01093 } 01094 01095 void nRF24L01P::flushTx(void) 01096 { 01097 nCS_ = 0; 01098 spi_.write(_NRF24L01P_SPI_CMD_FLUSH_TX); 01099 nCS_ = 1; 01100 } 01101 01102 01103 void nRF24L01P::setRegister(int regAddress, int regData) { 01104 01105 // 01106 // Save the CE state 01107 // 01108 int originalCe = ce_; 01109 disable(); 01110 01111 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (regAddress & _NRF24L01P_REG_ADDRESS_MASK)); 01112 01113 nCS_ = 0; 01114 01115 int status = spi_.write(cn); 01116 01117 spi_.write(regData & 0xFF); 01118 01119 nCS_ = 1; 01120 01121 ce_ = originalCe; 01122 wait_us( _NRF24L01P_TIMING_Tpece2csn_us ); 01123 01124 } 01125 01126 01127 int nRF24L01P::getRegister(int regAddress) { 01128 01129 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (regAddress & _NRF24L01P_REG_ADDRESS_MASK)); 01130 01131 nCS_ = 0; 01132 01133 int status = spi_.write(cn); 01134 01135 int dn = spi_.write(_NRF24L01P_SPI_CMD_NOP); 01136 01137 nCS_ = 1; 01138 01139 return dn; 01140 01141 } 01142 01143 int nRF24L01P::getStatusRegister(void) { 01144 01145 nCS_ = 0; 01146 01147 int status = spi_.write(_NRF24L01P_SPI_CMD_NOP); 01148 01149 nCS_ = 1; 01150 01151 return status; 01152 01153 }
Generated on Mon Jul 25 2022 04:30:24 by
1.7.2
