Versie 0.2 Het versturen via de NRF werkt nog niet helemaal omdat er per 4 bytes verstuurd moet worden. Wordt gefixt d.m.v. dynamic stuff!
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