David Rimer / RadioHead-148
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RH_NRF24.cpp Source File

RH_NRF24.cpp

00001 // NRF24.cpp
00002 //
00003 // Copyright (C) 2012 Mike McCauley
00004 // $Id: RH_NRF24.cpp,v 1.21 2015/03/29 03:53:47 mikem Exp $
00005 
00006 #include <RH_NRF24.h>
00007 
00008 RH_NRF24::RH_NRF24(PINS chipEnablePin, PINS slaveSelectPin, RHGenericSPI& spi)
00009     :
00010     RHNRFSPIDriver(slaveSelectPin, spi),
00011     _rxBufValid(0)
00012 {
00013     _configuration = RH_NRF24_EN_CRC | RH_NRF24_CRCO; // Default: 2 byte CRC enabled
00014     _chipEnablePin = chipEnablePin;
00015 }
00016 
00017 bool RH_NRF24::init()
00018 {
00019     // Teensy with nRF24 is unreliable at 8MHz:
00020     // so is Arduino with RF73
00021     _spi.setFrequency(RHGenericSPI::Frequency1MHz);
00022     if (!RHNRFSPIDriver::init())
00023     return false;
00024 
00025     // Initialise the slave select pin
00026 #if (RH_PLATFORM != RH_PLATFORM_MBED)
00027     pinMode(_chipEnablePin, OUTPUT);
00028 #endif
00029     digitalWrite(_chipEnablePin, LOW);
00030   
00031     // Clear interrupts
00032     spiWriteRegister(RH_NRF24_REG_07_STATUS, RH_NRF24_RX_DR | RH_NRF24_TX_DS | RH_NRF24_MAX_RT);
00033     // Enable dynamic payload length on all pipes
00034     spiWriteRegister(RH_NRF24_REG_1C_DYNPD, RH_NRF24_DPL_ALL);
00035     // Enable dynamic payload length, disable payload-with-ack, enable noack
00036     spiWriteRegister(RH_NRF24_REG_1D_FEATURE, RH_NRF24_EN_DPL | RH_NRF24_EN_DYN_ACK);
00037     // Test if there is actually a device connected and responding
00038     // CAUTION: RFM73 and version 2.0 silicon may require ACTIVATE
00039     if (spiReadRegister(RH_NRF24_REG_1D_FEATURE) != (RH_NRF24_EN_DPL | RH_NRF24_EN_DYN_ACK))
00040     { 
00041     spiWrite(RH_NRF24_COMMAND_ACTIVATE, 0x73);
00042         // Enable dynamic payload length, disable payload-with-ack, enable noack
00043         spiWriteRegister(RH_NRF24_REG_1D_FEATURE, RH_NRF24_EN_DPL | RH_NRF24_EN_DYN_ACK);
00044         if (spiReadRegister(RH_NRF24_REG_1D_FEATURE) != (RH_NRF24_EN_DPL | RH_NRF24_EN_DYN_ACK))
00045             return false;
00046     }
00047 
00048     // Make sure we are powered down
00049     setModeIdle();
00050 
00051     // Flush FIFOs
00052     flushTx();
00053     flushRx();
00054 
00055     setChannel(2); // The default, in case it was set by another app without powering down
00056     setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm);
00057 
00058     return true;
00059 }
00060 
00061 // Use the register commands to read and write the registers
00062 uint8_t RH_NRF24::spiReadRegister(uint8_t reg)
00063 {
00064     return spiRead((reg & RH_NRF24_REGISTER_MASK) | RH_NRF24_COMMAND_R_REGISTER);
00065 }
00066 
00067 uint8_t RH_NRF24::spiWriteRegister(uint8_t reg, uint8_t val)
00068 {
00069     return spiWrite((reg & RH_NRF24_REGISTER_MASK) | RH_NRF24_COMMAND_W_REGISTER, val);
00070 }
00071 
00072 uint8_t RH_NRF24::spiBurstReadRegister(uint8_t reg, uint8_t* dest, uint8_t len)
00073 {
00074     return spiBurstRead((reg & RH_NRF24_REGISTER_MASK) | RH_NRF24_COMMAND_R_REGISTER, dest, len);
00075 }
00076 
00077 uint8_t RH_NRF24::spiBurstWriteRegister(uint8_t reg, uint8_t* src, uint8_t len)
00078 {
00079     return spiBurstWrite((reg & RH_NRF24_REGISTER_MASK) | RH_NRF24_COMMAND_W_REGISTER, src, len);
00080 }
00081 
00082 uint8_t RH_NRF24::statusRead()
00083 {
00084     // status is a side-effect of NOP, faster than reading reg 07
00085     return spiCommand(RH_NRF24_COMMAND_NOP); 
00086 }
00087 
00088 uint8_t RH_NRF24::flushTx()
00089 {
00090     return spiCommand(RH_NRF24_COMMAND_FLUSH_TX);
00091 }
00092 
00093 uint8_t RH_NRF24::flushRx()
00094 {
00095     return spiCommand(RH_NRF24_COMMAND_FLUSH_RX);
00096 }
00097 
00098 bool RH_NRF24::setChannel(uint8_t channel)
00099 {
00100     spiWriteRegister(RH_NRF24_REG_05_RF_CH, channel & RH_NRF24_RF_CH);
00101     return true;
00102 }
00103 
00104 bool RH_NRF24::setOpMode(uint8_t mode)
00105 {
00106     _configuration = mode;
00107     return true;
00108 }
00109 
00110 bool RH_NRF24::setNetworkAddress(uint8_t* address, uint8_t len)
00111 {
00112     if (len < 3 || len > 5)
00113     return false;
00114 
00115     // Set both TX_ADDR and RX_ADDR_P0 for auto-ack with Enhanced shockwave
00116     spiWriteRegister(RH_NRF24_REG_03_SETUP_AW, len-2);  // Mapping [3..5] = [1..3]
00117     spiBurstWriteRegister(RH_NRF24_REG_0A_RX_ADDR_P0, address, len);
00118     spiBurstWriteRegister(RH_NRF24_REG_10_TX_ADDR, address, len);
00119     return true;
00120 }
00121 
00122 bool RH_NRF24::setRF(DataRate data_rate, TransmitPower power)
00123 {
00124     uint8_t value = (power << 1) & RH_NRF24_PWR;
00125     // Ugly mapping of data rates to noncontiguous 2 bits:
00126     if (data_rate == DataRate250kbps)
00127     value |= RH_NRF24_RF_DR_LOW;
00128     else if (data_rate == DataRate2Mbps)
00129     value |= RH_NRF24_RF_DR_HIGH;
00130     // else DataRate1Mbps, 00
00131 
00132     // RFM73 needs this:
00133     value |= RH_NRF24_LNA_HCURR;
00134     
00135     spiWriteRegister(RH_NRF24_REG_06_RF_SETUP, value);
00136     // If we were using auto-ack, we would have to set the appropriate timeout in reg 4 here
00137     // see NRF24::setRF()
00138     return true;
00139 }
00140 
00141 void RH_NRF24::setModeIdle()
00142 {
00143     if (_mode != RHModeIdle)
00144     {
00145     spiWriteRegister(RH_NRF24_REG_00_CONFIG, _configuration);
00146     digitalWrite(_chipEnablePin, LOW);
00147     _mode = RHModeIdle;
00148     }
00149 }
00150 
00151 bool RH_NRF24::sleep()
00152 {
00153     if (_mode != RHModeSleep)
00154     {
00155     spiWriteRegister(RH_NRF24_REG_00_CONFIG, 0); // Power Down mode
00156     digitalWrite(_chipEnablePin, LOW);
00157     _mode = RHModeSleep;
00158     }
00159 }
00160 
00161 void RH_NRF24::setModeRx()
00162 {
00163     if (_mode != RHModeRx)
00164     {
00165     spiWriteRegister(RH_NRF24_REG_00_CONFIG, _configuration | RH_NRF24_PWR_UP | RH_NRF24_PRIM_RX);
00166     digitalWrite(_chipEnablePin, HIGH);
00167     _mode = RHModeRx;
00168     }
00169 }
00170 
00171 void RH_NRF24::setModeTx()
00172 {
00173     if (_mode != RHModeTx)
00174     {
00175     // Its the CE rising edge that puts us into TX mode
00176     // CE staying high makes us go to standby-II when the packet is sent
00177     digitalWrite(_chipEnablePin, LOW);
00178     // Ensure DS is not set
00179     spiWriteRegister(RH_NRF24_REG_07_STATUS, RH_NRF24_TX_DS | RH_NRF24_MAX_RT);
00180     spiWriteRegister(RH_NRF24_REG_00_CONFIG, _configuration | RH_NRF24_PWR_UP);
00181     digitalWrite(_chipEnablePin, HIGH);
00182     _mode = RHModeTx;
00183     }
00184 }
00185 
00186 bool RH_NRF24::send(const uint8_t* data, uint8_t len)
00187 {
00188     if (len > RH_NRF24_MAX_MESSAGE_LEN)
00189     return false;
00190     // Set up the headers
00191     _buf[0] = _txHeaderTo;
00192     _buf[1] = _txHeaderFrom;
00193     _buf[2] = _txHeaderId;
00194     _buf[3] = _txHeaderFlags;
00195     memcpy(_buf+RH_NRF24_HEADER_LEN, data, len);
00196     spiBurstWrite(RH_NRF24_COMMAND_W_TX_PAYLOAD_NOACK, _buf, len + RH_NRF24_HEADER_LEN);
00197     setModeTx();
00198     // Radio will return to Standby II mode after transmission is complete
00199     _txGood++;
00200     return true;
00201 }
00202 
00203 bool RH_NRF24::waitPacketSent()
00204 {
00205     // If we are not currently in transmit mode, there is no packet to wait for
00206     if (_mode != RHModeTx)
00207     return false;
00208 
00209     // Wait for either the Data Sent or Max ReTries flag, signalling the 
00210     // end of transmission
00211     // We dont actually use auto-ack, so prob dont expect to see RH_NRF24_MAX_RT
00212     uint8_t status;
00213     while (!((status = statusRead()) & (RH_NRF24_TX_DS | RH_NRF24_MAX_RT)))
00214     YIELD;
00215 
00216     // Must clear RH_NRF24_MAX_RT if it is set, else no further comm
00217     if (status & RH_NRF24_MAX_RT)
00218     flushTx();
00219     setModeIdle();
00220     spiWriteRegister(RH_NRF24_REG_07_STATUS, RH_NRF24_TX_DS | RH_NRF24_MAX_RT);
00221     // Return true if data sent, false if MAX_RT
00222     return status & RH_NRF24_TX_DS;
00223 }
00224 
00225 bool RH_NRF24::isSending()
00226 {
00227     return !(spiReadRegister(RH_NRF24_REG_00_CONFIG) & RH_NRF24_PRIM_RX) && 
00228        !(statusRead() & (RH_NRF24_TX_DS | RH_NRF24_MAX_RT));
00229 }
00230 
00231 bool RH_NRF24::printRegisters()
00232 {
00233 #ifdef RH_HAVE_SERIAL
00234     // Iterate over register range, but don't process registers not in use.
00235     for (uint8_t r = RH_NRF24_REG_00_CONFIG; r <= RH_NRF24_REG_1D_FEATURE; r++)
00236     {
00237       if ((r <= RH_NRF24_REG_17_FIFO_STATUS) || (r >= RH_NRF24_REG_1C_DYNPD))
00238       {
00239         Serial.print(r, HEX);
00240         Serial.print(": ");
00241         uint8_t len = 1;
00242         // Address registers are 5 bytes in size
00243         if (    (RH_NRF24_REG_0A_RX_ADDR_P0 == r)
00244              || (RH_NRF24_REG_0B_RX_ADDR_P1 == r)
00245              || (RH_NRF24_REG_10_TX_ADDR    == r) )
00246         {
00247           len = 5;
00248         }
00249         uint8_t buf[5];
00250         spiBurstReadRegister(r, buf, len);
00251         for (uint8_t j = 0; j < len; ++j)
00252         {
00253           Serial.print(buf[j], HEX);
00254           Serial.print(" ");
00255         }
00256         Serial.println("");
00257       }
00258     }
00259 #endif
00260 
00261     return true;
00262 }
00263 
00264 // Check whether the latest received message is complete and uncorrupted
00265 void RH_NRF24::validateRxBuf()
00266 {
00267     if (_bufLen < 4)
00268     return; // Too short to be a real message
00269     // Extract the 4 headers
00270     _rxHeaderTo    = _buf[0];
00271     _rxHeaderFrom  = _buf[1];
00272     _rxHeaderId    = _buf[2];
00273     _rxHeaderFlags = _buf[3];
00274     if (_promiscuous ||
00275     _rxHeaderTo == _thisAddress ||
00276     _rxHeaderTo == RH_BROADCAST_ADDRESS)
00277     {
00278     _rxGood++;
00279     _rxBufValid = true;
00280     }
00281 }
00282 
00283 bool RH_NRF24::available()
00284 {
00285     if (!_rxBufValid)
00286     {
00287     if (_mode == RHModeTx)
00288         return false;
00289     setModeRx();
00290     if (spiReadRegister(RH_NRF24_REG_17_FIFO_STATUS) & RH_NRF24_RX_EMPTY)
00291         return false;
00292     // Manual says that messages > 32 octets should be discarded
00293     uint8_t len = spiRead(RH_NRF24_COMMAND_R_RX_PL_WID);
00294     if (len > 32)
00295     {
00296         flushRx();
00297         clearRxBuf();
00298         setModeIdle();
00299         return false;
00300     }
00301     // Clear read interrupt
00302     spiWriteRegister(RH_NRF24_REG_07_STATUS, RH_NRF24_RX_DR);
00303     // Get the message into the RX buffer, so we can inspect the headers
00304     spiBurstRead(RH_NRF24_COMMAND_R_RX_PAYLOAD, _buf, len);
00305     _bufLen = len;
00306     // 140 microsecs (32 octet payload)
00307     validateRxBuf(); 
00308     if (_rxBufValid)
00309         setModeIdle(); // Got one
00310     }
00311     return _rxBufValid;
00312 }
00313 
00314 void RH_NRF24::clearRxBuf()
00315 {
00316     _rxBufValid = false;
00317     _bufLen = 0;
00318 }
00319 
00320 bool RH_NRF24::recv(uint8_t* buf, uint8_t* len)
00321 {
00322     if (!available())
00323     return false;
00324     if (buf && len)
00325     {
00326     // Skip the 4 headers that are at the beginning of the rxBuf
00327     if (*len > _bufLen-RH_NRF24_HEADER_LEN)
00328         *len = _bufLen-RH_NRF24_HEADER_LEN;
00329     memcpy(buf, _buf+RH_NRF24_HEADER_LEN, *len);
00330     }
00331     clearRxBuf(); // This message accepted and cleared
00332     return true;
00333 }
00334 
00335 uint8_t RH_NRF24::maxMessageLength()
00336 {
00337     return RH_NRF24_MAX_MESSAGE_LEN;
00338 }