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.