JNP3_IOT_2016Z / nRF24L01P

Dependents:   JNP3_IOT_6_RADIO_ECHO_FIXED nRF24L01P_NET_GW nRF24L01P_NET_SENSOR Kubus ... more

Fork of nRF24L01P by Owen Edwards

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 void nRF24L01P::enableDynamicPayload(int pipe) {
00568 
00569     if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
00570 
00571         error( "nRF24L01P: Invalid Enable AutoAcknowledge pipe number %d\r\n", pipe );
00572         return;
00573 
00574     }
00575     
00576     int feature = getRegister(_NRF24L01P_REG_FEATURE);
00577     feature |= ( 1 << 2 );
00578     setRegister(_NRF24L01P_REG_FEATURE, feature);
00579 
00580     int dynpd = getRegister(_NRF24L01P_REG_DYNPD);
00581     dynpd |= ( 1 << (pipe - NRF24L01P_PIPE_P0) );
00582     setRegister(_NRF24L01P_REG_DYNPD, dynpd);
00583 
00584 }
00585 
00586 
00587 void nRF24L01P::disableDynamicPayload(void) {
00588     
00589     int feature = getRegister(_NRF24L01P_REG_FEATURE);
00590     feature &= !( 1 << 2 );
00591     setRegister(_NRF24L01P_REG_FEATURE, feature);
00592 }
00593 
00594 
00595 void nRF24L01P::disableAutoRetransmit(void) {
00596 
00597     setRegister(_NRF24L01P_REG_SETUP_RETR, _NRF24L01P_SETUP_RETR_NONE);
00598     a_retr_enabled = false;
00599 
00600 }
00601 
00602 void nRF24L01P::enableAutoRetransmit(int delay, int count) {
00603     delay = (0x00F0 & (delay << 4));
00604     count = (0x000F & count);
00605 
00606     setRegister(_NRF24L01P_REG_SETUP_RETR, delay|count);
00607     a_retr_enabled = true;
00608 
00609 }
00610 
00611 int nRF24L01P::getRetrCount(){
00612     return getRegister(_NRF24L01P_REG_OBSERVE_TX) & 0x0F;
00613 }
00614 
00615 void nRF24L01P::setRxAddress(unsigned long long address, int width, int pipe) {
00616 
00617     if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
00618 
00619         error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe );
00620         return;
00621 
00622     }
00623 
00624     if ( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) {
00625 
00626         int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & ~_NRF24L01P_SETUP_AW_AW_MASK;
00627     
00628         switch ( width ) {
00629     
00630             case 3:
00631                 setupAw |= _NRF24L01P_SETUP_AW_AW_3BYTE;
00632                 break;
00633     
00634             case 4:
00635                 setupAw |= _NRF24L01P_SETUP_AW_AW_4BYTE;
00636                 break;
00637     
00638             case 5:
00639                 setupAw |= _NRF24L01P_SETUP_AW_AW_5BYTE;
00640                 break;
00641     
00642             default:
00643                 error( "nRF24L01P: Invalid setRxAddress width setting %d\r\n", width );
00644                 return;
00645     
00646         }
00647     
00648         setRegister(_NRF24L01P_REG_SETUP_AW, setupAw);
00649 
00650     } else {
00651     
00652         width = 1;
00653     
00654     }
00655 
00656     int rxAddrPxRegister = _NRF24L01P_REG_RX_ADDR_P0 + ( pipe - NRF24L01P_PIPE_P0 );
00657 
00658     int cn = (_NRF24L01P_SPI_CMD_WR_REG | (rxAddrPxRegister & _NRF24L01P_REG_ADDRESS_MASK));
00659 
00660     nCS_ = 0;
00661 
00662     int status = spi_.write(cn);
00663 
00664     while ( width-- > 0 ) {
00665 
00666         //
00667         // LSByte first
00668         //
00669         spi_.write((int) (address & 0xFF));
00670         address >>= 8;
00671 
00672     }
00673 
00674     nCS_ = 1;
00675 
00676     int enRxAddr = getRegister(_NRF24L01P_REG_EN_RXADDR);
00677 
00678     enRxAddr |= (1 << ( pipe - NRF24L01P_PIPE_P0 ) );
00679 
00680     setRegister(_NRF24L01P_REG_EN_RXADDR, enRxAddr);
00681 }
00682 
00683 void nRF24L01P::disablePipeRX(int pipe) {
00684     
00685     if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
00686         error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe );
00687         return;
00688     }
00689     
00690     int enRxAddr = getRegister(_NRF24L01P_REG_EN_RXADDR);
00691 
00692     enRxAddr &= ~(1 << ( pipe - NRF24L01P_PIPE_P0 ) );
00693 
00694     setRegister(_NRF24L01P_REG_EN_RXADDR, enRxAddr);
00695     
00696 }
00697 
00698 void nRF24L01P::enablePipeRX(int pipe) {
00699     
00700     if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
00701         error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe );
00702         return;
00703     }
00704     
00705     int enRxAddr = getRegister(_NRF24L01P_REG_EN_RXADDR);
00706 
00707     enRxAddr |= (1 << ( pipe - NRF24L01P_PIPE_P0 ) );
00708 
00709     setRegister(_NRF24L01P_REG_EN_RXADDR, enRxAddr);
00710     
00711 }
00712 
00713 /*
00714  * This version of setRxAddress is just a wrapper for the version that takes 'long long's,
00715  *  in case the main code doesn't want to deal with long long's.
00716  */
00717 void nRF24L01P::setRxAddress(unsigned long msb_address, unsigned long lsb_address, int width, int pipe) {
00718 
00719     unsigned long long address = ( ( (unsigned long long) msb_address ) << 32 ) | ( ( (unsigned long long) lsb_address ) << 0 );
00720 
00721     setRxAddress(address, width, pipe);
00722 
00723 }
00724 
00725 
00726 /*
00727  * This version of setTxAddress is just a wrapper for the version that takes 'long long's,
00728  *  in case the main code doesn't want to deal with long long's.
00729  */
00730 void nRF24L01P::setTxAddress(unsigned long msb_address, unsigned long lsb_address, int width) {
00731 
00732     unsigned long long address = ( ( (unsigned long long) msb_address ) << 32 ) | ( ( (unsigned long long) lsb_address ) << 0 );
00733 
00734     setTxAddress(address, width);
00735 
00736 }
00737 
00738 
00739 void nRF24L01P::setTxAddress(unsigned long long address, int width) {
00740 
00741     int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & ~_NRF24L01P_SETUP_AW_AW_MASK;
00742 
00743     switch ( width ) {
00744 
00745         case 3:
00746             setupAw |= _NRF24L01P_SETUP_AW_AW_3BYTE;
00747             break;
00748 
00749         case 4:
00750             setupAw |= _NRF24L01P_SETUP_AW_AW_4BYTE;
00751             break;
00752 
00753         case 5:
00754             setupAw |= _NRF24L01P_SETUP_AW_AW_5BYTE;
00755             break;
00756 
00757         default:
00758             error( "nRF24L01P: Invalid setTxAddress width setting %d\r\n", width );
00759             return;
00760 
00761     }
00762 
00763     setRegister(_NRF24L01P_REG_SETUP_AW, setupAw);
00764 
00765     int cn = (_NRF24L01P_SPI_CMD_WR_REG | (_NRF24L01P_REG_TX_ADDR & _NRF24L01P_REG_ADDRESS_MASK));
00766 
00767     nCS_ = 0;
00768 
00769     int status = spi_.write(cn);
00770 
00771     while ( width-- > 0 ) {
00772 
00773         //
00774         // LSByte first
00775         //
00776         spi_.write((int) (address & 0xFF));
00777         address >>= 8;
00778 
00779     }
00780 
00781     nCS_ = 1;
00782 
00783 }
00784 
00785 
00786 unsigned long long nRF24L01P::getRxAddress(int pipe) {
00787 
00788     if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
00789 
00790         error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe );
00791         return 0;
00792 
00793     }
00794 
00795     int width;
00796 
00797     if ( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) {
00798 
00799         int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & _NRF24L01P_SETUP_AW_AW_MASK;
00800 
00801         switch ( setupAw ) {
00802 
00803             case _NRF24L01P_SETUP_AW_AW_3BYTE:
00804                 width = 3;
00805                 break;
00806 
00807             case _NRF24L01P_SETUP_AW_AW_4BYTE:
00808                 width = 4;
00809                 break;
00810 
00811             case _NRF24L01P_SETUP_AW_AW_5BYTE:
00812                 width = 5;
00813                 break;
00814 
00815             default:
00816                 error( "nRF24L01P: Unknown getRxAddress width value %d\r\n", setupAw );
00817                 return 0;
00818 
00819         }
00820 
00821     } else {
00822 
00823         width = 1;
00824 
00825     }
00826 
00827     int rxAddrPxRegister = _NRF24L01P_REG_RX_ADDR_P0 + ( pipe - NRF24L01P_PIPE_P0 );
00828 
00829     int cn = (_NRF24L01P_SPI_CMD_RD_REG | (rxAddrPxRegister & _NRF24L01P_REG_ADDRESS_MASK));
00830 
00831     unsigned long long address = 0;
00832 
00833     nCS_ = 0;
00834 
00835     int status = spi_.write(cn);
00836 
00837     for ( int i=0; i<width; i++ ) {
00838 
00839         //
00840         // LSByte first
00841         //
00842         address |= ( ( (unsigned long long)( spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF ) ) << (i*8) );
00843 
00844     }
00845 
00846     nCS_ = 1;
00847 
00848     if ( !( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) ) {
00849 
00850         address |= ( getRxAddress(NRF24L01P_PIPE_P1) & ~((unsigned long long) 0xFF) );
00851 
00852     }
00853 
00854     return address;
00855 
00856 }
00857 
00858     
00859 unsigned long long nRF24L01P::getTxAddress(void) {
00860 
00861     int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & _NRF24L01P_SETUP_AW_AW_MASK;
00862 
00863     int width;
00864 
00865     switch ( setupAw ) {
00866 
00867         case _NRF24L01P_SETUP_AW_AW_3BYTE:
00868             width = 3;
00869             break;
00870 
00871         case _NRF24L01P_SETUP_AW_AW_4BYTE:
00872             width = 4;
00873             break;
00874 
00875         case _NRF24L01P_SETUP_AW_AW_5BYTE:
00876             width = 5;
00877             break;
00878 
00879         default:
00880             error( "nRF24L01P: Unknown getTxAddress width value %d\r\n", setupAw );
00881             return 0;
00882 
00883     }
00884 
00885     int cn = (_NRF24L01P_SPI_CMD_RD_REG | (_NRF24L01P_REG_TX_ADDR & _NRF24L01P_REG_ADDRESS_MASK));
00886 
00887     unsigned long long address = 0;
00888 
00889     nCS_ = 0;
00890 
00891     int status = spi_.write(cn);
00892 
00893     for ( int i=0; i<width; i++ ) {
00894 
00895         //
00896         // LSByte first
00897         //
00898         address |= ( ( (unsigned long long)( spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF ) ) << (i*8) );
00899 
00900     }
00901 
00902     nCS_ = 1;
00903 
00904     return address;
00905 }
00906 
00907 
00908 bool nRF24L01P::readable(int pipe) {
00909 
00910     if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
00911 
00912         error( "nRF24L01P: Invalid readable pipe number %d\r\n", pipe );
00913         return false;
00914 
00915     }
00916 
00917     int status = getStatusRegister();
00918 
00919     return ( ( status & _NRF24L01P_STATUS_RX_DR ) && ( ( ( status & _NRF24L01P_STATUS_RX_P_NO ) >> 1 ) == ( pipe & 0x7 ) ) );
00920 
00921 }
00922 
00923 
00924 int nRF24L01P::write(int pipe, char *data, int count) {
00925     
00926     // Note: the pipe number is ignored in a Transmit / write
00927 
00928     //
00929     // Save the CE state
00930     //
00931     int originalCe = ce_;
00932     disable();
00933 
00934     if ( count <= 0 ) return 0;
00935 
00936     if ( count > _NRF24L01P_TX_FIFO_SIZE ) count = _NRF24L01P_TX_FIFO_SIZE;
00937 
00938     // Clear the Status bit
00939     setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_TX_DS);
00940     setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_MAX_RT);
00941     
00942     nCS_ = 0;
00943 
00944     int status = spi_.write(_NRF24L01P_SPI_CMD_WR_TX_PAYLOAD);
00945 
00946     for ( int i = 0; i < count; i++ ) {
00947 
00948         spi_.write(*data++);
00949 
00950     }
00951 
00952     nCS_ = 1;
00953 
00954     int originalMode = mode;
00955     setTransmitMode();
00956 
00957     enable();
00958     wait_us(_NRF24L01P_TIMING_Thce_us);
00959     disable();
00960 
00961     while ( !( getStatusRegister() & (_NRF24L01P_STATUS_TX_DS | _NRF24L01P_STATUS_MAX_RT) ) ) {
00962     }
00963     
00964     int s = getStatusRegister();
00965     
00966     if (s & _NRF24L01P_STATUS_MAX_RT){
00967         //max retransmissions
00968         flushTx();
00969         count = -1;
00970     }
00971 
00972     // Clear the Status bit
00973     setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_TX_DS);
00974     setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_MAX_RT);
00975 
00976     if ( originalMode == _NRF24L01P_MODE_RX ) {
00977 
00978         setReceiveMode();
00979 
00980     }
00981 
00982     ce_ = originalCe;
00983     wait_us( _NRF24L01P_TIMING_Tpece2csn_us );
00984 
00985     return count;
00986 
00987 }
00988 
00989 
00990 int nRF24L01P::read(int pipe, char *data, int count) {
00991 
00992     if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
00993 
00994         error( "nRF24L01P: Invalid read pipe number %d\r\n", pipe );
00995         return -1;
00996 
00997     }
00998 
00999     if ( count <= 0 ) return 0;
01000 
01001     if ( count > _NRF24L01P_RX_FIFO_SIZE ) count = _NRF24L01P_RX_FIFO_SIZE;
01002 
01003     if ( readable(pipe) ) {
01004 
01005         nCS_ = 0;
01006 
01007         int status = spi_.write(_NRF24L01P_SPI_CMD_R_RX_PL_WID);
01008 
01009         int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF;
01010         
01011         nCS_ = 1;
01012 
01013         if ( ( rxPayloadWidth < 0 ) || ( rxPayloadWidth > _NRF24L01P_RX_FIFO_SIZE ) ) {
01014     
01015             // Received payload error: need to flush the FIFO
01016 
01017             nCS_ = 0;
01018     
01019             int status = spi_.write(_NRF24L01P_SPI_CMD_FLUSH_RX);
01020     
01021             int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP);
01022             
01023             nCS_ = 1;
01024             
01025             //
01026             // At this point, we should retry the reception,
01027             //  but for now we'll just fall through...
01028             //
01029 
01030         } else {
01031 
01032             if ( rxPayloadWidth < count ) count = rxPayloadWidth;
01033 
01034             nCS_ = 0;
01035         
01036             int status = spi_.write(_NRF24L01P_SPI_CMD_RD_RX_PAYLOAD);
01037         
01038             for ( int i = 0; i < count; i++ ) {
01039         
01040                 *data++ = spi_.write(_NRF24L01P_SPI_CMD_NOP);
01041         
01042             }
01043 
01044             nCS_ = 1;
01045 
01046             // Clear the Status bit
01047             setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_RX_DR);
01048 
01049             return count;
01050 
01051         }
01052 
01053     } else {
01054 
01055         //
01056         // What should we do if there is no 'readable' data?
01057         //  We could wait for data to arrive, but for now, we'll
01058         //  just return with no data.
01059         //
01060         return 0;
01061 
01062     }
01063 
01064     //
01065     // We get here because an error condition occured;
01066     //  We could wait for data to arrive, but for now, we'll
01067     //  just return with no data.
01068     //
01069     return -1;
01070 
01071 }
01072 
01073 bool nRF24L01P::getRPD(){
01074     uint8_t rpd = getRegister(_NRF24L01P_REG_RPD);
01075     return (rpd>0);
01076 }
01077  
01078 uint8_t nRF24L01P::getRSSI(){
01079     uint8_t rssi =0;
01080     for(int i=0; i<256; i++){
01081         rssi += getRPD();
01082         wait_us(50);
01083         flushRx();
01084     }
01085     return rssi;
01086 }
01087 
01088 void nRF24L01P::flushRx(void)
01089 {
01090     nCS_ = 0;
01091     spi_.write(_NRF24L01P_SPI_CMD_FLUSH_RX);
01092     nCS_ = 1;
01093 }
01094  
01095 void nRF24L01P::flushTx(void)
01096 {
01097     nCS_ = 0;
01098     spi_.write(_NRF24L01P_SPI_CMD_FLUSH_TX);
01099     nCS_ = 1;
01100 }
01101 
01102 
01103 void nRF24L01P::setRegister(int regAddress, int regData) {
01104 
01105     //
01106     // Save the CE state
01107     //
01108     int originalCe = ce_;
01109     disable();
01110 
01111     int cn = (_NRF24L01P_SPI_CMD_WR_REG | (regAddress & _NRF24L01P_REG_ADDRESS_MASK));
01112 
01113     nCS_ = 0;
01114 
01115     int status = spi_.write(cn);
01116 
01117     spi_.write(regData & 0xFF);
01118 
01119     nCS_ = 1;
01120 
01121     ce_ = originalCe;
01122     wait_us( _NRF24L01P_TIMING_Tpece2csn_us );
01123 
01124 }
01125 
01126 
01127 int nRF24L01P::getRegister(int regAddress) {
01128 
01129     int cn = (_NRF24L01P_SPI_CMD_RD_REG | (regAddress & _NRF24L01P_REG_ADDRESS_MASK));
01130 
01131     nCS_ = 0;
01132 
01133     int status = spi_.write(cn);
01134 
01135     int dn = spi_.write(_NRF24L01P_SPI_CMD_NOP);
01136 
01137     nCS_ = 1;
01138 
01139     return dn;
01140 
01141 }
01142 
01143 int nRF24L01P::getStatusRegister(void) {
01144 
01145     nCS_ = 0;
01146 
01147     int status = spi_.write(_NRF24L01P_SPI_CMD_NOP);
01148 
01149     nCS_ = 1;
01150 
01151     return status;
01152 
01153 }