Tomasz T / nRF24L01P

Dependents:   JNP3_IOT_6_RADIO_ECHO_FIXED2

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