Implementation of LIN stack base on UART

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Implementation of LIN stack base on UART

1,224 Views
jeffcharles
Contributor III

Hi,

I want to use KEA128 to do some applications as a LIN slave node. Unlike S12ZVL, the hardware interface of KEA128 is UART. I compare the lowest layer code of LIN stack 4.6.5 about UART and SCI and find that UART needs to do the following additional processing about break detection:

if ((uart_flag_sr2 & UARTSR2_RXEDGIF_MASK) && (!(uart_flag_sr2 & UARTSR2_LBKDIF_MASK)))
    {
        /* Clear flag */
        pUART->uartsr2.bit.rxedgif = 1;

        /* Disable rx edged detection */
        pUART->uartbdh.byte &= ~UARTBDH_RXEDGIE_MASK;

        /* Enable Break interrupt */
        pUART->uartbdh.byte |= UARTBDH_LBKDIE_MASK ;

        /* Receive data not inverted */
        pUART->uartsr2.bit.rxinv = 0;
        /* check state of node is SLEEP_MODE */
        if (SLEEP_MODE == state)
		{
			lin_goto_idle_state();
	        return;
		}
    }

Besides that, break detect feature will be disabled when a valid break signal is received.

if (uart_flag_sr2 & UARTSR2_LBKDIF_MASK)
    {
        /* Clear flag */
        pUART->uartsr2.bit.lbkdif = 1;

        /* check state of node is SLEEP_MODE */
	    if (SLEEP_MODE == state)
	    {
		    lin_goto_idle_state();
		    return;
	    }

#if (AUTOBAUD == 1)
		frame_timeout_cnt =lin_max_frame_res_timeout_val_autobaud[7];
		if (baudrate_adjusted_flag == 0)
		{
			autobaud_tmr_capture_index = 0;
			/* Capture only on failing edges */
			stop_flag = 0;
		}
		else

#else
	    else
	    {
		    /* Enable Active Edge interrupt */
		    pUART->uartbdh.byte |= UARTBDH_RXEDGIE_MASK;

		    /* Disable Break interrupt */
		    pUART->uartbdh.byte &= ~UARTBDH_LBKDIE_MASK ;
	    }
		/* Set max frame timeout */
		frame_timeout_cnt = lin_max_frame_res_timeout_val[7];
#endif /* End (AUTOBAUD == 1)*/
		{
			/* Disable LBK detect */
			pUART->uartsr2.bit.lbkde = 0;
	        /* Enable Active Edge interrupt */
	        pUART->uartbdh.byte |= 0x40 ; /* UARTBDH_RXEDGIE_MASK; */
		}

        /* reset lin status */
        l_status.byte = LIN_STA_BUS_ACTIVITY;

        /******************************
        *** 1.2 SLAVE NODE: Wait for SYN
        *******************************/
        /* Start resyn */
        state = RECV_SYN;

        return;
    }

What is the purpose of this code?

 

Thanks

Jeff 

0 Kudos
3 Replies

1,202 Views
nxf56274
NXP Employee
NXP Employee

Hi,

AUTOBAUD宏定义在lin_hw_cfg.h定义是1,所以lin带了波特率自适应功能。代码里然后关中断,开边沿检测中断应该是为了测量通讯波特率的

Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 days after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

1,197 Views
jeffcharles
Contributor III

Hi,

According to the manual, 'RXEDGIF is set when an active edge, falling if RXINV = 0, rising if RXINV = 1.' The RXINV is always 0 in the LIN stack, which means that RXEDGIF is set when a falling edge. The RXEDGIE is enabled when a valid break signal is detected, so the software will jump into the ISR at the start bit(falling edge) of the Sync field, but then the RXEDGIE is disabled immediately in the ISR(See the first code of my screenshot). How to measure the Tbit?

In addition, I think whether the automatic baud rate is enabled or not is only related to the internal clock tolerance of the MCU, but not necessarily related to the communication interface(SCI or UART). So why is this code not needed when the interface is SCI ?

 

Thanks,

Jeff

0 Kudos

1,184 Views
nxf56274
NXP Employee
NXP Employee

Hi,

我们可以讨论下,这是我的观点。我看的代码是从机代码,逻辑可能与主机又一定区别。

一帧报文由主机的header和从机的response构成。

lin.jpg

首先在lin初始化时候调用lin_lld_uart_init,设置了lin的中断类型为LBKDIE,同时也调用自适应波特率初始化autobaud_init,所以首先进中断处理的应该是你的第二段参考代码而不是第一段代码。

主机首先发送break信号,从机收到break信号,从机进入第二段代码以后它禁用了break中断,然后又开启边沿检测中断,目的是为了边沿来临时再进入你贴的第一段参考代码,重新使能LBKDIE。这样就可以重新检测下一次主机header的break区域。

autobaud_init初始化里还初始化了FTM0,设置为输入捕获串口0,它应该是根据synch域来调整自己lin的波特率。主机是没有自适应波特率功能的。

Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 days after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos