Break-Sync pattern, the Auto-Baud chirp, and a PID which is
termed a LIN header. The subscribing slave node picks up
the frame from there and supplies the data bytes and the
frame checksum which — according to the LIN Specification
— is the response. To illustrate this concept, I’ve written a
function called send_lin_header that will transmit only the
LIN frame header. I’ll use the slave response feature of the
LIN Serial Analyzer to subscribe to the header and return
three bytes (0x11, 0x22, 0x33) to the master as a response
to the 0x01 identifier:
#define LIN_TX
#define
LIN_RX
CS_ON; \ //MCP2021 ON
TX_ON; \ //MCP2021 Tx ON
CREN = 0; //disable Rx
CS_ON; \ //MCP2021 ON
TX_OFF; \ //MCP2021 Tx OFF
CREN = 0; \
CREN = 1; //reset EUSART Rx
//***********************************************
//*SEND A LIN HEADER
//***********************************************
void send_lin_header(char hdr)
{
char i;
lin_buf[id_loc] = hdr;
//CALCULATE PROTECTED ID CHECKSUM
id_bits.id0 = lin_buf[id_loc] & 0b00000001;
id_bits.id1 = (lin_buf[id_loc] & 0b00000010)
>> 1;
id_bits.id2 = (lin_buf[id_loc] & 0b00000100)
>> 2;
id_bits.id3 = (lin_buf[id_loc] & 0b00001000)
>> 3;
id_bits.id4 = (lin_buf[id_loc] & 0b00010000)
>> 4;
id_bits.id5 = (lin_buf[id_loc] & 0b00100000)
>> 5;
id_bits.p0 = id_bits.id0 id_bits.id1 ^
id_bits.id2 id_bits.id4;
id_bits.p1 = ~(id_bits.id1 id_bits.id3 ^
id_bits.id4 id_bits.id5);
if(id_bits.p1)
{
lin_buf[id_loc] = lin_buf[id_loc] +
0b10000000;
}
if(id_bits.p0)
{
lin_buf[id_loc] = lin_buf[id_loc] +
0b01000000;
}
LIN_TX; //place MCP2201 in transmit mode
SENDB = 1; //set SEND BREAK bit
46 SERVO 07.2009
sendchar(0x55); //send dummy character
sendchar(0x55); //send Auto-Baud chirp
sendchar(lin_buf[id_loc]);
LIN_RX;
mdelay1(17);
}
The send_lin_header function is nothing more than a
trimmed send_lin_frame function that sends the header
and transitions to receive mode to await the response from
the slave. I captured the LIN Serial Analyzer’s response in
Screenshot 2 and inserted an MPLAB view of the
PIC18F2620’s EUSART receive buffer that contains the
response sent by the LIN Serial Analyzer.
So far, we’ve explored the master node side of a LIN
link. Believe it or not, we already have a framework for the
slave driver. All we need to do is gather the resources and
put them to work.
A LIN Slave RX Driver
Let’s cut to the chase. This is all it takes for a slave LIN
node to navigate the Break-Sync pattern and sync up with
the master node’s incoming signal:
if(RCIDL)
{
//make sure receive not
// in progress
LIN_RX; //put MCP2021 in Rx mode
disable_RXint;//disable the Rx interrupt
SET_WUE; //enable Auto Wake-Up
SET_ABDEN; //enable Auto-Baud feature
IDLEN = 1; //idle CPU only while
// sleeping
//snooze
//wait for Break sequence
// to complete
bytein = RCREG; //discard the byte,
// clear RCIF flag
while(ABDEN); //measure the chirp
bytein = RCREG; //discard the byte,
// clear RCIF flag
enable_RXint; //get ready for
// real data
SLEEP();
while(WUE);
}
do{
LED1 ^= 1;
sdelay1(2);
}while(1);
//kill time waiting
// for incoming data
We don’t want the LIN slave node to go to sleep if a
receive operation is in progress. So, before preparing to
capture a Break-Sync pattern, we’ll check the RCIDL bit
which (when set) tells us that the PIC18F2620’s EUSART
receiver is idle. The macro LIN_RX cleans up the EUSART
and puts the MCP2021 into receive mode.