diff options
-rw-r--r-- | Makefile | 13 | ||||
-rw-r--r-- | include/driver/nrf24l01.h | 340 | ||||
-rw-r--r-- | src/app/nrf24l01test/main.cc | 41 | ||||
-rw-r--r-- | src/arch/msp430fr5969lp/Makefile.inc | 2 | ||||
-rw-r--r-- | src/driver/nrf24l01.cc | 199 |
5 files changed, 441 insertions, 154 deletions
@@ -60,9 +60,16 @@ endif ifneq ($(findstring nrf24l01,${drivers}), ) CXX_TARGETS += src/driver/nrf24l01.cc - nrf24l01_en_pin ?= p4_3 - nrf24l01_cs_pin ?= p2_4 - nrf24l01_irq_pin ?= p1_5 + ifeq (${arch}, msp430fr5994lp) + nrf24l01_cs_pin ?= p1_3 + nrf24l01_en_pin ?= p6_2 + nrf24l01_irq_pin ?= p8_3 + endif + ifeq (${arch}, msp430fr5969lp) + nrf24l01_en_pin ?= p4_3 + nrf24l01_cs_pin ?= p2_4 + nrf24l01_irq_pin ?= p1_5 + endif COMMON_FLAGS += -DDRIVER_NRF24L01 COMMON_FLAGS += -DNRF24L01_EN_PIN=GPIO::${nrf24l01_en_pin} COMMON_FLAGS += -DNRF24L01_CS_PIN=GPIO::${nrf24l01_cs_pin} diff --git a/include/driver/nrf24l01.h b/include/driver/nrf24l01.h index 6b69029..e753604 100644 --- a/include/driver/nrf24l01.h +++ b/include/driver/nrf24l01.h @@ -11,27 +11,27 @@ class Nrf24l01 { private: - Nrf24l01(const Nrf24l01 ©); - unsigned char txbuf[2]; - unsigned char rxbuf[2]; - - bool p_variant; /* False for RF24L01 and true for RF24L01P */ - uint8_t payload_size; /**< Fixed size of payloads */ - bool dynamic_payloads_enabled; /**< Whether dynamic payloads are enabled. */ - uint8_t pipe0_reading_address[5]; /**< Last address set on pipe 0 for reading. */ - uint8_t addr_width; /**< The address width to use - 3,4 or 5 bytes. */ - uint32_t txRxDelay; /**< Var for adjusting delays depending on datarate */ - - /** + Nrf24l01(const Nrf24l01 ©); + unsigned char txbuf[2]; + unsigned char rxbuf[2]; + + bool p_variant; /* False for RF24L01 and true for RF24L01P */ + uint8_t payload_size; /**< Fixed size of payloads */ + bool dynamic_payloads_enabled; /**< Whether dynamic payloads are enabled. */ + uint8_t pipe0_reading_address[5]; /**< Last address set on pipe 0 for reading. */ + uint8_t addr_width; /**< The address width to use - 3,4 or 5 bytes. */ + uint32_t txRxDelay; /**< Var for adjusting delays depending on datarate */ + + /** * Write a single byte to a register * * @param reg Which register. Use constants from nRF24L01.h * @param value The new value to write * @return Current value of status register */ - uint8_t writeRegister(uint8_t reg, uint8_t value); + uint8_t writeRegister(uint8_t reg, uint8_t value); - /** + /** * Write a chunk of data to a register * * @param reg Which register. Use constants from nRF24L01.h @@ -39,17 +39,17 @@ private: * @param len How many bytes of data to transfer * @return Current value of status register */ - uint8_t writeRegister(uint8_t reg, const uint8_t *buf, uint8_t len); + uint8_t writeRegister(uint8_t reg, const uint8_t *buf, uint8_t len); - /** + /** * Read single byte from a register * * @param reg Which register. Use constants from nRF24L01.h * @return Current value of register @p reg */ - uint8_t readRegister(uint8_t reg); + uint8_t readRegister(uint8_t reg); - /** + /** * Write the transmit payload * * The size of data written is the fixed payload size, see getPayloadSize() @@ -58,69 +58,80 @@ private: * @param len Number of bytes to be sent * @return Current value of status register */ - uint8_t writePayload(const void *buf, uint8_t data_len, const uint8_t writeType); - - inline void csnHigh() - { - gpio.write(NRF24L01_CS_PIN, 1); - arch.delay_us(5); - } - inline void csnLow() - { - gpio.write(NRF24L01_CS_PIN, 0); - arch.delay_us(5); - } - inline void beginTransaction() - { - csnLow(); - } - inline void endTransaction() - { - csnHigh(); - } + uint8_t writePayload(const void *buf, uint8_t data_len, const uint8_t writeType); + + /** + * Read the receive payload + * + * The size of data read is the fixed payload size, see getPayloadSize() + * + * @param buf Where to put the data + * @param len Maximum number of bytes to read + * @return Current value of status register + */ + uint8_t readPayload(void* buf, uint8_t len); + + inline void csnHigh() + { + gpio.write(NRF24L01_CS_PIN, 1); + arch.delay_us(5); + } + inline void csnLow() + { + gpio.write(NRF24L01_CS_PIN, 0); + arch.delay_us(5); + } + inline void beginTransaction() + { + csnLow(); + } + inline void endTransaction() + { + csnHigh(); + } public: - Nrf24l01() : payload_size(32), dynamic_payloads_enabled(false), addr_width(5) { pipe0_reading_address[0] = 0; } + Nrf24l01() : payload_size(32), dynamic_payloads_enabled(false), addr_width(5) { pipe0_reading_address[0] = 0; } - /** + /** * Power Amplifier level. * * For use with setPALevel() */ - enum rf24_pa_dbm_e - { - RF24_PA_MIN = 0, - RF24_PA_LOW, - RF24_PA_HIGH, - RF24_PA_MAX, - RF24_PA_ERROR - }; - - /** + enum rf24_pa_dbm_e + { + RF24_PA_MIN = 0, + RF24_PA_LOW, + RF24_PA_HIGH, + RF24_PA_MAX, + RF24_PA_ERROR + }; + + /** * Data rate. How fast data moves through the air. * * For use with setDataRate() */ - enum rf24_datarate_e - { - RF24_1MBPS = 0, - RF24_2MBPS, - RF24_250KBPS - }; - - /** + enum rf24_datarate_e + { + RF24_1MBPS = 0, + RF24_2MBPS, + RF24_250KBPS + }; + + /** * CRC Length. How big (if any) of a CRC is included. * * For use with setCRCLength() */ - enum rf24_crclength_e - { - RF24_CRC_DISABLED = 0, - RF24_CRC_8, - RF24_CRC_16 - }; - - /** + enum rf24_crclength_e + { + RF24_CRC_DISABLED = 0, + RF24_CRC_8, + RF24_CRC_16 + }; + + /** * Enter low-power mode * * To return to normal power mode, call powerUp(). @@ -137,33 +148,43 @@ public: * radio.powerUp(); * @endcode */ - void powerDown(void); + void powerDown(void); - /** + /** * Leave low-power mode - required for normal radio operation after calling powerDown() * * To return to low power mode, call powerDown(). * @note This will take up to 5ms for maximum compatibility */ - void powerUp(void); + void powerUp(void); - /** + /** + * Initialize the radio. Open a reading pipe at addr and set channel. + * + * @param addr Address at which the reading pipe will be opened. + * @param channel that will be used, can be 0-125. Channel bandwidth = 1 MHz starting at 2400 Mhz. + * @return 0: success, -1: invalid channel, -2 error setting channel, -3: other error. + * + */ + //int init(uint8_t addr, uint8_t channel, rf24_datarate_e datarate = RF24_2MBPS); + + /** * Empty the transmit buffer. This is generally not required in standard operation. * May be required in specific cases after stopListening() , if operating at 250KBPS data rate. * * @return Current value of status register */ - uint8_t flushTx(void); + uint8_t flushTx(void); - /** + /** * Empty the receive buffer * * @return Current value of status register */ - uint8_t flushRx(void); + uint8_t flushRx(void); - void setup(); - /** + void setup(); + /** * Set Power Amplifier (PA) level to one of four levels: * RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX * @@ -174,40 +195,40 @@ public: * * @param level Desired PA level. */ - void setPALevel(uint8_t level); // 0 (-18B), 1 (-12dB), 2 (-6dB), 3 (0dB) + void setPALevel(uint8_t level); // 0 (-18B), 1 (-12dB), 2 (-6dB), 3 (0dB) - /** + /** * Set the address width from 3 to 5 bytes (24, 32 or 40 bit) * * @param a_width The address width to use: 3,4 or 5 */ - void setAddressWidth(uint8_t a_width); + void setAddressWidth(uint8_t a_width); - /** + /** * Set the number and delay of retries upon failed submit * * @param delay How long to wait between each retry, in multiples of 250us, * max is 15. 0 means 250us, 15 means 4000us. * @param count How many retries before giving up, max 15 */ - void setRetries(uint8_t delay, uint8_t count); + void setRetries(uint8_t delay, uint8_t count); - /** + /** * Set RF communication channel * * @param channel Which RF channel to communicate on, 0-125 */ - void setChannel(uint8_t channel); + void setChannel(uint8_t channel); - /** + /** * Get RF communication channel * * @return The currently configured RF Channel */ - uint8_t getChannel(void); + uint8_t getChannel(void); - /** + /** * Set Static Payload Size * * This implementation uses a pre-stablished fixed payload size for all @@ -219,18 +240,18 @@ public: * * @param size The number of bytes in the payload */ - void setPayloadSize(uint8_t size); + void setPayloadSize(uint8_t size); - /** + /** * Get Static Payload Size * * @see setPayloadSize() * * @return The number of bytes in the payload */ - uint8_t getPayloadSize(void); + uint8_t getPayloadSize(void); - /** + /** * Set the transmission data rate * * @warning setting RF24_250KBPS will fail for non-plus units @@ -238,9 +259,9 @@ public: * @param speed RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps * @return true if the change was successful */ - bool setDataRate(rf24_datarate_e speed); + bool setDataRate(rf24_datarate_e speed); - /** + /** * The radio will generate interrupt signals when a transmission is complete, * a transmission fails, or a payload is received. This allows users to mask * those interrupts to prevent them from generating a signal on the interrupt @@ -256,17 +277,17 @@ public: * @param tx_fail Mask transmit failure interrupts * @param rx_ready Mask payload received interrupts */ - void maskIRQ(bool tx_ok, bool tx_fail, bool rx_ready); + void maskIRQ(bool tx_ok, bool tx_fail, bool rx_ready); - /** + /** * Turn on or off the special features of the chip * * The chip has certain 'features' which are only available when the 'features' * are enabled. See the datasheet for details. */ - void toggleFeatures(void); + void toggleFeatures(void); - /** + /** * Enable dynamically-sized payloads * * This way you don't always have to send large packets just to send them @@ -275,9 +296,9 @@ public: * @param enable desired DynamicPayloads status * */ - void setDynamicPayloads(bool enabled); + void setDynamicPayloads(bool enabled); - /** + /** * Enable dynamic ACKs (single write multicast or unicast) for chosen messages * * @param enable desired DynamicAck status @@ -291,9 +312,9 @@ public: * radio.write(&data,32,0); // Sends a payload using auto-retry/autoACK * @endcode */ - void setDynamicAck(bool enabled); + void setDynamicAck(bool enabled); - /** + /** * Enable or disable auto-acknowlede packets * * This is enabled by default, so it's only needed if you want to turn @@ -301,9 +322,9 @@ public: * * @param enable Whether to enable (true) or disable (false) auto-acks */ - void setAutoAck(bool enable); + void setAutoAck(bool enable); - /** + /** * Enable or disable auto-acknowlede packets on a per pipeline basis. * * AA is enabled by default, so it's only needed if you want to turn @@ -312,9 +333,20 @@ public: * @param pipe Which pipeline to modify * @param enable Whether to enable (true) or disable (false) auto-acks */ - void setAutoAck(uint8_t pipe, bool enable); + void setAutoAck(uint8_t pipe, bool enable); + + /** + * Enable custom payloads on the acknowledge packets + * + * Ack payloads are a handy way to return data back to senders without + * manually changing the radio modes on both units. + * + * @note Ack payloads are dynamic payloads. This only works on pipes 0&1 by default. Call + * enableDynamicPayloads() to enable on all pipes. + */ + void enableAckPayload(void); - /** + /** * Be sure to call openWritingPipe() first to set the destination * of where to write to. * @@ -337,9 +369,9 @@ public: * @endcode * @return True if the payload was delivered successfully false if not */ - uint8_t write(const void *buf, uint8_t len, bool await_ack, bool blocking); + uint8_t write(const void *buf, uint8_t len, bool await_ack, bool blocking); - /** + /** * Start listening on the pipes opened for reading. * * 1. Be sure to call openReadingPipe() first. @@ -354,9 +386,9 @@ public: * radio.startListening(); * @endcode */ - void startListening(void); + void startListening(void); - /** + /** * Stop listening for incoming messages, and switch to transmit mode. * * Do this before calling write(). @@ -365,9 +397,9 @@ public: * radio.write(&data,sizeof(data)); * @endcode */ - void stopListening(void); + void stopListening(void); - /** + /** * Check whether there are bytes available to be read * @code * if(radio.available()){ @@ -376,9 +408,27 @@ public: * @endcode * @return True if there is a payload available, false if none is */ - bool available(void); + bool available(void); + + /** + * Test whether there are bytes available to be read in the + * FIFO buffers. + * + * @param[out] pipe_num Which pipe has the payload available + * + * @code + * uint8_t pipeNum; + * if(radio.available(&pipeNum)){ + * radio.read(&data,sizeof(data)); + * Serial.print("Got data on pipe"); + * Serial.println(pipeNum); + * } + * @endcode + * @return True if there is a payload available, false if none is + */ + bool available(uint8_t *pipe_num); - /** + /** * Read the available payload * * The size of data read is the fixed payload size, see getPayloadSize() @@ -400,9 +450,9 @@ public: * @endcode * @return No return value. Use available(). */ - void read(void *buf, uint8_t len); + void read(void *buf, uint8_t len); - /** + /** * Open a pipe for reading * * Up to 6 pipes can be open for reading at once. Open all the required @@ -429,16 +479,72 @@ public: * @param number Which pipe# to open, 0-5. * @param address The 24, 32 or 40 bit address of the pipe to open. */ - void openReadingPipe(uint8_t number, const uint8_t *address); + void openReadingPipe(uint8_t number, const uint8_t *address); - /** + /** * Close a pipe after it has been previously opened. * Can be safely called without having previously opened a pipe. * @param pipe Which pipe # to close, 0-5. */ - void closeReadingPipe(uint8_t pipe); + void closeReadingPipe(uint8_t pipe); + + /** + * New: Open a pipe for writing via byte array. Old addressing format retained + * for compatibility. + * + * Only one writing pipe can be open at once, but you can change the address + * you'll write to. Call stopListening() first. + * + * Addresses are assigned via a byte array, default is 5 byte address length +s * + * @code + * uint8_t addresses[][6] = {"1Node","2Node"}; + * radio.openWritingPipe(addresses[0]); + * @endcode + * @code + * uint8_t address[] = { 0xCC,0xCE,0xCC,0xCE,0xCC }; + * radio.openWritingPipe(address); + * address[0] = 0x33; + * radio.openReadingPipe(1,address); + * @endcode + * @see setAddressWidth + * + * @param address The address of the pipe to open. Coordinate these pipe + * addresses amongst nodes on the network. + */ + + void openWritingPipe(const uint8_t *address); + + /** + * Test whether there was a carrier on the line for the + * previous listening period. + * + * Useful to check for interference on the current channel. + * + * @return true if was carrier, false if not + */ + bool testCarrier(void); + + /** + * Test whether a signal (carrier or otherwise) greater than + * or equal to -64dBm is present on the channel. Valid only + * on nRF24L01P (+) hardware. On nRF24L01, use testCarrier(). + * + * Useful to check for interference on the current channel and + * channel hopping strategies. + * + * @code + * bool goodSignal = radio.testRPD(); + * if(radio.available()){ + * Serial.println(goodSignal ? "Strong signal > 64dBm" : "Weak signal < 64dBm" ); + * radio.read(0,0); + * } + * @endcode + * @return true if signal => -64dBm, false if not + */ + bool testRPD(void); - uint8_t getStatus(); + uint8_t getStatus(); }; extern Nrf24l01 nrf24l01; diff --git a/src/app/nrf24l01test/main.cc b/src/app/nrf24l01test/main.cc index f1d7ef0..d0961d4 100644 --- a/src/app/nrf24l01test/main.cc +++ b/src/app/nrf24l01test/main.cc @@ -10,6 +10,8 @@ counter.stop(); \ kout << endl << index << " :: " << dec << counter.value << "/" << counter.overflow << endl; +char buf[32]; + void loop(void) { gpio.led_toggle(1); @@ -33,17 +35,22 @@ void loop(void) } kout << endl; +#ifdef MULTIPASS_ARCH_msp430fr5969lp kout << "write: "; - nrf24l01.setRetries(0, 0); - nrf24l01.setDynamicPayloads(false); - nrf24l01.setDynamicAck(false); - TIMEIT("blocking write(3)", nrf24l01.write("foo", 3, true, true)); - TIMEIT("blocking write(10)", nrf24l01.write("123456789", 10, true, true)); - TIMEIT("blocking write(20)", nrf24l01.write("123456789123456789", 20, true, true)); - //TIMEIT("blocking write(30)", nrf24l01.write("123456789123456789123456789", 30, true, true)); - nrf24l01.startListening(); - arch.delay_ms(10); + //kout << nrf24l01.write("foo", 3, true, true) << " "; + //kout << nrf24l01.write("123456789", 10, true, true) << " "; + kout << nrf24l01.write("123456789123456789", 20, true, true) << endl; +#else + kout << "carrier " << nrf24l01.testCarrier() << " / RPD " << nrf24l01.testRPD(); + if (nrf24l01.available()) { + nrf24l01.read(buf, 32); + kout << " / data = " << buf << endl; + } else { + kout << " / no data" << endl; + } nrf24l01.stopListening(); + nrf24l01.startListening(); +#endif } int main(void) @@ -56,6 +63,22 @@ int main(void) nrf24l01.setup(); kout << " OK" << endl; + kout << "nrf24l01 configure ..."; + unsigned char addr[5] = {0, 'D', 'E', 'R', 'F'}; + //nrf24l01.setAutoAck(1); + //nrf24l01.enableAckPayload(); + nrf24l01.setDynamicPayloads(true); + nrf24l01.setPALevel(Nrf24l01::RF24_PA_MAX); + nrf24l01.setChannel(25); + nrf24l01.setDataRate(Nrf24l01::RF24_2MBPS); +#ifdef MULTIPASS_ARCH_msp430fr5994lp + nrf24l01.openReadingPipe(1, addr); + nrf24l01.startListening(); +#else + nrf24l01.openWritingPipe((const uint8_t*)addr); +#endif + kout << " OK" << endl; + gpio.led_on(0); arch.idle_loop(); diff --git a/src/arch/msp430fr5969lp/Makefile.inc b/src/arch/msp430fr5969lp/Makefile.inc index 244fcc2..912048a 100644 --- a/src/arch/msp430fr5969lp/Makefile.inc +++ b/src/arch/msp430fr5969lp/Makefile.inc @@ -93,7 +93,7 @@ build/system.hex: build/system.elf program: build/system.hex ${QUIET}LD_LIBRARY_PATH=${MSP430_FLASHER_DIR} \ ${MSP430_FLASHER_DIR}/MSP430Flasher \ - -i ${DEBUG_PORT} \ + -i /dev/${DEBUG_PORT} \ -w build/system.hex -v -g -z '[VCC]' arch_clean: diff --git a/src/driver/nrf24l01.cc b/src/driver/nrf24l01.cc index 921f69d..abd42ea 100644 --- a/src/driver/nrf24l01.cc +++ b/src/driver/nrf24l01.cc @@ -77,7 +77,41 @@ void Nrf24l01::setup() // PTX should use only 22uA of power writeRegister(NRF_CONFIG, (readRegister(NRF_CONFIG)) & ~(1 << PRIM_RX)); } - +/* +int Nrf24l01::init(uint8_t addr, uint8_t channel, rf24_datarate_e datarate){ + + if(channel > 125){ + return -1; + } + + unsigned char node_addr[5] = {addr, 'x', 'S', 'D', 'P'}; + + setAutoAck(1); + enableAckPayload(); + maskIRQ(true, true, false); + enableDynamicPayloads(); + setPALevel(RF24_PA_MAX); + setChannel(channel); + setDataRate(datarate); + openWritingPipe((const uint8_t*)GATEWAY_NAME); // GATEWAY_NAME is defined in the MSP430FR5969 RF24_arch_config.h + currentWritingPipe = 0; + openReadingPipe(1, node_addr); +#ifdef CONFIG_Apps_SolarDoorplate_PacketHandler + node_addr[0] = CONFIG_PACKETHANDLER_BROADCAST_ID; + openReadingPipe(2, node_addr); +#endif + if(getChannel() != channel){ + return -2; + } + + if(getDataRate() != datarate){ + return -3; + } + + return 0; + +} +*/ //Power up now. Radio will not power down unless instructed by MCU for config changes etc. void Nrf24l01::powerUp(void) { @@ -172,6 +206,25 @@ void Nrf24l01::toggleFeatures(void) endTransaction(); } +void Nrf24l01::enableAckPayload(void) +{ + // + // enable ack payload and dynamic payload features + // + + //toggle_features(); + writeRegister(FEATURE, readRegister(FEATURE) | (1 << EN_ACK_PAY) | (1 << EN_DPL)); + + //IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE))); + + // + // Enable dynamic payload on pipes 0 & 1 + // + + writeRegister(DYNPD, readRegister(DYNPD) | (1 << DPL_P1) | (1 << DPL_P0)); + dynamic_payloads_enabled = true; +} + void Nrf24l01::setChannel(uint8_t channel) { writeRegister(RF_CH, rf24_min(channel, 125)); @@ -182,16 +235,17 @@ uint8_t Nrf24l01::write(const void *buf, uint8_t len, bool await_ack, bool block writePayload(buf, len, await_ack ? W_TX_PAYLOAD : W_TX_PAYLOAD_NO_ACK); gpio.write(NRF24L01_EN_PIN, 1); - arch.delay_us(10); - gpio.write(NRF24L01_EN_PIN, 0); if (!blocking) { + arch.delay_us(10); + gpio.write(NRF24L01_EN_PIN, 0); return 0; } while (!(getStatus() & ((1 << TX_DS) | (1 << MAX_RT)))) ; + gpio.write(NRF24L01_EN_PIN, 1); uint8_t status = writeRegister(NRF_STATUS, ((1 << TX_DS) | (1 << MAX_RT))); if (status & (1 << MAX_RT)) @@ -241,6 +295,41 @@ void Nrf24l01::stopListening(void) writeRegister(EN_RXADDR, readRegister(EN_RXADDR) | (1 << child_pipe_enable[0])); // Enable RX on pipe0 } +bool Nrf24l01::available(void) +{ + return available(NULL); +} + +/****************************************************************************/ + +bool Nrf24l01::available(uint8_t *pipe_num) +{ + if (!(readRegister(FIFO_STATUS) & (1 << RX_EMPTY))) + { + + // If the caller wants the pipe number, include that + if (pipe_num) + { + uint8_t status = getStatus(); + *pipe_num = (status >> RX_P_NO) & 0b111; + } + return 1; + } + return 0; +} + +bool Nrf24l01::testCarrier(void) +{ + return (readRegister(CD) & 1); +} + +/****************************************************************************/ + +bool Nrf24l01::testRPD(void) +{ + return (readRegister(RPD) & 1); +} + void Nrf24l01::openReadingPipe(uint8_t child, const uint8_t *address) { // If this is pipe 0, cache the address. This is needed because @@ -281,6 +370,29 @@ void Nrf24l01::closeReadingPipe(uint8_t pipe) writeRegister(EN_RXADDR, readRegister(EN_RXADDR) & ~(1 << child_pipe_enable[pipe])); } +/****************************************************************************/ +void Nrf24l01::openWritingPipe(const uint8_t *address) +{ + // Note that AVR 8-bit uC's store this LSB first, and the NRF24L01(+) + // expects it LSB first too, so we're good. + + writeRegister(RX_ADDR_P0, address, addr_width); + writeRegister(TX_ADDR, address, addr_width); + + //const uint8_t max_payload_size = 32; + //write_register(RX_PW_P0,rf24_min(payload_size,max_payload_size)); + writeRegister(RX_PW_P0, payload_size); +} + +void Nrf24l01::setAddressWidth(uint8_t a_width) +{ + if (a_width -= 2) + { + writeRegister(SETUP_AW, a_width % 4); + addr_width = (a_width % 4) + 2; + } +} + void Nrf24l01::maskIRQ(bool tx, bool fail, bool rx) { @@ -338,6 +450,45 @@ uint8_t Nrf24l01::writeRegister(uint8_t reg, uint8_t value) return rxbuf[0]; } +uint8_t Nrf24l01::readPayload(void *buf, uint8_t data_len) +{ + uint8_t status; + uint8_t *current = reinterpret_cast<uint8_t *>(buf); + + if (data_len > payload_size) + data_len = payload_size; + uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len; + + beginTransaction(); + txbuf[0] = R_RX_PAYLOAD; + spi.xmit(1, txbuf, 1, rxbuf); + status = rxbuf[0]; + txbuf[0] = 0xf; + ; + while (data_len--) + { + spi.xmit(1, txbuf, 1, rxbuf); + *current++ = rxbuf[0]; + } + while (blank_len--) + { + spi.xmit(1, txbuf, 1, rxbuf); + } + endTransaction(); + + return status; +} + +void Nrf24l01::read(void *buf, uint8_t len) +{ + + // Fetch the payload + readPayload(buf, len); + + //Clear the two possible interrupt flags with one command + writeRegister(NRF_STATUS, (1 << RX_DR) | (1 << MAX_RT) | (1 << TX_DS)); +} + void Nrf24l01::setDynamicPayloads(const bool enabled) { if (enabled) @@ -368,27 +519,27 @@ void Nrf24l01::setDynamicAck(const bool enabled) void Nrf24l01::setAutoAck(bool enable) { - if ( enable ) - writeRegister(EN_AA, 0b111111); - else - writeRegister(EN_AA, 0); -} - -void Nrf24l01::setAutoAck( uint8_t pipe, bool enable ) -{ - if ( pipe <= 6 ) - { - uint8_t en_aa = readRegister( EN_AA ) ; - if( enable ) - { - en_aa |= (1<<pipe) ; - } - else - { - en_aa &= ~(1<<pipe) ; - } - writeRegister( EN_AA, en_aa ) ; - } + if (enable) + writeRegister(EN_AA, 0b111111); + else + writeRegister(EN_AA, 0); +} + +void Nrf24l01::setAutoAck(uint8_t pipe, bool enable) +{ + if (pipe <= 6) + { + uint8_t en_aa = readRegister(EN_AA); + if (enable) + { + en_aa |= (1 << pipe); + } + else + { + en_aa &= ~(1 << pipe); + } + writeRegister(EN_AA, en_aa); + } } uint8_t Nrf24l01::writePayload(const void *buf, uint8_t data_len, const uint8_t writeType) |