LIN on DEVKIT-MPC5748G Board

cancel
Showing results for 
Search instead for 
Did you mean: 

LIN on DEVKIT-MPC5748G Board

705 Views
marek_cz
Contributor II

Hi

I have a question about LIN on DEVKIT-MPC5748G Board.

I am trying to configure it as SLAVE (on the board only LINFlexD_0 available).

I configured INPUT anOUTPUT as belo:

    /* Configure PB2 for AF1 func: LIN0TX */
    SIUL2.MSCR[PB2].B.SSS = 1;    /* Pad PB2: Source signal is LIN0_TXD  */
    SIUL2.MSCR[PB2].B.OBE = 1;    /* Pad PB2: Output Buffer Enable */
    SIUL2.MSCR[PB2].B.ODE = 1;    /* Pad PB2: Output Drain Enable */
    SIUL2.MSCR[PB2].B.PUS = 1;    /* Pad PB2: Pull up selected */
    SIUL2.MSCR[PB2].B.PUE = 1;    /* Pad PB2: Pull Enable */
    SIUL2.MSCR[PB2].B.SRC = 3;    /* Pad PB2: Maximum slew rate */

    /* Configure  PB3 for LIN0RX */
    SIUL2.MSCR[PB3].B.IBE = 1;    /* Pad PB3: Enable pad for input - LIN0_RXD */
    SIUL2.IMCR[165].B.SSS = 1;   /* LIN0_RXD: connected to pad PB3 */

I also configured LIN module:


    /* enter INIT mode */
    LINFlexD_0.LINCR1.R = 0x0081; /* SLEEP=0, INIT=1 */

    /* wait for the INIT mode */
    while (0x1000 != (LINFlexD_0.LINSR.R & 0xF000)) {}

    /* configure baudrate 19200 */
    LINFlexD_0.LINFBRR.R = 3;
    LINFlexD_0.LINIBRR.R = 130;

    LINFlexD_0.LINCR2.B.IOBE = 1; /* IOBE=1, Bit error resets LIN state machine */

    LINFlexD_0.LINTCSR.R = 0; /* LIN timeout mode, no idle on timeout */

    LINFlexD_0.BIDR.B.CCS = 0; /* enhanced checksum for LIN Slave */

    LINFlexD_0.LINIER.B.HEIE = 1;

    LINFlexD_0.LINIER.B.DTIE = 1;
    LINFlexD_0.LINIER.B.DRIE = 1;

    /* enter NORMAL mode */

    LINFlexD_0.LINCR1.B.LASE = 1;
    LINFlexD_0.LINCR1.B.MBL = 0b0011;
    LINFlexD_0.LINCR1.B.MME = 0;
    LINFlexD_0.LINCR1.B.SSBL = 0;
    LINFlexD_0.LINCR1.B.INIT = 0;

I place also interrupts vectors:

(uint32_t) &LINFlexD_0_RX_ISR, /* Vector # 376 LinFLEX0_0 LinFlex_0_RXI */
(uint32_t) &LINFlexD_0_TX_ISR, /* Vector # 377 LinFlex0_1 LinFlex_0_TXI */

I am sure that on (LIN0_RX, PB3,  MCU pin 1) signal is proper, but MCU doesn't call interrupt function?

I have checked LINESR.SZF is set to "1".

Could you give me a suggestion what could be a problem, I wasn't able to find anything in documentation

2 Replies

331 Views
marek_cz
Contributor II

proper LIN0 configuration as slave in polling mode  for MPC5748G (DEVKIT-MPC5748G Board) is as bellow:

    /* Configure pad PB2: LIN0TX */
    SIUL2.MSCR[PB2].B.SSS = 1;    /* Pad PB2: Source signal is LIN0_TXD  */
    SIUL2.MSCR[PB2].B.OBE = 1;    /* Pad PB2: Output Buffer Enable */
    SIUL2.MSCR[PB2].B.ODE = 1;    /* Pad PB2: Output Drain Enable */
    SIUL2.MSCR[PB2].B.PUS = 1;    /* Pad PB2: Pull up selected */
    SIUL2.MSCR[PB2].B.PUE = 1;    /* Pad PB2: Pull Enable */
    SIUL2.MSCR[PB2].B.SRC = 3;    /* Pad PB2: Maximum slew rate */

    /* Configure pad PB3 for LIN0RX */
    SIUL2.MSCR[PB3].B.IBE = 1;    /* Pad PB3: Enable pad for input - LIN0_RXD */
    SIUL2.IMCR[712-512].B.SSS = 2;   /* LIN0_RXD: connected to pad PB3 */

   /*LIN0 initialization*/

    /* enter INIT mode */

    LINFlexD_0.LINCR1.R = 0x0081; /* SLEEP=0, INIT=1 */

    /* wait for the INIT mode */
    while (0x1000 != (LINFlexD_0.LINSR.R & 0xF000)) {}

    /* configure baudrate 19200 , LIN0  is clocked from F40 so reference clock is 40MHz*/

    VU32 _baudRate;
    VU32 _fraction;
    VU32 _integer;

