From f0ad73ff8fe391d2aac4bc437128618647d46b4f Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Tue, 25 Jun 2019 12:02:33 +0200 Subject: Nrf24: dynamic payload size and dynamic acks --- include/driver/nrf24l01.h | 26 +++++++++++++++++++++++++- src/app/nrf24l01test/main.cc | 36 ++++++++++++++++++++++++++++++++++-- src/driver/nrf24l01.cc | 29 ++++++++++++++++++++++++++--- 3 files changed, 85 insertions(+), 6 deletions(-) diff --git a/include/driver/nrf24l01.h b/include/driver/nrf24l01.h index 44f8205..82297bd 100644 --- a/include/driver/nrf24l01.h +++ b/include/driver/nrf24l01.h @@ -265,6 +265,30 @@ public: * are enabled. See the datasheet for details. */ void toggleFeatures(void); + + /** + * Enable dynamically-sized payloads + * + * This way you don't always have to send large packets just to send them + * once in a while. This enables dynamic payloads on ALL pipes. + * + */ + void enableDynamicPayloads(void); + + /** + * Enable dynamic ACKs (single write multicast or unicast) for chosen messages + * + * @note To enable full multicast or per-pipe multicast, use setAutoAck() + * + * @warning This MUST be called prior to attempting single write NOACK calls + * @code + * radio.enableDynamicAck(); + * radio.write(&data,32,1); // Sends a payload with no acknowledgement requested + * radio.write(&data,32,0); // Sends a payload using auto-retry/autoACK + * @endcode + */ + void enableDynamicAck(); + /** * Be sure to call openWritingPipe() first to set the destination * of where to write to. @@ -288,7 +312,7 @@ public: * @endcode * @return True if the payload was delivered successfully false if not */ - uint8_t write(const void *buf, uint8_t len, bool blocking); + uint8_t write(const void *buf, uint8_t len, bool await_ack, bool blocking); /** * Start listening on the pipes opened for reading. diff --git a/src/app/nrf24l01test/main.cc b/src/app/nrf24l01test/main.cc index ad1bc11..187a9c1 100644 --- a/src/app/nrf24l01test/main.cc +++ b/src/app/nrf24l01test/main.cc @@ -2,13 +2,45 @@ #include "driver/gpio.h" #include "driver/stdout.h" #include "driver/nrf24l01.h" +#include "driver/counter.h" + +#define TIMEIT(index, functioncall) \ + counter.start(); \ + functioncall; \ + counter.stop(); \ + kout << endl << index << " :: " << dec << counter.value << "/" << counter.overflow << endl; void loop(void) { gpio.led_toggle(1); - kout << "status: " << hex << nrf24l01.getStatus() << endl; + uint8_t status = nrf24l01.getStatus(); + + kout << "status: " << hex << status; + if (status & 0x40) { + kout << " RX_DR"; + } + if (status & 0x20) { + kout << " TX_DS"; + } + if (status & 0x10) { + kout << " MAX_RT"; + } + if ((status & 0x0e) == 0x0e) { + kout << " RX_EMPTY"; + } + if (status & 0x01) { + kout << " TX_FULL"; + } + kout << endl; + kout << "write: "; - kout << nrf24l01.write("foo", 3, true) << endl; + nrf24l01.setRetries(0, 0); + nrf24l01.enableDynamicPayloads(); + nrf24l01.enableDynamicAck(); + TIMEIT("blocking write(3)", nrf24l01.write("foo", 3, false, true)); + TIMEIT("blocking write(10)", nrf24l01.write("123456789", 10, false, true)); + TIMEIT("blocking write(20)", nrf24l01.write("123456789123456789", 20, false, true)); + TIMEIT("blocking write(30)", nrf24l01.write("123456789123456789123456789", 30, false, true)); nrf24l01.startListening(); arch.delay_ms(10); nrf24l01.stopListening(); diff --git a/src/driver/nrf24l01.cc b/src/driver/nrf24l01.cc index 5992b17..a678655 100644 --- a/src/driver/nrf24l01.cc +++ b/src/driver/nrf24l01.cc @@ -166,9 +166,9 @@ void Nrf24l01::setChannel(uint8_t channel) writeRegister(RF_CH, rf24_min(channel, 125)); } -uint8_t Nrf24l01::write(const void *buf, uint8_t len, bool blocking) +uint8_t Nrf24l01::write(const void *buf, uint8_t len, bool await_ack, bool blocking) { - writePayload(buf, len, W_TX_PAYLOAD); + writePayload(buf, len, await_ack ? W_TX_PAYLOAD : W_TX_PAYLOAD_NO_ACK); gpio.write(NRF24L01_EN_PIN, 1); arch.delay_us(10); @@ -185,7 +185,7 @@ uint8_t Nrf24l01::write(const void *buf, uint8_t len, bool blocking) if (status & (1 << MAX_RT)) { - // flush_tx(); //Only going to be 1 packet int the FIFO at a time using this method, so just flush + flushTx(); return 0; } return 1; @@ -327,6 +327,29 @@ uint8_t Nrf24l01::writeRegister(uint8_t reg, uint8_t value) return rxbuf[0]; } +void Nrf24l01::enableDynamicPayloads(void) +{ + // Enable dynamic payload throughout the system + + //toggle_features(); + writeRegister(FEATURE, readRegister(FEATURE) | (1 << EN_DPL)); + + //IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE))); + + // Enable dynamic payload on all pipes + // + // Not sure the use case of only having dynamic payload on certain + // pipes, so the library does not support it. + writeRegister(DYNPD, readRegister(DYNPD) | (1 << DPL_P5) | (1 << DPL_P4) | (1 << DPL_P3) | (1 << DPL_P2) | (1 << DPL_P1) | (1 << DPL_P0)); + + dynamic_payloads_enabled = true; +} + +void Nrf24l01::enableDynamicAck(void) +{ + writeRegister(FEATURE, readRegister(FEATURE) | (1 << EN_DYN_ACK)); +} + uint8_t Nrf24l01::writePayload(const void *buf, uint8_t data_len, const uint8_t writeType) { data_len = rf24_min(data_len, payload_size); -- cgit v1.2.3