AN891

AN891
Interrupt-based PIC18 Master LIN Driver in C
for Enhanced USART
Author:
Caio Gübel
Microchip Technology Inc.
The LIN protocol was originally designed by a group of
European carmakers to be used as a low-cost, short distance, low-speed network for automotive applications
(see Appendix C: “References”).
The main characteristics of the LIN protocol are:
•
•
•
•
•
•
Serial communication
Single master, multiple slave concept
Low-cost, one-wire implementation
Speed up to 20 Kbit/s
Self-synchronization (on the slave side)
Ensured latency time in transmission
FILES
The implementation presented in this application note
is based on the LIN Specification Package Version 1.3.
This specification adheres to Microchip’s Application
Maestro standard and contains the following files:
• ELINMInt.c – C source file, contains all
functions and variables used by the LIN protocol.
• ELINMInt.h – Header file, contains constants,
unions and structures definitions, function
prototypes and macro definitions used by the LIN
protocol.
• ELINMInt.def – Contains the definitions used
to configure the LIN protocol.
• ELINMInt.ex.txt – Example of code using the
driver.
This application note presents a Microchip Application
Maestro™ compatible interrupt driven implementation
of the Master Side Driver of the LIN protocol in a
PIC18F device in C language (Microchip and HI-TECH
‘C’ compatible), which takes advantage of the new
features provided by the PIC18 Enhanced USART
module.
 2003 Microchip Technology Inc.
DS00891A-page 1
AN891
MACROS
The following macros are defined in the ELINMInt.h file:
Name
Usage
Description
Page
mELINMIntInitialize
Initialization
Initializes EUSART and driver’s variables
3
mELINMIntTXBufferAvailable
Transmission
Checks for available transmission buffers
4
mELINMIntGetTXPointer
Transmission
Sets a tag and returns a buffer data pointer
5
mELINMIntSendMessage
Transmission
Requests the transmission of a message
6
mELINMIntTXStatus
Transmission
Returns the status of a sent message
8
mELINMIntMessageSent
Transmission
Checks for end of a message transmission
9
mELINMIntTXErrorDetected
Transmission
Checks for transmission errors
10
mELINMIntTXErrorTag
Transmission
Returns the tag of a message with error
11
mELINMIntTXErrorCode
Transmission
Returns the error code of a transmission
12
mELINMIntRXBufferAvailable
Reception
Checks for available reception buffers
13
mELINMIntReceiveMessage(tag,i,s) Reception
Requests a slave to send a message
14
mELINMIntMessageReceived
Reception
Checks for end of reception process
15
mELINMIntGetMessageTag
Reception
Returns the tag of a received message
16
mELINMIntGetRXPointer
Reception
Returns a pointer to a received message
17
mELINMIntRXMessageAvailable
Reception
Checks for any message arrival
18
mELINMIntRXStatus
Reception
Returns the status of a received message
19
mELINMIntRXErrorDetected
Reception
Checks for errors in reception
20
mELINMIntRXErrorTag
Reception
Returns the error tag
21
mELINMIntRXErrorCode
Reception
Returns the error code of a reception
22
mELINMIntCheckWakeUPReceived
Bus Control
Signals that a slave issued a wake-up
23
mELINMIntSendWakeUPSignal
Bus Control
Sends a wake-up signal to the slaves
24
mELINMIntSleepTimeOut
Bus Control
Signals when bus Idle time exceeded Sleep
time-out
25
DS00891A-page 2
 2003 Microchip Technology Inc.
AN891
mELINMIntInitialize()
This macro initializes the driver.
Syntax
mELINMIntInitialize();
Parameters
None
Return Values
0 – Initialization OK
!= 0 – Error in initialization
Preconditions
None
Side Effects
None
Remarks
In this first version of the protocol, no error can be returned. However, in order to be compatible with future versions
that may incorporate error returns, designers must include the proper test.
Example
if(mELINMIntInitialize())
{
// if an error in initialization was detected
// error handling
}
else
{
// if NO error (macro returned 0)
// normal processing
}
 2003 Microchip Technology Inc.
DS00891A-page 3
AN891
mELINMIntTXBufferAvailable()
This macro checks if there is a transmission buffer available. The application must call this macro before trying to
initiate any transmission.
Syntax
mELINMIntTXBufferAvailable();
Parameters
None
Return Values
1 – There is an available buffer to be used to transmit a message
0 – No buffer is currently available for transmission
Preconditions
The protocol must have been successfully initialized using the ELINMIntInitialize(void) function.
Side Effects
None
Remarks
None
Example
if(mELINMIntTXBufferAvailable())
{
// check if there is an available TX buffer
// init transmission from this point
}
DS00891A-page 4
 2003 Microchip Technology Inc.
AN891
mELINMIntGetTXPointer()
This macro returns a pointer to the available transmission buffer.
Syntax
mELINMIntGetTXPointer(tag);
Parameters
tag
The tag of a message. This is an identification of the message to be saved and used by the LIN protocol
to inform the application of an eventual error that the transmission of a specific message suffered. In the
event of an error being detected, the user can access the tag of the error message and with this tag, read
the error code.
Return Values
(BYTE *) – A byte type data pointer to the transmission buffer. The application will load the message to be
transmitted using this pointer.
Preconditions
1.
2.
The protocol must have been successfully initialized by the ELINMIntInitialize(void) function.
The mELINMIntTXBufferAvailable() macro must have been invoked with success.
Side Effects
None
Remarks
The total size of the message to be loaded must not exceed the maximum allowed size defined by
ELINMINT_MAX_MESSAGE_SIZE (ELINMInt.def).
Example
pt=mELINMIntGetTXPointer(3);
pt[0]=mymsg[0];
pt[1]=mymsg[1];
 2003 Microchip Technology Inc.
