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.
Fork of FYDP_Final2 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 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 16:56:36 by
