V148
Fork of RadioHead-148 by
RH_NRF24.cpp@0:ab4e012489ef, 2015-10-15 (annotated)
- Committer:
- davidr99
- Date:
- Thu Oct 15 01:27:00 2015 +0000
- Revision:
- 0:ab4e012489ef
Messy start, but a port for RadioHead.; Currently the SPI modulus are the only ones that work.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
davidr99 | 0:ab4e012489ef | 1 | // NRF24.cpp |
davidr99 | 0:ab4e012489ef | 2 | // |
davidr99 | 0:ab4e012489ef | 3 | // Copyright (C) 2012 Mike McCauley |
davidr99 | 0:ab4e012489ef | 4 | // $Id: RH_NRF24.cpp,v 1.21 2015/03/29 03:53:47 mikem Exp $ |
davidr99 | 0:ab4e012489ef | 5 | |
davidr99 | 0:ab4e012489ef | 6 | #include <RH_NRF24.h> |
davidr99 | 0:ab4e012489ef | 7 | |
davidr99 | 0:ab4e012489ef | 8 | RH_NRF24::RH_NRF24(PINS chipEnablePin, PINS slaveSelectPin, RHGenericSPI& spi) |
davidr99 | 0:ab4e012489ef | 9 | : |
davidr99 | 0:ab4e012489ef | 10 | RHNRFSPIDriver(slaveSelectPin, spi), |
davidr99 | 0:ab4e012489ef | 11 | _rxBufValid(0) |
davidr99 | 0:ab4e012489ef | 12 | { |
davidr99 | 0:ab4e012489ef | 13 | _configuration = RH_NRF24_EN_CRC | RH_NRF24_CRCO; // Default: 2 byte CRC enabled |
davidr99 | 0:ab4e012489ef | 14 | _chipEnablePin = chipEnablePin; |
davidr99 | 0:ab4e012489ef | 15 | } |
davidr99 | 0:ab4e012489ef | 16 | |
davidr99 | 0:ab4e012489ef | 17 | bool RH_NRF24::init() |
davidr99 | 0:ab4e012489ef | 18 | { |
davidr99 | 0:ab4e012489ef | 19 | // Teensy with nRF24 is unreliable at 8MHz: |
davidr99 | 0:ab4e012489ef | 20 | // so is Arduino with RF73 |
davidr99 | 0:ab4e012489ef | 21 | _spi.setFrequency(RHGenericSPI::Frequency1MHz); |
davidr99 | 0:ab4e012489ef | 22 | if (!RHNRFSPIDriver::init()) |
davidr99 | 0:ab4e012489ef | 23 | return false; |
davidr99 | 0:ab4e012489ef | 24 | |
davidr99 | 0:ab4e012489ef | 25 | // Initialise the slave select pin |
davidr99 | 0:ab4e012489ef | 26 | #if (RH_PLATFORM != RH_PLATFORM_MBED) |
davidr99 | 0:ab4e012489ef | 27 | pinMode(_chipEnablePin, OUTPUT); |
davidr99 | 0:ab4e012489ef | 28 | #endif |
davidr99 | 0:ab4e012489ef | 29 | digitalWrite(_chipEnablePin, LOW); |
davidr99 | 0:ab4e012489ef | 30 | |
davidr99 | 0:ab4e012489ef | 31 | // Clear interrupts |
davidr99 | 0:ab4e012489ef | 32 | spiWriteRegister(RH_NRF24_REG_07_STATUS, RH_NRF24_RX_DR | RH_NRF24_TX_DS | RH_NRF24_MAX_RT); |
davidr99 | 0:ab4e012489ef | 33 | // Enable dynamic payload length on all pipes |
davidr99 | 0:ab4e012489ef | 34 | spiWriteRegister(RH_NRF24_REG_1C_DYNPD, RH_NRF24_DPL_ALL); |
davidr99 | 0:ab4e012489ef | 35 | // Enable dynamic payload length, disable payload-with-ack, enable noack |
davidr99 | 0:ab4e012489ef | 36 | spiWriteRegister(RH_NRF24_REG_1D_FEATURE, RH_NRF24_EN_DPL | RH_NRF24_EN_DYN_ACK); |
davidr99 | 0:ab4e012489ef | 37 | // Test if there is actually a device connected and responding |
davidr99 | 0:ab4e012489ef | 38 | // CAUTION: RFM73 and version 2.0 silicon may require ACTIVATE |
davidr99 | 0:ab4e012489ef | 39 | if (spiReadRegister(RH_NRF24_REG_1D_FEATURE) != (RH_NRF24_EN_DPL | RH_NRF24_EN_DYN_ACK)) |
davidr99 | 0:ab4e012489ef | 40 | { |
davidr99 | 0:ab4e012489ef | 41 | spiWrite(RH_NRF24_COMMAND_ACTIVATE, 0x73); |
davidr99 | 0:ab4e012489ef | 42 | // Enable dynamic payload length, disable payload-with-ack, enable noack |
davidr99 | 0:ab4e012489ef | 43 | spiWriteRegister(RH_NRF24_REG_1D_FEATURE, RH_NRF24_EN_DPL | RH_NRF24_EN_DYN_ACK); |
davidr99 | 0:ab4e012489ef | 44 | if (spiReadRegister(RH_NRF24_REG_1D_FEATURE) != (RH_NRF24_EN_DPL | RH_NRF24_EN_DYN_ACK)) |
davidr99 | 0:ab4e012489ef | 45 | return false; |
davidr99 | 0:ab4e012489ef | 46 | } |
davidr99 | 0:ab4e012489ef | 47 | |
davidr99 | 0:ab4e012489ef | 48 | // Make sure we are powered down |
davidr99 | 0:ab4e012489ef | 49 | setModeIdle(); |
davidr99 | 0:ab4e012489ef | 50 | |
davidr99 | 0:ab4e012489ef | 51 | // Flush FIFOs |
davidr99 | 0:ab4e012489ef | 52 | flushTx(); |
davidr99 | 0:ab4e012489ef | 53 | flushRx(); |
davidr99 | 0:ab4e012489ef | 54 | |
davidr99 | 0:ab4e012489ef | 55 | setChannel(2); // The default, in case it was set by another app without powering down |
davidr99 | 0:ab4e012489ef | 56 | setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm); |
davidr99 | 0:ab4e012489ef | 57 | |
davidr99 | 0:ab4e012489ef | 58 | return true; |
davidr99 | 0:ab4e012489ef | 59 | } |
davidr99 | 0:ab4e012489ef | 60 | |
davidr99 | 0:ab4e012489ef | 61 | // Use the register commands to read and write the registers |
davidr99 | 0:ab4e012489ef | 62 | uint8_t RH_NRF24::spiReadRegister(uint8_t reg) |
davidr99 | 0:ab4e012489ef | 63 | { |
davidr99 | 0:ab4e012489ef | 64 | return spiRead((reg & RH_NRF24_REGISTER_MASK) | RH_NRF24_COMMAND_R_REGISTER); |
davidr99 | 0:ab4e012489ef | 65 | } |
davidr99 | 0:ab4e012489ef | 66 | |
davidr99 | 0:ab4e012489ef | 67 | uint8_t RH_NRF24::spiWriteRegister(uint8_t reg, uint8_t val) |
davidr99 | 0:ab4e012489ef | 68 | { |
davidr99 | 0:ab4e012489ef | 69 | return spiWrite((reg & RH_NRF24_REGISTER_MASK) | RH_NRF24_COMMAND_W_REGISTER, val); |
davidr99 | 0:ab4e012489ef | 70 | } |
davidr99 | 0:ab4e012489ef | 71 | |
davidr99 | 0:ab4e012489ef | 72 | uint8_t RH_NRF24::spiBurstReadRegister(uint8_t reg, uint8_t* dest, uint8_t len) |
davidr99 | 0:ab4e012489ef | 73 | { |
davidr99 | 0:ab4e012489ef | 74 | return spiBurstRead((reg & RH_NRF24_REGISTER_MASK) | RH_NRF24_COMMAND_R_REGISTER, dest, len); |
davidr99 | 0:ab4e012489ef | 75 | } |
davidr99 | 0:ab4e012489ef | 76 | |
davidr99 | 0:ab4e012489ef | 77 | uint8_t RH_NRF24::spiBurstWriteRegister(uint8_t reg, uint8_t* src, uint8_t len) |
davidr99 | 0:ab4e012489ef | 78 | { |
davidr99 | 0:ab4e012489ef | 79 | return spiBurstWrite((reg & RH_NRF24_REGISTER_MASK) | RH_NRF24_COMMAND_W_REGISTER, src, len); |
davidr99 | 0:ab4e012489ef | 80 | } |
davidr99 | 0:ab4e012489ef | 81 | |
davidr99 | 0:ab4e012489ef | 82 | uint8_t RH_NRF24::statusRead() |
davidr99 | 0:ab4e012489ef | 83 | { |
davidr99 | 0:ab4e012489ef | 84 | // status is a side-effect of NOP, faster than reading reg 07 |
davidr99 | 0:ab4e012489ef | 85 | return spiCommand(RH_NRF24_COMMAND_NOP); |
davidr99 | 0:ab4e012489ef | 86 | } |
davidr99 | 0:ab4e012489ef | 87 | |
davidr99 | 0:ab4e012489ef | 88 | uint8_t RH_NRF24::flushTx() |
davidr99 | 0:ab4e012489ef | 89 | { |
davidr99 | 0:ab4e012489ef | 90 | return spiCommand(RH_NRF24_COMMAND_FLUSH_TX); |
davidr99 | 0:ab4e012489ef | 91 | } |
davidr99 | 0:ab4e012489ef | 92 | |
davidr99 | 0:ab4e012489ef | 93 | uint8_t RH_NRF24::flushRx() |
davidr99 | 0:ab4e012489ef | 94 | { |
davidr99 | 0:ab4e012489ef | 95 | return spiCommand(RH_NRF24_COMMAND_FLUSH_RX); |
davidr99 | 0:ab4e012489ef | 96 | } |
davidr99 | 0:ab4e012489ef | 97 | |
davidr99 | 0:ab4e012489ef | 98 | bool RH_NRF24::setChannel(uint8_t channel) |
davidr99 | 0:ab4e012489ef | 99 | { |
davidr99 | 0:ab4e012489ef | 100 | spiWriteRegister(RH_NRF24_REG_05_RF_CH, channel & RH_NRF24_RF_CH); |
davidr99 | 0:ab4e012489ef | 101 | return true; |
davidr99 | 0:ab4e012489ef | 102 | } |
davidr99 | 0:ab4e012489ef | 103 | |
davidr99 | 0:ab4e012489ef | 104 | bool RH_NRF24::setOpMode(uint8_t mode) |
davidr99 | 0:ab4e012489ef | 105 | { |
davidr99 | 0:ab4e012489ef | 106 | _configuration = mode; |
davidr99 | 0:ab4e012489ef | 107 | return true; |
davidr99 | 0:ab4e012489ef | 108 | } |
davidr99 | 0:ab4e012489ef | 109 | |
davidr99 | 0:ab4e012489ef | 110 | bool RH_NRF24::setNetworkAddress(uint8_t* address, uint8_t len) |
davidr99 | 0:ab4e012489ef | 111 | { |
davidr99 | 0:ab4e012489ef | 112 | if (len < 3 || len > 5) |
davidr99 | 0:ab4e012489ef | 113 | return false; |
davidr99 | 0:ab4e012489ef | 114 | |
davidr99 | 0:ab4e012489ef | 115 | // Set both TX_ADDR and RX_ADDR_P0 for auto-ack with Enhanced shockwave |
davidr99 | 0:ab4e012489ef | 116 | spiWriteRegister(RH_NRF24_REG_03_SETUP_AW, len-2); // Mapping [3..5] = [1..3] |
davidr99 | 0:ab4e012489ef | 117 | spiBurstWriteRegister(RH_NRF24_REG_0A_RX_ADDR_P0, address, len); |
davidr99 | 0:ab4e012489ef | 118 | spiBurstWriteRegister(RH_NRF24_REG_10_TX_ADDR, address, len); |
davidr99 | 0:ab4e012489ef | 119 | return true; |
davidr99 | 0:ab4e012489ef | 120 | } |
davidr99 | 0:ab4e012489ef | 121 | |
davidr99 | 0:ab4e012489ef | 122 | bool RH_NRF24::setRF(DataRate data_rate, TransmitPower power) |
davidr99 | 0:ab4e012489ef | 123 | { |
davidr99 | 0:ab4e012489ef | 124 | uint8_t value = (power << 1) & RH_NRF24_PWR; |
davidr99 | 0:ab4e012489ef | 125 | // Ugly mapping of data rates to noncontiguous 2 bits: |
davidr99 | 0:ab4e012489ef | 126 | if (data_rate == DataRate250kbps) |
davidr99 | 0:ab4e012489ef | 127 | value |= RH_NRF24_RF_DR_LOW; |
davidr99 | 0:ab4e012489ef | 128 | else if (data_rate == DataRate2Mbps) |
davidr99 | 0:ab4e012489ef | 129 | value |= RH_NRF24_RF_DR_HIGH; |
davidr99 | 0:ab4e012489ef | 130 | // else DataRate1Mbps, 00 |
davidr99 | 0:ab4e012489ef | 131 | |
davidr99 | 0:ab4e012489ef | 132 | // RFM73 needs this: |
davidr99 | 0:ab4e012489ef | 133 | value |= RH_NRF24_LNA_HCURR; |
davidr99 | 0:ab4e012489ef | 134 | |
davidr99 | 0:ab4e012489ef | 135 | spiWriteRegister(RH_NRF24_REG_06_RF_SETUP, value); |
davidr99 | 0:ab4e012489ef | 136 | // If we were using auto-ack, we would have to set the appropriate timeout in reg 4 here |
davidr99 | 0:ab4e012489ef | 137 | // see NRF24::setRF() |
davidr99 | 0:ab4e012489ef | 138 | return true; |
davidr99 | 0:ab4e012489ef | 139 | } |
davidr99 | 0:ab4e012489ef | 140 | |
davidr99 | 0:ab4e012489ef | 141 | void RH_NRF24::setModeIdle() |
davidr99 | 0:ab4e012489ef | 142 | { |
davidr99 | 0:ab4e012489ef | 143 | if (_mode != RHModeIdle) |
davidr99 | 0:ab4e012489ef | 144 | { |
davidr99 | 0:ab4e012489ef | 145 | spiWriteRegister(RH_NRF24_REG_00_CONFIG, _configuration); |
davidr99 | 0:ab4e012489ef | 146 | digitalWrite(_chipEnablePin, LOW); |
davidr99 | 0:ab4e012489ef | 147 | _mode = RHModeIdle; |
davidr99 | 0:ab4e012489ef | 148 | } |
davidr99 | 0:ab4e012489ef | 149 | } |
davidr99 | 0:ab4e012489ef | 150 | |
davidr99 | 0:ab4e012489ef | 151 | bool RH_NRF24::sleep() |
davidr99 | 0:ab4e012489ef | 152 | { |
davidr99 | 0:ab4e012489ef | 153 | if (_mode != RHModeSleep) |
davidr99 | 0:ab4e012489ef | 154 | { |
davidr99 | 0:ab4e012489ef | 155 | spiWriteRegister(RH_NRF24_REG_00_CONFIG, 0); // Power Down mode |
davidr99 | 0:ab4e012489ef | 156 | digitalWrite(_chipEnablePin, LOW); |
davidr99 | 0:ab4e012489ef | 157 | _mode = RHModeSleep; |
davidr99 | 0:ab4e012489ef | 158 | } |
davidr99 | 0:ab4e012489ef | 159 | } |
davidr99 | 0:ab4e012489ef | 160 | |
davidr99 | 0:ab4e012489ef | 161 | void RH_NRF24::setModeRx() |
davidr99 | 0:ab4e012489ef | 162 | { |
davidr99 | 0:ab4e012489ef | 163 | if (_mode != RHModeRx) |
davidr99 | 0:ab4e012489ef | 164 | { |
davidr99 | 0:ab4e012489ef | 165 | spiWriteRegister(RH_NRF24_REG_00_CONFIG, _configuration | RH_NRF24_PWR_UP | RH_NRF24_PRIM_RX); |
davidr99 | 0:ab4e012489ef | 166 | digitalWrite(_chipEnablePin, HIGH); |
davidr99 | 0:ab4e012489ef | 167 | _mode = RHModeRx; |
davidr99 | 0:ab4e012489ef | 168 | } |
davidr99 | 0:ab4e012489ef | 169 | } |
davidr99 | 0:ab4e012489ef | 170 | |
davidr99 | 0:ab4e012489ef | 171 | void RH_NRF24::setModeTx() |
davidr99 | 0:ab4e012489ef | 172 | { |
davidr99 | 0:ab4e012489ef | 173 | if (_mode != RHModeTx) |
davidr99 | 0:ab4e012489ef | 174 | { |
davidr99 | 0:ab4e012489ef | 175 | // Its the CE rising edge that puts us into TX mode |
davidr99 | 0:ab4e012489ef | 176 | // CE staying high makes us go to standby-II when the packet is sent |
davidr99 | 0:ab4e012489ef | 177 | digitalWrite(_chipEnablePin, LOW); |
davidr99 | 0:ab4e012489ef | 178 | // Ensure DS is not set |
davidr99 | 0:ab4e012489ef | 179 | spiWriteRegister(RH_NRF24_REG_07_STATUS, RH_NRF24_TX_DS | RH_NRF24_MAX_RT); |
davidr99 | 0:ab4e012489ef | 180 | spiWriteRegister(RH_NRF24_REG_00_CONFIG, _configuration | RH_NRF24_PWR_UP); |
davidr99 | 0:ab4e012489ef | 181 | digitalWrite(_chipEnablePin, HIGH); |
davidr99 | 0:ab4e012489ef | 182 | _mode = RHModeTx; |
davidr99 | 0:ab4e012489ef | 183 | } |
davidr99 | 0:ab4e012489ef | 184 | } |
davidr99 | 0:ab4e012489ef | 185 | |
davidr99 | 0:ab4e012489ef | 186 | bool RH_NRF24::send(const uint8_t* data, uint8_t len) |
davidr99 | 0:ab4e012489ef | 187 | { |
davidr99 | 0:ab4e012489ef | 188 | if (len > RH_NRF24_MAX_MESSAGE_LEN) |
davidr99 | 0:ab4e012489ef | 189 | return false; |
davidr99 | 0:ab4e012489ef | 190 | // Set up the headers |
davidr99 | 0:ab4e012489ef | 191 | _buf[0] = _txHeaderTo; |
davidr99 | 0:ab4e012489ef | 192 | _buf[1] = _txHeaderFrom; |
davidr99 | 0:ab4e012489ef | 193 | _buf[2] = _txHeaderId; |
davidr99 | 0:ab4e012489ef | 194 | _buf[3] = _txHeaderFlags; |
davidr99 | 0:ab4e012489ef | 195 | memcpy(_buf+RH_NRF24_HEADER_LEN, data, len); |
davidr99 | 0:ab4e012489ef | 196 | spiBurstWrite(RH_NRF24_COMMAND_W_TX_PAYLOAD_NOACK, _buf, len + RH_NRF24_HEADER_LEN); |
davidr99 | 0:ab4e012489ef | 197 | setModeTx(); |
davidr99 | 0:ab4e012489ef | 198 | // Radio will return to Standby II mode after transmission is complete |
davidr99 | 0:ab4e012489ef | 199 | _txGood++; |
davidr99 | 0:ab4e012489ef | 200 | return true; |
davidr99 | 0:ab4e012489ef | 201 | } |
davidr99 | 0:ab4e012489ef | 202 | |
davidr99 | 0:ab4e012489ef | 203 | bool RH_NRF24::waitPacketSent() |
davidr99 | 0:ab4e012489ef | 204 | { |
davidr99 | 0:ab4e012489ef | 205 | // If we are not currently in transmit mode, there is no packet to wait for |
davidr99 | 0:ab4e012489ef | 206 | if (_mode != RHModeTx) |
davidr99 | 0:ab4e012489ef | 207 | return false; |
davidr99 | 0:ab4e012489ef | 208 | |
davidr99 | 0:ab4e012489ef | 209 | // Wait for either the Data Sent or Max ReTries flag, signalling the |
davidr99 | 0:ab4e012489ef | 210 | // end of transmission |
davidr99 | 0:ab4e012489ef | 211 | // We dont actually use auto-ack, so prob dont expect to see RH_NRF24_MAX_RT |
davidr99 | 0:ab4e012489ef | 212 | uint8_t status; |
davidr99 | 0:ab4e012489ef | 213 | while (!((status = statusRead()) & (RH_NRF24_TX_DS | RH_NRF24_MAX_RT))) |
davidr99 | 0:ab4e012489ef | 214 | YIELD; |
davidr99 | 0:ab4e012489ef | 215 | |
davidr99 | 0:ab4e012489ef | 216 | // Must clear RH_NRF24_MAX_RT if it is set, else no further comm |
davidr99 | 0:ab4e012489ef | 217 | if (status & RH_NRF24_MAX_RT) |
davidr99 | 0:ab4e012489ef | 218 | flushTx(); |
davidr99 | 0:ab4e012489ef | 219 | setModeIdle(); |
davidr99 | 0:ab4e012489ef | 220 | spiWriteRegister(RH_NRF24_REG_07_STATUS, RH_NRF24_TX_DS | RH_NRF24_MAX_RT); |
davidr99 | 0:ab4e012489ef | 221 | // Return true if data sent, false if MAX_RT |
davidr99 | 0:ab4e012489ef | 222 | return status & RH_NRF24_TX_DS; |
davidr99 | 0:ab4e012489ef | 223 | } |
davidr99 | 0:ab4e012489ef | 224 | |
davidr99 | 0:ab4e012489ef | 225 | bool RH_NRF24::isSending() |
davidr99 | 0:ab4e012489ef | 226 | { |
davidr99 | 0:ab4e012489ef | 227 | return !(spiReadRegister(RH_NRF24_REG_00_CONFIG) & RH_NRF24_PRIM_RX) && |
davidr99 | 0:ab4e012489ef | 228 | !(statusRead() & (RH_NRF24_TX_DS | RH_NRF24_MAX_RT)); |
davidr99 | 0:ab4e012489ef | 229 | } |
davidr99 | 0:ab4e012489ef | 230 | |
davidr99 | 0:ab4e012489ef | 231 | bool RH_NRF24::printRegisters() |
davidr99 | 0:ab4e012489ef | 232 | { |
davidr99 | 0:ab4e012489ef | 233 | #ifdef RH_HAVE_SERIAL |
davidr99 | 0:ab4e012489ef | 234 | // Iterate over register range, but don't process registers not in use. |
davidr99 | 0:ab4e012489ef | 235 | for (uint8_t r = RH_NRF24_REG_00_CONFIG; r <= RH_NRF24_REG_1D_FEATURE; r++) |
davidr99 | 0:ab4e012489ef | 236 | { |
davidr99 | 0:ab4e012489ef | 237 | if ((r <= RH_NRF24_REG_17_FIFO_STATUS) || (r >= RH_NRF24_REG_1C_DYNPD)) |
davidr99 | 0:ab4e012489ef | 238 | { |
davidr99 | 0:ab4e012489ef | 239 | Serial.print(r, HEX); |
davidr99 | 0:ab4e012489ef | 240 | Serial.print(": "); |
davidr99 | 0:ab4e012489ef | 241 | uint8_t len = 1; |
davidr99 | 0:ab4e012489ef | 242 | // Address registers are 5 bytes in size |
davidr99 | 0:ab4e012489ef | 243 | if ( (RH_NRF24_REG_0A_RX_ADDR_P0 == r) |
davidr99 | 0:ab4e012489ef | 244 | || (RH_NRF24_REG_0B_RX_ADDR_P1 == r) |
davidr99 | 0:ab4e012489ef | 245 | || (RH_NRF24_REG_10_TX_ADDR == r) ) |
davidr99 | 0:ab4e012489ef | 246 | { |
davidr99 | 0:ab4e012489ef | 247 | len = 5; |
davidr99 | 0:ab4e012489ef | 248 | } |
davidr99 | 0:ab4e012489ef | 249 | uint8_t buf[5]; |
davidr99 | 0:ab4e012489ef | 250 | spiBurstReadRegister(r, buf, len); |
davidr99 | 0:ab4e012489ef | 251 | for (uint8_t j = 0; j < len; ++j) |
davidr99 | 0:ab4e012489ef | 252 | { |
davidr99 | 0:ab4e012489ef | 253 | Serial.print(buf[j], HEX); |
davidr99 | 0:ab4e012489ef | 254 | Serial.print(" "); |
davidr99 | 0:ab4e012489ef | 255 | } |
davidr99 | 0:ab4e012489ef | 256 | Serial.println(""); |
davidr99 | 0:ab4e012489ef | 257 | } |
davidr99 | 0:ab4e012489ef | 258 | } |
davidr99 | 0:ab4e012489ef | 259 | #endif |
davidr99 | 0:ab4e012489ef | 260 | |
davidr99 | 0:ab4e012489ef | 261 | return true; |
davidr99 | 0:ab4e012489ef | 262 | } |
davidr99 | 0:ab4e012489ef | 263 | |
davidr99 | 0:ab4e012489ef | 264 | // Check whether the latest received message is complete and uncorrupted |
davidr99 | 0:ab4e012489ef | 265 | void RH_NRF24::validateRxBuf() |
davidr99 | 0:ab4e012489ef | 266 | { |
davidr99 | 0:ab4e012489ef | 267 | if (_bufLen < 4) |
davidr99 | 0:ab4e012489ef | 268 | return; // Too short to be a real message |
davidr99 | 0:ab4e012489ef | 269 | // Extract the 4 headers |
davidr99 | 0:ab4e012489ef | 270 | _rxHeaderTo = _buf[0]; |
davidr99 | 0:ab4e012489ef | 271 | _rxHeaderFrom = _buf[1]; |
davidr99 | 0:ab4e012489ef | 272 | _rxHeaderId = _buf[2]; |
davidr99 | 0:ab4e012489ef | 273 | _rxHeaderFlags = _buf[3]; |
davidr99 | 0:ab4e012489ef | 274 | if (_promiscuous || |
davidr99 | 0:ab4e012489ef | 275 | _rxHeaderTo == _thisAddress || |
davidr99 | 0:ab4e012489ef | 276 | _rxHeaderTo == RH_BROADCAST_ADDRESS) |
davidr99 | 0:ab4e012489ef | 277 | { |
davidr99 | 0:ab4e012489ef | 278 | _rxGood++; |
davidr99 | 0:ab4e012489ef | 279 | _rxBufValid = true; |
davidr99 | 0:ab4e012489ef | 280 | } |
davidr99 | 0:ab4e012489ef | 281 | } |
davidr99 | 0:ab4e012489ef | 282 | |
davidr99 | 0:ab4e012489ef | 283 | bool RH_NRF24::available() |
davidr99 | 0:ab4e012489ef | 284 | { |
davidr99 | 0:ab4e012489ef | 285 | if (!_rxBufValid) |
davidr99 | 0:ab4e012489ef | 286 | { |
davidr99 | 0:ab4e012489ef | 287 | if (_mode == RHModeTx) |
davidr99 | 0:ab4e012489ef | 288 | return false; |
davidr99 | 0:ab4e012489ef | 289 | setModeRx(); |
davidr99 | 0:ab4e012489ef | 290 | if (spiReadRegister(RH_NRF24_REG_17_FIFO_STATUS) & RH_NRF24_RX_EMPTY) |
davidr99 | 0:ab4e012489ef | 291 | return false; |
davidr99 | 0:ab4e012489ef | 292 | // Manual says that messages > 32 octets should be discarded |
davidr99 | 0:ab4e012489ef | 293 | uint8_t len = spiRead(RH_NRF24_COMMAND_R_RX_PL_WID); |
davidr99 | 0:ab4e012489ef | 294 | if (len > 32) |
davidr99 | 0:ab4e012489ef | 295 | { |
davidr99 | 0:ab4e012489ef | 296 | flushRx(); |
davidr99 | 0:ab4e012489ef | 297 | clearRxBuf(); |
davidr99 | 0:ab4e012489ef | 298 | setModeIdle(); |
davidr99 | 0:ab4e012489ef | 299 | return false; |
davidr99 | 0:ab4e012489ef | 300 | } |
davidr99 | 0:ab4e012489ef | 301 | // Clear read interrupt |
davidr99 | 0:ab4e012489ef | 302 | spiWriteRegister(RH_NRF24_REG_07_STATUS, RH_NRF24_RX_DR); |
davidr99 | 0:ab4e012489ef | 303 | // Get the message into the RX buffer, so we can inspect the headers |
davidr99 | 0:ab4e012489ef | 304 | spiBurstRead(RH_NRF24_COMMAND_R_RX_PAYLOAD, _buf, len); |
davidr99 | 0:ab4e012489ef | 305 | _bufLen = len; |
davidr99 | 0:ab4e012489ef | 306 | // 140 microsecs (32 octet payload) |
davidr99 | 0:ab4e012489ef | 307 | validateRxBuf(); |
davidr99 | 0:ab4e012489ef | 308 | if (_rxBufValid) |
davidr99 | 0:ab4e012489ef | 309 | setModeIdle(); // Got one |
davidr99 | 0:ab4e012489ef | 310 | } |
davidr99 | 0:ab4e012489ef | 311 | return _rxBufValid; |
davidr99 | 0:ab4e012489ef | 312 | } |
davidr99 | 0:ab4e012489ef | 313 | |
davidr99 | 0:ab4e012489ef | 314 | void RH_NRF24::clearRxBuf() |
davidr99 | 0:ab4e012489ef | 315 | { |
davidr99 | 0:ab4e012489ef | 316 | _rxBufValid = false; |
davidr99 | 0:ab4e012489ef | 317 | _bufLen = 0; |
davidr99 | 0:ab4e012489ef | 318 | } |
davidr99 | 0:ab4e012489ef | 319 | |
davidr99 | 0:ab4e012489ef | 320 | bool RH_NRF24::recv(uint8_t* buf, uint8_t* len) |
davidr99 | 0:ab4e012489ef | 321 | { |
davidr99 | 0:ab4e012489ef | 322 | if (!available()) |
davidr99 | 0:ab4e012489ef | 323 | return false; |
davidr99 | 0:ab4e012489ef | 324 | if (buf && len) |
davidr99 | 0:ab4e012489ef | 325 | { |
davidr99 | 0:ab4e012489ef | 326 | // Skip the 4 headers that are at the beginning of the rxBuf |
davidr99 | 0:ab4e012489ef | 327 | if (*len > _bufLen-RH_NRF24_HEADER_LEN) |
davidr99 | 0:ab4e012489ef | 328 | *len = _bufLen-RH_NRF24_HEADER_LEN; |
davidr99 | 0:ab4e012489ef | 329 | memcpy(buf, _buf+RH_NRF24_HEADER_LEN, *len); |
davidr99 | 0:ab4e012489ef | 330 | } |
davidr99 | 0:ab4e012489ef | 331 | clearRxBuf(); // This message accepted and cleared |
davidr99 | 0:ab4e012489ef | 332 | return true; |
davidr99 | 0:ab4e012489ef | 333 | } |
davidr99 | 0:ab4e012489ef | 334 | |
davidr99 | 0:ab4e012489ef | 335 | uint8_t RH_NRF24::maxMessageLength() |
davidr99 | 0:ab4e012489ef | 336 | { |
davidr99 | 0:ab4e012489ef | 337 | return RH_NRF24_MAX_MESSAGE_LEN; |
davidr99 | 0:ab4e012489ef | 338 | } |