// get the pointer to message #3
// insert first message byte
// insert second message byte
DS00891A-page 5
AN891
mELINMIntSendMessage(tag,i,s)
This macro requests the transmission of a message through LIN.
Syntax
mELINMIntSendMessage(tag,i,s);
Parameters
tag
The tag that identifies a message, previously defined by the application when calling the
mELINMIntGetTXPointer macro.
i
The ID of the message, ranging from 0x00 to 0x3F. Bits 6 and 7 of the ID will be filled with parity bits and
their original content ignored.
s
The size of the message, limited to 8 for all standard messages and to ELINMINT_MAX_MESSAGE_SIZE
in the case of an extended frame (ID = 0x3E or ID = 0x3F).
Return Values
None
Preconditions
1.
2.
3.
The mELINMIntTXBufferAvailable macro must have been successfully invoked.
The mELINMIntGetTXPointer macro must have been invoked.
The data buffer shall have been loaded with the message pointer.
Side Effects
None
Remarks
1.
2.
3.
Calling this macro doesn’t ensure that the message will be successfully transmitted. The application must
check the result of the transmissions by:
• Waiting until the message transmission is completed (using mELINMIntMessageSent) and then
checking if an error was detected in that message.
• Checking if a transmission buffer is available (using mELINMIntTXBufferAvailable) and if an error
is detected, evaluating which message (identified by its tag) presented a problem and the nature of the
problem.
The ID = 0x3F is reserved by the LIN Consortium for future expansion (see LIN Specification Package 1.3,
Protocol Specification Chapter 3.2) and therefore, it’s use may compromise future compatibility.
The macro takes the size of the message and calculates the minimum and maximum frame times to be used
by the underlying function. If the size is passed in a variable, the calculations are done in real-time, requiring
several cycles; however, if the application always calls this macro with fixed values instead of variables, then
these calculations can be made in compile time, therefore, saving both code space and processing time.
Example 1 (Fixed Size)
mELINMIntSendMessage(tag,myID,4);
//
while(mELINMIntMessageSent(tag)==0)
//
;
if(mELINMIntTXStatus(tag)==ELINMINT_NO_ERROR)//
{
//
}
else
//
{
//
}
DS00891A-page 6
requests transmission, size = 4, better!
wait transmission to be completed
check transmission status
no error, normal processing
if error detected
error handling
 2003 Microchip Technology Inc.
AN891
Example 2 (Variable Size)
mELINMIntSendMessage(tag,myID,msgSize);
//
while(mELINMIntMessageSent(tag)==0)
//
;
if(mELINMIntTXStatus(tag)==ELINMINT_NO_ERROR)//
{
//
}
else
//
{
//
}
 2003 Microchip Technology Inc.
requests transmission, variable size
wait transmission to be completed
check transmission status
no error, normal processing
if error detected
error handling
DS00891A-page 7
AN891
mELINMIntTXStatus(tag)
This macro checks the status of a message already transmitted.
Syntax
mELINMIntTXStatus(tag);
Parameters
tag
This byte contains a message tag which is an identification of the message that was sent.
Return Values
The error code, defined according to the following table:
#define
Definition
ELINMINT_NO_ERROR
No error was detected
ELINMINT_THMIN_ERROR
Header time too short
ELINMINT_THMAX_ERROR
Header time too long
ELINMINT_TFMIN_ERROR
Frame time too short
ELINMINT_TFMAX_ERROR
Frame time too long
ELINMINT_CHECKSUM_ERROR
Checksum incorrect
ELINMINT_DATA_ERROR
Received and transmitted bytes don’t match
ELINMINT_FRAMING_ERROR
Framing error
Preconditions
The mELINMIntSendMessage macro must have been invoked.
The message transmission was completed, checked by mELINMIntMessageSent.
Side Effects
None
Remarks
This macro returns the result of the transmission of a specific message identified by tag.
Example
mELINMIntSendMessage(9,0x04,2);
while(mELINMIntMessageSent(9)==0)
;
if(mELINMIntTXStatus(9)==ELINMINT_NO_ERROR)
{
// send a message
// wait transmission message #9 completed
// check transmission status
// no error, normal processing
}
else
{
// if error detected
// error handling
}
DS00891A-page 8
 2003 Microchip Technology Inc.
AN891
mELINMIntMessageSent(tag)
This macro checks if a message identified by tag was already sent.
Syntax
mELINMIntMessageSent(tag);
Parameters
tag
This byte contains a message tag which is an identification of the message, which the driver can use to
track a specific message.
Return Values
1 – Message already sent
0 – Message not yet sent
Preconditions
The mELINMIntSendMessage macro must have been invoked.
Side Effects
None
Remarks
This macro flags when a specific message transmission is complete. However, it doesn’t ensure that the
transmission was successful. The application must check it using mELINMIntTXErrorDetected.
Example
mELINMIntSendMessage(9,0x04,2);
while(mELINMIntMessageSent(9)==0)
;
 2003 Microchip Technology Inc.
