Versie 0.2 Het versturen via de NRF werkt nog niet helemaal omdat er per 4 bytes verstuurd moet worden. Wordt gefixt d.m.v. dynamic stuff!

Dependencies:   RTOS mbed

Fork of rtos_basic by mbed official

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 //Use for debug!!
00041 extern DigitalOut check1;
00042 extern DigitalOut check2;
00043 extern DigitalOut check3;
00044 // End debug
00045 
00046 /**
00047  * Defines
00048  *
00049  * (Note that all defines here start with an underscore, e.g. '_NRF24L01P_MODE_UNKNOWN',
00050  *  and are local to this library.  The defines in the nRF24L01P.h file do not start
00051  *  with the underscore, and can be used by code to access this library.)
00052  */
00053 
00054 typedef enum {
00055     _NRF24L01P_MODE_UNKNOWN,
00056     _NRF24L01P_MODE_POWER_DOWN,
00057     _NRF24L01P_MODE_STANDBY,
00058     _NRF24L01P_MODE_RX,
00059     _NRF24L01P_MODE_TX,
00060 } nRF24L01P_Mode_Type;
00061 
00062 /*
00063  * The following FIFOs are present in nRF24L01+:
00064  *   TX three level, 32 byte FIFO
00065  *   RX three level, 32 byte FIFO
00066  */
00067 #define _NRF24L01P_TX_FIFO_COUNT   3
00068 #define _NRF24L01P_RX_FIFO_COUNT   3
00069 
00070 #define _NRF24L01P_TX_FIFO_SIZE   32
00071 #define _NRF24L01P_RX_FIFO_SIZE   32
00072 
00073 #define _NRF24L01P_SPI_MAX_DATA_RATE     10000000
00074 
00075 #define _NRF24L01P_SPI_CMD_RD_REG            0x00
00076 #define _NRF24L01P_SPI_CMD_WR_REG            0x20
00077 #define _NRF24L01P_SPI_CMD_RD_RX_PAYLOAD     0x61   
00078 #define _NRF24L01P_SPI_CMD_WR_TX_PAYLOAD     0xa0
00079 #define _NRF24L01P_SPI_CMD_FLUSH_TX          0xe1
00080 #define _NRF24L01P_SPI_CMD_FLUSH_RX          0xe2
00081 #define _NRF24L01P_SPI_CMD_REUSE_TX_PL       0xe3
00082 #define _NRF24L01P_SPI_CMD_R_RX_PL_WID       0x60
00083 #define _NRF24L01P_SPI_CMD_W_ACK_PAYLOAD     0xa8
00084 #define _NRF24L01P_SPI_CMD_W_TX_PYLD_NO_ACK  0xb0
00085 #define _NRF24L01P_SPI_CMD_NOP               0xff
00086 
00087 
00088 #define _NRF24L01P_REG_CONFIG                0x00
00089 #define _NRF24L01P_REG_EN_AA                 0x01
00090 #define _NRF24L01P_REG_EN_RXADDR             0x02
00091 #define _NRF24L01P_REG_SETUP_AW              0x03
00092 #define _NRF24L01P_REG_SETUP_RETR            0x04
00093 #define _NRF24L01P_REG_RF_CH                 0x05
00094 #define _NRF24L01P_REG_RF_SETUP              0x06
00095 #define _NRF24L01P_REG_STATUS                0x07
00096 #define _NRF24L01P_REG_OBSERVE_TX            0x08
00097 #define _NRF24L01P_REG_RPD                   0x09
00098 #define _NRF24L01P_REG_RX_ADDR_P0            0x0a
00099 #define _NRF24L01P_REG_RX_ADDR_P1            0x0b
00100 #define _NRF24L01P_REG_RX_ADDR_P2            0x0c
00101 #define _NRF24L01P_REG_RX_ADDR_P3            0x0d
00102 #define _NRF24L01P_REG_RX_ADDR_P4            0x0e
00103 #define _NRF24L01P_REG_RX_ADDR_P5            0x0f
00104 #define _NRF24L01P_REG_TX_ADDR               0x10
00105 #define _NRF24L01P_REG_RX_PW_P0              0x11
00106 #define _NRF24L01P_REG_RX_PW_P1              0x12
00107 #define _NRF24L01P_REG_RX_PW_P2              0x13
00108 #define _NRF24L01P_REG_RX_PW_P3              0x14
00109 #define _NRF24L01P_REG_RX_PW_P4              0x15
00110 #define _NRF24L01P_REG_RX_PW_P5              0x16
00111 #define _NRF24L01P_REG_FIFO_STATUS           0x17
00112 #define _NRF24L01P_REG_DYNPD                 0x1c
00113 #define _NRF24L01P_REG_FEATURE               0x1d
00114 
00115 #define _NRF24L01P_REG_ADDRESS_MASK          0x1f
00116 
00117 // CONFIG register:
00118 #define _NRF24L01P_CONFIG_PRIM_RX        (1<<0)
00119 #define _NRF24L01P_CONFIG_PWR_UP         (1<<1)
00120 #define _NRF24L01P_CONFIG_CRC0           (1<<2)
00121 #define _NRF24L01P_CONFIG_EN_CRC         (1<<3)
00122 #define _NRF24L01P_CONFIG_MASK_MAX_RT    (1<<4)
00123 #define _NRF24L01P_CONFIG_MASK_TX_DS     (1<<5)
00124 #define _NRF24L01P_CONFIG_MASK_RX_DR     (1<<6)
00125 
00126 #define _NRF24L01P_CONFIG_CRC_MASK       (_NRF24L01P_CONFIG_EN_CRC|_NRF24L01P_CONFIG_CRC0)
00127 #define _NRF24L01P_CONFIG_CRC_NONE       (0)
00128 #define _NRF24L01P_CONFIG_CRC_8BIT       (_NRF24L01P_CONFIG_EN_CRC)
00129 #define _NRF24L01P_CONFIG_CRC_16BIT      (_NRF24L01P_CONFIG_EN_CRC|_NRF24L01P_CONFIG_CRC0)
00130 
00131 // EN_AA register:
00132 #define _NRF24L01P_EN_AA_NONE            0
00133 
00134 // EN_RXADDR register:
00135 #define _NRF24L01P_EN_RXADDR_NONE        0
00136 
00137 // SETUP_AW register:
00138 #define _NRF24L01P_SETUP_AW_AW_MASK      (0x3<<0)
00139 #define _NRF24L01P_SETUP_AW_AW_3BYTE     (0x1<<0)
00140 #define _NRF24L01P_SETUP_AW_AW_4BYTE     (0x2<<0)
00141 #define _NRF24L01P_SETUP_AW_AW_5BYTE     (0x3<<0)
00142 
00143 // SETUP_RETR register:
00144 #define _NRF24L01P_SETUP_RETR_NONE       0
00145 
00146 // RF_SETUP register:
00147 #define _NRF24L01P_RF_SETUP_RF_PWR_MASK          (0x3<<1)
00148 #define _NRF24L01P_RF_SETUP_RF_PWR_0DBM          (0x3<<1)
00149 #define _NRF24L01P_RF_SETUP_RF_PWR_MINUS_6DBM    (0x2<<1)
00150 #define _NRF24L01P_RF_SETUP_RF_PWR_MINUS_12DBM   (0x1<<1)
00151 #define _NRF24L01P_RF_SETUP_RF_PWR_MINUS_18DBM   (0x0<<1)
00152 
00153 #define _NRF24L01P_RF_SETUP_RF_DR_HIGH_BIT       (1 << 3)
00154 #define _NRF24L01P_RF_SETUP_RF_DR_LOW_BIT        (1 << 5)
00155 #define _NRF24L01P_RF_SETUP_RF_DR_MASK           (_NRF24L01P_RF_SETUP_RF_DR_LOW_BIT|_NRF24L01P_RF_SETUP_RF_DR_HIGH_BIT)
00156 #define _NRF24L01P_RF_SETUP_RF_DR_250KBPS        (_NRF24L01P_RF_SETUP_RF_DR_LOW_BIT)
00157 #define _NRF24L01P_RF_SETUP_RF_DR_1MBPS          (0)
00158 #define _NRF24L01P_RF_SETUP_RF_DR_2MBPS          (_NRF24L01P_RF_SETUP_RF_DR_HIGH_BIT)
00159 
00160 // STATUS register:
00161 #define _NRF24L01P_STATUS_TX_FULL        (1<<0)
00162 #define _NRF24L01P_STATUS_RX_P_NO        (0x7<<1)
00163 #define _NRF24L01P_STATUS_MAX_RT         (1<<4)
00164 #define _NRF24L01P_STATUS_TX_DS          (1<<5)
00165 #define _NRF24L01P_STATUS_RX_DR          (1<<6)
00166 
00167 // RX_PW_P0..RX_PW_P5 registers:
00168 #define _NRF24L01P_RX_PW_Px_MASK         0x3F
00169 
00170 #define _NRF24L01P_TIMING_Tundef2pd_us     100000   // 100mS
00171 #define _NRF24L01P_TIMING_Tstby2a_us          130   // 130uS
00172 #define _NRF24L01P_TIMING_Thce_us              10   //  10uS
00173 #define _NRF24L01P_TIMING_Tpd2stby_us        4500   // 4.5mS worst case
00174 #define _NRF24L01P_TIMING_Tpece2csn_us          4   //   4uS
00175 
00176 /**
00177  * Methods
00178  */
00179 
00180 nRF24L01P::nRF24L01P(PinName mosi, 
00181                      PinName miso, 
00182                      PinName sck, 
00183                      PinName csn,
00184                      PinName ce,
00185                      PinName irq) : spi_(mosi, miso, sck), nCS_(csn), ce_(ce), nIRQ_(irq) {
00186 
00187     mode = _NRF24L01P_MODE_UNKNOWN;
00188 
00189     disable();
00190 
00191     nCS_ = 1;
00192 
00193     spi_.frequency(_NRF24L01P_SPI_MAX_DATA_RATE/5);     // 2Mbit, 1/5th the maximum transfer rate for the SPI bus
00194     spi_.format(8,0);                                   // 8-bit, ClockPhase = 0, ClockPolarity = 0
00195 
00196     wait_us(_NRF24L01P_TIMING_Tundef2pd_us);    // Wait for Power-on reset
00197 
00198     setRegister(_NRF24L01P_REG_CONFIG, 0); // Power Down
00199 
00200     setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_MAX_RT|_NRF24L01P_STATUS_TX_DS|_NRF24L01P_STATUS_RX_DR);   // Clear any pending interrupts
00201 
00202     //
00203     // Setup default configuration
00204     //
00205     disableAllRxPipes();
00206     setRfFrequency();
00207     setRfOutputPower();
00208     setAirDataRate();
00209     setCrcWidth();
00210     setTxAddress();
00211     setRxAddress();
00212     disableAutoAcknowledge();
00213     disableAutoRetransmit();
00214     setTransferSize();
00215 
00216     mode = _NRF24L01P_MODE_POWER_DOWN;
00217 
00218 }
00219 
00220 
00221 void nRF24L01P::powerUp(void) {
00222 
00223     int config = getRegister(_NRF24L01P_REG_CONFIG);
00224 
00225     config |= _NRF24L01P_CONFIG_PWR_UP;
00226 
00227     setRegister(_NRF24L01P_REG_CONFIG, config);
00228 
00229     // Wait until the nRF24L01+ powers up
00230     wait_us( _NRF24L01P_TIMING_Tpd2stby_us );
00231 
00232     mode = _NRF24L01P_MODE_STANDBY;
00233 
00234 }
00235 
00236 
00237 void nRF24L01P::powerDown(void) {
00238 
00239     int config = getRegister(_NRF24L01P_REG_CONFIG);
00240 
00241     config &= ~_NRF24L01P_CONFIG_PWR_UP;
00242 
00243     setRegister(_NRF24L01P_REG_CONFIG, config);
00244 
00245     // Wait until the nRF24L01+ powers down
00246     wait_us( _NRF24L01P_TIMING_Tpd2stby_us );    // This *may* not be necessary (no timing is shown in the Datasheet), but just to be safe
00247 
00248     mode = _NRF24L01P_MODE_POWER_DOWN;
00249 
00250 }
00251 
00252 
00253 void nRF24L01P::setReceiveMode(void) {
00254 
00255     if ( _NRF24L01P_MODE_POWER_DOWN == mode ) powerUp();
00256 
00257     int config = getRegister(_NRF24L01P_REG_CONFIG);
00258 
00259     config |= _NRF24L01P_CONFIG_PRIM_RX;
00260 
00261     setRegister(_NRF24L01P_REG_CONFIG, config);
00262 
00263     mode = _NRF24L01P_MODE_RX;
00264 
00265 }
00266 
00267 
00268 void nRF24L01P::setTransmitMode(void) {
00269 
00270     if ( _NRF24L01P_MODE_POWER_DOWN == mode ) powerUp();
00271 
00272     int config = getRegister(_NRF24L01P_REG_CONFIG);
00273 
00274     config &= ~_NRF24L01P_CONFIG_PRIM_RX;
00275 
00276     setRegister(_NRF24L01P_REG_CONFIG, config);
00277 
00278     mode = _NRF24L01P_MODE_TX;
00279 
00280 }
00281 
00282 
00283 void nRF24L01P::enable(void) {
00284 
00285     ce_ = 1;
00286     wait_us( _NRF24L01P_TIMING_Tpece2csn_us );
00287 
00288 }
00289 
00290 
00291 void nRF24L01P::disable(void) {
00292 
00293     ce_ = 0;
00294 
00295 }
00296 
00297 void nRF24L01P::setRfFrequency(int frequency) {
00298 
00299     if ( ( frequency < NRF24L01P_MIN_RF_FREQUENCY ) || ( frequency > NRF24L01P_MAX_RF_FREQUENCY ) ) {
00300 
00301         error( "nRF24L01P: Invalid RF Frequency setting %d\r\n", frequency );
00302         return;
00303 
00304     }
00305 
00306     int channel = ( frequency - NRF24L01P_MIN_RF_FREQUENCY ) & 0x7F;
00307 
00308     setRegister(_NRF24L01P_REG_RF_CH, channel);
00309 
00310 }
00311 
00312 
00313 int nRF24L01P::getRfFrequency(void) {
00314 
00315     int channel = getRegister(_NRF24L01P_REG_RF_CH) & 0x7F;
00316 
00317     return ( channel + NRF24L01P_MIN_RF_FREQUENCY );
00318 
00319 }
00320 
00321 
00322 void nRF24L01P::setRfOutputPower(int power) {
00323 
00324     int rfSetup = getRegister(_NRF24L01P_REG_RF_SETUP) & ~_NRF24L01P_RF_SETUP_RF_PWR_MASK;
00325 
00326     switch ( power ) {
00327 
00328         case NRF24L01P_TX_PWR_ZERO_DB:
00329             rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_0DBM;
00330             break;
00331 
00332         case NRF24L01P_TX_PWR_MINUS_6_DB:
00333             rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_MINUS_6DBM;
00334             break;
00335 
00336         case NRF24L01P_TX_PWR_MINUS_12_DB:
00337             rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_MINUS_12DBM;
00338             break;
00339 
00340         case NRF24L01P_TX_PWR_MINUS_18_DB:
00341             rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_MINUS_18DBM;
00342             break;
00343 
00344         default:
00345             error( "nRF24L01P: Invalid RF Output Power setting %d\r\n", power );
00346             return;
00347 
00348     }
00349 
00350     setRegister(_NRF24L01P_REG_RF_SETUP, rfSetup);
00351 
00352 }
00353 
00354 
00355 int nRF24L01P::getRfOutputPower(void) {
00356 
00357     int rfPwr = getRegister(_NRF24L01P_REG_RF_SETUP) & _NRF24L01P_RF_SETUP_RF_PWR_MASK;
00358 
00359     switch ( rfPwr ) {
00360 
00361         case _NRF24L01P_RF_SETUP_RF_PWR_0DBM:
00362             return NRF24L01P_TX_PWR_ZERO_DB;
00363 
00364         case _NRF24L01P_RF_SETUP_RF_PWR_MINUS_6DBM:
00365             return NRF24L01P_TX_PWR_MINUS_6_DB;
00366 
00367         case _NRF24L01P_RF_SETUP_RF_PWR_MINUS_12DBM:
00368             return NRF24L01P_TX_PWR_MINUS_12_DB;
00369 
00370         case _NRF24L01P_RF_SETUP_RF_PWR_MINUS_18DBM:
00371             return NRF24L01P_TX_PWR_MINUS_18_DB;
00372 
00373         default:
00374             error( "nRF24L01P: Unknown RF Output Power value %d\r\n", rfPwr );
00375             return 0;
00376 
00377     }
00378 }
00379 
00380 
00381 void nRF24L01P::setAirDataRate(int rate) {
00382 
00383     int rfSetup = getRegister(_NRF24L01P_REG_RF_SETUP) & ~_NRF24L01P_RF_SETUP_RF_DR_MASK;
00384 
00385     switch ( rate ) {
00386 
00387         case NRF24L01P_DATARATE_250_KBPS:
00388             rfSetup |= _NRF24L01P_RF_SETUP_RF_DR_250KBPS;
00389             break;
00390 
00391         case NRF24L01P_DATARATE_1_MBPS:
00392             rfSetup |= _NRF24L01P_RF_SETUP_RF_DR_1MBPS;
00393             break;
00394 
00395         case NRF24L01P_DATARATE_2_MBPS:
00396             rfSetup |= _NRF24L01P_RF_SETUP_RF_DR_2MBPS;
00397             break;
00398 
00399         default:
00400             error( "nRF24L01P: Invalid Air Data Rate setting %d\r\n", rate );
00401             return;
00402 
00403     }
00404 
00405     setRegister(_NRF24L01P_REG_RF_SETUP, rfSetup);
00406 
00407 }
00408 
00409 
00410 int nRF24L01P::getAirDataRate(void) {
00411 
00412     int rfDataRate = getRegister(_NRF24L01P_REG_RF_SETUP) & _NRF24L01P_RF_SETUP_RF_DR_MASK;
00413 
00414     switch ( rfDataRate ) {
00415 
00416         case _NRF24L01P_RF_SETUP_RF_DR_250KBPS:
00417             return NRF24L01P_DATARATE_250_KBPS;
00418 
00419         case _NRF24L01P_RF_SETUP_RF_DR_1MBPS:
00420             return NRF24L01P_DATARATE_1_MBPS;
00421 
00422         case _NRF24L01P_RF_SETUP_RF_DR_2MBPS:
00423             return NRF24L01P_DATARATE_2_MBPS;
00424 
00425         default:
00426             error( "nRF24L01P: Unknown Air Data Rate value %d\r\n", rfDataRate );
00427             return 0;
00428 
00429     }
00430 }
00431 
00432 
00433 void nRF24L01P::setCrcWidth(int width) {
00434 
00435     int config = getRegister(_NRF24L01P_REG_CONFIG) & ~_NRF24L01P_CONFIG_CRC_MASK;
00436 
00437     switch ( width ) {
00438 
00439         case NRF24L01P_CRC_NONE:
00440             config |= _NRF24L01P_CONFIG_CRC_NONE;
00441             break;
00442 
00443         case NRF24L01P_CRC_8_BIT:
00444             config |= _NRF24L01P_CONFIG_CRC_8BIT;
00445             break;
00446 
00447         case NRF24L01P_CRC_16_BIT:
00448             config |= _NRF24L01P_CONFIG_CRC_16BIT;
00449             break;
00450 
00451         default:
00452             error( "nRF24L01P: Invalid CRC Width setting %d\r\n", width );
00453             return;
00454 
00455     }
00456 
00457     setRegister(_NRF24L01P_REG_CONFIG, config);
00458 
00459 }
00460 
00461 
00462 int nRF24L01P::getCrcWidth(void) {
00463 
00464     int crcWidth = getRegister(_NRF24L01P_REG_CONFIG) & _NRF24L01P_CONFIG_CRC_MASK;
00465 
00466     switch ( crcWidth ) {
00467 
00468         case _NRF24L01P_CONFIG_CRC_NONE:
00469             return NRF24L01P_CRC_NONE;
00470 
00471         case _NRF24L01P_CONFIG_CRC_8BIT:
00472             return NRF24L01P_CRC_8_BIT;
00473 
00474         case _NRF24L01P_CONFIG_CRC_16BIT:
00475             return NRF24L01P_CRC_16_BIT;
00476 
00477         default:
00478             error( "nRF24L01P: Unknown CRC Width value %d\r\n", crcWidth );
00479             return 0;
00480 
00481     }
00482 }
00483 
00484 
00485 void nRF24L01P::setTransferSize(int size, int pipe) {
00486 
00487     if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
00488 
00489         error( "nRF24L01P: Invalid Transfer Size pipe number %d\r\n", pipe );
00490         return;
00491 
00492     }
00493 
00494     if ( ( size < 0 ) || ( size > _NRF24L01P_RX_FIFO_SIZE ) ) {
00495 
00496         error( "nRF24L01P: Invalid Transfer Size setting %d\r\n", size );
00497         return;
00498 
00499     }
00500 
00501     int rxPwPxRegister = _NRF24L01P_REG_RX_PW_P0 + ( pipe - NRF24L01P_PIPE_P0 );
00502 
00503     setRegister(rxPwPxRegister, ( size & _NRF24L01P_RX_PW_Px_MASK ) );
00504 
00505 }
00506 
00507 
00508 int nRF24L01P::getTransferSize(int pipe) {
00509 
00510     if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
00511 
00512         error( "nRF24L01P: Invalid Transfer Size pipe number %d\r\n", pipe );
00513         return 0;
00514 
00515     }
00516 
00517     int rxPwPxRegister = _NRF24L01P_REG_RX_PW_P0 + ( pipe - NRF24L01P_PIPE_P0 );
00518 
00519     int size = getRegister(rxPwPxRegister);
00520     
00521     return ( size & _NRF24L01P_RX_PW_Px_MASK );
00522 
00523 }
00524 
00525 
00526 void nRF24L01P::disableAllRxPipes(void) {
00527 
00528     setRegister(_NRF24L01P_REG_EN_RXADDR, _NRF24L01P_EN_RXADDR_NONE);
00529 
00530 }
00531 
00532 
00533 void nRF24L01P::disableAutoAcknowledge(void) {
00534 
00535     setRegister(_NRF24L01P_REG_EN_AA, _NRF24L01P_EN_AA_NONE);
00536 
00537 }
00538 
00539 
00540 void nRF24L01P::enableAutoAcknowledge(int pipe) {
00541 
00542     if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
00543 
00544         error( "nRF24L01P: Invalid Enable AutoAcknowledge pipe number %d\r\n", pipe );
00545         return;
00546 
00547     }
00548 
00549     int enAA = getRegister(_NRF24L01P_REG_EN_AA);
00550 
00551     enAA |= ( 1 << (pipe - NRF24L01P_PIPE_P0) );
00552 
00553     setRegister(_NRF24L01P_REG_EN_AA, enAA);
00554 
00555 }
00556 
00557 
00558 void nRF24L01P::disableAutoRetransmit(void) {
00559 
00560     setRegister(_NRF24L01P_REG_SETUP_RETR, _NRF24L01P_SETUP_RETR_NONE);
00561 
00562 }
00563 
00564 void nRF24L01P::setRxAddress(unsigned long long address, int width, int pipe) {
00565 
00566     if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
00567 
00568         error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe );
00569         return;
00570 
00571     }
00572 
00573     if ( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) {
00574 
00575         int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & ~_NRF24L01P_SETUP_AW_AW_MASK;
00576     
00577         switch ( width ) {
00578     
00579             case 3:
00580                 setupAw |= _NRF24L01P_SETUP_AW_AW_3BYTE;
00581                 break;
00582     
00583             case 4:
00584                 setupAw |= _NRF24L01P_SETUP_AW_AW_4BYTE;
00585                 break;
00586     
00587             case 5:
00588                 setupAw |= _NRF24L01P_SETUP_AW_AW_5BYTE;
00589                 break;
00590     
00591             default:
00592                 error( "nRF24L01P: Invalid setRxAddress width setting %d\r\n", width );
00593                 return;
00594     
00595         }
00596     
00597         setRegister(_NRF24L01P_REG_SETUP_AW, setupAw);
00598 
00599     } else {
00600     
00601         width = 1;
00602     
00603     }
00604 
00605     int rxAddrPxRegister = _NRF24L01P_REG_RX_ADDR_P0 + ( pipe - NRF24L01P_PIPE_P0 );
00606 
00607     int cn = (_NRF24L01P_SPI_CMD_WR_REG | (rxAddrPxRegister & _NRF24L01P_REG_ADDRESS_MASK));
00608 
00609     nCS_ = 0;
00610 
00611     int status = spi_.write(cn);
00612 
00613     while ( width-- > 0 ) {
00614 
00615         //
00616         // LSByte first
00617         //
00618         spi_.write((int) (address & 0xFF));
00619         address >>= 8;
00620 
00621     }
00622 
00623     nCS_ = 1;
00624 
00625     int enRxAddr = getRegister(_NRF24L01P_REG_EN_RXADDR);
00626 
00627     enRxAddr |= (1 << ( pipe - NRF24L01P_PIPE_P0 ) );
00628 
00629     setRegister(_NRF24L01P_REG_EN_RXADDR, enRxAddr);
00630 }
00631 
00632 /*
00633  * This version of setRxAddress is just a wrapper for the version that takes 'long long's,
00634  *  in case the main code doesn't want to deal with long long's.
00635  */
00636 void nRF24L01P::setRxAddress(unsigned long msb_address, unsigned long lsb_address, int width, int pipe) {
00637 
00638     unsigned long long address = ( ( (unsigned long long) msb_address ) << 32 ) | ( ( (unsigned long long) lsb_address ) << 0 );
00639 
00640     setRxAddress(address, width, pipe);
00641 
00642 }
00643 
00644 
00645 /*
00646  * This version of setTxAddress is just a wrapper for the version that takes 'long long's,
00647  *  in case the main code doesn't want to deal with long long's.
00648  */
00649 void nRF24L01P::setTxAddress(unsigned long msb_address, unsigned long lsb_address, int width) {
00650 
00651     unsigned long long address = ( ( (unsigned long long) msb_address ) << 32 ) | ( ( (unsigned long long) lsb_address ) << 0 );
00652 
00653     setTxAddress(address, width);
00654 
00655 }
00656 
00657 
00658 void nRF24L01P::setTxAddress(unsigned long long address, int width) {
00659 
00660     int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & ~_NRF24L01P_SETUP_AW_AW_MASK;
00661 
00662     switch ( width ) {
00663 
00664         case 3:
00665             setupAw |= _NRF24L01P_SETUP_AW_AW_3BYTE;
00666             break;
00667 
00668         case 4:
00669             setupAw |= _NRF24L01P_SETUP_AW_AW_4BYTE;
00670             break;
00671 
00672         case 5:
00673             setupAw |= _NRF24L01P_SETUP_AW_AW_5BYTE;
00674             break;
00675 
00676         default:
00677             error( "nRF24L01P: Invalid setTxAddress width setting %d\r\n", width );
00678             return;
00679 
00680     }
00681 
00682     setRegister(_NRF24L01P_REG_SETUP_AW, setupAw);
00683 
00684     int cn = (_NRF24L01P_SPI_CMD_WR_REG | (_NRF24L01P_REG_TX_ADDR & _NRF24L01P_REG_ADDRESS_MASK));
00685 
00686     nCS_ = 0;
00687 
00688     int status = spi_.write(cn);
00689 
00690     while ( width-- > 0 ) {
00691 
00692         //
00693         // LSByte first
00694         //
00695         spi_.write((int) (address & 0xFF));
00696         address >>= 8;
00697 
00698     }
00699 
00700     nCS_ = 1;
00701 
00702 }
00703 
00704 
00705 unsigned long long nRF24L01P::getRxAddress(int pipe) {
00706 
00707     if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
00708 
00709         error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe );
00710         return 0;
00711 
00712     }
00713 
00714     int width;
00715 
00716     if ( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) {
00717 
00718         int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & _NRF24L01P_SETUP_AW_AW_MASK;
00719 
00720         switch ( setupAw ) {
00721 
00722             case _NRF24L01P_SETUP_AW_AW_3BYTE:
00723                 width = 3;
00724                 break;
00725 
00726             case _NRF24L01P_SETUP_AW_AW_4BYTE:
00727                 width = 4;
00728                 break;
00729 
00730             case _NRF24L01P_SETUP_AW_AW_5BYTE:
00731                 width = 5;
00732                 break;
00733 
00734             default:
00735                 error( "nRF24L01P: Unknown getRxAddress width value %d\r\n", setupAw );
00736                 return 0;
00737 
00738         }
00739 
00740     } else {
00741 
00742         width = 1;
00743 
00744     }
00745 
00746     int rxAddrPxRegister = _NRF24L01P_REG_RX_ADDR_P0 + ( pipe - NRF24L01P_PIPE_P0 );
00747 
00748     int cn = (_NRF24L01P_SPI_CMD_RD_REG | (rxAddrPxRegister & _NRF24L01P_REG_ADDRESS_MASK));
00749 
00750     unsigned long long address = 0;
00751 
00752     nCS_ = 0;
00753 
00754     int status = spi_.write(cn);
00755 
00756     for ( int i=0; i<width; i++ ) {
00757 
00758         //
00759         // LSByte first
00760         //
00761         address |= ( ( (unsigned long long)( spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF ) ) << (i*8) );
00762 
00763     }
00764 
00765     nCS_ = 1;
00766 
00767     if ( !( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) ) {
00768 
00769         address |= ( getRxAddress(NRF24L01P_PIPE_P1) & ~((unsigned long long) 0xFF) );
00770 
00771     }
00772 
00773     return address;
00774 
00775 }
00776 
00777     
00778 unsigned long long nRF24L01P::getTxAddress(void) {
00779 
00780     int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & _NRF24L01P_SETUP_AW_AW_MASK;
00781 
00782     int width;
00783 
00784     switch ( setupAw ) {
00785 
00786         case _NRF24L01P_SETUP_AW_AW_3BYTE:
00787             width = 3;
00788             break;
00789 
00790         case _NRF24L01P_SETUP_AW_AW_4BYTE:
00791             width = 4;
00792             break;
00793 
00794         case _NRF24L01P_SETUP_AW_AW_5BYTE:
00795             width = 5;
00796             break;
00797 
00798         default:
00799             error( "nRF24L01P: Unknown getTxAddress width value %d\r\n", setupAw );
00800             return 0;
00801 
00802     }
00803 
00804     int cn = (_NRF24L01P_SPI_CMD_RD_REG | (_NRF24L01P_REG_TX_ADDR & _NRF24L01P_REG_ADDRESS_MASK));
00805 
00806     unsigned long long address = 0;
00807 
00808     nCS_ = 0;
00809 
00810     int status = spi_.write(cn);
00811 
00812     for ( int i=0; i<width; i++ ) {
00813 
00814         //
00815         // LSByte first
00816         //
00817         address |= ( ( (unsigned long long)( spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF ) ) << (i*8) );
00818 
00819     }
00820 
00821     nCS_ = 1;
00822 
00823     return address;
00824 }
00825 
00826 
00827 bool nRF24L01P::readable(int pipe) {
00828 
00829     if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
00830 
00831         error( "nRF24L01P: Invalid readable pipe number %d\r\n", pipe );
00832         return false;
00833 
00834     }
00835 
00836     int status = getStatusRegister();
00837 
00838     return ( ( status & _NRF24L01P_STATUS_RX_DR ) && ( ( ( status & _NRF24L01P_STATUS_RX_P_NO ) >> 1 ) == ( pipe & 0x7 ) ) );
00839 
00840 }
00841 
00842 
00843 int nRF24L01P::write(int pipe, char *data, int count) {
00844 
00845     // Note: the pipe number is ignored in a Transmit / write
00846 
00847     //
00848     // Save the CE state
00849     //
00850     int originalCe = ce_;
00851     disable();
00852 
00853     if ( count <= 0 ) return 0;
00854 
00855     if ( count > _NRF24L01P_TX_FIFO_SIZE ) count = _NRF24L01P_TX_FIFO_SIZE;
00856 
00857     // Clear the Status bit
00858     setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_TX_DS);
00859 
00860     nCS_ = 0;
00861     int status = spi_.write(_NRF24L01P_SPI_CMD_WR_TX_PAYLOAD);
00862     //int status = spi_.write(_NRF24L01P_SPI_CMD_W_ACK_PAYLOAD);
00863     for ( int i = 0; i < count; i++ ) {
00864 
00865         spi_.write(*data++);
00866 
00867     }
00868 
00869     nCS_ = 1;
00870 
00871     int originalMode = mode;
00872     setTransmitMode();
00873 
00874     enable();
00875     wait_us(_NRF24L01P_TIMING_Thce_us);
00876     disable();
00877 
00878     while ( !( getStatusRegister() & _NRF24L01P_STATUS_TX_DS ) ) {
00879 
00880         // Wait for the transfer to complete
00881 
00882     }
00883 
00884     // Clear the Status bit
00885     setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_TX_DS);
00886 
00887     if ( originalMode == _NRF24L01P_MODE_RX ) {
00888 
00889         setReceiveMode();
00890 
00891     }
00892 
00893     ce_ = originalCe;
00894     wait_us( _NRF24L01P_TIMING_Tpece2csn_us );
00895 
00896     return count;
00897 
00898 }
00899 
00900 
00901 int nRF24L01P::read(int pipe, char *data, int count) {
00902 
00903     if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
00904 
00905         error( "nRF24L01P: Invalid read pipe number %d\r\n", pipe );
00906         return -1;
00907 
00908     }
00909 
00910     if ( count <= 0 ) return 0;
00911 
00912     if ( count > _NRF24L01P_RX_FIFO_SIZE ) count = _NRF24L01P_RX_FIFO_SIZE;
00913 
00914     if ( readable(pipe) ) {
00915 
00916         nCS_ = 0;
00917 
00918         int status = spi_.write(_NRF24L01P_SPI_CMD_R_RX_PL_WID);
00919 
00920         int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP);
00921         
00922         nCS_ = 1;
00923 
00924         if ( ( rxPayloadWidth < 0 ) || ( rxPayloadWidth > _NRF24L01P_RX_FIFO_SIZE ) ) {
00925     
00926             // Received payload error: need to flush the FIFO
00927 
00928             nCS_ = 0;
00929     
00930             int status = spi_.write(_NRF24L01P_SPI_CMD_FLUSH_RX);
00931     
00932             int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP);
00933             
00934             nCS_ = 1;
00935             
00936             //
00937             // At this point, we should retry the reception,
00938             //  but for now we'll just fall through...
00939             //
00940 
00941         } else {
00942 
00943             if ( rxPayloadWidth < count ) count = rxPayloadWidth;
00944 
00945             nCS_ = 0;
00946         
00947             int status = spi_.write(_NRF24L01P_SPI_CMD_RD_RX_PAYLOAD);
00948         
00949             for ( int i = 0; i < count; i++ ) {
00950         
00951                 *data++ = spi_.write(_NRF24L01P_SPI_CMD_NOP);
00952         
00953             }
00954 
00955             nCS_ = 1;
00956 
00957             // Clear the Status bit
00958             setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_RX_DR);
00959 
00960             return count;
00961 
00962         }
00963 
00964     } else {
00965 
00966         //
00967         // What should we do if there is no 'readable' data?
00968         //  We could wait for data to arrive, but for now, we'll
00969         //  just return with no data.
00970         //
00971         return 0;
00972 
00973     }
00974 
00975     //
00976     // We get here because an error condition occured;
00977     //  We could wait for data to arrive, but for now, we'll
00978     //  just return with no data.
00979     //
00980     return -1;
00981 
00982 }
00983 
00984 
00985 void nRF24L01P::enableAutoRetransmit(int delay, int count) {
00986     if(count > 15) {
00987         count = 15;
00988     }
00989     if((0!=(delay % 250)) || (delay > 4000)) {
00990         return; 
00991     }
00992 
00993     setRegister(_NRF24L01P_REG_SETUP_RETR, 0x4A);
00994 }
00995 
00996 
00997 void nRF24L01P::setRegister(int regAddress, int regData) {
00998 
00999     //
01000     // Save the CE state
01001     //
01002     int originalCe = ce_;
01003     disable();
01004 
01005     int cn = (_NRF24L01P_SPI_CMD_WR_REG | (regAddress & _NRF24L01P_REG_ADDRESS_MASK));
01006 
01007     nCS_ = 0;
01008 
01009     int status = spi_.write(cn);
01010 
01011     spi_.write(regData & 0xFF);
01012 
01013     nCS_ = 1;
01014 
01015     ce_ = originalCe;
01016     wait_us( _NRF24L01P_TIMING_Tpece2csn_us );
01017 
01018 }
01019 
01020 
01021 int nRF24L01P::getRegister(int regAddress) {
01022 
01023     int cn = (_NRF24L01P_SPI_CMD_RD_REG | (regAddress & _NRF24L01P_REG_ADDRESS_MASK));
01024 
01025     nCS_ = 0;
01026 
01027     int status = spi_.write(cn);
01028 
01029     int dn = spi_.write(_NRF24L01P_SPI_CMD_NOP);
01030 
01031     nCS_ = 1;
01032 
01033     return dn;
01034 
01035 }
01036 
01037 int nRF24L01P::getStatusRegister(void) {
01038 
01039     nCS_ = 0;
01040 
01041     int status = spi_.write(_NRF24L01P_SPI_CMD_NOP);
01042 
01043     nCS_ = 1;
01044 
01045     return status;
01046 
01047 }