UART Interrupt

Status
Not open for further replies.

brtaylor

Well-known member
Hi all, I'm working on improving some classes that I have to read and interpret sensor data, which is sent to one of the Teensy Hardware Serial ports. Currently, my classes require calling a data collection function within void loop(), which reads any available serial data and runs it through a parser. Once the parser finds a good packet the results are stored and used later.

What I would like is an interrupt when the hardware serial receives a byte. Within my interrupt function, I would like to read that byte and store it within a ring buffer. Outside of the interrupt context, when the sensor data is actually being used, I would like to then feed the ring buffer into my parser and use the contents of the newest packet.

The issue that I am having is finding a way to attach an interrupt to the hardware serial receiving data. I looked at eventResponder, but didn't see how I could attach a function to the hardware serial receiving data...
 
Hi,

you are probably searching something like this:
Code:
class interruptChain {
  public:

    void chainInterrupt(int intNumber, void (*interruptPtr)(void)) {
        prevInterruptPtr = _VectorsRam[intNumber];
        _VectorsRam[intNumber] = interruptPtr
    }

    inline void callNext(void) {
      prevInterruptPtr();
    }

  protected:
    void (*prevInterruptPtr)(void);
};


interruptChain mySerialInterrupt;

void mySerialInterruptFunction(void) {
  mySerialInterrupt.callNext();
  if (Serial1.available()) {
    
    //Add your Code here
    
  }
  
}

void setup() {

  mySerialInterrupt.chainInterrupt(IRQ_UART0_STATUS, mySerialInterruptFunction);

}

void loop() {

}

(untested)
The "problem" is, the core already needs the original interrupt. The code above redirects the original intvector to your new function and calls it before " //Add your Code here"
You can re-use the class for all interrupts just by adding more "interruptChain" variables.
 
Last edited:
Hi,

you are probably searching something like this:
Code:
class interruptChain {
  public:

    void chainInterrupt(int intNumber, void (*interruptPtr)(void)) {
        prevInterruptPtr = _VectorsRam[intNumber];
        _VectorsRam[intNumber] = interruptPtr
    }

    inline void callNext(void) {
      prevInterruptPtr();
    }

  protected:
    void (*prevInterruptPtr)(void);
};


interruptChain mySerialInterrupt;

void mySerialInterruptFunction(void) {
  mySerialInterrupt.callNext();
  if (Serial1.available()) {
    
    //Add your Code here
    
  }
  
}

void setup() {

  mySerialInterrupt.chainInterrupt(IRQ_UART0_STATUS, mySerialInterruptFunction);

}

void loop() {

}

(untested)
The "problem" is, the core already needs the original interrupt. The code above redirects the original intvector to your new function and calls it before " //Add your Code here"
You can re-use the class for all interrupts just by adding more "interruptChain" variables.

Thanks! This looks like what I'm seeking, but it's not fully working. I try the following code on a Teensy 3.2:

Code:
class interruptChain {
  public:

    void chainInterrupt(int intNumber, void (*interruptPtr)(void)) {
        prevInterruptPtr = _VectorsRam[intNumber];
        _VectorsRam[intNumber] = interruptPtr;
    }

    inline void callNext(void) {
      prevInterruptPtr();
    }

  protected:
    void (*prevInterruptPtr)(void);
};

interruptChain mySerialInterrupt;

void mySerialInterruptFunction(void) {
  mySerialInterrupt.callNext();
  Serial.println("Interrupt");
  if (Serial1.available()) {
    Serial.println(Serial1.read(),HEX); 
  }
}

void setup() {
  Serial1.begin(100000,SERIAL_8E1_RXINV_TXINV);
  Serial.begin(115200);
  while(!Serial){}
  mySerialInterrupt.chainInterrupt(IRQ_UART0_STATUS, mySerialInterruptFunction);

}

void loop() {}

However, if I try this very simple example, I get output as expected:
Code:
void setup() {
  Serial1.begin(100000,SERIAL_8E1_RXINV_TXINV);
  Serial.begin(115200);
  while(!Serial){}
}

void loop() {
  if (Serial1.available()) {
    Serial.println(Serial1.read(),HEX);
  }
}
 
Ah, sorry, you have to add 16 :
mySerialInterrupt.chainInterrupt(IRQ_UART0_STATUS + 16, mySerialInterruptFunction);

Edit:
LOL,.. don't know... this 16-offset is always a source of confusion for me..
 
Ah, sorry, you have to add 16 :
mySerialInterrupt.chainInterrupt(IRQ_UART0_STATUS + 16, mySerialInterruptFunction);

Edit:
LOL,.. don't know... this 16-offset is always a source of confusion for me..

Awesome! Works great with the 16-offset.
 
Status
Not open for further replies.
Back
Top