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

« Back to documentation index

Show/hide line numbers RH_NRF905.cpp Source File

RH_NRF905.cpp

00001 // RH_NRF905.cpp
00002 //
00003 // Copyright (C) 2012 Mike McCauley
00004 // $Id: RH_NRF905.cpp,v 1.5 2015/08/12 23:18:51 mikem Exp $
00005 
00006 #include <RH_NRF905.h>
00007 
00008 RH_NRF905::RH_NRF905(PINS chipEnablePin, PINS txEnablePin, PINS slaveSelectPin, RHGenericSPI& spi)
00009     :
00010     RHNRFSPIDriver(slaveSelectPin, spi)
00011 {
00012     _chipEnablePin = chipEnablePin;
00013     _txEnablePin   = txEnablePin;
00014 }
00015 
00016 bool RH_NRF905::init()
00017 {
00018 #if defined (__MK20DX128__) || defined (__MK20DX256__)
00019     // Teensy is unreliable at 8MHz:
00020     _spi.setFrequency(RHGenericSPI::Frequency1MHz);
00021 #else
00022     _spi.setFrequency(RHGenericSPI::Frequency8MHz);
00023 #endif
00024     if (!RHNRFSPIDriver::init())
00025     return false;
00026 
00027     // Initialise the slave select pin and the tx Enable pin
00028 #if (RH_PLATFORM != RH_PLATFORM_MBED)
00029     pinMode(_chipEnablePin, OUTPUT);
00030     pinMode(_txEnablePin, OUTPUT);
00031 #endif
00032     digitalWrite(_chipEnablePin, LOW);
00033     digitalWrite(_txEnablePin, LOW);
00034 
00035     // Configure the chip
00036     // CRC 16 bits enabled. 16MHz crystal freq
00037     spiWriteRegister(RH_NRF905_CONFIG_9, RH_NRF905_CONFIG_9_CRC_EN | RH_NRF905_CONFIG_9_CRC_MODE_16BIT | RH_NRF905_CONFIG_9_XOF_16MHZ);
00038 
00039     // Make sure we are powered down
00040     setModeIdle();
00041 
00042     // Some innocuous defaults
00043     setChannel(108, LOW); // 433.2 MHz
00044     setRF(RH_NRF905::TransmitPowerm10dBm);
00045 
00046     return true;
00047 }
00048 
00049 // Use the register commands to read and write the registers
00050 uint8_t RH_NRF905::spiReadRegister(uint8_t reg)
00051 {
00052     return spiRead((reg & RH_NRF905_REG_MASK) | RH_NRF905_REG_R_CONFIG);
00053 }
00054 
00055 uint8_t RH_NRF905::spiWriteRegister(uint8_t reg, uint8_t val)
00056 {
00057     return spiWrite((reg & RH_NRF905_REG_MASK) | RH_NRF905_REG_W_CONFIG, val);
00058 }
00059 
00060 uint8_t RH_NRF905::spiBurstReadRegister(uint8_t reg, uint8_t* dest, uint8_t len)
00061 {
00062     return spiBurstRead((reg & RH_NRF905_REG_MASK) | RH_NRF905_REG_R_CONFIG, dest, len);
00063 }
00064 
00065 uint8_t RH_NRF905::spiBurstWriteRegister(uint8_t reg, uint8_t* src, uint8_t len)
00066 {
00067     return spiBurstWrite((reg & RH_NRF905_REG_MASK) | RH_NRF905_REG_W_CONFIG, src, len);
00068 }
00069 
00070 uint8_t RH_NRF905::statusRead()
00071 {
00072     // The status is a byproduct of sending a command
00073     return spiCommand(0);
00074 }
00075 
00076 bool RH_NRF905::setChannel(uint16_t channel, bool hiFrequency)
00077 {
00078     spiWriteRegister(RH_NRF905_CONFIG_0, channel & RH_NRF905_CONFIG_0_CH_NO);
00079     // Set or clear the high bit of the channel
00080     uint8_t bit8 = (channel >> 8) & 0x01;
00081     uint8_t reg1 = spiReadRegister(RH_NRF905_CONFIG_1);
00082     reg1 = (reg1 & ~0x01) | bit8;
00083     // Set or clear the HFREQ_PLL bit
00084     reg1 &= ~RH_NRF905_CONFIG_1_HFREQ_PLL;
00085     if (hiFrequency)
00086     reg1 |= RH_NRF905_CONFIG_1_HFREQ_PLL;
00087     spiWriteRegister(RH_NRF905_CONFIG_1, reg1);
00088     return true;
00089 }
00090 
00091 bool RH_NRF905::setNetworkAddress(uint8_t* address, uint8_t len)
00092 {
00093     if (len < 1 || len > 4)
00094     return false;
00095     // Set RX_AFW and TX_AFW
00096     spiWriteRegister(RH_NRF905_CONFIG_2, len | (len << 4));
00097     spiBurstWrite(RH_NRF905_REG_W_TX_ADDRESS, address, len);
00098     spiBurstWriteRegister(RH_NRF905_CONFIG_5, address, len);
00099     return true;
00100 }
00101 
00102 bool RH_NRF905::setRF(TransmitPower power)
00103 {
00104     // Enum definitions of power are the same numerical values as the register
00105     spiWriteRegister(RH_NRF905_CONFIG_1_PA_PWR, power);
00106     return true;
00107 }
00108 
00109 void RH_NRF905::setModeIdle()
00110 {
00111     if (_mode != RHModeIdle)
00112     {
00113     digitalWrite(_chipEnablePin, LOW);
00114     digitalWrite(_txEnablePin, LOW);
00115     _mode = RHModeIdle;
00116     }
00117 }
00118 
00119 void RH_NRF905::setModeRx()
00120 {
00121     if (_mode != RHModeRx)
00122     {
00123     digitalWrite(_txEnablePin, LOW);
00124     digitalWrite(_chipEnablePin, HIGH);
00125     _mode = RHModeRx;
00126     }
00127 }
00128 
00129 void RH_NRF905::setModeTx()
00130 {
00131     if (_mode != RHModeTx)
00132     {
00133     // Its the high transition that puts us into TX mode
00134     digitalWrite(_txEnablePin, HIGH);
00135     digitalWrite(_chipEnablePin, HIGH);
00136     _mode = RHModeTx;
00137     }
00138 }
00139 
00140 bool RH_NRF905::send(const uint8_t* data, uint8_t len)
00141 {
00142     if (len > RH_NRF905_MAX_MESSAGE_LEN)
00143     return false;
00144     // Set up the headers
00145     _buf[0] = _txHeaderTo;
00146     _buf[1] = _txHeaderFrom;
00147     _buf[2] = _txHeaderId;
00148     _buf[3] = _txHeaderFlags;
00149     _buf[4] = len;
00150     memcpy(_buf+RH_NRF905_HEADER_LEN, data, len);
00151     spiBurstWrite(RH_NRF905_REG_W_TX_PAYLOAD, _buf, len + RH_NRF905_HEADER_LEN);
00152     setModeTx();
00153     // Radio will return to Standby mode after transmission is complete
00154     _txGood++;
00155     return true;
00156 }
00157 
00158 bool RH_NRF905::waitPacketSent()
00159 {
00160     if (_mode != RHModeTx)
00161     return false;
00162 
00163     while (!(statusRead() & RH_NRF905_STATUS_DR))
00164     YIELD;
00165     setModeIdle();
00166     return true;
00167 }
00168 
00169 bool RH_NRF905::isSending()
00170 {
00171     if (_mode != RHModeTx)
00172     return false;
00173     
00174     return !(statusRead() & RH_NRF905_STATUS_DR);
00175 }
00176 
00177 bool RH_NRF905::printRegister(uint8_t reg)
00178 {
00179 #ifdef RH_HAVE_SERIAL
00180     Serial.print(reg, HEX);
00181     Serial.print(": ");
00182     Serial.println(spiReadRegister(reg), HEX);
00183 #endif
00184 
00185     return true;
00186 }
00187 
00188 bool RH_NRF905::printRegisters()
00189 {
00190     uint8_t registers[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
00191 
00192     uint8_t i;
00193     for (i = 0; i < sizeof(registers); i++)
00194     printRegister(registers[i]);
00195     return true;
00196 }
00197 
00198 // Check whether the latest received message is complete and uncorrupted
00199 void RH_NRF905::validateRxBuf()
00200 {
00201     // Check the length
00202     uint8_t len = _buf[4];
00203     if (len > RH_NRF905_MAX_MESSAGE_LEN)
00204     return; // Silly LEN header
00205 
00206     // Extract the 4 headers
00207     _rxHeaderTo    = _buf[0];
00208     _rxHeaderFrom  = _buf[1];
00209     _rxHeaderId    = _buf[2];
00210     _rxHeaderFlags = _buf[3];
00211     if (_promiscuous ||
00212     _rxHeaderTo == _thisAddress ||
00213     _rxHeaderTo == RH_BROADCAST_ADDRESS)
00214     {
00215     _rxGood++;
00216     _bufLen = len + RH_NRF905_HEADER_LEN; // _buf still includes the headers
00217     _rxBufValid = true;
00218     }
00219 }
00220 
00221 bool RH_NRF905::available()
00222 {
00223     if (!_rxBufValid)
00224     {
00225     if (_mode == RHModeTx)
00226         return false;
00227     setModeRx();
00228     if (!(statusRead() & RH_NRF905_STATUS_DR))
00229         return false;
00230     // Get the message into the RX buffer, so we can inspect the headers
00231     // we still dont know how long is the user message
00232     spiBurstRead(RH_NRF905_REG_R_RX_PAYLOAD, _buf, RH_NRF905_MAX_PAYLOAD_LEN);
00233     validateRxBuf(); 
00234     if (_rxBufValid)
00235         setModeIdle(); // Got one
00236     }
00237     return _rxBufValid;
00238 }
00239 
00240 void RH_NRF905::clearRxBuf()
00241 {
00242     _rxBufValid = false;
00243     _bufLen = 0;
00244 }
00245 
00246 bool RH_NRF905::recv(uint8_t* buf, uint8_t* len)
00247 {
00248     if (!available())
00249     return false;
00250     if (buf && len)
00251     {
00252     // Skip the 4 headers that are at the beginning of the rxBuf
00253     if (*len > _bufLen-RH_NRF905_HEADER_LEN)
00254         *len = _bufLen-RH_NRF905_HEADER_LEN;
00255     memcpy(buf, _buf+RH_NRF905_HEADER_LEN, *len);
00256     }
00257     clearRxBuf(); // This message accepted and cleared
00258     return true;
00259 }
00260 
00261 uint8_t RH_NRF905::maxMessageLength()
00262 {
00263     return RH_NRF905_MAX_MESSAGE_LEN;
00264 }