// send a message
// wait transmission message #9 completed
DS00891A-page 9
AN891
mELINMIntTXErrorDetected()
This macro flags if an error was detected in the transmission of a message.
Syntax
mELINMIntTXErrorDetected();
Parameters
None
Return Values
1 – Error detected
0 – No Error detected
Preconditions
Called after detecting that a message was transmitted either by the mELINMIntMessageSent macro or by the
mELINMIntTXBufferAvailable macro.
Side Effects
None
Remarks
None
Example 1
mELINMIntSendMessage(9,0x04,2);
while(mELINMIntMessageSent(9)==0)
;
if(mELINMIntTXErrorDetected())
{
errTx=mELINMIntTXErrorTag();
// send a message
// wait transmission #9 to complete
// check if an TX error was detected
// if detected let's find the message
// that caused the error
// error handling
}
Example 2
mELINMIntSendMessage(9,0x04,2);
while(mELINMIntTXBufferAvailable())
;
if(mELINMIntTXErrorDetected())
{
errTx=mELINMIntTXErrorTag();
// send a message
// wait for an available buffer
// check if an TX error was detected
// if detected let's find the message
// that caused the error
// error handling
}
DS00891A-page 10
 2003 Microchip Technology Inc.
AN891
mELINMIntTXErrorTag()
This macro returns the tag of the message that presented an error.
Syntax
mELINMIntTXErrorTag();
Parameters
None
Return Values
A byte with the tag of the error message.
Preconditions
Error has been previously detected by mELINMIntTXErrorDetected().
Side Effects
None
Remarks
None
Example
errorTag=mELINMIntTXErrorTag();
 2003 Microchip Technology Inc.
// read the tag of the message that had an error
DS00891A-page 11
AN891
mELINMIntTXErrorCode(tag)
This macro returns in one byte the error associated with a message.
Syntax
mELINMIntTXErrorCode(tag);
Parameters
tag
The identification of the message where an error was detected.
Return Values
The error code, defined according to the following table:
#define
Definition
ELINMINT_NO_ERROR
No error was detected
ELINMINT_THMIN_ERROR
Header time too short
ELINMINT_THMAX_ERROR
Header time too long
ELINMINT_TFMIN_ERROR
Frame time too short
ELINMINT_TFMAX_ERROR
Frame time too long
ELINMINT_CHECKSUM_ERROR
Checksum incorrect
ELINMINT_DATA_ERROR
Received and transmitted bytes don’t match
ELINMINT_FRAMING_ERROR
Framing error
Preconditions
1.
2.
Error detected by mELINMIntTXErrorDetected.
Tag of the related message read by mELINMIntTXErrorTag.
Side Effects
None
Remarks
None
Example
if(mELINMIntTXErrorDetected())
{
errorTag=mELINMIntTXErrorTag();
errorCode=mELINMIntTXErrorCode(errorTag);
// check if an TX error was detected
// get the tag of the message
// find the error code
// error handling
}
DS00891A-page 12
 2003 Microchip Technology Inc.
AN891
mELINMIntRXBufferAvailable()
This macro flags if there is a reception buffer available.
Syntax
mELINMIntRXBufferAvailable();
Parameters
None
Return Values
0 – No buffer available
1 – Buffer available
Preconditions
The protocol must have been successfully initialized by the ELINMIntInitialize(void) function.
Side Effects
None
Remarks
None
Example
if (mELINMIntRXBufferAvailable())
mELINMIntReceiveMessage(5,0x01,2);
 2003 Microchip Technology Inc.
// if there is a reception buffer available
// request data: tag #5, ID=0x01 and Size=2
DS00891A-page 13
AN891
mELINMIntReceiveMessage(tag,i,s)
This macro requests a message to be sent from a slave.
Syntax
mELINMIntReceiveMessage(tag,i,s);
Parameters
tag
The tag defined by the application to be associated with the incoming message requested.
i
The ID of the requested message.
s
The size of the message in bytes.
Return Values
None
Preconditions
Reception buffer available (detected by mELINMIntRXBufferAvailable).
Side Effects
None
Remarks
The request of reception, like in the transmission, doesn’t ensure that the received message is correct; therefore,
the application must check the results.
Example
mELINMIntReceiveMessage(5,0x01,2);
DS00891A-page 14
// request data: tag #5, ID=0x01 and Size=2
 2003 Microchip Technology Inc.
AN891
mELINMIntMessageReceived(tag)
This macro checks if a message was received.
Syntax
mELINMIntMessageReceived(tag);
Parameters
tag
The received message identification.
Return Values
1 – Message received
0 – Message not yet received
Preconditions
Reception of a message previously requested by the mELINMIntReceiveMessage macro.
Side Effects
None
Remarks
This macro detects the reception of a message, but doesn’t ensure its correctness; therefore, the application must
check it.
Example
mELINMIntReceiveMessage(7,0x01,2);
while(mELINMIntMessageReceived(7)==0)
;
 2003 Microchip Technology Inc.
// request data:tag=5, ID=0x01, size=2
// wait this message to be received
DS00891A-page 15
AN891
mELINMIntGetMessageTag()
This macro returns the tag (identification) of a message that was received.
Syntax
mELINMIntGetMessageTag();
Parameters
None
Return Values
The tag (identification) of the received message.
Preconditions
1.
2.
3.
The reception of a message must have already been requested using the mELINMIntReceiveMessage
macro.
The message reception Acknowledged by the mELINMIntMessageReceived() macro.
No error detected as per the mELINMIntRXErrorDetected() macro (returning 0).
Side Effects
None
Remarks
None
Example
if(mELINMIntRXErrorDetected()==0)
{
Tag=mELINMIntGetMessageTag();
pt=mELINMIntGetRXPointer(Tag);
//
//
//
//
check if an reception error was detected
if no error then
get the tag of the message received
get the data pointer of the message
}
DS00891A-page 16
 2003 Microchip Technology Inc.
AN891
mELINMIntGetRXPointer(tag)
This macro returns a pointer to the received message.
Syntax
mELINMIntGetRXPointer(tag);
Parameters
tag
The tag identifying the message.
Return Values
(BYTE *) – A byte type data pointer to the reception buffer. The application can read the message using this pointer.
Preconditions
1.
2.
3.
Reception of a message detected by the mELINMIntMessageReceived macro.
No error detected by mELINMIntRXErrorDetected (return 0).
Tag of the message read using the mELINMIntGetMessageTag macro.
Side Effects
None
Remarks
None
Example
Tag=mELINMIntGetMessageTag();
pt=mELINMIntGetRXPointer(Tag);
 2003 Microchip Technology Inc.
