Hello all,

I have been working on LIN implementations on Teensy4.1, basing most everything I do from the LIN libraries from Markus Lange https://github.com/MarkusLange/Teens..._LC_LIN_Master

What I am trying to do is trigger an interrupt when the Break field of the LIN bus is detected. In my software below, when I enable the ISR and do not transmit any LIN frames from my external LIN tool, the ISR is never called.

As soon as I transmit a single LIN frame, the ISR gets repeated called and never stops. This infinite ISR the jams up the entire µC and stops the board LED heartbeat.

In the Setup() function, I output the values of the registers LPUART4_STAT, LPUART4_CTRL, and LPUART4_BAUD as a reference. The initial results are:

LPUART4_STAT = 0x04800000
LPUART4_CTRL = 0x003C0000
LPUART4_BAUD = 0x1F008048
Once I transmit out one LIN frame, then I receive this infinite stream of data - please look at the ISR code for the byte order
LIN2 Rx ISR Count: 0 3 45E2C000 5E00000 3C0000 1F008048
LIN2 Rx ISR Count: 1 3 5E00000 5E00000 3C0000 1F008048
LIN2 Rx ISR Count: 2 3 5E00000 5E00000 3C0000 1F008048
LIN2 Rx ISR Count: 3 3 5E00000 5E00000 3C0000 1F008048
LIN2 Rx ISR Count: 4 3 5E00000 5E00000 3C0000 1F008048
From this, I can see that LPUART4_CTRL, and LPUART4_BAUD do not change when the interrupt is called.

Over time, LPUART4_STAT goes from 0x05E00000 to 0x04E00000 - no clue why.

Does anyone know how to stop this infinite interrupt? For example, in the QuadTimer interrupts, you must manually clear the affected interrupt bit - I just cant seem to find that here for the LPUART.

Thank You!

Code:
unsigned long LIN_Baudrate = 19200;
unsigned long LIN2_Rx_Counter = 0;
const int pin_LED = 13;
boolean LED_St = 0;

unsigned long t1,t2,t3;
///////////////////////////////////////////////////////////////////////////////////////////////
void setup() 
{ 
  pinMode(pin_LED,OUTPUT);
  digitalWrite(pin_LED,LED_St);  
  LIN_Setup();

  //Just for reference sake
  Serial.print(LPUART4_STAT,HEX);
  Serial.print(" ");
  Serial.print(LPUART4_CTRL,HEX);
  Serial.print(" ");
  Serial.println(LPUART4_BAUD,HEX);

  t1 = millis();
  t2 = t1;
}
///////////////////////////////////////////////////////////////////////////////////////////////
void loop() 
{
  //Heartbeat Function
  if((t1-t2) >= 500)
  {
    LED_St = !LED_St;
    digitalWrite(pin_LED,LED_St);
    t2 = t1;
  }  
}
///////////////////////////////////////////////////////////////////////////////////////////////
void LIN_Setup()
{
  //Set Baudrate
  Serial2.begin(LIN_Baudate);   

  //Allows for LIN Break detection
  LPUART4_BAUD |= LPUART_BAUD_LBKDIE; 

  //Transmit Setup - LIN Master
  LPUART4_STAT |= LPUART_STAT_BRK13;
  LPUART4_BAUD &= ~LPUART_BAUD_SBNS;
  LPUART4_CTRL &= ~LPUART_CTRL_M;
  LPUART4_BAUD &= ~LPUART_BAUD_M10;
  LPUART4_CTRL &= ~LPUART_CTRL_M7;

  //LIN Rx Interrupt Enable
  attachInterruptVector(IRQ_LPUART4, LIN_Rx_ISR);
  NVIC_ENABLE_IRQ(IRQ_LPUART4);
}
///////////////////////////////////////////////////////////////////////////////////////////////
void LIN_Rx_ISR()
{
  int NumBytes = 0;

  //Count number of times this ISR has been visited
  Serial.print("LIN2 Rx ISR Count: ");
  Serial.print(LIN2_Rx_Counter);
  Serial.print(" ");
  LIN2_Rx_Counter = LIN2_Rx_Counter + 1;
  
  NumBytes = Serial2.available();
  Serial.print(NumBytes);
  Serial.print(" ");
  Serial.print(LPUART4_STAT,HEX);
  Serial.print(" ");

  //If the LBKDIF bit set within STAT register, write a 1 to this location to clear it
  if((LPUART4_STAT & LPUART_STAT_LBKDIF) > 0)
  {
    LPUART4_STAT |= LPUART_STAT_LBKDIF; //Resets this bit back to 0    
  }

  //Here I am just statically setting this to zero
  LPUART4_STAT &= ~(LPUART_STAT_LBKDIF); 

  //At this point, I am out of ideas
  LPUART4_STAT = 0x04800000;
  Serial.print(LPUART4_STAT,HEX);
  Serial.print(" ");

  //The 2 registers below are just for reference
  Serial.print(LPUART4_CTRL,HEX);
  Serial.print(" ");
  Serial.print(LPUART4_BAUD,HEX);
  Serial.println();
  __asm volatile ("dsb"); 
}