Energy harvesting mobile robot. Developed at Institute of Systems and Robotics — University of Coimbra.

Dependents:   Mapping VirtualForces_debug OneFileToRuleThemAll VirtualForces_with_class ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers nRF24L01P.cpp Source File

nRF24L01P.cpp

Go to the documentation of this file.
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 }
01030