// get the tag of the message received
// get the data pointer
DS00891A-page 17
AN891
mELINMIntRXMessageAvailable()
This macro checks for the reception of a message.
Syntax
mELINMIntRXMessageAvailable();
Parameters
None
Return Values
1 – Message Received
0 – No Message received
Preconditions
1.
2.
Protocol initialized – ELINMIntInitialize() macro invoked.
Message reception requested – LINMIntReceiveMessage macro invoked.
Side Effects
None
Remarks
Because the reception of a message is Acknowledged even when an error has occurred, the application will always
check the integrity of the received message.
Example
if(mELINMIntRXMessageAvailable())
{
// check for received message
//
}
DS00891A-page 18
 2003 Microchip Technology Inc.
AN891
mELINMIntRXStatus(tag)
This macro checks the status of a received message.
Syntax
mELINMIntRXStatus(tag);
Parameters
tag
The identification of the message.
Return Values
The error code, defined according to the following table:
#define
Definition
ELINMINT_NO_ERROR
No error was detected
ELINMINT_THMIN_ERROR
Header time too short
ELINMINT_THMAX_ERROR
Header time too long
ELINMINT_TFMIN_ERROR
Frame time too short
ELINMINT_TFMAX_ERROR
Frame time too long
ELINMINT_CHECKSUM_ERROR
Checksum incorrect
ELINMINT_DATA_ERROR
Received and transmitted bytes don’t match
ELINMINT_FRAMING_ERROR
Framing error
Preconditions
1.
2.
3.
Protocol initialized – ELINMIntInitialize() macro invoked.
Message reception requested using mELINMIntReceiveMessage.
Reception completed, checked with mELINMIntMessageReceived.
Side Effects
None
Remarks
None
Example
if(mELINMIntRXMessageReceived(tag))
{
status=mELINMIntRXStatus(tag);
if(status)
{
}
else
{
// check for received message
//
// if error handle it
// otherwise read it
}
}
 2003 Microchip Technology Inc.
DS00891A-page 19
AN891
mELINMIntRXErrorDetected()
This macro checks for reception errors.
Syntax
mELINMIntRXErrorDetected();
Parameters
None
Return Values
1 – Error detect
0 – No error detect
Preconditions
1.
2.
3.
Protocol initialized – ELINMIntInitialize() macro invoked.
Message reception requested – LINMIntReceiveMessage macro invoked.
Reception of message Acknowledged – mELINMIntMessageReceived.
Side Effects
None
Remarks
Because the reception of a message is Acknowledged even when an error has occurred, the application will always
check the integrity of the received message with this macro. In case of an error, the mELINMIntRXErrorTag and
the mELINMIntRXErrorCode macros are called to identify the exact nature of the problem.
Example
if(mELINMIntRXErrorDetected())
{
// check if an RX error was detected
// error handling
}
DS00891A-page 20
 2003 Microchip Technology Inc.
AN891
mELINMIntRXErrorTag()
This macro returns the tag of the message that presented an error.
Syntax
mELINMIntRXErrorCode();
Parameters
None
Return Values
tag
The identification of the error message that was received.
Preconditions
An error detected by the mELINMIntRXErrorDetected macro.
Side Effects
None
Remarks
None
Example
if(mELINMIntRXErrorDetected())
{
ErrorTag=mELINMIntRXErrorTag();
// check if an RX error was detected
// find the tag of the message with error
//
}
 2003 Microchip Technology Inc.
DS00891A-page 21
AN891
mELINMIntRXErrorCode(tag)
This macro returns the code identifying the error detected in the reception of the message identified by tag.
Syntax
mELINMIntRXErrorCode(tag);
Parameters
tag
The identification of the error message received.
Return Values
The error code, defined according to the following table:
#define
Definition
ELINMINT_NO_ERROR
No error was detected
ELINMINT_THMIN_ERROR
Header time too short
ELINMINT_THMAX_ERROR
Header time too long
ELINMINT_TFMIN_ERROR
Frame time too short
ELINMINT_TFMAX_ERROR
Frame time too long
ELINMINT_CHECKSUM_ERROR
Checksum incorrect
ELINMINT_DATA_ERROR
Received and transmitted bytes don’t match
ELINMINT_FRAMING_ERROR
Framing error
Preconditions
1.
2.
Error detected by the mELINMIntRXErrorDetected macro.
The tag of the error read with the mELINMIntRXErrorTag macro.
Side Effects
None
Remarks
None
Example
ErrorCode=mELINMIntRXErrorCode(ErrorTag);// read the error code for the given tag
DS00891A-page 22
 2003 Microchip Technology Inc.
AN891
mELINMIntCheckWakeUPReceived()
This macro flags the reception of a wake-up signal from the slave.
Syntax
mELINMIntCheckWakeUPReceived();
Parameters
None
Return Values
1 – Wake-up received
0 – No wake-up received
Preconditions
Protocol initialized by the ELINMIntInitialize function.
Side Effects
None
Remarks
1.
2.
This macro flags the reception of a wake-up (reception of 0x80 from a slave). According to the specifications
(LIN Specification Package 1.3, Twudel Parameter), the Master must wait at least a 4-bit time before starting
communication. Therefore, once the application detects the wake-up signal, it must allow this minimum time
before starting the communication process.
This signal is kept active until a message transmission or reception is completed.
Example
if(mELINMIntCheckWakeUPReceived())
{
// once received the wake-up from a slave
// process it to detect what happened
}
 2003 Microchip Technology Inc.
