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 rtos_basic 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 //Use for debug!! 00041 extern DigitalOut check1; 00042 extern DigitalOut check2; 00043 extern DigitalOut check3; 00044 // End debug 00045 00046 /** 00047 * Defines 00048 * 00049 * (Note that all defines here start with an underscore, e.g. '_NRF24L01P_MODE_UNKNOWN', 00050 * and are local to this library. The defines in the nRF24L01P.h file do not start 00051 * with the underscore, and can be used by code to access this library.) 00052 */ 00053 00054 typedef enum { 00055 _NRF24L01P_MODE_UNKNOWN, 00056 _NRF24L01P_MODE_POWER_DOWN, 00057 _NRF24L01P_MODE_STANDBY, 00058 _NRF24L01P_MODE_RX, 00059 _NRF24L01P_MODE_TX, 00060 } nRF24L01P_Mode_Type; 00061 00062 /* 00063 * The following FIFOs are present in nRF24L01+: 00064 * TX three level, 32 byte FIFO 00065 * RX three level, 32 byte FIFO 00066 */ 00067 #define _NRF24L01P_TX_FIFO_COUNT 3 00068 #define _NRF24L01P_RX_FIFO_COUNT 3 00069 00070 #define _NRF24L01P_TX_FIFO_SIZE 32 00071 #define _NRF24L01P_RX_FIFO_SIZE 32 00072 00073 #define _NRF24L01P_SPI_MAX_DATA_RATE 10000000 00074 00075 #define _NRF24L01P_SPI_CMD_RD_REG 0x00 00076 #define _NRF24L01P_SPI_CMD_WR_REG 0x20 00077 #define _NRF24L01P_SPI_CMD_RD_RX_PAYLOAD 0x61 00078 #define _NRF24L01P_SPI_CMD_WR_TX_PAYLOAD 0xa0 00079 #define _NRF24L01P_SPI_CMD_FLUSH_TX 0xe1 00080 #define _NRF24L01P_SPI_CMD_FLUSH_RX 0xe2 00081 #define _NRF24L01P_SPI_CMD_REUSE_TX_PL 0xe3 00082 #define _NRF24L01P_SPI_CMD_R_RX_PL_WID 0x60 00083 #define _NRF24L01P_SPI_CMD_W_ACK_PAYLOAD 0xa8 00084 #define _NRF24L01P_SPI_CMD_W_TX_PYLD_NO_ACK 0xb0 00085 #define _NRF24L01P_SPI_CMD_NOP 0xff 00086 00087 00088 #define _NRF24L01P_REG_CONFIG 0x00 00089 #define _NRF24L01P_REG_EN_AA 0x01 00090 #define _NRF24L01P_REG_EN_RXADDR 0x02 00091 #define _NRF24L01P_REG_SETUP_AW 0x03 00092 #define _NRF24L01P_REG_SETUP_RETR 0x04 00093 #define _NRF24L01P_REG_RF_CH 0x05 00094 #define _NRF24L01P_REG_RF_SETUP 0x06 00095 #define _NRF24L01P_REG_STATUS 0x07 00096 #define _NRF24L01P_REG_OBSERVE_TX 0x08 00097 #define _NRF24L01P_REG_RPD 0x09 00098 #define _NRF24L01P_REG_RX_ADDR_P0 0x0a 00099 #define _NRF24L01P_REG_RX_ADDR_P1 0x0b 00100 #define _NRF24L01P_REG_RX_ADDR_P2 0x0c 00101 #define _NRF24L01P_REG_RX_ADDR_P3 0x0d 00102 #define _NRF24L01P_REG_RX_ADDR_P4 0x0e 00103 #define _NRF24L01P_REG_RX_ADDR_P5 0x0f 00104 #define _NRF24L01P_REG_TX_ADDR 0x10 00105 #define _NRF24L01P_REG_RX_PW_P0 0x11 00106 #define _NRF24L01P_REG_RX_PW_P1 0x12 00107 #define _NRF24L01P_REG_RX_PW_P2 0x13 00108 #define _NRF24L01P_REG_RX_PW_P3 0x14 00109 #define _NRF24L01P_REG_RX_PW_P4 0x15 00110 #define _NRF24L01P_REG_RX_PW_P5 0x16 00111 #define _NRF24L01P_REG_FIFO_STATUS 0x17 00112 #define _NRF24L01P_REG_DYNPD 0x1c 00113 #define _NRF24L01P_REG_FEATURE 0x1d 00114 00115 #define _NRF24L01P_REG_ADDRESS_MASK 0x1f 00116 00117 // CONFIG register: 00118 #define _NRF24L01P_CONFIG_PRIM_RX (1<<0) 00119 #define _NRF24L01P_CONFIG_PWR_UP (1<<1) 00120 #define _NRF24L01P_CONFIG_CRC0 (1<<2) 00121 #define _NRF24L01P_CONFIG_EN_CRC (1<<3) 00122 #define _NRF24L01P_CONFIG_MASK_MAX_RT (1<<4) 00123 #define _NRF24L01P_CONFIG_MASK_TX_DS (1<<5) 00124 #define _NRF24L01P_CONFIG_MASK_RX_DR (1<<6) 00125 00126 #define _NRF24L01P_CONFIG_CRC_MASK (_NRF24L01P_CONFIG_EN_CRC|_NRF24L01P_CONFIG_CRC0) 00127 #define _NRF24L01P_CONFIG_CRC_NONE (0) 00128 #define _NRF24L01P_CONFIG_CRC_8BIT (_NRF24L01P_CONFIG_EN_CRC) 00129 #define _NRF24L01P_CONFIG_CRC_16BIT (_NRF24L01P_CONFIG_EN_CRC|_NRF24L01P_CONFIG_CRC0) 00130 00131 // EN_AA register: 00132 #define _NRF24L01P_EN_AA_NONE 0 00133 00134 // EN_RXADDR register: 00135 #define _NRF24L01P_EN_RXADDR_NONE 0 00136 00137 // SETUP_AW register: 00138 #define _NRF24L01P_SETUP_AW_AW_MASK (0x3<<0) 00139 #define _NRF24L01P_SETUP_AW_AW_3BYTE (0x1<<0) 00140 #define _NRF24L01P_SETUP_AW_AW_4BYTE (0x2<<0) 00141 #define _NRF24L01P_SETUP_AW_AW_5BYTE (0x3<<0) 00142 00143 // SETUP_RETR register: 00144 #define _NRF24L01P_SETUP_RETR_NONE 0 00145 00146 // RF_SETUP register: 00147 #define _NRF24L01P_RF_SETUP_RF_PWR_MASK (0x3<<1) 00148 #define _NRF24L01P_RF_SETUP_RF_PWR_0DBM (0x3<<1) 00149 #define _NRF24L01P_RF_SETUP_RF_PWR_MINUS_6DBM (0x2<<1) 00150 #define _NRF24L01P_RF_SETUP_RF_PWR_MINUS_12DBM (0x1<<1) 00151 #define _NRF24L01P_RF_SETUP_RF_PWR_MINUS_18DBM (0x0<<1) 00152 00153 #define _NRF24L01P_RF_SETUP_RF_DR_HIGH_BIT (1 << 3) 00154 #define _NRF24L01P_RF_SETUP_RF_DR_LOW_BIT (1 << 5) 00155 #define _NRF24L01P_RF_SETUP_RF_DR_MASK (_NRF24L01P_RF_SETUP_RF_DR_LOW_BIT|_NRF24L01P_RF_SETUP_RF_DR_HIGH_BIT) 00156 #define _NRF24L01P_RF_SETUP_RF_DR_250KBPS (_NRF24L01P_RF_SETUP_RF_DR_LOW_BIT) 00157 #define _NRF24L01P_RF_SETUP_RF_DR_1MBPS (0) 00158 #define _NRF24L01P_RF_SETUP_RF_DR_2MBPS (_NRF24L01P_RF_SETUP_RF_DR_HIGH_BIT) 00159 00160 // STATUS register: 00161 #define _NRF24L01P_STATUS_TX_FULL (1<<0) 00162 #define _NRF24L01P_STATUS_RX_P_NO (0x7<<1) 00163 #define _NRF24L01P_STATUS_MAX_RT (1<<4) 00164 #define _NRF24L01P_STATUS_TX_DS (1<<5) 00165 #define _NRF24L01P_STATUS_RX_DR (1<<6) 00166 00167 // RX_PW_P0..RX_PW_P5 registers: 00168 #define _NRF24L01P_RX_PW_Px_MASK 0x3F 00169 00170 #define _NRF24L01P_TIMING_Tundef2pd_us 100000 // 100mS 00171 #define _NRF24L01P_TIMING_Tstby2a_us 130 // 130uS 00172 #define _NRF24L01P_TIMING_Thce_us 10 // 10uS 00173 #define _NRF24L01P_TIMING_Tpd2stby_us 4500 // 4.5mS worst case 00174 #define _NRF24L01P_TIMING_Tpece2csn_us 4 // 4uS 00175 00176 /** 00177 * Methods 00178 */ 00179 00180 nRF24L01P::nRF24L01P(PinName mosi, 00181 PinName miso, 00182 PinName sck, 00183 PinName csn, 00184 PinName ce, 00185 PinName irq) : spi_(mosi, miso, sck), nCS_(csn), ce_(ce), nIRQ_(irq) { 00186 00187 mode = _NRF24L01P_MODE_UNKNOWN; 00188 00189 disable(); 00190 00191 nCS_ = 1; 00192 00193 spi_.frequency(_NRF24L01P_SPI_MAX_DATA_RATE/5); // 2Mbit, 1/5th the maximum transfer rate for the SPI bus 00194 spi_.format(8,0); // 8-bit, ClockPhase = 0, ClockPolarity = 0 00195 00196 wait_us(_NRF24L01P_TIMING_Tundef2pd_us); // Wait for Power-on reset 00197 00198 setRegister(_NRF24L01P_REG_CONFIG, 0); // Power Down 00199 00200 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_MAX_RT|_NRF24L01P_STATUS_TX_DS|_NRF24L01P_STATUS_RX_DR); // Clear any pending interrupts 00201 00202 // 00203 // Setup default configuration 00204 // 00205 disableAllRxPipes(); 00206 setRfFrequency(); 00207 setRfOutputPower(); 00208 setAirDataRate(); 00209 setCrcWidth(); 00210 setTxAddress(); 00211 setRxAddress(); 00212 disableAutoAcknowledge(); 00213 disableAutoRetransmit(); 00214 setTransferSize(); 00215 00216 mode = _NRF24L01P_MODE_POWER_DOWN; 00217 00218 } 00219 00220 00221 void nRF24L01P::powerUp(void) { 00222 00223 int config = getRegister(_NRF24L01P_REG_CONFIG); 00224 00225 config |= _NRF24L01P_CONFIG_PWR_UP; 00226 00227 setRegister(_NRF24L01P_REG_CONFIG, config); 00228 00229 // Wait until the nRF24L01+ powers up 00230 wait_us( _NRF24L01P_TIMING_Tpd2stby_us ); 00231 00232 mode = _NRF24L01P_MODE_STANDBY; 00233 00234 } 00235 00236 00237 void nRF24L01P::powerDown(void) { 00238 00239 int config = getRegister(_NRF24L01P_REG_CONFIG); 00240 00241 config &= ~_NRF24L01P_CONFIG_PWR_UP; 00242 00243 setRegister(_NRF24L01P_REG_CONFIG, config); 00244 00245 // Wait until the nRF24L01+ powers down 00246 wait_us( _NRF24L01P_TIMING_Tpd2stby_us ); // This *may* not be necessary (no timing is shown in the Datasheet), but just to be safe 00247 00248 mode = _NRF24L01P_MODE_POWER_DOWN; 00249 00250 } 00251 00252 00253 void nRF24L01P::setReceiveMode(void) { 00254 00255 if ( _NRF24L01P_MODE_POWER_DOWN == mode ) powerUp(); 00256 00257 int config = getRegister(_NRF24L01P_REG_CONFIG); 00258 00259 config |= _NRF24L01P_CONFIG_PRIM_RX; 00260 00261 setRegister(_NRF24L01P_REG_CONFIG, config); 00262 00263 mode = _NRF24L01P_MODE_RX; 00264 00265 } 00266 00267 00268 void nRF24L01P::setTransmitMode(void) { 00269 00270 if ( _NRF24L01P_MODE_POWER_DOWN == mode ) powerUp(); 00271 00272 int config = getRegister(_NRF24L01P_REG_CONFIG); 00273 00274 config &= ~_NRF24L01P_CONFIG_PRIM_RX; 00275 00276 setRegister(_NRF24L01P_REG_CONFIG, config); 00277 00278 mode = _NRF24L01P_MODE_TX; 00279 00280 } 00281 00282 00283 void nRF24L01P::enable(void) { 00284 00285 ce_ = 1; 00286 wait_us( _NRF24L01P_TIMING_Tpece2csn_us ); 00287 00288 } 00289 00290 00291 void nRF24L01P::disable(void) { 00292 00293 ce_ = 0; 00294 00295 } 00296 00297 void nRF24L01P::setRfFrequency(int frequency) { 00298 00299 if ( ( frequency < NRF24L01P_MIN_RF_FREQUENCY ) || ( frequency > NRF24L01P_MAX_RF_FREQUENCY ) ) { 00300 00301 error( "nRF24L01P: Invalid RF Frequency setting %d\r\n", frequency ); 00302 return; 00303 00304 } 00305 00306 int channel = ( frequency - NRF24L01P_MIN_RF_FREQUENCY ) & 0x7F; 00307 00308 setRegister(_NRF24L01P_REG_RF_CH, channel); 00309 00310 } 00311 00312 00313 int nRF24L01P::getRfFrequency(void) { 00314 00315 int channel = getRegister(_NRF24L01P_REG_RF_CH) & 0x7F; 00316 00317 return ( channel + NRF24L01P_MIN_RF_FREQUENCY ); 00318 00319 } 00320 00321 00322 void nRF24L01P::setRfOutputPower(int power) { 00323 00324 int rfSetup = getRegister(_NRF24L01P_REG_RF_SETUP) & ~_NRF24L01P_RF_SETUP_RF_PWR_MASK; 00325 00326 switch ( power ) { 00327 00328 case NRF24L01P_TX_PWR_ZERO_DB: 00329 rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_0DBM; 00330 break; 00331 00332 case NRF24L01P_TX_PWR_MINUS_6_DB: 00333 rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_MINUS_6DBM; 00334 break; 00335 00336 case NRF24L01P_TX_PWR_MINUS_12_DB: 00337 rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_MINUS_12DBM; 00338 break; 00339 00340 case NRF24L01P_TX_PWR_MINUS_18_DB: 00341 rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_MINUS_18DBM; 00342 break; 00343 00344 default: 00345 error( "nRF24L01P: Invalid RF Output Power setting %d\r\n", power ); 00346 return; 00347 00348 } 00349 00350 setRegister(_NRF24L01P_REG_RF_SETUP, rfSetup); 00351 00352 } 00353 00354 00355 int nRF24L01P::getRfOutputPower(void) { 00356 00357 int rfPwr = getRegister(_NRF24L01P_REG_RF_SETUP) & _NRF24L01P_RF_SETUP_RF_PWR_MASK; 00358 00359 switch ( rfPwr ) { 00360 00361 case _NRF24L01P_RF_SETUP_RF_PWR_0DBM: 00362 return NRF24L01P_TX_PWR_ZERO_DB; 00363 00364 case _NRF24L01P_RF_SETUP_RF_PWR_MINUS_6DBM: 00365 return NRF24L01P_TX_PWR_MINUS_6_DB; 00366 00367 case _NRF24L01P_RF_SETUP_RF_PWR_MINUS_12DBM: 00368 return NRF24L01P_TX_PWR_MINUS_12_DB; 00369 00370 case _NRF24L01P_RF_SETUP_RF_PWR_MINUS_18DBM: 00371 return NRF24L01P_TX_PWR_MINUS_18_DB; 00372 00373 default: 00374 error( "nRF24L01P: Unknown RF Output Power value %d\r\n", rfPwr ); 00375 return 0; 00376 00377 } 00378 } 00379 00380 00381 void nRF24L01P::setAirDataRate(int rate) { 00382 00383 int rfSetup = getRegister(_NRF24L01P_REG_RF_SETUP) & ~_NRF24L01P_RF_SETUP_RF_DR_MASK; 00384 00385 switch ( rate ) { 00386 00387 case NRF24L01P_DATARATE_250_KBPS: 00388 rfSetup |= _NRF24L01P_RF_SETUP_RF_DR_250KBPS; 00389 break; 00390 00391 case NRF24L01P_DATARATE_1_MBPS: 00392 rfSetup |= _NRF24L01P_RF_SETUP_RF_DR_1MBPS; 00393 break; 00394 00395 case NRF24L01P_DATARATE_2_MBPS: 00396 rfSetup |= _NRF24L01P_RF_SETUP_RF_DR_2MBPS; 00397 break; 00398 00399 default: 00400 error( "nRF24L01P: Invalid Air Data Rate setting %d\r\n", rate ); 00401 return; 00402 00403 } 00404 00405 setRegister(_NRF24L01P_REG_RF_SETUP, rfSetup); 00406 00407 } 00408 00409 00410 int nRF24L01P::getAirDataRate(void) { 00411 00412 int rfDataRate = getRegister(_NRF24L01P_REG_RF_SETUP) & _NRF24L01P_RF_SETUP_RF_DR_MASK; 00413 00414 switch ( rfDataRate ) { 00415 00416 case _NRF24L01P_RF_SETUP_RF_DR_250KBPS: 00417 return NRF24L01P_DATARATE_250_KBPS; 00418 00419 case _NRF24L01P_RF_SETUP_RF_DR_1MBPS: 00420 return NRF24L01P_DATARATE_1_MBPS; 00421 00422 case _NRF24L01P_RF_SETUP_RF_DR_2MBPS: 00423 return NRF24L01P_DATARATE_2_MBPS; 00424 00425 default: 00426 error( "nRF24L01P: Unknown Air Data Rate value %d\r\n", rfDataRate ); 00427 return 0; 00428 00429 } 00430 } 00431 00432 00433 void nRF24L01P::setCrcWidth(int width) { 00434 00435 int config = getRegister(_NRF24L01P_REG_CONFIG) & ~_NRF24L01P_CONFIG_CRC_MASK; 00436 00437 switch ( width ) { 00438 00439 case NRF24L01P_CRC_NONE: 00440 config |= _NRF24L01P_CONFIG_CRC_NONE; 00441 break; 00442 00443 case NRF24L01P_CRC_8_BIT: 00444 config |= _NRF24L01P_CONFIG_CRC_8BIT; 00445 break; 00446 00447 case NRF24L01P_CRC_16_BIT: 00448 config |= _NRF24L01P_CONFIG_CRC_16BIT; 00449 break; 00450 00451 default: 00452 error( "nRF24L01P: Invalid CRC Width setting %d\r\n", width ); 00453 return; 00454 00455 } 00456 00457 setRegister(_NRF24L01P_REG_CONFIG, config); 00458 00459 } 00460 00461 00462 int nRF24L01P::getCrcWidth(void) { 00463 00464 int crcWidth = getRegister(_NRF24L01P_REG_CONFIG) & _NRF24L01P_CONFIG_CRC_MASK; 00465 00466 switch ( crcWidth ) { 00467 00468 case _NRF24L01P_CONFIG_CRC_NONE: 00469 return NRF24L01P_CRC_NONE; 00470 00471 case _NRF24L01P_CONFIG_CRC_8BIT: 00472 return NRF24L01P_CRC_8_BIT; 00473 00474 case _NRF24L01P_CONFIG_CRC_16BIT: 00475 return NRF24L01P_CRC_16_BIT; 00476 00477 default: 00478 error( "nRF24L01P: Unknown CRC Width value %d\r\n", crcWidth ); 00479 return 0; 00480 00481 } 00482 } 00483 00484 00485 void nRF24L01P::setTransferSize(int size, int pipe) { 00486 00487 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00488 00489 error( "nRF24L01P: Invalid Transfer Size pipe number %d\r\n", pipe ); 00490 return; 00491 00492 } 00493 00494 if ( ( size < 0 ) || ( size > _NRF24L01P_RX_FIFO_SIZE ) ) { 00495 00496 error( "nRF24L01P: Invalid Transfer Size setting %d\r\n", size ); 00497 return; 00498 00499 } 00500 00501 int rxPwPxRegister = _NRF24L01P_REG_RX_PW_P0 + ( pipe - NRF24L01P_PIPE_P0 ); 00502 00503 setRegister(rxPwPxRegister, ( size & _NRF24L01P_RX_PW_Px_MASK ) ); 00504 00505 } 00506 00507 00508 int nRF24L01P::getTransferSize(int pipe) { 00509 00510 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00511 00512 error( "nRF24L01P: Invalid Transfer Size pipe number %d\r\n", pipe ); 00513 return 0; 00514 00515 } 00516 00517 int rxPwPxRegister = _NRF24L01P_REG_RX_PW_P0 + ( pipe - NRF24L01P_PIPE_P0 ); 00518 00519 int size = getRegister(rxPwPxRegister); 00520 00521 return ( size & _NRF24L01P_RX_PW_Px_MASK ); 00522 00523 } 00524 00525 00526 void nRF24L01P::disableAllRxPipes(void) { 00527 00528 setRegister(_NRF24L01P_REG_EN_RXADDR, _NRF24L01P_EN_RXADDR_NONE); 00529 00530 } 00531 00532 00533 void nRF24L01P::disableAutoAcknowledge(void) { 00534 00535 setRegister(_NRF24L01P_REG_EN_AA, _NRF24L01P_EN_AA_NONE); 00536 00537 } 00538 00539 00540 void nRF24L01P::enableAutoAcknowledge(int pipe) { 00541 00542 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00543 00544 error( "nRF24L01P: Invalid Enable AutoAcknowledge pipe number %d\r\n", pipe ); 00545 return; 00546 00547 } 00548 00549 int enAA = getRegister(_NRF24L01P_REG_EN_AA); 00550 00551 enAA |= ( 1 << (pipe - NRF24L01P_PIPE_P0) ); 00552 00553 setRegister(_NRF24L01P_REG_EN_AA, enAA); 00554 00555 } 00556 00557 00558 void nRF24L01P::disableAutoRetransmit(void) { 00559 00560 setRegister(_NRF24L01P_REG_SETUP_RETR, _NRF24L01P_SETUP_RETR_NONE); 00561 00562 } 00563 00564 void nRF24L01P::setRxAddress(unsigned long long address, int width, int pipe) { 00565 00566 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00567 00568 error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe ); 00569 return; 00570 00571 } 00572 00573 if ( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) { 00574 00575 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & ~_NRF24L01P_SETUP_AW_AW_MASK; 00576 00577 switch ( width ) { 00578 00579 case 3: 00580 setupAw |= _NRF24L01P_SETUP_AW_AW_3BYTE; 00581 break; 00582 00583 case 4: 00584 setupAw |= _NRF24L01P_SETUP_AW_AW_4BYTE; 00585 break; 00586 00587 case 5: 00588 setupAw |= _NRF24L01P_SETUP_AW_AW_5BYTE; 00589 break; 00590 00591 default: 00592 error( "nRF24L01P: Invalid setRxAddress width setting %d\r\n", width ); 00593 return; 00594 00595 } 00596 00597 setRegister(_NRF24L01P_REG_SETUP_AW, setupAw); 00598 00599 } else { 00600 00601 width = 1; 00602 00603 } 00604 00605 int rxAddrPxRegister = _NRF24L01P_REG_RX_ADDR_P0 + ( pipe - NRF24L01P_PIPE_P0 ); 00606 00607 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (rxAddrPxRegister & _NRF24L01P_REG_ADDRESS_MASK)); 00608 00609 nCS_ = 0; 00610 00611 int status = spi_.write(cn); 00612 00613 while ( width-- > 0 ) { 00614 00615 // 00616 // LSByte first 00617 // 00618 spi_.write((int) (address & 0xFF)); 00619 address >>= 8; 00620 00621 } 00622 00623 nCS_ = 1; 00624 00625 int enRxAddr = getRegister(_NRF24L01P_REG_EN_RXADDR); 00626 00627 enRxAddr |= (1 << ( pipe - NRF24L01P_PIPE_P0 ) ); 00628 00629 setRegister(_NRF24L01P_REG_EN_RXADDR, enRxAddr); 00630 } 00631 00632 /* 00633 * This version of setRxAddress is just a wrapper for the version that takes 'long long's, 00634 * in case the main code doesn't want to deal with long long's. 00635 */ 00636 void nRF24L01P::setRxAddress(unsigned long msb_address, unsigned long lsb_address, int width, int pipe) { 00637 00638 unsigned long long address = ( ( (unsigned long long) msb_address ) << 32 ) | ( ( (unsigned long long) lsb_address ) << 0 ); 00639 00640 setRxAddress(address, width, pipe); 00641 00642 } 00643 00644 00645 /* 00646 * This version of setTxAddress is just a wrapper for the version that takes 'long long's, 00647 * in case the main code doesn't want to deal with long long's. 00648 */ 00649 void nRF24L01P::setTxAddress(unsigned long msb_address, unsigned long lsb_address, int width) { 00650 00651 unsigned long long address = ( ( (unsigned long long) msb_address ) << 32 ) | ( ( (unsigned long long) lsb_address ) << 0 ); 00652 00653 setTxAddress(address, width); 00654 00655 } 00656 00657 00658 void nRF24L01P::setTxAddress(unsigned long long address, int width) { 00659 00660 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & ~_NRF24L01P_SETUP_AW_AW_MASK; 00661 00662 switch ( width ) { 00663 00664 case 3: 00665 setupAw |= _NRF24L01P_SETUP_AW_AW_3BYTE; 00666 break; 00667 00668 case 4: 00669 setupAw |= _NRF24L01P_SETUP_AW_AW_4BYTE; 00670 break; 00671 00672 case 5: 00673 setupAw |= _NRF24L01P_SETUP_AW_AW_5BYTE; 00674 break; 00675 00676 default: 00677 error( "nRF24L01P: Invalid setTxAddress width setting %d\r\n", width ); 00678 return; 00679 00680 } 00681 00682 setRegister(_NRF24L01P_REG_SETUP_AW, setupAw); 00683 00684 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (_NRF24L01P_REG_TX_ADDR & _NRF24L01P_REG_ADDRESS_MASK)); 00685 00686 nCS_ = 0; 00687 00688 int status = spi_.write(cn); 00689 00690 while ( width-- > 0 ) { 00691 00692 // 00693 // LSByte first 00694 // 00695 spi_.write((int) (address & 0xFF)); 00696 address >>= 8; 00697 00698 } 00699 00700 nCS_ = 1; 00701 00702 } 00703 00704 00705 unsigned long long nRF24L01P::getRxAddress(int pipe) { 00706 00707 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00708 00709 error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe ); 00710 return 0; 00711 00712 } 00713 00714 int width; 00715 00716 if ( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) { 00717 00718 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & _NRF24L01P_SETUP_AW_AW_MASK; 00719 00720 switch ( setupAw ) { 00721 00722 case _NRF24L01P_SETUP_AW_AW_3BYTE: 00723 width = 3; 00724 break; 00725 00726 case _NRF24L01P_SETUP_AW_AW_4BYTE: 00727 width = 4; 00728 break; 00729 00730 case _NRF24L01P_SETUP_AW_AW_5BYTE: 00731 width = 5; 00732 break; 00733 00734 default: 00735 error( "nRF24L01P: Unknown getRxAddress width value %d\r\n", setupAw ); 00736 return 0; 00737 00738 } 00739 00740 } else { 00741 00742 width = 1; 00743 00744 } 00745 00746 int rxAddrPxRegister = _NRF24L01P_REG_RX_ADDR_P0 + ( pipe - NRF24L01P_PIPE_P0 ); 00747 00748 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (rxAddrPxRegister & _NRF24L01P_REG_ADDRESS_MASK)); 00749 00750 unsigned long long address = 0; 00751 00752 nCS_ = 0; 00753 00754 int status = spi_.write(cn); 00755 00756 for ( int i=0; i<width; i++ ) { 00757 00758 // 00759 // LSByte first 00760 // 00761 address |= ( ( (unsigned long long)( spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF ) ) << (i*8) ); 00762 00763 } 00764 00765 nCS_ = 1; 00766 00767 if ( !( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) ) { 00768 00769 address |= ( getRxAddress(NRF24L01P_PIPE_P1) & ~((unsigned long long) 0xFF) ); 00770 00771 } 00772 00773 return address; 00774 00775 } 00776 00777 00778 unsigned long long nRF24L01P::getTxAddress(void) { 00779 00780 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & _NRF24L01P_SETUP_AW_AW_MASK; 00781 00782 int width; 00783 00784 switch ( setupAw ) { 00785 00786 case _NRF24L01P_SETUP_AW_AW_3BYTE: 00787 width = 3; 00788 break; 00789 00790 case _NRF24L01P_SETUP_AW_AW_4BYTE: 00791 width = 4; 00792 break; 00793 00794 case _NRF24L01P_SETUP_AW_AW_5BYTE: 00795 width = 5; 00796 break; 00797 00798 default: 00799 error( "nRF24L01P: Unknown getTxAddress width value %d\r\n", setupAw ); 00800 return 0; 00801 00802 } 00803 00804 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (_NRF24L01P_REG_TX_ADDR & _NRF24L01P_REG_ADDRESS_MASK)); 00805 00806 unsigned long long address = 0; 00807 00808 nCS_ = 0; 00809 00810 int status = spi_.write(cn); 00811 00812 for ( int i=0; i<width; i++ ) { 00813 00814 // 00815 // LSByte first 00816 // 00817 address |= ( ( (unsigned long long)( spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF ) ) << (i*8) ); 00818 00819 } 00820 00821 nCS_ = 1; 00822 00823 return address; 00824 } 00825 00826 00827 bool nRF24L01P::readable(int pipe) { 00828 00829 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00830 00831 error( "nRF24L01P: Invalid readable pipe number %d\r\n", pipe ); 00832 return false; 00833 00834 } 00835 00836 int status = getStatusRegister(); 00837 00838 return ( ( status & _NRF24L01P_STATUS_RX_DR ) && ( ( ( status & _NRF24L01P_STATUS_RX_P_NO ) >> 1 ) == ( pipe & 0x7 ) ) ); 00839 00840 } 00841 00842 00843 int nRF24L01P::write(int pipe, char *data, int count) { 00844 00845 // Note: the pipe number is ignored in a Transmit / write 00846 00847 // 00848 // Save the CE state 00849 // 00850 int originalCe = ce_; 00851 disable(); 00852 00853 if ( count <= 0 ) return 0; 00854 00855 if ( count > _NRF24L01P_TX_FIFO_SIZE ) count = _NRF24L01P_TX_FIFO_SIZE; 00856 00857 // Clear the Status bit 00858 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_TX_DS); 00859 00860 nCS_ = 0; 00861 int status = spi_.write(_NRF24L01P_SPI_CMD_WR_TX_PAYLOAD); 00862 //int status = spi_.write(_NRF24L01P_SPI_CMD_W_ACK_PAYLOAD); 00863 for ( int i = 0; i < count; i++ ) { 00864 00865 spi_.write(*data++); 00866 00867 } 00868 00869 nCS_ = 1; 00870 00871 int originalMode = mode; 00872 setTransmitMode(); 00873 00874 enable(); 00875 wait_us(_NRF24L01P_TIMING_Thce_us); 00876 disable(); 00877 00878 while ( !( getStatusRegister() & _NRF24L01P_STATUS_TX_DS ) ) { 00879 00880 // Wait for the transfer to complete 00881 00882 } 00883 00884 // Clear the Status bit 00885 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_TX_DS); 00886 00887 if ( originalMode == _NRF24L01P_MODE_RX ) { 00888 00889 setReceiveMode(); 00890 00891 } 00892 00893 ce_ = originalCe; 00894 wait_us( _NRF24L01P_TIMING_Tpece2csn_us ); 00895 00896 return count; 00897 00898 } 00899 00900 00901 int nRF24L01P::read(int pipe, char *data, int count) { 00902 00903 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { 00904 00905 error( "nRF24L01P: Invalid read pipe number %d\r\n", pipe ); 00906 return -1; 00907 00908 } 00909 00910 if ( count <= 0 ) return 0; 00911 00912 if ( count > _NRF24L01P_RX_FIFO_SIZE ) count = _NRF24L01P_RX_FIFO_SIZE; 00913 00914 if ( readable(pipe) ) { 00915 00916 nCS_ = 0; 00917 00918 int status = spi_.write(_NRF24L01P_SPI_CMD_R_RX_PL_WID); 00919 00920 int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP); 00921 00922 nCS_ = 1; 00923 00924 if ( ( rxPayloadWidth < 0 ) || ( rxPayloadWidth > _NRF24L01P_RX_FIFO_SIZE ) ) { 00925 00926 // Received payload error: need to flush the FIFO 00927 00928 nCS_ = 0; 00929 00930 int status = spi_.write(_NRF24L01P_SPI_CMD_FLUSH_RX); 00931 00932 int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP); 00933 00934 nCS_ = 1; 00935 00936 // 00937 // At this point, we should retry the reception, 00938 // but for now we'll just fall through... 00939 // 00940 00941 } else { 00942 00943 if ( rxPayloadWidth < count ) count = rxPayloadWidth; 00944 00945 nCS_ = 0; 00946 00947 int status = spi_.write(_NRF24L01P_SPI_CMD_RD_RX_PAYLOAD); 00948 00949 for ( int i = 0; i < count; i++ ) { 00950 00951 *data++ = spi_.write(_NRF24L01P_SPI_CMD_NOP); 00952 00953 } 00954 00955 nCS_ = 1; 00956 00957 // Clear the Status bit 00958 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_RX_DR); 00959 00960 return count; 00961 00962 } 00963 00964 } else { 00965 00966 // 00967 // What should we do if there is no 'readable' data? 00968 // We could wait for data to arrive, but for now, we'll 00969 // just return with no data. 00970 // 00971 return 0; 00972 00973 } 00974 00975 // 00976 // We get here because an error condition occured; 00977 // We could wait for data to arrive, but for now, we'll 00978 // just return with no data. 00979 // 00980 return -1; 00981 00982 } 00983 00984 00985 void nRF24L01P::enableAutoRetransmit(int delay, int count) { 00986 if(count > 15) { 00987 count = 15; 00988 } 00989 if((0!=(delay % 250)) || (delay > 4000)) { 00990 return; 00991 } 00992 00993 setRegister(_NRF24L01P_REG_SETUP_RETR, 0x4A); 00994 } 00995 00996 00997 void nRF24L01P::setRegister(int regAddress, int regData) { 00998 00999 // 01000 // Save the CE state 01001 // 01002 int originalCe = ce_; 01003 disable(); 01004 01005 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (regAddress & _NRF24L01P_REG_ADDRESS_MASK)); 01006 01007 nCS_ = 0; 01008 01009 int status = spi_.write(cn); 01010 01011 spi_.write(regData & 0xFF); 01012 01013 nCS_ = 1; 01014 01015 ce_ = originalCe; 01016 wait_us( _NRF24L01P_TIMING_Tpece2csn_us ); 01017 01018 } 01019 01020 01021 int nRF24L01P::getRegister(int regAddress) { 01022 01023 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (regAddress & _NRF24L01P_REG_ADDRESS_MASK)); 01024 01025 nCS_ = 0; 01026 01027 int status = spi_.write(cn); 01028 01029 int dn = spi_.write(_NRF24L01P_SPI_CMD_NOP); 01030 01031 nCS_ = 1; 01032 01033 return dn; 01034 01035 } 01036 01037 int nRF24L01P::getStatusRegister(void) { 01038 01039 nCS_ = 0; 01040 01041 int status = spi_.write(_NRF24L01P_SPI_CMD_NOP); 01042 01043 nCS_ = 1; 01044 01045 return status; 01046 01047 }
Generated on Sat Jul 16 2022 03:22:46 by
1.7.2