/*

    _baudRate  = (40 * 1000000) / 19200; //MHz * 1000000 /baudRate
    _integer   = _baudRate / 16;  => 130

    _fraction  = _baudRate - (_integer * 16); =>3

*/


    /* assuming 64 MHz peripheral set 1 clock */
     LINFlexD_0.LINIBRR.B.IBR= 130; /* Mantissa baud rate divider component */
     LINFlexD_0.LINFBRR.B.FBR = 3; /* Fraction baud rate divider comonent */

    LINFlexD_0.LINCR2.R = 0x40; /* IOBE=1, Bit error resets LIN state machine */
    LINFlexD_0.LINTCSR.R = 0; /* LIN timeout mode, no idle on timeout */

    LINFlexD_0.BIDR.B.CCS = 0; /* enhanced checksum for LIN Slave */

    /* enter NORMAL mode */
    /* CCD bit 16 = 0 ... checksum calculation by hardware
       CFD bit 17 = 0 ... checksum field is sent after the required number
       of data bytes is sent
       LASE bit 18 = 1 ... Slave automatic resync enable
       AWUM bit 19 = 0 ... The sleep mode is exited on software request
       MBL bits 20:23 = 0b0011 ... 13-bit LIN Master break length
       BF bit 24 = 1 ... bypass filter
       SFTM bit 25 = 0 ... Self Test mode disable
       LBKM bit 26 = 0 ... Loop Back mode disable
       MME bit 27 = 0 ... Slave mode
       SBDT bit 28 = 0 ... 11-bit Slave Mode break threshold
       RBLM bit 29 = 0 ... Receive Buffer not locked on overrun
       SLEEP bit 30 = 0
       INIT bit 31 = 0 ... entering Normal mode
       =
       0x2380

       */

    LINFlexD_0.LINCR1.R = 0x2380;
}

in polling function there is a need to checking LINFlexD_0.LINSR.B.HRF, when it will be set, set direction of data flow, checksum type, data count and data if it is RX frame:

        if (LINFlexD_0.LINSR.B.HRF==1){
            uint32_t id=LINFlexD_0.BIDR.B.ID;
            if (id==0x35) //TX frame set only checksum, data flow direction and data count
            {
                LINFlexD_0.BIDR.B.CCS=0;
                LINFlexD_0.BIDR.B.DFL=7;
                LINFlexD_0.BIDR.B.DIR=0;
            }
            if (id==0x37) // when RX frame also data should be set
            {
                LINFlexD_0.BIDR.B.DIR = 1; /* BDR direction - write */

                LINFlexD_0.BIDR.B.CCS = 0; // enhanced checksum for LIN Slave

                LINFlexD_0.BIDR.B.DFL = 0x07; // 8 bytes - 1

                // fill the data registers
                LINFlexD_0.BDRL.B.DATA0 = 'X';
                LINFlexD_0.BDRL.B.DATA1 = 'a';
                LINFlexD_0.BDRL.B.DATA2 = 'n';
                LINFlexD_0.BDRL.B.DATA3 = 's';
                LINFlexD_0.BDRM.B.DATA4 = 'w';
                LINFlexD_0.BDRM.B.DATA5 = 'e';
                LINFlexD_0.BDRM.B.DATA6 = 'r';
                LINFlexD_0.BDRM.B.DATA7 = ' ';

                // specify the data field length BIDR[DFL]

                // trigger the data transmission
                LINFlexD_0.LINCR2.B.DTRQ = 1;

                LINFlexD_0.LINSR.R = 0x1;    // clear HRF flag
            }
        }

to get received data use code:

       if (LINFlexD_0.LINSR.B.RMB==1)  
       {
        /* get the data */
        vuint32_t  rx_s_data[8];
        rx_s_data[0] = LINFlexD_0.BDRL.B.DATA0;
        rx_s_data[1] = LINFlexD_0.BDRL.B.DATA1;
        rx_s_data[2] = LINFlexD_0.BDRL.B.DATA2;
        rx_s_data[3] = LINFlexD_0.BDRL.B.DATA3;
        rx_s_data[4] = LINFlexD_0.BDRM.B.DATA4;
        rx_s_data[5] = LINFlexD_0.BDRM.B.DATA5;
        rx_s_data[6] = LINFlexD_0.BDRM.B.DATA6;
        rx_s_data[7] = LINFlexD_0.BDRM.B.DATA7;

        /* clear the HRF,DRF and RMB flags by writing 1 to them */
        LINFlexD_0.LINSR.R = 0x0205;
       }

it works for me, I have spent on it a few time, so maybe it will be usefull for others.

0 Kudos

331 Views
martin_kovar
NXP Employee
NXP Employee

Hello Marek,

from your description it looks like you do not have set priority for LIN interrupt. Check INTC PSR 376 register and set priority into PRIN field.

If this does not solve your problem, please let me know.

Regards,

Martin