1 Abstract In the previous time, I have shared one post about the kinetis L series LIN slave basic usage. Now, because the LPC54608 still don’t have any sample code about the LIN, so this post, I will share a simple code about the LPC54608 LIN master usage, and use the LPCXpresso 54608 board associated with the LIN analyzer to test the result. This document will realize the LIN master and LIN slave communication, LIN master will send the specific publisher frame and the subscriber frame, the LIN slave will detect the master data’s correction, and feedback the according data. 2 LPC54608 LIN master example Now use the LPCXpresso54608 board as the LIN master, the LIN analyzer tool as the LIN slave, test the LIN send and receive function between the LIN master and LIN slave. 2.1 Hardware requirement Hardware:LPCXpresso54608,KIT33662LEFEVB,PCAN-USB Pro FD LIN bus voltage is 12V, but the LPCXpresso54608 board don’t have the on board LIN transceiver, so we need to find the external LIN transceiver, then connect the LPC54608 UART port to the LIN transceiver. About the external LIN transceiver, we use the NXP official LIN driver board KIT33662LEFEVB, this board schematic can be found from this link: https://www.nxp.com/docs/en/user-guide/KT33662UG.pdf Fig 2-1. LIN transceiver schematic If you don’t have the KIT33662LEFEVB board, don’t worry, you also can use the TRK-KEA8, just like the kinetis LIN post which I have shared. TRK-KEA8 have the on board transceiver chip. 2.1.1 LPCXpresso5460 and IT33662LEF EVB connections No. LPCXpresso54608 KIT33662LEFEVB note 1 P4_RX J4-2 UART0_RX 2 P4_TX J4-1 UART0_TX 3 P4_GND J5-1 GND 4 JP2_3 J5_2 3.3V power supply 2.1.2 KIT33662LEFEVB 12V power supply and LIN slave connection KIT33662LEFEVB board J2_1: 12V power supply, also connect to LIN analyzer VBAT pin J2_3: 12V ground, also connect to LIN analyzer GND pin J2_2: LIN bus, connect to the LIN analyzer LIN pin 2.1.3 Use TRK-KEA8 on board LIN transceiver This chapter just for those don’t have KIT33662LEFEVB board, but have the TRK-KEA8 board. 1)LPCXpresso54608 and TRK-KEA8 connections LPCXpresso54608 need to connect the UART pin to the LIN transceiver, the connections like this: No. LPCXpresso54608 TRK-KEA8 note 1 P4_RX J10-5 UART0_RX 2 P4_TX J10-6 UART0_TX 3 P4_GND J14-1 GND 2) TRK-KEA8 and LIN analyzer connections LIN bus is the single wire, connect to LIN analyzer LIN pin, GND also need to connect together. TRK-KEA8 need to use the P1 powered by 12V DC power supply, LIN analyzer also need to connect to the 12V DC. Because the LPC54608 board is powered by the 3.3V, then also need to power the LPC54608 board with a 3.3V DC power supply. 2.1.4 Physical connections Fig 2-2. Physcial connections 2.2 Software code Now, talk about the LIN master send the LIN publisher data and the subscriber ID data, the software code is modified from the SDK_2.3.0_LPCXpresso54608 usart interrupt project, the detail code just as follows: void DEMO_USART_IRQHandler(void)
{
if(DEMO_USART->STAT & USART_INTENSET_DELTARXBRKEN_MASK) // detect LIN break
{
DEMO_USART->STAT |= USART_INTENSET_DELTARXBRKEN_MASK;// clear the bit
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 = 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
}
/********************************************************************************************/
/*Publisher LIN frame
/*13bit break+0x55 sync+0xad(0x2D's protected ID)+0x01+0x02+0x03+0x4C(check sum)
//All the above byte is sent by the LIN master
/********************************************************************************************/
void Lin_Master_Publisher(void)
{
unsigned int i=0;
//===============================LIN master send=====================
DEMO_USART->CTL |= USART_CTL_TXBRKEN_MASK;//enable TX break;
while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
{
USART_WriteByte(DEMO_USART, 0Xff);//dummy byte, no means
break; //just send one byte, otherwise, will send 16 bytes
}
for(i=0;i<10000;i++); // delay for the break generation.
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, 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;
DEMO_USART->CTL |= USART_CTL_TXBRKEN_MASK;//enable TX break;
while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
{
USART_WriteByte(DEMO_USART, 0Xff);//dummy byte, no means
break; //just send one byte, otherwise, will send 16 bytes
}
for(i=0;i<10000;i++); // delay for the break generation.
// for(i=0;i<5000;i++);
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, 0XEC);//0XEC
break; //just send one byte, otherwise, will send 16 bytes
}
}
/*!
* @brief Main function
*/
int main(void)
{
unsigned int i=0;
usart_config_t config;
/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
BOARD_InitPins();
BOARD_BootClockFROHF48M();
BOARD_InitDebugConsole();
/*
* config.baudRate_Bps = 19200U;
* config.parityMode = kUSART_ParityDisabled;
* config.stopBitCount = kUSART_OneStopBit;
* config.loopback = false;
* config.enableTxFifo = false;
* config.enableRxFifo = false;
*/
USART_GetDefaultConfig(&config);
config.baudRate_Bps = BOARD_DEBUG_UART_BAUDRATE;
config.enableTx = true;
config.enableRx = true;
USART_Init(DEMO_USART, &config, DEMO_USART_CLK_FREQ);
/* Enable RX interrupt. */
DEMO_USART->INTENSET |= USART_INTENSET_DELTARXBRKEN_MASK; //USART_INTENSET_STARTEN_MASK |
//enable USART interrupt
cnt=0;
USART_EnableInterrupts(DEMO_USART, kUSART_RxLevelInterruptEnable | kUSART_RxErrorInterruptEnable);
EnableIRQ(DEMO_USART_IRQn);//All ID datas will be received in the interrupt
Lin_Master_Publisher(); //LIN master send publisher ID 0x2D
for(i=0;i<65535;i++);//delay
Lin_Master_Subscribe();//LIN master send subscriber ID 0x2c
while (1)
{
}
}
In USART_Init function,add the LIN function enable code: /* setup configuration and enable USART */ base->CFG = USART_CFG_PARITYSEL(config->parityMode) | USART_CFG_STOPLEN(config->stopBitCount) | USART_CFG_DATALEN(config->bitCountPerChar) | USART_CFG_LOOP(config->loopback) | USART_CFG_ENABLE_MASK | USART_CFG_LINMODE_MASK;// 3 LPC54608 LIN master test result Master side define two ID frame: Unconditional ID Protected ID Direction Data checksum 0X2C 0XEC subscriber 0x01,0x02 0x10 0X2D 0XAD Publisher 0x01,0x02,0x03 0x4c Now, LIN master will send the above two ID frame to the slave, then give the test result about the feedback from the slave and the LIN bus wave. 3.1 LIN slave configuration The LIN baud rate is defined as 9600bps. The following picture is from the LIN analyzer (PEAK LIN tool) software: To get the data from the LIN slave, the master need to send the 0x2C frame at first, then the slave will send back the according data. The master subscriber frame is the slave’s publisher frame; the master publisher frame is the slave’s subscriber. Master send, slave receive. Master receive, then the slave is the send side. In the slave software side, need to configure the 0X2C ID according data, then press the space key, the slave will wait for the master’s according frame. 3.2 Send 0X2C and 0X2D frame From the slave side, we can find 0X2D is received successfully from the master, 0X2C can send the correct data to the master. 3.2.1 0X2D frame data LIN bus wave and debug result Yellow wave is the LPC54608 UART TX pin wave. Blue wave is the LIN bus wave. From the LIN bus wave, we can find that the LIN master can send out the correct LIN data, and the checksum also correct from the slave received side. 3.2.2 0X2C data LIN bus wave and debug result Yellow wave is the LPC54608 UART TX pin wave. Blue wave is the LIN bus wave. From the wave, we can find that after the LIN master send the 0X2C data, the slave will send back the according data to the master, now check the LPC54608 debug data from IAR: From the received data and the checksum data, we can find the slave feedback is correct. So, the above modified code can realize the LPC54608 LIN master frame basic send and receive function. Next time, I will also share a post about the LPC54608 LIN slave code. Wish it helps you!
View full article