Interrupts

I’m having trouble understanding how (or if) the Imp implements interrupts. I am writing the receive part of an NRF24 library. When a valid packet is in the receive FIFO of this device a falling edge is generated it’s IRQ line. When I implement the receive code on a PIC this falling edge triggers a interrupt service routine, in which a simple flag, dataWaiting, is set. Back in the main loop this flag state change is detected and the received data is handled, all of this happens within a few milli seconds and so the danger of lost packets is low.

I understand that the Imp should not be put into an infinite loop as the TCP stuff won’t get handled however using imp.wakeup(1, checkIfNrfHasDataWaiting); doesn’t seem like a good way to check if a packet has been received as there seems a good chance of the RX FIFO buffer overflowing before it gets checked and cleared - even with a much smaller timer being set. Is it possible to put the Imp in to some state where the TCP stuff still gets handled AND if there is a falling edge on the IRQ line a (high priority) interrupt service routine is called to handle this?

I’m managing to set a dataReceived flag when the IRQ falls using the digitalIn callback however this doesn’t seem to fully override the wakeup timer.

As I said at the start, I feel like I’m not grasping some key concept of how the Imp handles callbacks and interrupts - pointers would be appreciated.

Would an Imp based FIFO array, where the NRF24 stores it’s data, be a solution?

I think someone has already written a library for NRF24 https://github.com/stanleyseow/electricimp-nRF24L01

The UART has a callback
https://electricimp.com/docs/api/hardware/uart/configure/

@DolfTraanberg yes, that would work.

I’ve managed to wrap my head around this a bit more overnight and I’ve realised I’m treating the callback function for the digital input change as an interrupt service routine (ie: trying to do as little as possible in it as you would with a typical ISR) however there’s no reason for this to be the case (since it’s not an ISR) so I’m just going to handle the data in the pin change function.

I think the conceptual problem I was having is understanding that the imp doesn’t have an infinite main loop so doesn’t have somewhere to “go back to” once interrupt is handled.

@controlCloud I spent some time with this library over the weekend but couldn’t get a link established between the Imp and remote PIC so decided to port the one I was using on the PIC. It’s good to have options for libraries :slight_smile:

Ok , I made a circular FIFO array, which has as an advantage that it can’t overrun!
Maybe some Squirrel guru can turn this in a class…
imp.enableblinkup(false); const ARRAY_LENGHT = 10; const SAMPLE_TIME = 1.0; local front = -1; local rear = -1; ARRAY <- []; ARRAY.resize(ARRAY_LENGHT, "empty"); server.log("ARRAY_LENGHT: " + ARRAY.len() + " cells"); function showArrayContent(){ server.log(" "); foreach(i,val in ARRAY){ if((rear == i) && (ARRAY[rear] != "empty")){ server.log("ARRAY["+i+"] = " + val + " <- replaced "); }else{ server.log("ARRAY["+i+"] = " + val ); } //server.log("ARRAY["+i+"] typeof = " + ARRAY[i].typeof() + "\ "); } } function IsEmpty(){ if( front == -1 && rear == -1){ return true; } else{ return false; } }; function IsFull(){ //if(rear == (ARRAY.len() - 1)){ if(rear == (ARRAY_LENGHT - 1)){ return true; }else{ return false; } }; function Enqueue(x){ if(rear + 1 %ARRAY_LENGHT == front){ return }else{ if(IsEmpty()){ front = 0; rear = 0; }else{ rear = (rear + 1) %ARRAY_LENGHT; } } ARRAY[rear] = x; }; /* function Dequeue(){ if(IsEmpty()){ return; } else{ server.log("Dequeued...") if(front==rear){ front = -1; rear = -1; } else{ front = (front + 1) ; } } }; */ function triggerInput(){ Enqueue(hardware.lightlevel()); showArrayContent() imp.wakeup(SAMPLE_TIME, triggerInput); } triggerInput();

Take a look at the state diagram
http://electricimp.com/docs/resources/wifistatediagram/

Basically if no events then Device and Agent go to idle.
My understanding is both Device & Agent use an event reactor often called an even loop hence you will see references to blocking and non blocking IO operations. May be one way is to think of the Device & Agent ruining the main loop for you. Hear’s a short bit on event loops http://berb.github.io/diploma-thesis/original/042_serverarch.html#event