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.
Fork of RadioHead-148 by
RH_NRF24.cpp@1:b7641da2b203, 2017-10-25 (annotated)
- Committer:
- ilkaykozak
- Date:
- Wed Oct 25 05:14:09 2017 +0000
- Revision:
- 1:b7641da2b203
- Parent:
- 0:ab4e012489ef
V148
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 | } |
