From 02b28c8dcf33f289df10dae7a2b5a16ee0c4b9ee Mon Sep 17 00:00:00 2001 From: Brendan <2bndy5@gmail.com> Date: Sat, 17 Feb 2024 04:05:59 -0800 Subject: [PATCH] separate ISR handling from IRQ processing --- .../InterruptConfigure/InterruptConfigure.ino | 75 ++++++++++--------- examples_linux/interruptConfigure.cpp | 27 +++---- 2 files changed, 55 insertions(+), 47 deletions(-) diff --git a/examples/InterruptConfigure/InterruptConfigure.ino b/examples/InterruptConfigure/InterruptConfigure.ino index bae6dff8..c95750e4 100644 --- a/examples/InterruptConfigure/InterruptConfigure.ino +++ b/examples/InterruptConfigure/InterruptConfigure.ino @@ -18,8 +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 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 +bool wait_for_event = false; // used to wait for an IRQ event to trigger #define CE_PIN 7 #define CSN_PIN 8 @@ -136,6 +137,42 @@ 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; + } if (role && !wait_for_event) { // delay(1); // wait for IRQ pin to fully RISE @@ -271,6 +308,7 @@ void loop() { // Fill the TX FIFO with 3 ACK payloads for the first 3 received // transmissions on pipe 1 radio.flush_tx(); // make sure there is room for 3 new ACK payloads + radio.flush_rx(); // make sure there is room for 3 incoming payloads 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); @@ -284,38 +322,7 @@ void loop() { * when the IRQ pin goes active LOW, call this fuction print out why */ void interruptHandler() { - // 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 = true; wait_for_event = false; // ready to continue with loop() operations } // interruptHandler diff --git a/examples_linux/interruptConfigure.cpp b/examples_linux/interruptConfigure.cpp index 22de739d..25cea06f 100644 --- a/examples_linux/interruptConfigure.cpp +++ b/examples_linux/interruptConfigure.cpp @@ -25,7 +25,7 @@ using namespace std; #define IRQ_PIN 12 // this needs to be a digital input capable pin // this example is a sequential program. so we need to wait for the event to be handled -volatile bool wait_for_event = false; // used to signify that the event is handled +volatile bool got_interrupt = false; // used to signify that the event started /****************** Linux ***********************/ // Radio CE Pin, CSN Pin, SPI Speed @@ -245,12 +245,12 @@ void slave() */ void ping_n_wait() { + got_interrupt = false; + // use the non-blocking call to write a payload and begin transmission // the "false" argument means we are expecting an ACK packet response radio.startFastWrite(tx_payloads[pl_iterator], tx_pl_size, false); - - wait_for_event = true; - while (wait_for_event) { + while (!got_interrupt) { /* * IRQ pin is LOW when activated. Otherwise it is always HIGH * Wait in this empty loop until IRQ pin is activated. @@ -260,13 +260,6 @@ void ping_n_wait() * default, we don't need a timeout check to prevent an infinite loop. */ } -} - -/** - * when the IRQ pin goes active LOW, call this fuction print out why - */ -void interruptHandler() -{ // print IRQ status and all masking flags' states cout << "\tIRQ pin is actively LOW" << endl; // show that this function was called @@ -292,8 +285,16 @@ void interruptHandler() else if (pl_iterator == 3) cout << " 'Data Fail' event test " << (tx_df ? "passed" : "failed") << endl; - wait_for_event = false; // ready to continue -} // interruptHandler + got_interrupt = false; +} + +/** + * when the IRQ pin goes active LOW, call this fuction print out why + */ +void interruptHandler() +{ + got_interrupt = true; // ready to continue +} /** * Print the entire RX FIFO with one buffer. This will also flush the RX FIFO.