From 7680fa338bb2ae12c17d3d03bd575a2b5ee4b113 Mon Sep 17 00:00:00 2001 From: Brendan <2bndy5@gmail.com> Date: Thu, 7 Mar 2024 23:22:13 -0800 Subject: [PATCH] tested pico and arduino interruptConfigure examples --- .../InterruptConfigure/InterruptConfigure.ino | 121 +++++++++--------- examples_linux/interruptConfigure.cpp | 3 +- examples_pico/interruptConfigure.cpp | 24 +++- 3 files changed, 83 insertions(+), 65 deletions(-) diff --git a/examples/InterruptConfigure/InterruptConfigure.ino b/examples/InterruptConfigure/InterruptConfigure.ino index c95750e49..19ef9c504 100644 --- a/examples/InterruptConfigure/InterruptConfigure.ino +++ b/examples/InterruptConfigure/InterruptConfigure.ino @@ -18,9 +18,9 @@ #include "RF24.h" // We will be using the nRF24L01's IRQ pin for this example -#define IRQ_PIN 2 // this needs to be a digital input capable pin -volatile bool got_interrupt = false; // used to signal processing of interrupt -bool wait_for_event = false; // used to wait for an IRQ event to trigger +#define IRQ_PIN 2 // this needs to be a digital input capable pin +volatile bool got_interrupt = false; // used to signal processing of interrupt +volatile bool wait_for_event = false; // used to wait for an IRQ event to trigger #define CE_PIN 7 #define CSN_PIN 8 @@ -138,44 +138,10 @@ void setup() { void loop() { if (got_interrupt) { - // print IRQ status and all masking flags' states - - Serial.println(F("\tIRQ pin is actively LOW")); // show that this function was called - delayMicroseconds(250); - bool tx_ds, tx_df, rx_dr; // declare variables for IRQ masks - radio.whatHappened(tx_ds, tx_df, rx_dr); // get values for IRQ masks - // whatHappened() clears the IRQ masks also. This is required for - // continued TX operations when a transmission fails. - // clearing the IRQ masks resets the IRQ pin to its inactive state (HIGH) - - Serial.print(F("\tdata_sent: ")); - Serial.print(tx_ds); // print "data sent" mask state - Serial.print(F(", data_fail: ")); - Serial.print(tx_df); // print "data fail" mask state - Serial.print(F(", data_ready: ")); - Serial.println(rx_dr); // print "data ready" mask state - - if (tx_df) // if TX payload failed - radio.flush_tx(); // clear all payloads from the TX FIFO - - // print if test passed or failed. Unintentional fails mean the RX node was not listening. - // pl_iterator has already been incremented by now - if (pl_iterator <= 1) { - Serial.print(F(" 'Data Ready' event test ")); - Serial.println(rx_dr ? F("passed") : F("failed")); - } else if (pl_iterator == 2) { - Serial.print(F(" 'Data Sent' event test ")); - Serial.println(tx_ds ? F("passed") : F("failed")); - } else if (pl_iterator == 4) { - Serial.print(F(" 'Data Fail' event test ")); - Serial.println(tx_df ? F("passed") : F("failed")); - } - got_interrupt = false; - wait_for_event = false; + assessInterruptEvent(); } - if (role && !wait_for_event) { - // delay(1); // wait for IRQ pin to fully RISE + if (role && !wait_for_event) { // This device is a TX node. This if block is only triggered when // NOT waiting for an IRQ event to happen @@ -255,25 +221,22 @@ void loop() { pl_iterator++; // proceed from step 3 to last step (stop at step 4 for readability) } - } else if (!role) { - // This device is a RX node - - if (radio.rxFifoFull()) { - // wait until RX FIFO is full then stop listening + } else if (!role && radio.rxFifoFull()) { + // This device is a RX node: + // wait until RX FIFO is full then stop listening - delay(100); // let ACK payload finish transmitting - radio.stopListening(); // also discards unused ACK payloads - printRxFifo(); // flush the RX FIFO + delay(100); // let ACK payload finish transmitting + radio.stopListening(); // also discards unused ACK payloads + printRxFifo(); // flush the RX FIFO - // Fill the TX FIFO with 3 ACK payloads for the first 3 received - // transmissions on pipe 1. - radio.writeAckPayload(1, &ack_payloads[0], ack_pl_size); - radio.writeAckPayload(1, &ack_payloads[1], ack_pl_size); - radio.writeAckPayload(1, &ack_payloads[2], ack_pl_size); + // Fill the TX FIFO with 3 ACK payloads for the first 3 received + // transmissions on pipe 1. + radio.writeAckPayload(1, &ack_payloads[0], ack_pl_size); + radio.writeAckPayload(1, &ack_payloads[1], ack_pl_size); + radio.writeAckPayload(1, &ack_payloads[2], ack_pl_size); - delay(100); // let TX node finish its role - radio.startListening(); // We're ready to start over. Begin listening. - } + delay(100); // let TX node finish its role + radio.startListening(); // We're ready to start over. Begin listening. } // role @@ -319,13 +282,53 @@ void loop() { /** - * when the IRQ pin goes active LOW, call this fuction print out why + * when the IRQ pin goes active LOW. + * Here we just tell the main loop() to call `assessInterruptEve4nt()`. */ void interruptHandler() { - got_interrupt = true; - wait_for_event = false; // ready to continue with loop() operations -} // interruptHandler + got_interrupt = true; // forward event handling back to main loop() +} +/** + * Called when an event has been triggered. + * Here, we want to verify the expected IRQ flag has been asserted. + */ +void assessInterruptEvent() { + // print IRQ status and all masking flags' states + + Serial.println(F("\tIRQ pin is actively LOW")); // show that this function was called + delayMicroseconds(250); + bool tx_ds, tx_df, rx_dr; // declare variables for IRQ masks + radio.whatHappened(tx_ds, tx_df, rx_dr); // get values for IRQ masks + // whatHappened() clears the IRQ masks also. This is required for + // continued TX operations when a transmission fails. + // clearing the IRQ masks resets the IRQ pin to its inactive state (HIGH) + + Serial.print(F("\tdata_sent: ")); + Serial.print(tx_ds); // print "data sent" mask state + Serial.print(F(", data_fail: ")); + Serial.print(tx_df); // print "data fail" mask state + Serial.print(F(", data_ready: ")); + Serial.println(rx_dr); // print "data ready" mask state + + if (tx_df) // if TX payload failed + radio.flush_tx(); // clear all payloads from the TX FIFO + + // print if test passed or failed. Unintentional fails mean the RX node was not listening. + // pl_iterator has already been incremented by now + if (pl_iterator <= 1) { + Serial.print(F(" 'Data Ready' event test ")); + Serial.println(rx_dr ? F("passed") : F("failed")); + } else if (pl_iterator == 2) { + Serial.print(F(" 'Data Sent' event test ")); + Serial.println(tx_ds ? F("passed") : F("failed")); + } else if (pl_iterator == 4) { + Serial.print(F(" 'Data Fail' event test ")); + Serial.println(tx_df ? F("passed") : F("failed")); + } + got_interrupt = false; // reset this flag to prevent calling this function from loop() + wait_for_event = false; // ready to continue with loop() operations +} /** * Print the entire RX FIFO with one buffer. This will also flush the RX FIFO. diff --git a/examples_linux/interruptConfigure.cpp b/examples_linux/interruptConfigure.cpp index 25cea06f3..99694d5fc 100644 --- a/examples_linux/interruptConfigure.cpp +++ b/examples_linux/interruptConfigure.cpp @@ -289,7 +289,8 @@ void ping_n_wait() } /** - * when the IRQ pin goes active LOW, call this fuction print out why + * when the IRQ pin goes active LOW. + * Here we just set a flag to unblock ping_n_wait() */ void interruptHandler() { diff --git a/examples_pico/interruptConfigure.cpp b/examples_pico/interruptConfigure.cpp index 0b59aff6b..27a272696 100644 --- a/examples_pico/interruptConfigure.cpp +++ b/examples_pico/interruptConfigure.cpp @@ -21,6 +21,7 @@ // We will be using the nRF24L01's IRQ pin for this example volatile bool wait_for_event = false; // used to wait for an IRQ event to trigger +volatile bool got_interrupt = false; // used to signal when an IRQ event has been triggered // instantiate an object for the nRF24L01 transceiver RF24 radio(CE_PIN, CSN_PIN); @@ -40,6 +41,7 @@ char ack_payloads[][ack_pl_size + 1] = {"Yak ", "Back", " ACK"}; void interruptHandler(uint gpio, uint32_t events); // prototype to handle IRQ events void printRxFifo(); // prototype to print RX FIFO with 1 buffer +void assessInterruptEvent(); // prototype to assess IRQ flags triggered bool setup() { @@ -121,7 +123,6 @@ bool setup() } // For debugging info - // printf_begin(); // needed only once for printing details // radio.printDetails(); // (smaller) function that prints raw register values // radio.printPrettyDetails(); // (larger) function that prints human readable data @@ -231,6 +232,10 @@ void loop() } // role + if (got_interrupt) { + assessInterruptEvent(); + } + char input = getchar_timeout_us(0); // get char from buffer for user input if (input != PICO_ERROR_TIMEOUT) { // change the role via the serial terminal @@ -239,7 +244,7 @@ void loop() // Become the TX node if (!role) printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n"); - else if (role && wait_for_event) // don't interrupt on ongoing test + else if (role && wait_for_event) // don't interrupt an ongoing test return; // exit now; start next loop() else printf("*** RESTARTING IRQ PIN TEST ***\n"); @@ -277,16 +282,24 @@ void loop() } // loop /** - * when the IRQ pin goes active LOW, call this fuction print out why + * when the IRQ pin goes active LOW. + * Here we just tell the main loop() to call `assessInterruptEve4nt()`. */ void interruptHandler(uint gpio, uint32_t events) { - if (gpio != IRQ_PIN && !(events | GPIO_IRQ_EDGE_FALL)) { // the gpio pin and event does not match the configuration we specified return; } + got_interrupt = true; // forward event handling back to main loop() +} +/** + * Called when an event has been triggered. + * Here, we want to verify the expected IRQ flag has been asserted. + */ +void assessInterruptEvent() +{ // print IRQ status and all masking flags' states printf("\tIRQ pin is actively LOW\n"); // show that this function was called bool tx_ds, tx_df, rx_dr; // declare variables for IRQ masks @@ -315,8 +328,9 @@ void interruptHandler(uint gpio, uint32_t events) else if (pl_iterator == 4) { printf(" 'Data Fail' event test %s\n", tx_df ? "passed" : "failed"); } + got_interrupt = false; // reset this flag to prevent calling this function from loop() wait_for_event = false; // ready to continue with loop() operations -} // interruptHandler +} /** * Print the entire RX FIFO with one buffer. This will also flush the RX FIFO.