I-O DATA DEV2 / nRF24L01P

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