Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 }
Generated on Tue Jul 12 2022 18:05:55 by
1.7.2