LIN Bus - Slave node detect Break Pulse

Dimitri

Well-known member
Hi All,

Has anyone been able to detect a LIN bus break pulse? I am trying to build a LIN bus sniffer and would like to actually detect the 13 dominant (low) bits that indicate Start-Of-Frame.

Thanks!
 
Progress

Hi Everyone,

I am able to detect the Break Pulse! - However when I do this, I am unable to read the incoming data bytes. Serial2.available() always returns zero. When I go into the i.MX RT documentation, I see that by enabling Break detection, the data buffer packing is disabled (happens when LBKDE bit of STAT register is set)..... If anyone has any ideas, please let me know!

If you go to the i.MX RT documentation and go to page 2924 (total pages: 3522) you'll see the STAT register definitions, and LBKDE is bit 25.

It Reads:
LIN Break Detection Enable
LBKDE selects a longer break character detection length. While LBKDE is set, receive data is not stored
in the receive FIFO.
NOTE: The LBKDE bit enables the LIN break detect circuit and disables writing receive data to FIFO. So
it essentially ignores all characters except a LIN break.
0b - LIN break detect is disabled, normal break character can be detected.
1b - LIN break detect is enabled. LIN break character is detected at length of 11 bit times (if M = 0)
or 12 (if M = 1) or 13 (M10 = 1).

Now for what I did....

Go into HardwareSerial.cpp and within
void HardwareSerial::begin(uint32_t baud, uint16_t format)
add the following code:

Code:
port->STAT |= LPUART_STAT_BRK13;
port->STAT |= LPUART_STAT_LBKDE;


In the ISR
void HardwareSerial::IRQHandler()
I add the following code to process the Break generated interrupt.

Code:
if(port->STAT & LPUART_STAT_LBKDIF)
{
	LIN_Break_Cnt++;
	LIN_Break_Detected = 1;
	port->STAT |= LPUART_STAT_LBKDIF;
}

I also add these functions - The one returns how many Breaks have been detected and the other returns if a LIN break is currently detected.

Code:
unsigned int HardwareSerial::LIN_GetBreakNum()
{
	//LIN_Break_Cnt++;
	return LIN_Break_Cnt;
}

bool HardwareSerial::LIN_Available()
{
	bool TempVal;
	
	TempVal = LIN_Break_Detected;
	LIN_Break_Detected = 0;
	
	return TempVal;
}

Within HardwareSerial.h, in the public area of
class HardwareSerial : public Stream
I add function declarations:
Code:
unsigned int LIN_GetBreakNum();
bool LIN_Available();

In the private area of the class, I add the variables:
Code:
unsigned int LIN_Break_Cnt = 0;
bool LIN_Break_Detected = 0;
 
Hi Everyone,

I am able to detect the Break Pulse! - However when I do this, I am unable to read the incoming data bytes. Serial2.available() always returns zero. When I go into the i.MX RT documentation, I see that by enabling Break detection, the data buffer packing is disabled (happens when LBKDE bit of STAT register is set)..... If anyone has any ideas, please let me know!

OK, so here's an unconventional approach that might potentially work for you as follows: jumper the RX pin of Serial2 to the RX pin of another (previously unused) serial port. Configure Serial2 without Break detection, & leave it to receive the data without interference. Configure the other serial port for Break detection & use it to detect the LIN bus break pulses. Might that work for your use case ??

Mark J Culross
KD5RXT
 
Hi Mark,

I was thinking about doing exactly what you are saying - however I have to imagine that there's a way to get the LIN functionality to behave on a single channel. I am going to keep plugging away here...
 
Quasi Solution!

Hi All,

I did what mark said, and I tied the LIN line to two UART channels, Teensy Ch2 and Teensy Ch6. I configured Ch6 to detect the LIN break, and left Ch2 to accept the data.

Sure enough, Ch6 detects the LIN break and Ch2 can pull in the data. Only issue is that, Ch2 pulls in the first byte of the LIN frame before Ch6 reports the interrupt for the LIN break.

In other words, you'd usually see this data stream for the LIN frame:

[0x00] [0x55] [Protected ID] [Data] [Data] [Data] [Data] [CRC]



Now, if I say
Lets start buffering data when the LIN Break is detected
you will see:

[0x55] [Protected ID] [Data] [Data] [Data] [Data] [CRC] [0x00]


The trick here is to know to either omit the last [0x00] or when pulling in Serial data into your data buffer, create a timeout feature that doesn't accept data a certain amount of time after the LIN break is detected. This timeout parameter would be dependent on your baudrate of course. It could also be a function of the number of bytes in the frame, however that could get more complex.


Thats all I got for you guys, it's not ideal, but I hope this helps!
 
Back
Top