summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <daniel.friesel@uos.de>2019-07-16 12:21:26 +0200
committerDaniel Friesel <daniel.friesel@uos.de>2019-07-16 12:21:26 +0200
commita426c8d552d4b477758f90d6bb08619fb1ff3edd (patch)
tree602c80f8160a10837d5a562d6c5036dae6bf45f9
parent946db125a96c805df5b411b18c729d3173a6c7d7 (diff)
Working Nrf24 ping-pong
-rw-r--r--Makefile13
-rw-r--r--include/driver/nrf24l01.h340
-rw-r--r--src/app/nrf24l01test/main.cc41
-rw-r--r--src/arch/msp430fr5969lp/Makefile.inc2
-rw-r--r--src/driver/nrf24l01.cc199
5 files changed, 441 insertions, 154 deletions
diff --git a/Makefile b/Makefile
index 5740eec..f9c245e 100644
--- a/Makefile
+++ b/Makefile
@@ -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 &copy);
- 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 &copy);
+ 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)