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.