DS00891A-page 23
AN891
mELINMIntSendWakeUPSignal()
This macro sends a wake-up signal to the slaves.
Syntax
mELINMIntSendWakeUPSignal();
Parameters
None
Return Values
None
Preconditions
Protocol initialized by the ELINMIntInitialize function.
Side Effects
None
Remarks
This macro sends a wake-up signal (0x80). According to the LIN specifications (LIN Specification Package 1.3,
Twudel Parameter), the Master must wait at least a 4-bit time before starting communication. Therefore, once the
application sends the wake-up signal, it must allow this minimum time before starting the communication process.
Example
mELINMIntSendWakeUPSignal();
DS00891A-page 24
 2003 Microchip Technology Inc.
AN891
mELINMIntSleepTimeOut()
This macro detects the time-out of the bus.
Syntax
mELINMIntSleepTimeOut();
Parameters
None
Return Values
1 – Time-out
0 – No time-out
Preconditions
None
Side Effects
None
Remarks
The time-out condition is detected when no bus activity is observed for a time interval larger than 25000 bits. In this
case a flag is set and the condition can be detected by calling this macro and if necessary, a wake-up signal may
be issued (mELINMIntSendWakeUPSignal).
Example
if(mELINMIntSleepTimeOut())
{
// if an sleep time-out is detected
//
}
 2003 Microchip Technology Inc.
DS00891A-page 25
AN891
DRIVER USAGE
There are two ways to add the driver to a project:
1.
Through Application Maestro™ Software:
Select the module, adjust the parameters and
select the directory location of the files that are
going to be copied. Please refer to the Application
Maestro documentation of this module for further
explanation.
After this, the designer must include the
ELINMInt.c file in the project (inside
MPLAB® IDE, as a C18 C Compiler source code
file) and copy the following include file in all
source code files accessing the protocol:
2.
Manually:
To add the driver into the project, do the following:
a) Copy all three files in the source code
directory of the project.
b) Include the ELINMInt.c file in the project
(inside MPLAB® IDE, as a C18 C Compiler
source code file).
c) Copy the following include file in all source
code files accessing the protocol:
include “ELINMInt.h”
d)
#include “ELINMInt.h”
Note:
DS00891A-page 26
Adjust the parameters of the driver. These
parameters are located inside the
ELINMInt.def file and are described in
Appendix B: “ELINMInt.def Parameter
Setup”.
This first version of the protocol supports
only one communication buffer, therefore,
the use of tags wouldn’t be necessary.
Future versions will implement multiple
buffers (queuing), therefore, the application shall always send and receive the
messages with the proper tag assignment.
 2003 Microchip Technology Inc.
