LPC54608 LIN master basic usage sharing

Document created by Kerry Zhou Employee on Sep 14, 2018
Version 1Show Document
  • View in full screen mode

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

     HardwareLPCXpresso54608KIT33662LEFEVBPCAN-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.

1LPCXpresso54608 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 functionadd 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!

 

1 person found this helpful

Outcomes