V148

Fork of RadioHead-148 by David Rimer

Committer:
ilkaykozak
Date:
Wed Oct 25 05:14:09 2017 +0000
Revision:
1:b7641da2b203
Parent:
0:ab4e012489ef
V148

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davidr99 0:ab4e012489ef 1 // RH_NRF905.cpp
davidr99 0:ab4e012489ef 2 //
davidr99 0:ab4e012489ef 3 // Copyright (C) 2012 Mike McCauley
davidr99 0:ab4e012489ef 4 // $Id: RH_NRF905.cpp,v 1.5 2015/08/12 23:18:51 mikem Exp $
davidr99 0:ab4e012489ef 5
davidr99 0:ab4e012489ef 6 #include <RH_NRF905.h>
davidr99 0:ab4e012489ef 7
davidr99 0:ab4e012489ef 8 RH_NRF905::RH_NRF905(PINS chipEnablePin, PINS txEnablePin, PINS slaveSelectPin, RHGenericSPI& spi)
davidr99 0:ab4e012489ef 9 :
davidr99 0:ab4e012489ef 10 RHNRFSPIDriver(slaveSelectPin, spi)
davidr99 0:ab4e012489ef 11 {
davidr99 0:ab4e012489ef 12 _chipEnablePin = chipEnablePin;
davidr99 0:ab4e012489ef 13 _txEnablePin = txEnablePin;
davidr99 0:ab4e012489ef 14 }
davidr99 0:ab4e012489ef 15
davidr99 0:ab4e012489ef 16 bool RH_NRF905::init()
davidr99 0:ab4e012489ef 17 {
davidr99 0:ab4e012489ef 18 #if defined (__MK20DX128__) || defined (__MK20DX256__)
davidr99 0:ab4e012489ef 19 // Teensy is unreliable at 8MHz:
davidr99 0:ab4e012489ef 20 _spi.setFrequency(RHGenericSPI::Frequency1MHz);
davidr99 0:ab4e012489ef 21 #else
davidr99 0:ab4e012489ef 22 _spi.setFrequency(RHGenericSPI::Frequency8MHz);
davidr99 0:ab4e012489ef 23 #endif
davidr99 0:ab4e012489ef 24 if (!RHNRFSPIDriver::init())
davidr99 0:ab4e012489ef 25 return false;
davidr99 0:ab4e012489ef 26
davidr99 0:ab4e012489ef 27 // Initialise the slave select pin and the tx Enable pin
davidr99 0:ab4e012489ef 28 #if (RH_PLATFORM != RH_PLATFORM_MBED)
davidr99 0:ab4e012489ef 29 pinMode(_chipEnablePin, OUTPUT);
davidr99 0:ab4e012489ef 30 pinMode(_txEnablePin, OUTPUT);
davidr99 0:ab4e012489ef 31 #endif
davidr99 0:ab4e012489ef 32 digitalWrite(_chipEnablePin, LOW);
davidr99 0:ab4e012489ef 33 digitalWrite(_txEnablePin, LOW);
davidr99 0:ab4e012489ef 34
davidr99 0:ab4e012489ef 35 // Configure the chip
davidr99 0:ab4e012489ef 36 // CRC 16 bits enabled. 16MHz crystal freq
davidr99 0:ab4e012489ef 37 spiWriteRegister(RH_NRF905_CONFIG_9, RH_NRF905_CONFIG_9_CRC_EN | RH_NRF905_CONFIG_9_CRC_MODE_16BIT | RH_NRF905_CONFIG_9_XOF_16MHZ);
davidr99 0:ab4e012489ef 38
davidr99 0:ab4e012489ef 39 // Make sure we are powered down
davidr99 0:ab4e012489ef 40 setModeIdle();
davidr99 0:ab4e012489ef 41
davidr99 0:ab4e012489ef 42 // Some innocuous defaults
davidr99 0:ab4e012489ef 43 setChannel(108, LOW); // 433.2 MHz
davidr99 0:ab4e012489ef 44 setRF(RH_NRF905::TransmitPowerm10dBm);
davidr99 0:ab4e012489ef 45
davidr99 0:ab4e012489ef 46 return true;
davidr99 0:ab4e012489ef 47 }
davidr99 0:ab4e012489ef 48
davidr99 0:ab4e012489ef 49 // Use the register commands to read and write the registers
davidr99 0:ab4e012489ef 50 uint8_t RH_NRF905::spiReadRegister(uint8_t reg)
davidr99 0:ab4e012489ef 51 {
davidr99 0:ab4e012489ef 52 return spiRead((reg & RH_NRF905_REG_MASK) | RH_NRF905_REG_R_CONFIG);
davidr99 0:ab4e012489ef 53 }
davidr99 0:ab4e012489ef 54
davidr99 0:ab4e012489ef 55 uint8_t RH_NRF905::spiWriteRegister(uint8_t reg, uint8_t val)
davidr99 0:ab4e012489ef 56 {
davidr99 0:ab4e012489ef 57 return spiWrite((reg & RH_NRF905_REG_MASK) | RH_NRF905_REG_W_CONFIG, val);
davidr99 0:ab4e012489ef 58 }
davidr99 0:ab4e012489ef 59
davidr99 0:ab4e012489ef 60 uint8_t RH_NRF905::spiBurstReadRegister(uint8_t reg, uint8_t* dest, uint8_t len)
davidr99 0:ab4e012489ef 61 {
davidr99 0:ab4e012489ef 62 return spiBurstRead((reg & RH_NRF905_REG_MASK) | RH_NRF905_REG_R_CONFIG, dest, len);
davidr99 0:ab4e012489ef 63 }
davidr99 0:ab4e012489ef 64
davidr99 0:ab4e012489ef 65 uint8_t RH_NRF905::spiBurstWriteRegister(uint8_t reg, uint8_t* src, uint8_t len)
davidr99 0:ab4e012489ef 66 {
davidr99 0:ab4e012489ef 67 return spiBurstWrite((reg & RH_NRF905_REG_MASK) | RH_NRF905_REG_W_CONFIG, src, len);
davidr99 0:ab4e012489ef 68 }
davidr99 0:ab4e012489ef 69
davidr99 0:ab4e012489ef 70 uint8_t RH_NRF905::statusRead()
davidr99 0:ab4e012489ef 71 {
davidr99 0:ab4e012489ef 72 // The status is a byproduct of sending a command
davidr99 0:ab4e012489ef 73 return spiCommand(0);
davidr99 0:ab4e012489ef 74 }
davidr99 0:ab4e012489ef 75
davidr99 0:ab4e012489ef 76 bool RH_NRF905::setChannel(uint16_t channel, bool hiFrequency)
davidr99 0:ab4e012489ef 77 {
davidr99 0:ab4e012489ef 78 spiWriteRegister(RH_NRF905_CONFIG_0, channel & RH_NRF905_CONFIG_0_CH_NO);
davidr99 0:ab4e012489ef 79 // Set or clear the high bit of the channel
davidr99 0:ab4e012489ef 80 uint8_t bit8 = (channel >> 8) & 0x01;
davidr99 0:ab4e012489ef 81 uint8_t reg1 = spiReadRegister(RH_NRF905_CONFIG_1);
davidr99 0:ab4e012489ef 82 reg1 = (reg1 & ~0x01) | bit8;
davidr99 0:ab4e012489ef 83 // Set or clear the HFREQ_PLL bit
davidr99 0:ab4e012489ef 84 reg1 &= ~RH_NRF905_CONFIG_1_HFREQ_PLL;
davidr99 0:ab4e012489ef 85 if (hiFrequency)
davidr99 0:ab4e012489ef 86 reg1 |= RH_NRF905_CONFIG_1_HFREQ_PLL;
davidr99 0:ab4e012489ef 87 spiWriteRegister(RH_NRF905_CONFIG_1, reg1);
davidr99 0:ab4e012489ef 88 return true;
davidr99 0:ab4e012489ef 89 }
davidr99 0:ab4e012489ef 90
davidr99 0:ab4e012489ef 91 bool RH_NRF905::setNetworkAddress(uint8_t* address, uint8_t len)
davidr99 0:ab4e012489ef 92 {
davidr99 0:ab4e012489ef 93 if (len < 1 || len > 4)
davidr99 0:ab4e012489ef 94 return false;
davidr99 0:ab4e012489ef 95 // Set RX_AFW and TX_AFW
davidr99 0:ab4e012489ef 96 spiWriteRegister(RH_NRF905_CONFIG_2, len | (len << 4));
davidr99 0:ab4e012489ef 97 spiBurstWrite(RH_NRF905_REG_W_TX_ADDRESS, address, len);
davidr99 0:ab4e012489ef 98 spiBurstWriteRegister(RH_NRF905_CONFIG_5, address, len);
davidr99 0:ab4e012489ef 99 return true;
davidr99 0:ab4e012489ef 100 }
davidr99 0:ab4e012489ef 101
davidr99 0:ab4e012489ef 102 bool RH_NRF905::setRF(TransmitPower power)
davidr99 0:ab4e012489ef 103 {
davidr99 0:ab4e012489ef 104 // Enum definitions of power are the same numerical values as the register
davidr99 0:ab4e012489ef 105 spiWriteRegister(RH_NRF905_CONFIG_1_PA_PWR, power);
davidr99 0:ab4e012489ef 106 return true;
davidr99 0:ab4e012489ef 107 }
davidr99 0:ab4e012489ef 108
davidr99 0:ab4e012489ef 109 void RH_NRF905::setModeIdle()
davidr99 0:ab4e012489ef 110 {
davidr99 0:ab4e012489ef 111 if (_mode != RHModeIdle)
davidr99 0:ab4e012489ef 112 {
davidr99 0:ab4e012489ef 113 digitalWrite(_chipEnablePin, LOW);
davidr99 0:ab4e012489ef 114 digitalWrite(_txEnablePin, LOW);
davidr99 0:ab4e012489ef 115 _mode = RHModeIdle;
davidr99 0:ab4e012489ef 116 }
davidr99 0:ab4e012489ef 117 }
davidr99 0:ab4e012489ef 118
davidr99 0:ab4e012489ef 119 void RH_NRF905::setModeRx()
davidr99 0:ab4e012489ef 120 {
davidr99 0:ab4e012489ef 121 if (_mode != RHModeRx)
davidr99 0:ab4e012489ef 122 {
davidr99 0:ab4e012489ef 123 digitalWrite(_txEnablePin, LOW);
davidr99 0:ab4e012489ef 124 digitalWrite(_chipEnablePin, HIGH);
davidr99 0:ab4e012489ef 125 _mode = RHModeRx;
davidr99 0:ab4e012489ef 126 }
davidr99 0:ab4e012489ef 127 }
davidr99 0:ab4e012489ef 128
davidr99 0:ab4e012489ef 129 void RH_NRF905::setModeTx()
davidr99 0:ab4e012489ef 130 {
davidr99 0:ab4e012489ef 131 if (_mode != RHModeTx)
davidr99 0:ab4e012489ef 132 {
davidr99 0:ab4e012489ef 133 // Its the high transition that puts us into TX mode
davidr99 0:ab4e012489ef 134 digitalWrite(_txEnablePin, HIGH);
davidr99 0:ab4e012489ef 135 digitalWrite(_chipEnablePin, HIGH);
davidr99 0:ab4e012489ef 136 _mode = RHModeTx;
davidr99 0:ab4e012489ef 137 }
davidr99 0:ab4e012489ef 138 }
davidr99 0:ab4e012489ef 139
davidr99 0:ab4e012489ef 140 bool RH_NRF905::send(const uint8_t* data, uint8_t len)
davidr99 0:ab4e012489ef 141 {
davidr99 0:ab4e012489ef 142 if (len > RH_NRF905_MAX_MESSAGE_LEN)
davidr99 0:ab4e012489ef 143 return false;
davidr99 0:ab4e012489ef 144 // Set up the headers
davidr99 0:ab4e012489ef 145 _buf[0] = _txHeaderTo;
davidr99 0:ab4e012489ef 146 _buf[1] = _txHeaderFrom;
davidr99 0:ab4e012489ef 147 _buf[2] = _txHeaderId;
davidr99 0:ab4e012489ef 148 _buf[3] = _txHeaderFlags;
davidr99 0:ab4e012489ef 149 _buf[4] = len;
davidr99 0:ab4e012489ef 150 memcpy(_buf+RH_NRF905_HEADER_LEN, data, len);
davidr99 0:ab4e012489ef 151 spiBurstWrite(RH_NRF905_REG_W_TX_PAYLOAD, _buf, len + RH_NRF905_HEADER_LEN);
davidr99 0:ab4e012489ef 152 setModeTx();
davidr99 0:ab4e012489ef 153 // Radio will return to Standby mode after transmission is complete
davidr99 0:ab4e012489ef 154 _txGood++;
davidr99 0:ab4e012489ef 155 return true;
davidr99 0:ab4e012489ef 156 }
davidr99 0:ab4e012489ef 157
davidr99 0:ab4e012489ef 158 bool RH_NRF905::waitPacketSent()
davidr99 0:ab4e012489ef 159 {
davidr99 0:ab4e012489ef 160 if (_mode != RHModeTx)
davidr99 0:ab4e012489ef 161 return false;
davidr99 0:ab4e012489ef 162
davidr99 0:ab4e012489ef 163 while (!(statusRead() & RH_NRF905_STATUS_DR))
davidr99 0:ab4e012489ef 164 YIELD;
davidr99 0:ab4e012489ef 165 setModeIdle();
davidr99 0:ab4e012489ef 166 return true;
davidr99 0:ab4e012489ef 167 }
davidr99 0:ab4e012489ef 168
davidr99 0:ab4e012489ef 169 bool RH_NRF905::isSending()
davidr99 0:ab4e012489ef 170 {
davidr99 0:ab4e012489ef 171 if (_mode != RHModeTx)
davidr99 0:ab4e012489ef 172 return false;
davidr99 0:ab4e012489ef 173
davidr99 0:ab4e012489ef 174 return !(statusRead() & RH_NRF905_STATUS_DR);
davidr99 0:ab4e012489ef 175 }
davidr99 0:ab4e012489ef 176
davidr99 0:ab4e012489ef 177 bool RH_NRF905::printRegister(uint8_t reg)
davidr99 0:ab4e012489ef 178 {
davidr99 0:ab4e012489ef 179 #ifdef RH_HAVE_SERIAL
davidr99 0:ab4e012489ef 180 Serial.print(reg, HEX);
davidr99 0:ab4e012489ef 181 Serial.print(": ");
davidr99 0:ab4e012489ef 182 Serial.println(spiReadRegister(reg), HEX);
davidr99 0:ab4e012489ef 183 #endif
davidr99 0:ab4e012489ef 184
davidr99 0:ab4e012489ef 185 return true;
davidr99 0:ab4e012489ef 186 }
davidr99 0:ab4e012489ef 187
davidr99 0:ab4e012489ef 188 bool RH_NRF905::printRegisters()
davidr99 0:ab4e012489ef 189 {
davidr99 0:ab4e012489ef 190 uint8_t registers[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
davidr99 0:ab4e012489ef 191
davidr99 0:ab4e012489ef 192 uint8_t i;
davidr99 0:ab4e012489ef 193 for (i = 0; i < sizeof(registers); i++)
davidr99 0:ab4e012489ef 194 printRegister(registers[i]);
davidr99 0:ab4e012489ef 195 return true;
davidr99 0:ab4e012489ef 196 }
davidr99 0:ab4e012489ef 197
davidr99 0:ab4e012489ef 198 // Check whether the latest received message is complete and uncorrupted
davidr99 0:ab4e012489ef 199 void RH_NRF905::validateRxBuf()
davidr99 0:ab4e012489ef 200 {
davidr99 0:ab4e012489ef 201 // Check the length
davidr99 0:ab4e012489ef 202 uint8_t len = _buf[4];
davidr99 0:ab4e012489ef 203 if (len > RH_NRF905_MAX_MESSAGE_LEN)
davidr99 0:ab4e012489ef 204 return; // Silly LEN header
davidr99 0:ab4e012489ef 205
davidr99 0:ab4e012489ef 206 // Extract the 4 headers
davidr99 0:ab4e012489ef 207 _rxHeaderTo = _buf[0];
davidr99 0:ab4e012489ef 208 _rxHeaderFrom = _buf[1];
davidr99 0:ab4e012489ef 209 _rxHeaderId = _buf[2];
davidr99 0:ab4e012489ef 210 _rxHeaderFlags = _buf[3];
davidr99 0:ab4e012489ef 211 if (_promiscuous ||
davidr99 0:ab4e012489ef 212 _rxHeaderTo == _thisAddress ||
davidr99 0:ab4e012489ef 213 _rxHeaderTo == RH_BROADCAST_ADDRESS)
davidr99 0:ab4e012489ef 214 {
davidr99 0:ab4e012489ef 215 _rxGood++;
davidr99 0:ab4e012489ef 216 _bufLen = len + RH_NRF905_HEADER_LEN; // _buf still includes the headers
davidr99 0:ab4e012489ef 217 _rxBufValid = true;
davidr99 0:ab4e012489ef 218 }
davidr99 0:ab4e012489ef 219 }
davidr99 0:ab4e012489ef 220
davidr99 0:ab4e012489ef 221 bool RH_NRF905::available()
davidr99 0:ab4e012489ef 222 {
davidr99 0:ab4e012489ef 223 if (!_rxBufValid)
davidr99 0:ab4e012489ef 224 {
davidr99 0:ab4e012489ef 225 if (_mode == RHModeTx)
davidr99 0:ab4e012489ef 226 return false;
davidr99 0:ab4e012489ef 227 setModeRx();
davidr99 0:ab4e012489ef 228 if (!(statusRead() & RH_NRF905_STATUS_DR))
davidr99 0:ab4e012489ef 229 return false;
davidr99 0:ab4e012489ef 230 // Get the message into the RX buffer, so we can inspect the headers
davidr99 0:ab4e012489ef 231 // we still dont know how long is the user message
davidr99 0:ab4e012489ef 232 spiBurstRead(RH_NRF905_REG_R_RX_PAYLOAD, _buf, RH_NRF905_MAX_PAYLOAD_LEN);
davidr99 0:ab4e012489ef 233 validateRxBuf();
davidr99 0:ab4e012489ef 234 if (_rxBufValid)
davidr99 0:ab4e012489ef 235 setModeIdle(); // Got one
davidr99 0:ab4e012489ef 236 }
davidr99 0:ab4e012489ef 237 return _rxBufValid;
davidr99 0:ab4e012489ef 238 }
davidr99 0:ab4e012489ef 239
davidr99 0:ab4e012489ef 240 void RH_NRF905::clearRxBuf()
davidr99 0:ab4e012489ef 241 {
davidr99 0:ab4e012489ef 242 _rxBufValid = false;
davidr99 0:ab4e012489ef 243 _bufLen = 0;
davidr99 0:ab4e012489ef 244 }
davidr99 0:ab4e012489ef 245
davidr99 0:ab4e012489ef 246 bool RH_NRF905::recv(uint8_t* buf, uint8_t* len)
davidr99 0:ab4e012489ef 247 {
davidr99 0:ab4e012489ef 248 if (!available())
davidr99 0:ab4e012489ef 249 return false;
davidr99 0:ab4e012489ef 250 if (buf && len)
davidr99 0:ab4e012489ef 251 {
davidr99 0:ab4e012489ef 252 // Skip the 4 headers that are at the beginning of the rxBuf
davidr99 0:ab4e012489ef 253 if (*len > _bufLen-RH_NRF905_HEADER_LEN)
davidr99 0:ab4e012489ef 254 *len = _bufLen-RH_NRF905_HEADER_LEN;
davidr99 0:ab4e012489ef 255 memcpy(buf, _buf+RH_NRF905_HEADER_LEN, *len);
davidr99 0:ab4e012489ef 256 }
davidr99 0:ab4e012489ef 257 clearRxBuf(); // This message accepted and cleared
davidr99 0:ab4e012489ef 258 return true;
davidr99 0:ab4e012489ef 259 }
davidr99 0:ab4e012489ef 260
davidr99 0:ab4e012489ef 261 uint8_t RH_NRF905::maxMessageLength()
davidr99 0:ab4e012489ef 262 {
davidr99 0:ab4e012489ef 263 return RH_NRF905_MAX_MESSAGE_LEN;
davidr99 0:ab4e012489ef 264 }