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