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/Teensy_3.x_4.x_and_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:
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
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!
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/Teensy_3.x_4.x_and_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");
}