LPC55S16 LIN basic usage example

cancel
Showing results for 
Search instead for 
Did you mean: 

LPC55S16 LIN basic usage example

No ratings

LPC55S16 LIN basic usage example

INTRODUCTION

The goal of this example is to demonstrate basic LIN communication between two devices where one active as Master another as Slave. In this case, the two devices used are LPC55S16 EVK's.

LIN master will send a specific publisher frame and a subscriber frame, the LIN slave will detect the master data and feedback the data accordingly.

This article will mainly focus on the software side, for hardware please refer https://community.nxp.com/t5/LPC-Microcontrollers-Knowledge/LPC54608-LIN-master-basic-usage-sharing/....

LIN MASTER EXAMPLE

LIN master sends the LIN publisher data and the subscriber ID data, the software code is modified from the SDK_2.8.2_LPCXpresso55S16 usart_interrupt_rb_transfer project, the detailed code is as follows:

/* USART callback */
void FLEXCOMM3_IRQHandler()
{
	  if(DEMO_USART->STAT & USART_STAT_RXBRK_MASK) // detect LIN break
	     {
	       Lin_BKflag = 1;
	       cnt = 0;
	       state = RECV_DATA;
	       DisableLinBreak;
	     }
	    if((kUSART_RxFifoNotEmptyFlag | kUSART_RxError) & USART_GetStatusFlags(DEMO_USART))
	     {
	       USART_ClearStatusFlags(DEMO_USART,kUSART_TxError | kUSART_RxError);
	    	 rxbuff[cnt] = USART_ReadByte(DEMO_USART);;

	         switch(state)
	         {
	            case RECV_SYN:
	                          if(0x55 == rxbuff[cnt])
	                          {
	                              state = RECV_PID;
	                          }
	                          else
	                          {
	                              state = IDLE;
	                              DisableLinBreak;
	                          }
	                          break;
	            case RECV_PID:
	                          if(0xAD == rxbuff[cnt])
	                          {
	                              state = SEND_DATA;
	                          }
	                          else if(0XEC == rxbuff[cnt])
	                          {
	                              state = RECV_DATA;
	                          }
	                          else
	                          {
	                              state = IDLE;
	                              DisableLinBreak;
	                          }
	                          break;
	            case RECV_DATA:
	                         Sub_rxbuff[recdatacnt++]= rxbuff[cnt];
	                          if(recdatacnt >= 3) // 2 Bytes data + 1 Bytes checksum
	                          {
	                              recdatacnt=0;
	                              state = RECV_SYN;
	                              EnableLinBreak;
	                          }
	                          break;
	            case SEND_DATA:
	                          recdatacnt++;
	                          if(recdatacnt >= 4) // 2 Bytes data + 1 Bytes checksum
	                          {
	                              recdatacnt=0;
	                              state = RECV_SYN;
	                              EnableLinBreak;
	                          }
	                          break;
	         default:break;
	         }
	         cnt++;
	     }


	    /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
	      exception return operation might vector to incorrect interrupt */
	#if defined __CORTEX_M && (__CORTEX_M == 4U)
	    __DSB();
	#endif
}

void Lin_Master_Publisher(void)
{
    unsigned int i=0;
    unsigned char ch =0xa0;//dummy byte
//===============================LIN master send=====================

       DEMO_USART->CTL |= USART_CTL_TXBRKEN_MASK;//enable TX break;
       while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
      	 USART_WriteBlocking(DEMO_USART,&ch,1);//dummy data

            break;  //just send one byte, otherwise, will send 16 bytes
        }
       DEMO_USART->CTL &= ~(USART_CTL_TXBRKEN_MASK); //disable TX break

       // Send the sync byte 0x55.
        while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
            USART_WriteByte(DEMO_USART, 0X55);
            break;  //just send one byte, otherwise, will send 16 bytes
        }
       //protected ID
        while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
            USART_WriteByte(DEMO_USART, 0Xad);
            break;  //just send one byte, otherwise, will send 16 bytes
        }
        //Data1
       while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
            USART_WriteByte(DEMO_USART, 0X01);
            break;  //just send one byte, otherwise, will send 16 bytes
        }
        //Data2
        while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
            USART_WriteByte(DEMO_USART, 0X02);
            break;  //just send one byte, otherwise, will send 16 bytes
        }
        //Data3
        while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
            USART_WriteByte(DEMO_USART, 0X03);
            break;  //just send one byte, otherwise, will send 16 bytes
        }
        // checksum byte
        while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
            USART_WriteByte(DEMO_USART, 0X4c);//0X4c
            break;  //just send one byte, otherwise, will send 16 bytes
        }

}

