Hello, I'm inquiring because I'm having trouble making the LIN Slave code. I've looked at the example code and I'm sending Rx data from LIN Slave around infinite loop with for statement, I want to send and receive Rx data with 100ms routine. May I ask for your advice on what parts of the code I've come up with to fix? Here's the code.
static uint16_t CRC15(const uint32_t bStart, uint8_t data)
{
/* holds the actual CRC code */
static uint32_t crc_rg = 0;
/* used in CRC-15 algorithm */
register uint32_t crcnxt = 0;
/* loop counter */
register int32_t i = 0;
if(CRC15_START == bStart)
{
/* CRC_RG = 0; */
crc_rg = 0;
}
/* crc15 code for 8 input bits, lsb first */
for(i=0;i<8;i++)
{
/* CRCNXT = NXTBIT EXOR CRC_RG(14); */
crcnxt = data ^ (crc_rg >> 14);
crcnxt = (crcnxt & 0x00000001);
/* CRC_RG(14:1) = CRC_RG(13:0);
* CRC_RG(0) = 0; */
crc_rg = (crc_rg << 1); /* left shift by 1 position */
crc_rg = crc_rg & 0x00007FFF;
/* IF CRCNXT THEN
* CRC_RG(14:0) = CRC_RG(14:0) EXOR (4599hex) */
if(crcnxt)
{
crc_rg = (crc_rg ^ 0x00004599);
crc_rg = (crc_rg & 0x00007FFF);
}
/* prepare next bit */
data = (uint8_t)(data >> 1);
}
return (uint16_t)crc_rg;
}
uint32_t fsm = 0;
uint32_t idx = 0;
uint16_t crc15 = 0;
void LIN_Slave_Send_Recevie(uint32_t *check)
{
uint32_t i = 0;
*check = fsm;
switch(fsm)
{
case FSM_RECEIVE_CHARACTERS:
/* wait for a received char
* Break will cause framing error (Stop bit received as 0) */
if(1 == eSCI_B.IFSR1.B.RDRF)
{
eSCI_B.IFSR1.R = 0x2000; /* clear RDRF and FRM */
/* move received char into the memory */
rx_char[idx] = (uint8_t)eSCI_B.SDR.B.RDTD;
/* check Master header */
switch(idx)
{
case 0: /* check 1st received char for Break */
if(0x00 == rx_char[idx])
{
idx = 1;
}
break;
case 1: /* check 2nd received char for Sync */
if(0x55 == rx_char[idx])
{
idx = 2;
}
break;
case 2:
/* check 3rd byte - ID and two ID's parity bits */
/* ID = 0x38
* 0x78 = ID + 2 parity bits
* application specified as LIN Rx frame
* with 4 bytes payload and 2 bytes of CRC */
if(0x78 == rx_char[idx])
{
fsm = FSM_SLAVE_RESPONSE_CRC;
idx = 0;
}
else if(0x34 == rx_char[idx])
{
/* ID = 0x39
* 0x39 = ID + 2 parity bits
* application specified as LIN Tx frame
* with 4 data bytes
* thus 9 bytes received in total
* Break+Sync+ID+Data_bytes+CRC1+CRC2 */
/* receive next data byte */
idx++;
}
break;
default:
/* this part for LIN Tx Frame only
* receive all remaining data bytes and 2 CRC bytes */
idx++;
if(idx>10)
{
fsm = FSM_MASTER_RESPONSE_CRC;
idx = 0;
}
break;
}
}
break;
case FSM_SLAVE_RESPONSE_CRC:
/* disable the receiver during Slave response */
eSCI_B.CR1.B.RE = 0;
/* compute CRC-15 for the Slave response */
crc15 = CRC15(CRC15_START, 0x78); /* ID (including ID's parity) */
for(i=0; i<8; i++)
{
crc15 = CRC15(0, tx_char[i]); /* data0..data7 */
}
/* MSBit of the TX'ed CRC must be high */
crc15 = (uint16_t)(crc15 | 0x8000);
/* CRC1 is LSByte of the actual CRC code */
tx_char[8] = (uint8_t)crc15;
/* CRC2 is MSByte of the actual CRC code */
tx_char[9] = (uint8_t)(crc15 >> 8);
fsm = FSM_SLAVE_RESPONSE_TX;
break;
case FSM_SLAVE_RESPONSE_TX:
/* Transmit Slave response */
if(1 == eSCI_B.IFSR1.B.TDRE)
{
eSCI_B.SDR.B.RDTD = (uint16_t)(0x00FF & tx_char[idx]);
eSCI_B.IFSR1.B.TDRE = 0x8000;
/* last CRC byte TX'ed */
if(5 == idx)
{
fsm = FSM_FRAME_COMPLETE;
}
/* Tx next byte */
idx++;
}
break;
case FSM_FRAME_COMPLETE:
idx = 0; /* reset array index */
fsm = FSM_RECEIVE_CHARACTERS;
/* re-enable the receiver */
eSCI_B.CR1.B.RE = 1;
break;
case FSM_MASTER_RESPONSE_CRC:
/* LIN Tx Frame - data and CRC received from Master */
/* compute CRC-15 for the received Master response */
crc15 = CRC15(CRC15_START, 0x34); /* ID (including ID's parity) */
for(i=3; i<11; i++)
{
crc15 = CRC15(0, rx_char[i]); /* data0..data7 */
}
/* MSBit of the computed CRC must be high */
crc15 = (uint16_t)(crc15 | 0x8000);
/* compare CRC1 with LSByte */
if(rx_char[11] == (uint8_t)crc15)
{
/* compare CRC2 with MSByte */
if(rx_char[12] == (uint8_t)(crc15 >> 8))
{
/* received data are correct */
fsm = FSM_FRAME_COMPLETE;
}
else
{
fsm = FSM_FRAME_COMPLETE;
//fsm = FSM_ERROR;
}
}
else
{
fsm = FSM_FRAME_COMPLETE;
//fsm = FSM_ERROR;
}
break;
case FSM_ERROR:
break;
}
}
Currently, it is not possible to send and receive Rx data.
Thanks for your help