AN891
Software License Agreement
The software supplied herewith by Microchip Technology Incorporated (the “Company”) is intended and supplied to you, the
Company’s customer, for use solely and exclusively with products manufactured by the Company.
The software is owned by the Company and/or its supplier, and is protected under applicable copyright laws. All rights are reserved.
Any use in violation of the foregoing restrictions may subject the user to criminal sanctions under applicable laws, as well as to civil
liability for the breach of the terms and conditions of this license.
THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR
SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
APPENDIX A:
CODE EXAMPLE
#include "ELINMInt.h"
// source files that reference
void InterruptVectorHigh(void);
void InterruptVectorLow(void);
void InterruptHandler(void);
void main(void);
// .H file – to be added in all
// LIN routines or constants
// prototype of the routines used in this test
BYTE my_msg[8];
// message buffer, for tests
/*********************************************************************
* Function:
void Main(void)
*
* PreCondition:
*
* Input:
*
* Output:
*
* Side Effects:
*
* Stack Requirements:
*
* Overview:Main function of the LIN Master Test Firmware
*
********************************************************************/
void main(void)
{
char leds;
unsigned int mydelay;
BYTE *pt;
BYTE ErrorCode;
BYTE ErrorTag;
BYTE Tag;
BYTE rxtag;
mydelay=2000;
TRISC=0x9F;
PORTCbits.RC5=0;
if(mELINMIntInitialize()==0)
ErrorCode=mELINMIntInitErrorCode();
T0CON=0xC8;
INTCON_TMR0IE=1;
INTCON_PEIE=1;
PORTCbits.RC5=1;
INTCON_GIE=1;
while(mydelay--)
 2003 Microchip Technology Inc.
//
//
//
//
//
//
//
//
//
//
initialize the delay variable
init serial pins - TX and control (LIN driver)
negative edge (initial) pulse in the control
initialize Enhanced USART and LIN
if an error was detected return the Initialization
error code
initialize TIMER0
enable timer0 int.
enable ints.
positive edge pulse in the control pin (LIN Driver)
// initial delay -> necessary to MCP201.
// (Data Sheet - param. Tcsor)
DS00891A-page 27
AN891
;
while(1)
// run forever
{
Tag=0;
// init Tag
mydelay=600;
while(mydelay--)
// give a delay between messages, to make scope
;
// visalization easier
//*****************************************************
// First receive a single message using fixed value tag
// checking for the reception of that specific message
//*****************************************************
while(mELINMIntRXBufferAvailable()==0)
;
mELINMIntReceiveMessage(5,0x01,2);
while(mELINMIntMessageReceived(5)==0)
;
if((ErrorCode=mELINMIntRXStatus(5)))
{
leds++;
}
else
{
pt=mELINMIntGetRXPointer(5);
my_msg[0]=*pt;
pt++;
my_msg[1]=*pt;
// if there is no RX buffer available wait
// request data using tag=5 (message number),
// ID=0x01, size=2
// wait until the message is received
// check if an RX error was detected
// error handling - to be added at this point by
// application
// otherwise (no error)
// get the data pointer
// read the message
// received message handling - to be added at this
// point by the application
}
// else
mydelay=600;
while(mydelay--)
;
// give another delay
//*****************************************************
// Send a single message using fixed value tag
// checking for the transmission of that specific message
//*****************************************************
while(mELINMIntTXBufferAvailable()==0)
;
pt= mELINMIntGetTXPointer(3);
*pt=my_msg[0];
pt++;
*pt=0;
mELINMIntSendMessage(3,0x04,2);
while(mELINMIntMessageSent(3)==0)
;
if((ErrorCode=mELINMIntTXStatus(3)))
{
leds++;
}
mydelay=600;
while(mydelay--)
;
DS00891A-page 28
// Wait TX buffer available
// get available pointer and tag it's message as 3
// insert data
//
//
//
//
send message
wait until transmission message #3 completes
the application
check if an TX error was detected (!=0)
// error handling - to be added at this point by
// the application
// application
// give another delay
 2003 Microchip Technology Inc.
AN891
//*****************************************************
// Check for Sleep Time-Out and wake-up if necessary
//*****************************************************
if(mELINMIntSleepTimeOut())
{
mELINMIntSendWakeUPSignal();
//
//
//
//
if timeout set (more than 25000 bit-time
of silence in the BUS)
send wake-up signal to the slaves
add application code here
}
//*****************************************************
// Check for Wake-Up Signal sent by slave
//*****************************************************
if(mELINMIntCheckWakeUPReceived())
{
if(mELINMIntSleepTimeOut())
{
}
else
{
// check for Wake-Up signals received
// if timeout already set (more than 25000 bit-time)
// of silence in the BUS
// if no timeout something unexpected happened, process
}
}
} // while (1)
} // void main(void)
//*****************************************************************************
// High priority interrupt vector
#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh(void)
{
_asm
bra InterruptHandler
// jump to interrupt routine
_endasm
}
#pragma code InterruptVectorHigh = 0x08
void InterruptVectorLow(void)
{
_asm
bra InterruptHandler
// jump to interrupt routine
_endasm
}
/*********************************************************************
* Function:
void InterruptHandler(void)
*
* PreCondition:
*
* Input:
*
* Output:
*
* Side Effects:
*
* Stack Requirements:
*
* Overview:High priority interrupt routine
*
 2003 Microchip Technology Inc.
DS00891A-page 29
AN891
********************************************************************/
#pragma code
#pragma interrupt InterruptHandler
void InterruptHandler(void)
{
if(INTCON_TMR0IF)
ELINMIntHandler();
// process LIN int. based protocol
TMR0L|=0x80;
// timer0 int. every 128 counts - 128 instructions
// time as timer0 is not using any prescaler (1:1)
INTCON_TMR0IF=0;
// reset int0 flag
}
DS00891A-page 30
 2003 Microchip Technology Inc.
AN891
APPENDIX B:
ELINMInt.def PARAMETER SETUP
The ELINMInt.def file has many parameters, some of which must be adjusted by the designer. The parameters that
require adjustment are:
CLOCK_FREQ
Description
This is the main clock frequency used by the microcontroller when running the driver.
Minimum
4000000L
Maximum
40000000L
Remarks
None
Example
#define
CLOCK_FREQ16000000L
// define the main clock as 16MHz
ELINMINT_BAUD
Description
This is the baud rate to be used in the bus by the LIN driver.
Minimum
1000L
Maximum
20000L
Remarks
None
Example
#define
ELINMINT_BAUD19200L
// Baud Rate adjusted to 19200 Baud
ELINMINT_MAX_MESSAGE_SIZE
Description
This is the maximum size of a message either to be transmitted or received.
Minimum
2
Maximum
255
Remarks
None
Example
#define
ELINMINT_MAX_MESSAGE_SIZE16
 2003 Microchip Technology Inc.
// maximum size 16 bytes
DS00891A-page 31
AN891
ELINMINT_INTERRUPT_PERIOD
Description
This is the interrupt period of the interrupt routine (in microseconds) used by the application.
Minimum
The minimum period of this timer-based interrupt must be larger than the sum of the total time used
by the LIN interrupt handler, plus the interrupt latency and any other task run by the application in the
interrupt. The minimum time required by the LIN interrupt handler is calculated inside (ELINMInt.H)
as follows:
// number of instructions run by the protocol during an interrupt
#define
ELINMINT_NINST_HANDLER_MIN112L
// here the necessary time to run the protocol during an int. is calculated as a
// function of the uC's clock frequency (CLOCK_FREQ) and the number of inst. of the
// LIN int. handler
#define ELINMINT_INT_HANDLER_TIME((1000000L*(4*(ELINMINT_NINST_HANDLER_MIN+5)))/CLOCK_FREQ)
// after that the processing time of the protocol is compared with the interrupt.
// execution time and if smaller ( interrupt period > processing time)
// then set an error message.
#if ELINMINT_INT_HANDLER_TIME>ELINMINT_INTERRUPT_PERIOD
#error "LIN TIMING NOT VIABLE - INTERRUPT PERIOD TOO SMALL !!"
#endif
A safe approach is to assume that the handler is going to take about ELINMINT_NINST_HANDLER_MIN instructions, multiply by a safety margin value (e.g., 1.2) and calculate the time spent in microseconds (multiplying the
result by (4/CLOCK_FREQ)).
If the interrupt process time becomes larger than the interrupt period, an error message will be issued and the
compiling process will fail.
Maximum
8*(ELINMINT_BAUD)
Remarks
As a rule of thumb, a good interrupt period should be smaller than 3-bits time (3/ELINMINT_BAUD) because this
time may affect the interbyte delay.
Example
#define
DS00891A-page 32
ELINMINT_INTERRUPT_PERIOD
128L
// 128usec interrupt rate
 2003 Microchip Technology Inc.