void Lin_Master_Subscribe(void)
{
  unsigned int i=0;

unsigned char ch=0xf0;//dummy byte

     DEMO_USART->CTL |= USART_CTL_TXBRKEN_MASK;//enable TX break;
     while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
      {
    	 USART_WriteBlocking(DEMO_USART,&ch,1);

          break;  //just send one byte, otherwise, will send 16 bytes
      }
       DEMO_USART->CTL &= ~(USART_CTL_TXBRKEN_MASK); //disable TX break

       // Send the syncy byte 0x55.
        while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
            USART_WriteByte(DEMO_USART, 0X55);
            break;  //just send one byte, otherwise, will send 16 bytes
        }
       //protected ID
        while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
            USART_WriteByte(DEMO_USART, 0X3C);
            break;  //just send one byte, otherwise, will send 16 bytes
        }
	       state = RECV_DATA;
}

The main task here was to generate and detect the LIN break field.

If one look closely, to generate the LIN break field in publisher and subscriber frame, we first set the Tx break and then send a dummy byte and then disable the Tx break. The function used to send the dummy byte is USART_WriteBlocking whereas USART_WriteByte is used to send data other than dummy byte. This is because if we use USART_WriteByte during dummy byte then it was not a continuous low as in the other case. I still need to find the reason for this, will update here once done.

 

LIN SLAVE EXAMPLE

LIN Slave receives the LIN publisher data and the subscriber ID data from Master and respond back id required, the software code is modified from the SDK_2.8.2_LPCXpresso55S16 usart_interrupt_rb_transfer project, the detailed code is as follows:

void FLEXCOMM3_IRQHandler()
{
 if(DEMO_USART->STAT & USART_STAT_RXBRK_MASK) // detect LIN break
	     {
	       Lin_BKflag = 1;
	       cnt = 0;
	       state = RECV_SYN;
	       DisableLinBreak;
	     }

	    if((kUSART_RxFifoNotEmptyFlag | kUSART_RxError) & USART_GetStatusFlags(DEMO_USART))
	     {
	       USART_ClearStatusFlags(DEMO_USART,kUSART_TxError | kUSART_RxError);
	    	 rxbuff[cnt] = USART_ReadByte(DEMO_USART);;

	         switch(state)
	         {
	            case RECV_SYN:
	                          if(0x55 == rxbuff[cnt])
	                          {
	                              state = RECV_PID;
	                          }
	                          else
	                          {
	                              state = IDLE;
	                              DisableLinBreak;
	                          }
	                          break;
	            case RECV_PID:
	                          if(0xAD == rxbuff[cnt])
	                          {
	                              state = RECV_DATA;
	                          }
	                          else if(0X3C == rxbuff[cnt])
	                          {
	                              state = SEND_DATA;
	                              senddata();
	                          }
	                          else
	                          {
	                              state = IDLE;
	                              DisableLinBreak;
	                          }
	                          break;
	            case RECV_DATA:
	                          recdatacnt++;
	                          if(recdatacnt >= 4) // 3 Bytes data + 1 Bytes checksum
	                          {
	                              recdatacnt=0;
	                              state = RECV_SYN;
	                              EnableLinBreak;
	                          }
	                          break;
	         default:break;

	         }

	         cnt++;
	     }


	    /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
	      exception return operation might vector to incorrect interrupt */
	#if defined __CORTEX_M && (__CORTEX_M == 4U)
	    __DSB();
	#endif
}

void senddata(void)
{
	        {

	         while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
	         {
	             USART_WriteByte(DEMO_USART, 0X01);
	             break;  //just send one byte, otherwise, will send 16 bytes
	         }
	         while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
	         {
	             USART_WriteByte(DEMO_USART, 0X02);
	             break;  //just send one byte, otherwise, will send 16 bytes
	         }
	         while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
	         {
	             USART_WriteByte(DEMO_USART, 0X10);// 0X10 correct 0Xaa wrong
	             break;  //just send one byte, otherwise, will send 16 bytes
	         }

	           recdatacnt=0;
	           state = RECV_SYN;
	           EnableLinBreak;
	        }
}

In the next revison, I will update the CRO traces of the LIN frames also. Attaching herewith the codes of the Master and Slave.

I hope it helps!!

Labels (1)
Attachments
Version history
Revision #:
2 of 2
Last update:
‎01-31-2021 01:45 PM
Updated by:
 
Contributors