AN891
ELINMINT_INTERBYTE_SPACE
Description
This is the delay time added between the transmission of two bytes in a message. This delay time is automatically
calculated based on the baud rate and the interruption period.
Minimum
0
Maximum
Remarks
In some systems, the slave requires a delay slightly larger than the one provided. In these cases, the designer may
have to increase the size of the delay. It is recommended to increase this value in steps of one, as an excessive
increment in the delays may lead to errors, like excessive header time or excessive frame time.
Example
With ‘1’ added to the original Interbyte space.
#define ELINMINT_INTERBYTE_SPACE ((ELINMINT_INTERBYTE_MIN+ELINMINT_INTERBYTE_MAX)/2 +1)
 2003 Microchip Technology Inc.
DS00891A-page 33
AN891
APPENDIX C:
REFERENCES
• LIN Consortium (http://www.lin-subbus.de)
The authoritative reference, the LIN Consortium
provides all standards and specifications necessary to understand and implement LIN-based
communication systems.
• Microchip (http://www.microchip.com)
Microchip provides extensive support to LIN:
- Hardware:
Transceivers, LIN Enabled Microcontrollers,
Development Boards
- Software:
Application Notes, Code Examples and
Templates
DS00891A-page 34
 2003 Microchip Technology Inc.
Note the following details of the code protection feature on Microchip devices:
•
Microchip products meet the specification contained in their particular Microchip Data Sheet.
•
Microchip believes that its family of products is one of the most secure families of its kind on the market today, when used in the
intended manner and under normal conditions.
•
There are dishonest and possibly illegal methods used to breach the code protection feature. All of these methods, to our
knowledge, require using the Microchip products in a manner outside the operating specifications contained in Microchip's Data
Sheets. Most likely, the person doing so is engaged in theft of intellectual property.
•
Microchip is willing to work with the customer who is concerned about the integrity of their code.
•
Neither Microchip nor any other semiconductor manufacturer can guarantee the security of their code. Code protection does not
mean that we are guaranteeing the product as “unbreakable.”
Code protection is constantly evolving. We at Microchip are committed to continuously improving the code protection features of our
products. Attempts to break microchip’s code protection feature may be a violation of the Digital Millennium Copyright Act. If such acts
allow unauthorized access to your software or other copyrighted work, you may have a right to sue for relief under that Act.
Information contained in this publication regarding device
applications and the like is intended through suggestion only
and may be superseded by updates. It is your responsibility to
ensure that your application meets with your specifications.
No representation or warranty is given and no liability is
assumed by Microchip Technology Incorporated with respect
to the accuracy or use of such information, or infringement of
patents or other intellectual property rights arising from such
use or otherwise. Use of Microchip’s products as critical components in life support systems is not authorized except with
express written approval by Microchip. No licenses are conveyed, implicitly or otherwise, under any intellectual property
rights.
Trademarks
The Microchip name and logo, the Microchip logo, Accuron,
dsPIC, KEELOQ, MPLAB, PIC, PICmicro, PICSTART,
PRO MATE and PowerSmart are registered trademarks of
Microchip Technology Incorporated in the U.S.A. and other
countries.
AmpLab, FilterLab, microID, MXDEV, MXLAB, PICMASTER,
SEEVAL, SmartShunt and The Embedded Control Solutions
Company are registered trademarks of Microchip Technology
Incorporated in the U.S.A.
Application Maestro, dsPICDEM, dsPICDEM.net,
dsPICworks, ECAN, ECONOMONITOR, FanSense,
FlexROM, fuzzyLAB, In-Circuit Serial Programming, ICSP,
ICEPIC, microPort, Migratable Memory, MPASM, MPLIB,
MPLINK, MPSIM, PICkit, PICDEM, PICDEM.net, PowerCal,
PowerInfo, PowerMate, PowerTool, rfLAB, rfPIC, Select
Mode, SmartSensor, SmartTel and Total Endurance are
trademarks of Microchip Technology Incorporated in the
U.S.A. and other countries.
Serialized Quick Turn Programming (SQTP) is a service mark
of Microchip Technology Incorporated in the U.S.A.
All other trademarks mentioned herein are property of their
respective companies.
© 2003, Microchip Technology Incorporated, Printed in the
U.S.A., All Rights Reserved.
Printed on recycled paper.
Microchip received ISO/TS-16949:2002 quality system certification for
its worldwide headquarters, design and wafer fabrication facilities in
Chandler and Tempe, Arizona and Mountain View, California in October
2003 . The Company’s quality system processes and procedures are
for its PICmicro® 8-bit MCUs, KEELOQ® code hopping devices, Serial
EEPROMs, microperipherals, non-volatile memory and analog
products. In addition, Microchip’s quality system for the design and
manufacture of development systems is ISO 9001:2000 certified.
DS00891A-page 35
 2003 Microchip Technology Inc.
WORLDWIDE SALES AND SERVICE
AMERICAS
ASIA/PACIFIC
Korea
Corporate Office
Australia
2355 West Chandler Blvd.
Chandler, AZ 85224-6199
Tel: 480-792-7200
Fax: 480-792-7277
Technical Support: 480-792-7627
Web Address: http://www.microchip.com
Suite 22, 41 Rawson Street
Epping 2121, NSW
Australia
Tel: 61-2-9868-6733
Fax: 61-2-9868-6755
168-1, Youngbo Bldg. 3 Floor
Samsung-Dong, Kangnam-Ku
Seoul, Korea 135-882
Tel: 82-2-554-7200 Fax: 82-2-558-5932 or
82-2-558-5934
Atlanta
Unit 706B
Wan Tai Bei Hai Bldg.
No. 6 Chaoyangmen Bei Str.
Beijing, 100027, China
Tel: 86-10-85282100
Fax: 86-10-85282104
3780 Mansell Road, Suite 130
Alpharetta, GA 30022
Tel: 770-640-0034
Fax: 770-640-0307
Boston
2 Lan Drive, Suite 120
Westford, MA 01886
Tel: 978-692-3848
Fax: 978-692-3821
Chicago
333 Pierce Road, Suite 180
Itasca, IL 60143
Tel: 630-285-0071
Fax: 630-285-0075
Dallas
4570 Westgrove Drive, Suite 160
Addison, TX 75001
Tel: 972-818-7423
Fax: 972-818-2924
Detroit
Tri-Atria Office Building
32255 Northwestern Highway, Suite 190
Farmington Hills, MI 48334
Tel: 248-538-2250
Fax: 248-538-2260
Kokomo
2767 S. Albright Road
Kokomo, IN 46902
Tel: 765-864-8360
Fax: 765-864-8387
Los Angeles
China - Beijing
China - Chengdu
Rm. 2401-2402, 24th Floor,
Ming Xing Financial Tower
No. 88 TIDU Street
Chengdu 610016, China
Tel: 86-28-86766200
Fax: 86-28-86766599
China - Fuzhou
Unit 28F, World Trade Plaza
No. 71 Wusi Road
Fuzhou 350001, China
Tel: 86-591-7503506
Fax: 86-591-7503521
China - Hong Kong SAR
Unit 901-6, Tower 2, Metroplaza
223 Hing Fong Road
Kwai Fong, N.T., Hong Kong
Tel: 852-2401-1200
Fax: 852-2401-3431
China - Shanghai
Room 701, Bldg. B
Far East International Plaza
No. 317 Xian Xia Road
Shanghai, 200051
Tel: 86-21-6275-5700
Fax: 86-21-6275-5060
China - Shenzhen
18201 Von Karman, Suite 1090
Irvine, CA 92612
Tel: 949-263-1888
Fax: 949-263-1338
Rm. 1812, 18/F, Building A, United Plaza
No. 5022 Binhe Road, Futian District
Shenzhen 518033, China
Tel: 86-755-82901380
Fax: 86-755-8295-1393
Phoenix
China - Shunde
2355 West Chandler Blvd.
Chandler, AZ 85224-6199
Tel: 480-792-7966
Fax: 480-792-4338
Room 401, Hongjian Building
No. 2 Fengxiangnan Road, Ronggui Town
Shunde City, Guangdong 528303, China
Tel: 86-765-8395507 Fax: 86-765-8395571
San Jose
China - Qingdao
1300 Terra Bella Avenue
Mountain View, CA 94043
Tel: 650-215-1444
Rm. B505A, Fullhope Plaza,
No. 12 Hong Kong Central Rd.
Qingdao 266071, China
Tel: 86-532-5027355 Fax: 86-532-5027205
Toronto
6285 Northam Drive, Suite 108
Mississauga, Ontario L4V 1X5, Canada
Tel: 905-673-0699
Fax: 905-673-6509
India
Divyasree Chambers
1 Floor, Wing A (A3/A4)
No. 11, O’Shaugnessey Road
Bangalore, 560 025, India
Tel: 91-80-2290061 Fax: 91-80-2290062
Japan
Benex S-1 6F
3-18-20, Shinyokohama
Kohoku-Ku, Yokohama-shi
Kanagawa, 222-0033, Japan
Tel: 81-45-471- 6166 Fax: 81-45-471-6122
DS00891A-page 36
Singapore
200 Middle Road
#07-02 Prime Centre
Singapore, 188980
Tel: 65-6334-8870 Fax: 65-6334-8850
Taiwan
Kaohsiung Branch
30F - 1 No. 8
Min Chuan 2nd Road
Kaohsiung 806, Taiwan
Tel: 886-7-536-4818
Fax: 886-7-536-4803
Taiwan
Taiwan Branch
11F-3, No. 207
Tung Hua North Road
Taipei, 105, Taiwan
Tel: 886-2-2717-7175 Fax: 886-2-2545-0139
EUROPE
Austria
Durisolstrasse 2
A-4600 Wels
Austria
Tel: 43-7242-2244-399
Fax: 43-7242-2244-393
Denmark
Regus Business Centre
Lautrup hoj 1-3
Ballerup DK-2750 Denmark
Tel: 45-4420-9895 Fax: 45-4420-9910
France
Parc d’Activite du Moulin de Massy
43 Rue du Saule Trapu
Batiment A - ler Etage
91300 Massy, France
Tel: 33-1-69-53-63-20
Fax: 33-1-69-30-90-79
Germany
Steinheilstrasse 10
D-85737 Ismaning, Germany
Tel: 49-89-627-144-0
Fax: 49-89-627-144-44
Italy
Via Quasimodo, 12
20025 Legnano (MI)
Milan, Italy
Tel: 39-0331-742611
Fax: 39-0331-466781
Netherlands
P. A. De Biesbosch 14
NL-5152 SC Drunen, Netherlands
Tel: 31-416-690399
Fax: 31-416-690340
United Kingdom
505 Eskdale Road
Winnersh Triangle
Wokingham
Berkshire, England RG41 5TU
Tel: 44-118-921-5869
Fax: 44-118-921-5820
11/24/03
 2003 Microchip Technology Inc.