You are on page 1of 35

AN729

LIN Protocol Implementation Using PICmicro MCUs


ever, instead of having a clock line, each byte is marked
Authors: Dan Butler via start and stop bits and the individual bits are asyn-
Thomas Schmidt chronously timed like RS232.
Thorsten Waclawczyk
Microchip Technology Inc. ELECTRICAL CONNECTIONS
Figure 1 shows a typical LIN Protocol configuration.
INTRODUCTION The bus uses a single wire pulled high through a resis-
tor with open collector drivers. A Dominant state is sig-
LIN Protocol was designed by a consortium of Euro-
naled by a ground level on the bus and occurs when
pean auto manufacturers as a low cost, short distance,
any node pulls the bus low. A Recessive state is when
low speed network. Designed to communicate changes
the bus is at VBAT (9 - 18V) and requires that all nodes
in switch settings and respond to switch changes, it is
let the bus float. In the idle state, the bus floats high,
intended to communicate events that happen in
pulled up through the resistor.
"human" time (hundreds of milliseconds).
The bus operates between 9V and 18V, but parts must
This Application Note is not intended to replace or
survive 40V on the bus. Typically, the microcontroller is
recreate the LIN Protocol Specification. Rather, it is
isolated from the bus levels by a line driver/receiver.
intended to provide a broad overview of the bus and
This allows the microcontrollers to operate at 5V levels,
provide a high level look at how it works, how to imple-
while the bus operates at higher levels.
ment a Slave node on a PICmicro device and what its
designed to do. The complete LIN Protocol Specifica- The bus is terminated to VBAT at each node. The Mas-
tion is expected to be available via the worldwide web ter is terminated through a 1K resistor, while the
at www.lin-subbus.com. However, until then, copies of Slaves are terminated through a 20-47K resistor.
the LIN Protocol Specification may only be distributed Maximum bus length is designed to be 40 meters.
by Audi AG, BMW AG, DaimlerChrysler AG, Motorola, At press time (early 2000), K-Line drivers are used until
Inc., Volcano Communication Technologies AB, Volk- true LIN drivers are available.
swagen AG, and Volvo Car Corporation.

BUS FEATURES
LIN Protocol supports bi-directional communication on
a single wire, while using inexpensive microcontrollers
driven by RC oscillators, to avoid the cost of crystals or
ceramic resonators. Instead of paying the price for
accurate hardware, it pays the price in time and soft-
ware. The protocol includes an autobaud step on every
message. Transfer rates of up to 20Kbaud are sup-
ported, along with a low power SLEEP mode, where
the bus is shut down to prevent draining the battery, but
the bus can be powered up by any node on the bus.
The bus itself is a cross between I2CTM and RS232.
The bus is pulled high via a resistor and each node
pulls it low, via an open collector driver like I2C. How-

2000 Microchip Technology Inc. Preliminary DS00729A-page 1


AN729
FIGURE 1: BUS CONFIGURATION

40m
Maxi-
LIN Protocol

1K 30K nom 30K nom 30K nom


VBAT VBAT VBAT VBAT

LIN LIN LIN LIN


Transceiver Transceiver Transceiver Transceiver

Master Slave 1 Slave 2 Slave n <16


C C C C

BYTE PROTOCOL
Each byte is framed by start and stop bits as shown in
Figure 2. Within each byte, data is transmitted LSb first.
The start bit is the opposite of the idle state or zero, and
the stop bit equals the idle state (1).

FIGURE 2: BYTE PROTOCOL

bit 0 1 2 3 4 5 6 7
Start Stop
Bus Idle LSb MSb
bit bit

Each byte is framed by a start bit and stop bit, and data is transmitted Least Significant bit first.

DS00729A-page 2 Preliminary 2000 Microchip Technology Inc.


AN729
MESSAGE PROTOCOL clocks may have drifted as much as 15%. Therefore,
the synch break may be received by a Slave as only 11
The Master controls the bus by polling Slaves to share bit times, or as long as 15 bit times.
their data with the rest of the bus. Slave nodes only The second byte of each message is an ident byte,
transmit when commanded by the Master, which allows which tells the bus what data will follow and indicates
bi-directional communication without further arbitration. which node should answer and how long the answer
Message transfers start with the Master issuing a shall be. Only one Slave may respond to a given
synch break, followed by a synch field and a message command.
field. It also sets the clock for the entire bus by transmit-
ting a synch field at the beginning of each message, Slaves only transmit data on the bus when directed by
which is used for clock synchronization. Each Slave the Master. Once the data is on the bus, any node may
must use this synch byte to adjust their baud rate. receive that data. Therefore, communication from one
Slave to another does not have to be directed through
The synch break is bus dominant, held for 13 bit times, the Master.
followed by a stop bit (recessive). This lets the Slaves
know that a message is coming. The Master and Slave

FIGURE 3: MESSAGE PROTOCOL

Message

Header Response
Bus Idle Synch Synch Ident Data Data Data
Checksum
Break Field Field Byte 1 Byte 2 Byte 3

Interframe Response Space

2000 Microchip Technology Inc. Preliminary DS00729A-page 3


AN729
CLOCK SYNCHRONIZATION IDENTIFIER FIELD
LIN Protocol is designed to use low cost RC oscillators Following the synch field, is an identifier field, which
on the controllers. To keep communication working as tells the bus whats coming next. The ident field is bro-
each nodes clock drifts, Slaves must detect the Mas- ken up into 3 fields: 4 bits (0-3) address devices on the
ters baud rate on every transfer and adjust to the cur- bus, 2 bits (4-5) indicate the length of the message to
rent baud rate. For this reason, each transaction starts follow and the last 2 bits (6-7) are used for parity.
with a synch field. The synch field is a one byte 0x55 The 4 address bits can address up to 16 Slaves, and
(alternating 0s and 1s). This allows every Slave node each Slave can send a 2, 4 or 8 byte response, for a
to detect 8 bit times. By counting these transitions, total of 64 different messages.
dividing by 8 and rounding, each Slave adjusts their
The LIN Protocol Specification does not define the con-
timing to the Master.
tent of each message, except for the SLEEP command
detailed in the Lower Power Sleep section. Instead, that
is left up to the application.
Messages from one node to another may be sent
directly, as directed by the Master. The data does not
have to be received by the Master and retransmitted to
the receiving node. Instead, any message may be
received and acted upon by any node.

FIGURE 4: SYNCH FIELD

Start Stop
Bus Idle 1 0 1 0 1 0 1 0
bit bit
LSb MSb

Start 1 2 3 4
Clock

Count time for 4 successive falling edges, then divide by 8 and round, to get a single bit time. The divide
and round is easily implemented as 3 right shifts and add the carry back in.

DS00729A-page 4 Preliminary 2000 Microchip Technology Inc.


AN729
FIGURE 5: IDENT FIELD

P1 P0 ID5 ID4 ID3 ID2 ID1 ID0

P0: Parity bit ID0 ID1 ID2 ID4


P1: Parity bit ID1 ID3 ID4 ID5
ID0 - 3: Device Address
ID4 - 5: Message Length

ID5 ID4 Date Bytes


0 0 2
0 1 2
1 0 4
1 1 8

2000 Microchip Technology Inc. Preliminary DS00729A-page 5


AN729
ERROR DETECTION LIN Protocol is not directly compatible to CANBUS,
however, it is anticipated that the two will operate in
The following errors must be detected and counted conjunction with one another. CANBUS might be used
within each node: for communication throughout the car, while LIN Proto-
Bit Errors: The transmitting node should compare col would only be used within a small section of the car,
what it thinks should be on the bus against what say within the door.
actually is on the bus. The controllers must wait A CAN-LIN Protocol interface node would be neces-
long enough for the bus to respond before testing sary to connect the two busses. The interface node
for the bit. Given the minimum edge slew rates would collect information from the LIN Protocol nodes
are 1V/uS, and the maximum bus voltage (18V), and pass that information along on CANBUS.
the transmitter should wait 18S before testing, to
see if the bit on the bus is correct. LOWER POWER SLEEP
Checksum Errors: The data content of each mes-
The Master may direct all nodes to enter a SLEEP
sage is protected by a checksum byte, which is
mode by sending a ident code of 0x80. This is the only
the inverted module-256 checksum of the data
message ID defined in the LIN Protocol Specification.
bytes.
The content of the data bytes following the SLEEP
Parity Errors: The command byte uses 2 parity command is not defined. Slaves receiving the SLEEP
bits to protect the other 6. These need to be command should set-up for a wake-up on change from
recalculated and compared. the bus and power-down to minimum current drain. The
If there is an error, the command should be ignored and bus will float high and not consume current.
the error logged. Any node may wake-up the bus by sending a wake-up
signal, which is a character 0x80 (low for 7 bit times fol-
ERROR REPORTING lowed by 1 bit time high). When this signal is received,
There is no direct error reporting mechanism. However, all nodes should wake-up and wait for the Master to
each Slave node is expected to track its own errors. start polling the bus in the normal fashion.
The Master may then request error status as part of a If the Master fails to wake up after 128 bit times
normal message protocol. (6400uS @ 20Kbaud), the node that is attempting to
wake the Master should try again. This may be
CANBUS INTERFACE attempted a total of 3 times before waiting 15000 bit
times (750mS @ 20Kbaud).

FIGURE 6: SLEEP MESSAGE

SLEEP Mode Frame Any Slave Master


Sync Sync SLEEP Data Data Check- Wake-up Synch
Break Field 0x80 1 2 sum 0x80 Break

DS00729A-page 6 Preliminary 2000 Microchip Technology Inc.


AN729
DEMONSTRATION SOFTWARE SOFTWARE FUNCTION
The code in Appendix A demonstrates communication In order to initialize the LIN Protocol Slave handler, the
on the LIN Protocol. The hardware consists of 2 buttons user has to call the routine InitLinSlave. This rou-
and 3 LEDs, as shown in Figure 7. LED #1 changes tine initializes the RB0 interrupt pin and the TMR0.
state for every 10 button pushes of button #1. Likewise, TMR0 will be used to measure the bit length and to
LED #2 changes state for every 10 presses of button generate the baudrate. After initialization, the user can
#2. In response to ID 1, the button counts are transmit- execute his code. The code will be interrupted once a
ted on the bus. In response to ID 4, the button counts falling edge is detected on RB0. If a falling edge is
are updated from the bus. detected, the code will branch into the interrupt service
routine. All interrupts, except for TMR0 and RB0, must
FIGURE 7: DEMONSTRATION HARDWARE be disabled to accurately time the synch field. After the
baudrate is calculated, the interrupt service routine is
LIN Protocol exited. Upon the next interrupt on RB0, the LIN Proto-
col Slavehandler goes automatically into receive mode
30K nom in order to receive the identifier field or data bytes.
VBAT
Once the start bit of the identifier field or data byte is
detected, where the program branches into the inter-
PICmicro MCU B0 LIN Protocol rupt service routine, the identifier field is received and
Driver decoded. Depending on the received identifier, code is
B4
executed, for example, storing data, turn on LED, etc.
This code has to be included by the user into the sub-
routine DecodeIdTable after the routine is executed.
B1 B2 B5 B6 B7
After the bus frame is completed, the flag FCOMPLETE
is set. This flag indicates that all data is received cor-
rectly and ready for further processing. This flag has to
be cleared by the users firmware.
Note: TMR0 is used for bit time measurement and
baudrate generation. Therefore, TMR0 is
not available to application software.

SOFTWARE OPERATION
The LIN Protocol code works on the interrupt as trig-
gered from RB0. This is necessary to implement the
SLEEP/Wake- up requirement. Once the interrupt is
triggered, it counts the length of the low bit time. Then
the synch byte is read and the local bit time is deter-
mined. This is then compared against the original bit
time to determine if the original low time was more than
10 bit times and thus, signaled a synch break, or less
than 10, signaling a wake up from SLEEP.
If its a wake up from SLEEP, the code exits and contin-
ues waiting for a synch break.
If its a synch break, it then reads in the command byte,
checks the parity bits and checks the action table to
determine its actions from there. The action table
defines the source or destination for the data on the
bus.

2000 Microchip Technology Inc. Preliminary DS00729A-page 7


AN729
ERROR DETECTION When the Slave code detects an error, its recorded in
the ERRORFLAGS register as shown in figure 8, and the
The Slave node process detects the following errors: message is ignored. These error flags are cleared
Checksum error once a valid ident field is received.
Bit errors
Missing Stop bit
Parity error
Time-out errors

FIGURE 8: ERROR FLAGS

7 6... 4 3 2 1 0

Time Not Bit CRC ID Parity No


Out Used Error Error Error Response

These flags are set when detected.

SOFTWARE PERFORMANCE INTEGRATION INTO CUSTOM CODE


The LIN Protocol Slavehandler can operate up to a The user has to edit the subroutine DecodeIDTable.
speed of 20Kbaud. In this section, the user defines what action has to be
The LIN Protocol Slavehandler requires 420 words of taken upon a certain identifier. Furthermore, the user
program memory (not including program memory for can define what action has to be taken upon certain
macros for the In Out IDs) and 23 bytes of data mem- errors, (i.e., timing error or others).
ory.
This application is ideal for Microchips internal RC
oscillator operating at 4MHz.

DS00729A-page 8 Preliminary 2000 Microchip Technology Inc.


2000 Microchip Technology Inc.

Software License Agreement


The software supplied herewith by Microchip Technology Incorporated (the Company) for its PICmicro Microcontroller is
intended and supplied to you, the Companys customer, for use solely and exclusively on Microchip PICmicro Microcontroller prod-
ucts.
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 STATU-
TORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICU-
LAR 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: SOURCE CODE

MPASM 02.30.09 Intermediate LINSLAVE.ASM 1-27-2000 9:57:59 PAGE 1


Preliminary

LOC OBJECT CODE LINE SOURCE TEXT


VALUE

00001 ; Software License Agreement


00002 ;
00003 ; The software supplied herewith by Microchip Technology Incorporated (the "Company")
00004 ; for its PICmicro Microcontroller is intended and supplied to you, the Companys
00005 ; customer, for use solely and exclusively on Microchip PICmicro Microcontroller
00006 ; products.
00007 ;
00008 ; The software is owned by the Company and/or its supplier, and is protected under
00009 ; applicable copyright laws. All rights are reserved. Any use in violation of the
00010 ; foregoing restrictions may subject the user to criminal sanctions under applicable
00011 ; laws, as well as to civil liability for the breach of the terms and conditions of
00012 ; this license.
00013 ;
00014 ; THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, WHETHER EXPRESS,
00015 ; IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF

AN729
DS00729A-page 9

00016 ; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE
00017 ; COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
00018 ; CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
00019 ;
00020 ; ###############################################################################
00021 ; filename: LINSLAVE.ASM
00022 ; LIN ( Local Interconnect Network ) SpecRev 1.0
00023 ;
00024 ; ###############################################################################
00025 ;
00026 ; Author: Thorsten Waclawczyk
00027 ; Company: Arizona Microchip Technology GmbH
00028 ;
AN729

DS00729A-page 10
00029 ; Revision: 1.7
00030 ; Date: 18-JAN-2000
00031 ; Assembled using MPASM 2.30.07
00032 ;
00033 ;################################################################################
00034 ;
00035 ; include files:
00036 ; p16C622.inc Rev 1.01
00037 ;
00038 ;################################################################################
00039 ;
00040 ; Implements the LIN slave handler conforming the LIN spec revision 1.0 with
00041 ; using the external interupt INTE and TMR0 as an interrupt based system.
00042 ;
00043 ; LIN HANDLER DESCRIPTION
00044 ;
00045 ; The linslave handler must be initialized before starting the main task
00046 ; by calling the routine "InitLinSlave".
00047 ;
00048 ; After initialization the interrupt based LIN handler waits on first falling

Preliminary
00049 ; and a second rising edge to measure the length of synchbreak lowtime.
00050 ; Then the LIN handler waits for the next falling edge to count the processor
00051 ; cycles between the next four falling edge detections.
00052 ;
00053 ; This result is divided by 8 to get the bitlength. To make sure that
00054 ; this is the header sequence, the bitlength is multiplied by 10 and
00055 ; compared to the initial synchbreak count. If the synchbreak count is
00056 ; longer, we know it was a synchbreak.
00057 ;
00058 ; After that the LIN handler is set in receive mode to read the identifier
00059 ; by using the bitlength value set into the timer0.
00060 ; When the byte has received it will be checked and decoded in the subroutine
00061 ; "CheckIdentifierByte" so that the LIN handler can handle the incoming or
00062 ; outgoing resonse frame.
00063 ;
00064 ; The timing and error checking will be handled by the LIN handler so that
00065 ; the only thing the user has to do is define the DecodeIdTable.
00066 ; This gives an action to each of the 16 possible IDs that may come across
00067 ; from the master. Three actions are possible: MacroLstMode, listen but
00068 ; take no action on the data. MacroRsMode, which provides a buffer for

2000 Microchip Technology Inc.


00069 ; recieving data. MacroTxMode while sets up a buffer to transmit from.
00070 ;
00071 ; When a complete message frame has been done a flag "COMFLAGS,FCOMPLETE"
00072 ; is set. So after that the user can process the data in the buffer
00073 ; if there are no errors. After data is processed the complete flag must
00074 ; be cleared by the user to signal that the data has been processed.
00075 ;
00076 ; DEMO PROGRAM DESCRIPTION
00077 ;
00078 ; The slave node has two buttons and three LEDs. The buttons are read in
00079 ; and counted. The button counts are transmitted in response to ID1.
00080 ;

2000 Microchip Technology Inc.


00081 ; LEDs 1 and 2 change state when the value of the register corresponding
00082 ; counter (COMPLED1 or COMPLED2) matches the delimiter value, currently
00083 ; set to 10.
00084 ;
00085 ; ID4 updates the counters via the LIN bus.
00086 ;
00087 ; LED3 toggles each time it detects a complete message frame.
00088 ;
00089 ; ###############################################################################
00090 ;
00091 ; whats changed
00092 ;
00093 ; changes date of changes
00094 ;
00095 ;

Preliminary
00096 ; ###############################################################################
00097 ;
00098 ; program and data usage
00099 ; program : 0x0420
00100 ; data : 0x24
00101 ; stacklevel : 2
00102 ;
00103 ; ###############################################################################
00104
00105 LIST p=16C622,F=INHX8M
00106
00107 #include <p16c622.inc>
00001 LIST
00002 ; P16C622.INC Standard Header File, Version 1.01 Microchip Technology, Inc.
00165 LIST
00108
2007 3FFB 00109 __CONFIG _CP_OFF & _WDT_OFF & _RC_OSC
00110
00111 ; #### defines ##################################################################
00112
AN729

DS00729A-page 11
00113 #define RSLINEPIN 0 ; PB0 connected to the receive line
00114 #define TXLINEPIN 4 ; PB4 connected to the send line
00115
00116 #define LINSLAVERAM 0x20 ; startadress
00117
00118 ; ---- RAM location used by LINSLAVE modul --------------------------------------
00119
AN729

DS00729A-page 12
00120 CBLOCK LINSLAVERAM
00000020 00121 COPYWREG ; holds a copy of WREG
00000021 00122 COPYSTATUS ; holds a copy of STATUS
00123
00000022 00124 HICOUNT:0,TIMEOUTLO,TIMEOUTHI ; temporary highbyte for TMR0
00125 ; and timeout counter
00000024 00126 COUNTEDGES ;
00000025 00127 COUNTVALUE:0,COUNTVALUELO,COUNTVALUEHI ; software counter for baudrate
00128
00000027 00129 SYNCLENGTH:0,SYNCLENGTHLO,SYNCLENGTHHI
00000029 00130 BITREG:0,BITNBR,BITLENGTH ; bitposition and bitlength
0000002B 00131 DATABLOCKLENGTH ; numbers of send/receive block
0000002C 00132 PREIDNUMBER ; carries the id field bits5..0
0000002D 00133 IDNUMBER ; carries the ID_number
0000002E 00134 ERRORFLAGS ; protocols communication errors
0000002F 00135 COMFLAGS ; linbus communication bits
00000030 00136 BUFFERPTR
00000031 00137 COMBUFFER
00000032 00138 DATACRC ; checksum over xmit / rcsv block
00000033 00139 TXDATAFIELD:8 ; data transmission buffer

Preliminary
0000003B 00140 RSDATAFIELD:8 ; data receive block buffer
00000043 00141 DUMMY:2
00142 ENDC
00143
000000A0 00144 MIRRCOPYWREG EQU (COPYWREG + 80h) ; reserve RAM location on page1
00145
00146 #define LINSLAVEBLOCKLENGTH (DUMMY+1 - LINSLAVERAM)
00147 #define LINBLOCKEND (DUMMY+1)
00148 ;#############################################################
00149 ; ; calculate the needed RAM
00150 ; space by LINslave
00151
00152 ; #### bit defines #
00153 ; defines for the errorflag variable
00154
00155 #define FTIMEOUT 7 ; no communication on receive / transmit
00156 #define FBITERROR 3 ; an outgoing bit value is
00157 ; different than the line value
00158 #define FCRCERROR 2 ; CRC isnt correct
00159 #define FIDPARITYERROR 1 ; parity over ID not correct

2000 Microchip Technology Inc.


00160 #define FNORESPONSE 0 ; no echo on bus
00161
00162 ; defines for the comflag variable
00163
00164 #define FSYNCHBREAK 0 ; synch_break detected
00165 #define FID 1 ; ID byte receives as next byte
00166 #define FRSDATA 2 ; data block read
00167 #define FTXDATA 3 ; data block to be sent
00168 #define FCOMDATA 4 ; communication is running
00169 #define FLISTENONLY 5 ; ID byte is a command only for
00170 #define FCOMPLETE 6 ; communication completed
00171 #define FSLEEPMODE 7 ; sleep-mode frame
00172

2000 Microchip Technology Inc.


00173
00174 ; ###############################################################################
00175 ; #### main task declaration ####################################################
00176 ;
00177 ; at this point used variables for the demo program will be defined
00178 ;
00179
00180 #define LED1 5 ; Toggles after 10 presses of button 1
00181 #define LED2 6 ; toggles after 10 presses of button 2
00182 #define LED3 7 ; indicates complete message frame
00183
00184 #define BUTTON1 1 ; input
00185 #define BUTTON2 2
00186

Preliminary
00187 CBLOCK TXDATAFIELD
00000033 00188 BUTTONPRESSED1 ; register used by ID1
00000034 00189 BUTTONPRESSED2 ;
00190 ENDC
00191
00192 CBLOCK RSDATAFIELD
0000003B 00193 COMPLED1 ; register used by ID4
0000003C 00194 COMPLED2 ;
00195 ENDC
00196
00197 ; define global variables used by the main task
00198
00199 CBLOCK LINBLOCKEND+1
00000045 00200 COMPERATOR ; contains the delimiter to
00201 ; switch on/off the LEDs
00000046 00202 B1FILTER ; debouncefilter button1

00000047 00203 B2FILTER ; debouncefilter button2


00000048 00204 DEBOUNCECOUNTER
00000049 00205 COPYPORTB
AN729

DS00729A-page 13
0000004A 00206 EDGEDETECT
00207 ENDC
00208
00209 ; ###############################################################################
00210 ;################################################################################
00211
00212 ; #### declare MODE macros ######################################################
AN729

DS00729A-page 14
00213
00214 MacroRsMode MACRO StartAddrOfPtr
00215 bsf COMFLAGS,FRSDATA ; indicates the receive mode
00216 movlw StartAddrOfPtr ; get the wanted ram location
00217 ; where the data will stored
00218 movwf BUFFERPTR ; and initialize the pointer
00219 retlw 0
00220 ENDM
00221
00222 MacroTxMode MACRO StartAddrOfPtr
00223 bsf COMFLAGS,FTXDATA ; indicates the transmission mode
00224 movlw StartAddrOfPtr ; get the wanted ram location
00225 ; where the data will read from
00226 movwf BUFFERPTR ; and initialize the pointer
00227 retlw 0
00228 ENDM
00229
00230 MacroLstMode MACRO
00231 bsf COMFLAGS,FLISTENONLY ; indicates the receive mode
00232 ; without saving the received data

Preliminary
00233 nop ; this is necessary to have
00234 nop ; a correct jump table length
00235 retlw 0
00236 ENDM
00237
00238 ; #### RESETvector ##############################################################
00239
0000 00240 RESET org 0x0000 ; reset-vector
00241
0000 29A9 00242 goto Main
00243
00244 ; #### INTvector ################################################################
00245
0004 00246 INTvector org 0x0004
0004 00A0 00247 movwf COPYWREG ; save the used registers WREG
0005 0803 00248 movf STATUS,W ;
0006 1283 00249 bcf STATUS,RP0 ; switch to bank0
0007 00A1 00250 movwf COPYSTATUS ; save STATUS in page0
0008 00251 TMR0int
0008 1D0B 00252 btfss INTCON,T0IF

2000 Microchip Technology Inc.


0009 2815 00253 goto ExtInt ; if timer int enabled
00254
000A 0AA2 00255 incf HICOUNT,F ; increment highbyte is also
000B 1D03 00256 btfss STATUS,Z ; the lowbyte of timeout counter
000C 2810 00257 goto TMR0Int1
00258
000D 0AA3 00259 incf TIMEOUTHI,F ; timeout sequence after
000E 19A3 00260 btfsc TIMEOUTHI,3 ; 3000 * 256 cycles
000F 17AE 00261 bsf ERRORFLAGS,FTIMEOUT ; signal the timeout
00262
0010 00263 TMR0Int1
0010 110B 00264 bcf INTCON,T0IF ; clear overflow flag

2000 Microchip Technology Inc.


0011 192F 00265 btfsc COMFLAGS,FRSDATA ; check if receiver mode
0012 2881 00266 goto GetData
00267
0013 19AF 00268 btfsc COMFLAGS,FTXDATA ; check if transmit mode
0014 28BE 00269 goto PutData
00270
0015 00271 ExtInt
0015 1E0B 00272 btfss INTCON,INTE ; check if external interupt
0016 28F8 00273 goto IntrEnd ; is eanabled and
0017 1C8B 00274 btfss INTCON,INTF ; possibly occured
0018 28F8 00275 goto IntrEnd
00276
0019 3026 00277 movlw 0x26 ; +12 cycles
001A 052F 00278 andwf COMFLAGS,W ; if next byte is ID or falling

Preliminary
001B 1D03 00279 btfss STATUS,Z ; edge of startbit initialize
001C 286D 00280 goto GetDataInit ; reading a byte from bus
00281
001D 182F 00282 btfsc COMFLAGS,FSYNCHBREAK ; was it a synch_break?
001E 2832 00283 goto CountSynchByte ; yes : then the sequence to measure
00284 ; the synch_byte will be expected
001F 1683 00285 bsf STATUS,RP0
Message[302]: Register in operand not in bank 0. Ensure that bank bits are correct.
0020 1B01 00286 btfsc OPTION_REG,INTEDG ; is rising edge selected
0021 2827 00287 goto CopySyncBreakLength ; then save the count of synchbreak
Message[302]: Register in operand not in bank 0. Ensure that bank bits are correct.
0022 1701 00288 bsf OPTION_REG,INTEDG ; else set rising edge sensitivity
0023 1283 00289 bcf STATUS,RP0
00290
0024 0181 00291 clrf TMR0 ; initialize the used counter
0025 01A2 00292 clrf HICOUNT ; to measure the synch break
0026 28F8 00293 goto IntrEnd ; and now wait for rising edge int
00294
0027 00295 CopySyncBreakLength
Message[302]: Register in operand not in bank 0. Ensure that bank bits are correct.
0027 1301 00296 bcf OPTION_REG,INTEDG ; set the falling edge sensitivity
AN729

DS00729A-page 15
0028 1283 00297 bcf STATUS,RP0 ; to detect the startbit of
0029 0801 00298 movf TMR0,W ; the identifier byte
002A 00A7 00299 movwf SYNCLENGTH ; save the counter value
002B 0822 00300 movf HICOUNT,W
002C 00A8 00301 movwf SYNCLENGTH+1 ; if the hibyte is cleared the
002D 1903 00302 btfsc STATUS,Z ; received value was no synch break
002E 2868 00303 goto LowerSynchLength ; sequence so start another
AN729

DS00729A-page 16
00304 ; loop to detect a synch break
002F 01A4 00305 clrf COUNTEDGES ; otherwise initialize the synch
0030 142F 00306 bsf COMFLAGS,FSYNCHBREAK ; byte detection and measurement
0031 28F8 00307 goto IntrEnd
00308
00309 ; ---- CountSynchByte -----------------------------------------------------------
00310 ;
00311 ; Counts the cycles between five falling edges to calculate single bitlength
00312 ; for communicating with the master. The first falling edge clears the count
00313 ; registers. After the fifth edge, the bitlength is calculated by dividing
00314 ; the count by 8 and rounding.
00315 ;
0032 00316 CountSynchByte ; uses 17 cycles to arrive
0032 0824 00317 movf COUNTEDGES,W
0033 1D03 00318 btfss STATUS,Z ; if first falling edge then
0034 2837 00319 goto CountSynchEdges
0035 0181 00320 clrf TMR0 ;initialize bytelength couter
0036 01A2 00321 clrf HICOUNT
00322
0037 00323 CountSynchEdges

Preliminary
0037 1924 00324 btfsc COUNTEDGES,2 ; else check count of passed edges
0038 283B 00325 goto GetSynchLength
0039 0AA4 00326 incf COUNTEDGES,F ; wait for next falling edge
003A 28F8 00327 goto IntrEnd
003B 00328 GetSynchLength
003B 190B 00329 btfsc INTCON,T0IF ; if all edges counted in
003C 0AA2 00330 incf HICOUNT,F ; calculate actual bitlength in
003D 0801 00331 movf TMR0,W ; cycle counts by
003E 00AA 00332 movwf BITLENGTH
003F 1003 00333 bcf STATUS,C ; dividing the 16Bit result by 8
0040 0CA2 00334 rrf HICOUNT,F
0041 0CAA 00335 rrf BITLENGTH,F
0042 1003 00336 bcf STATUS,C
0043 0CA2 00337 rrf HICOUNT,F
0044 0CAA 00338 rrf BITLENGTH,F
0045 1003 00339 bcf STATUS,C
0046 0CA2 00340 rrf HICOUNT,F
0047 0CAA 00341 rrf BITLENGTH,F ; result is in bitlength
0048 082A 00342 movf BITLENGTH,W ;
0049 3C31 00343 sublw .49 ; BITLENGTH lower than fastest

2000 Microchip Technology Inc.


004A 1803 00344 btfsc STATUS,C ; bitrate
004B 2868 00345 goto LowerSynchLength
00346
00347 ; ---- CheckSynchBreakLength ----------------------------------------------------
00348 ;
00349 ; Multiplies the counted bitlength by 10 to see if the synch break
00350 ; is longer than a normal data byte. A normal data byte contains a dominant
00351 ; startbit, 8 databits and a recessive stopbit, so if the measured lowtime
00352 ; of the synchbreak is longer than 10 bitlength times its a synchbreak.
00353 ;
00354
004C 00355 CheckSynchBreakLength

2000 Microchip Technology Inc.


004C 01C4 00356 clrf DUMMY+1 ; no -> do synch break length
004D 082A 00357 movf BITLENGTH,W ; store bitlength
004E 00C3 00358 movwf DUMMY
004F 1003 00359 bcf STATUS,C
0050 0DC3 00360 rlf DUMMY,F ; multiply bitlengh with 8
0051 0DC4 00361 rlf DUMMY+1,F ;
0052 0DC3 00362 rlf DUMMY,F
0053 0DC4 00363 rlf DUMMY+1,F
0054 0DC3 00364 rlf DUMMY,F
0055 0DC4 00365 rlf DUMMY+1,F
0056 07C3 00366 addwf DUMMY,F ; and add bitlength value
0057 1803 00367 btfsc STATUS,C ; twice to multiply by 10
0058 0AC4 00368 incf DUMMY+1,F
0059 07C3 00369 addwf DUMMY,F

Preliminary
005A 1803 00370 btfsc STATUS,C
005B 0AC4 00371 incf DUMMY+1,F
005C 0844 00372 movf DUMMY+1,W
005D 0228 00373 subwf SYNCLENGTH+1,W ; first check the highbytes
005E 1C03 00374 btfss STATUS,C ; bitlength *10 < synch length
005F 2868 00375 goto LowerSynchLength ; yes -> no header detected
0060 1D03 00376 btfss STATUS,Z ; bitlength *10 = synch length
0061 286B 00377 goto HigherSyncLength ; no -> header detected
0062 0843 00378 movf DUMMY,W ; highbytes are equal
0063 0227 00379 subwf SYNCLENGTH,W ; check the lowbytes
0064 1C03 00380 btfss STATUS,C
0065 2868 00381 goto LowerSynchLength
0066 1D03 00382 btfss STATUS,Z
0067 286B 00383 goto HigherSyncLength
00384
0068 00385 LowerSynchLength
0068 01AF 00386 clrf COMFLAGS ; reset the linslave
0069 160B 00387 bsf INTCON,INTE ; allow external interrupt
006A 28F8 00388 goto IntrEnd ; to dedicate first faling edge
00389
006B 00390 HigherSyncLength
AN729

DS00729A-page 17
006B 14AF 00391 bsf COMFLAGS,FID ; next databyte comming in is the
006C 28F8 00392 goto IntrEnd ; identifier byte
00393
00394 ; ---- GetDataInit --------------------------------------------------------------
00395 ;
00396 ; This function initializes the bitlength timer (TMR0) when the falling
00397 ; edge of an start bit is detected so reading the bit takes place in the
AN729

DS00729A-page 18
00398 ; center of the bit time.
00399 ;
00400 ; For typical communication speeds 9600 to 19.2kbaud, we can set timer 0
00401 ; to 1.5 bit times so we skip the remainder of the start bit and wake up
00402 ; midway through the 1st data bit. However for slow baud rates, slower
00403 ; than about 6 kbaud, 1.5 bit times may overflow the 8 bit timer. In
00404 ; this case we set timer 0 to a half bit time so well wake up mid way
00405 ; through the start bit and adjust the bit counter to account for the
00406 ; extra bit.
00407 ;
00408
006D 00409 GetDataInit
006D 01B1 00410 clrf COMBUFFER ; clear input buffer
006E 01A9 00411 clrf BITNBR ; and the bit counter
006F 132F 00412 bcf COMFLAGS,FCOMPLETE ; clear communication complete
00413 ; indicator
0070 082A 00414 movf BITLENGTH,W ; check if baudrate is less than
0071 3CA6 00415 sublw .166 ; ca. 6 kBd
0072 1C03 00416 btfss STATUS,C ; if higher then
0073 2879 00417 goto SetHalfStartbitLength ; set center position into startbit

Preliminary
00418
0074 1003 00419 bcf STATUS,C ; else center position into
0075 0AA9 00420 incf BITNBR,F ; first databit by calculating
0076 0C2A 00421 rrf BITLENGTH,W ; one and a half bitlength
0077 072A 00422 addwf BITLENGTH,W
0078 287A 00423 goto GetDataInitEnd
00424
0079 00425 SetHalfStartbitLength
0079 0C2A 00426 rrf BITLENGTH,W ; center stopbit
00427
007A 00428 GetDataInitEnd
007A 3AFF 00429 xorlw 0xff ; build complement for timer
007B 3E3E 00430 addlw (.62) ; correct timer to center stopbit
007C 0081 00431 movwf TMR0
007D 3020 00432 movlw 0x20 ; INTE off,T0IE on, clear flags
007E 008B 00433 movwf INTCON ; set interrupts
007F 152F 00434 bsf COMFLAGS,FRSDATA ; indicates receive mode
0080 28F8 00435 goto IntrEnd
00436
00437 ; ---- GetData ------------------------------------------------------------------

2000 Microchip Technology Inc.


00438 ;
00439 ; Timer 0 has been set up to return here in time to test the incoming bit
00440 ; midway through the bit time. This function samples the bit and rotates
00441 ; the bit value into the data buffer.
00442 ;
00443 ; If it was an identifier byte, we call DecodeIDTable to figure out what
00444 ; to do next (Recieve message, transmit message or ignore message).
00445 ; If it was a data byte, it is stored in the buffer previously set up by
00446 ; the call to DecodeIDTable. When the all data has been received, the
00447 ; checksum is calculated and compared against the transmitted value. If
00448 ; there are no errors, the FCOMPLETE flag is set to signal that the
00449 ; buffer should be processed.

2000 Microchip Technology Inc.


00450 ;
00451 ; We sample after TMR0 overflows, the routine copies the pin value into the
00452 ; communication buffer and at checks the stopbit level to see if the data
00453 ; is correct. After receiving all bits of a byte there are two possibilities.
00454 ;
00455 ; 1. The received byte is the identifier byte. At this point the
00456 ; routine analyzes the byte to either set up the receive buffer,
00457 ; transmit buffer or neither as designated by the function
00458 ; "DecodeIDTable".
00459 ;
00460 ; 2. The received byte is a data byte of the response frame.
00461 ; The data is stored in the receive buffer and the value is added
00462 ; with the previous carry to build a modulo 256 checksum. The
00463 ; last byte is the message checksum, which is compared with the

Preliminary
00464 ; calculated checksum to check for message integrity.
00465 ;
00466
0081 00467 GetData ; delay of 13 cycles
0081 01A2 00468 clrf TIMEOUTLO ; reset the timeout counter
0082 01A3 00469 clrf TIMEOUTHI
0083 00470 CheckBitPosition
0083 3009 00471 movlw .9 ; how many bits left
0084 0629 00472 xorwf BITNBR,W ; stopbit received ?
0085 1903 00473 btfsc STATUS,Z ; no : copy receive pin value
0086 2891 00474 goto GetStopbit
00475
0087 1C06 00476 btfss PORTB,RSLINEPIN ; copy portvalue in data buffer
0088 1003 00477 bcf STATUS,C ; using the Carryflag
0089 1806 00478 btfsc PORTB,RSLINEPIN
008A 1403 00479 bsf STATUS,C
008B 0CB1 00480 rrf COMBUFFER,F ; shift carry into the buffer
00481
008C 00482 GetDataSetTMR
008C 0AA9 00483 incf BITNBR,F ; count received bit
008D 092A 00484 comf BITLENGTH,W ; and center TMR0 to next bit
AN729

DS00729A-page 19
008E 3E1F 00485 addlw (.31) ; with the correct value
008F 0081 00486 movwf TMR0
0090 28BD 00487 goto GetDataEnd
00488
0091 00489 GetStopbit
0091 1C06 00490 btfss PORTB,RSLINEPIN ; check polarity of stopbit
0092 15AE 00491 bsf ERRORFLAGS,FBITERROR ; if low level set error flag
AN729

DS00729A-page 20
00492
0093 18AF 00493 btfsc COMFLAGS,FID ; if identifier byte is received
0094 28AF 00494 goto GetAction ; check this byte to initialize
00495 ; the commanded slave mode
0095 032B 00496 decf DATABLOCKLENGTH,W ; else if all bytes came in
0096 1903 00497 btfsc STATUS,Z
0097 28A7 00498 goto GetCheckCRC ; the last byte is the Checksum
0098 03AB 00499 decf DATABLOCKLENGTH,F ; else wait for the next byte
00500
0099 082E 00501 movf ERRORFLAGS,W ; check if there are no errors
009A 1D03 00502 btfss STATUS,Z ; if an error has detected
009B 28A5 00503 goto SetNextLoc ; dont store the value
00504
009C 1AAF 00505 btfsc COMFLAGS,FLISTENONLY ; or if slave monitors line
009D 28A5 00506 goto SetNextLoc ; ignore the next steps
00507
009E 0830 00508 movf BUFFERPTR,W ; get pointer
009F 0084 00509 movwf FSR ; and point to location
00A0 0831 00510 movf COMBUFFER,W ; catch the actual data
00A1 0080 00511 movwf INDF ; and ship it into the block

Preliminary
00512
00513 ;
00514 ; caluclate the checksum over received data bytes with MOD256
00515 ; DATACRC = DATACRC + COMBUFFER + Carry
00516 ;
00A2 07B2 00517 addwf DATACRC,F ; add new data into CRC
00A3 1803 00518 btfsc STATUS,C ; add carry if mod 256
00A4 0AB2 00519 incf DATACRC,F ; produces an overflow
00520
00A5 00521 SetNextLoc
00A5 0AB0 00522 incf BUFFERPTR,F ; point to next location
00A6 28B0 00523 goto InitGetData
00524
00A7 00525 GetCheckCRC
00A7 1AAF 00526 btfsc COMFLAGS,FLISTENONLY ; ignore checksum calculation
00A8 28B7 00527 goto GetDataFinish ; if slave reads only messages
00528
00529 ;
00530 ; generate sum of inverted mod 256 over data block plus CRC is 0xFF
00531 ; calculate 0xFF - SUM[RSDATAFIELD] = received CRC

2000 Microchip Technology Inc.


00532
00A9 30FF 00533 movlw 0xFF ; do the complement of CRC
00AA 0632 00534 xorwf DATACRC,W
00535
00AB 0631 00536 xorwf COMBUFFER,W ; check received CRC with
00AC 1D03 00537 btfss STATUS,Z ; calculated CRC
00AD 152E 00538 bsf ERRORFLAGS,FCRCERROR ; set flag if not identical
00AE 28B7 00539 goto GetDataFinish
00540
00AF 00541 GetAction
00AF 212C 00542 call CheckIdentifierByte ; decode and check the ID byte
00543

2000 Microchip Technology Inc.


00B0 00544 InitGetData
00B0 01A9 00545 clrf BITNBR ; clear register for next action
00B1 1DAF 00546 btfss COMFLAGS,FTXDATA ; if next action transmission
00B2 28BA 00547 goto GetDataFinish+3 ; initialize only the interrupts
00548
00B3 120B 00549 bcf INTCON,INTE ; disable external interrupt
00B4 092A 00550 comf BITLENGTH,W ; do a delay before sending data
00B5 0081 00551 movwf TMR0
00B6 28BD 00552 goto GetDataEnd
00553
00B7 00554 GetDataFinish
00B7 30C0 00555 movlw 0xC0
00B8 05AF 00556 andwf COMFLAGS,F ; clear all flags used bits
00B9 172F 00557 bsf COMFLAGS,FCOMPLETE ; indicates receive mode complete

Preliminary
00BA 3010 00558 movlw 0x10 ; no T0IE, set INTE, clear flags
00BB 008B 00559 movwf INTCON ; wait for next falling synch break
00BC 0181 00560 clrf TMR0
00561
00BD 00562 GetDataEnd
00563 ; bcf INTCON,T0IF
00BD 28F8 00564 goto IntrEnd
00565
00566 ; ---- PutData ------------------------------------------------------------------
00567 ;
00568 ; This routine shifts out all wanted databits including a start and stopbit
00569 ; By setting the stopbit the routine will calulate the mod256 checksum
00570 ; and after all outgoing databit the checksum byte will be sent out.
00571 ;
00572
00BE 00573 PutData
00BE 01A2 00574 clrf TIMEOUTLO
00BF 01A3 00575 clrf TIMEOUTHI
00576
00C0 0829 00577 movf BITNBR,W ; if first call set startbit
00C1 1003 00578 bcf STATUS,C
AN729

DS00729A-page 21
00C2 1903 00579 btfsc STATUS,Z
00C3 28D7 00580 goto SetStartbit
00581
00C4 0829 00582 movf BITNBR,W ; if all bits are out
00C5 3A09 00583 xorlw .9 ; do the stopbit
00C6 1903 00584 btfsc STATUS,Z
00C7 28E3 00585 goto SetStopbit
AN729

DS00729A-page 22
00586
00C8 00587 ShiftDatabitOut
00C8 0CB1 00588 rrf COMBUFFER,F ; else copy bits into C
00C9 0806 00589 movf PORTB,W ; get Portvalue
00CA 39EF 00590 andlw ((1<<TXLINEPIN)^0xFF) ; clear used bit
00CB 1803 00591 btfsc STATUS,C ; and then set txline value
00CC 3810 00592 iorlw (1<<TXLINEPIN) ; if nessasary
00CD 0086 00593 movwf PORTB
00594
00CE 00595 CheckBitPending
00CE 0DC3 00596 rlf DUMMY,F ; shift carry into variable
00CF 0606 00597 xorwf PORTB,W ; test polarity of incomming bit
00D0 3901 00598 andlw (1<<RSLINEPIN) ; maskout of the indicated bit
00D1 1D03 00599 btfss STATUS,Z ; if same polarity its okay
00D2 15AE 00600 bsf ERRORFLAGS,FBITERROR
00601
00D3 00602 PutDataSetTMR0
00D3 092A 00603 comf BITLENGTH,W ; preload timer with bitlength
00D4 3E27 00604 addlw (.39) ; correct the timer
00D5 0081 00605 movwf TMR0

Preliminary
00D6 28F7 00606 goto PutDataEnd
00607
00D7 00608 SetStartbit
00D7 1206 00609 bcf PORTB,TXLINEPIN
00D8 0830 00610 movf BUFFERPTR,W
00D9 0084 00611 movwf FSR ; and point to it
00DA 0800 00612 movf INDF,W ; fetch the actual data
00DB 00B1 00613 movwf COMBUFFER
00614
00615 ;
00616 ; generate CRC with MOD 256 -> DATACRC = COMBUFFER + DATACRC + Carry
00617 ;
00DC 00618 CalculateTxCRC
00DC 07B2 00619 addwf DATACRC,F ; create checksum
00DD 1803 00620 btfsc STATUS,C ; add Carry onto data_CRC
00DE 0AB2 00621 incf DATACRC,F ; if overflow occurs
00DF 092A 00622 comf BITLENGTH,W ; preload timer with bitlength
00E0 3E2E 00623 addlw (.46) ; correct the timer
00E1 0081 00624 movwf TMR0
00E2 28F7 00625 goto PutDataEnd

2000 Microchip Technology Inc.


00626
00E3 00627 SetStopbit
00E3 30FF 00628 movlw -1
00E4 00A9 00629 movwf BITNBR ; prepare for clearing reg
00E5 1606 00630 bsf PORTB,TXLINEPIN ; set line for stopbit
00E6 0181 00631 clrf TMR0 ; wait 1*Tbit + x us
00E7 0AB0 00632 incf BUFFERPTR,F ; array ptr to next cell
00E8 03AB 00633 decf DATABLOCKLENGTH,F ; all data bytes xmit ?
00E9 082B 00634 movf DATABLOCKLENGTH,W
00EA 1903 00635 btfsc STATUS,Z ; all data bytes out include
00EB 28F4 00636 goto PutDataFinish ; the CRC byte ?
00EC 3A01 00637 xorlw .1 ; no : is there only the CRC byte ?

2000 Microchip Technology Inc.


00ED 1D03 00638 btfss STATUS,Z
00EE 28F7 00639 goto PutDataEnd ; no : okay wait for the next bit
00640
00641 ;
00642 ; generate inverted MOD256 Checksum
00643 ; COMBUFFER = DATACRC XOR 0xFF, so SUM(TxData_field)+DATACRC = 0xFF
00644 ;
00645
00EF 00646 SetPtr2CRC
00EF 30FF 00647 movlw 0xFF
00F0 06B2 00648 xorwf DATACRC,F ; generate correct checksum
00649
00F1 3032 00650 movlw DATACRC ; get adress of checksum reg
00F2 00B0 00651 movwf BUFFERPTR ; and save value

Preliminary
00F3 28F7 00652 goto PutDataEnd
00653
00F4 00654 PutDataFinish
00F4 01AF 00655 clrf COMFLAGS ; reset communication flags
00F5 172F 00656 bsf COMFLAGS,FCOMPLETE ; indicate the complete flag
00F6 160B 00657 bsf INTCON,INTE ; and new start with
00658 ; synchbreak detection
00F7 00659 PutDataEnd
00F7 0AA9 00660 incf BITNBR,F ; set bitcounter to zero
00661
00662 ; ---- IntrEnd ------------------------------------------------------------------
00663 ;
00664 ; Restore the saved registers and clear the interrupt flags, return from
00665 ; interrupt.
00666
00F8 00667 IntrEnd
00F8 30F0 00668 movlw 0xF0 ; clear all pending int flags
00F9 058B 00669 andwf INTCON,F
00FA 168B 00670 bsf INTCON,T0IE ; and set timer0 overflow int
00671
00FB 0821 00672 movf COPYSTATUS,W ; restore status
AN729

DS00729A-page 23
00FC 0083 00673 movwf STATUS
00FD 0EA0 00674 swapf COPYWREG,F ; and fetch old W from further
00FE 0E20 00675 swapf COPYWREG,W ; ram bank
00FF 0009 00676 retfie
00677
00678
00679 ; #### subroutines ##############################################################
AN729

DS00729A-page 24
00680 ;
00681 ;
00682 ; #### init_LinSlave ############################################################
00683 ;
00684 ; clears all ram locations which are used from the linslave and initializes
00685 ; the portpins and interruptflags
00686 ;
00687
0100 00688 InitLinSlave
0100 3020 00689 movlw LINSLAVERAM
0101 0084 00690 movwf FSR
0102 3024 00691 movlw LINSLAVEBLOCKLENGTH
0103 00692 ClearLINusedRAM
0103 0180 00693 clrf INDF ; clear register
0104 0A84 00694 incf FSR,F ; point to next cell
0105 0804 00695 movf FSR,W
0106 3C44 00696 sublw (LINSLAVEBLOCKLENGTH+LINSLAVERAM)
0107 1D03 00697 btfss STATUS,Z ; all done well?
0108 2903 00698 goto ClearLINusedRAM ; no : next loop
00699

Preliminary
0109 1606 00700 bsf PORTB,TXLINEPIN ; Portpin is high on programstart
010A 1683 00701 bsf STATUS,RP0
010B 1406 00702 bsf PORTB,RSLINEPIN ; receive line as input
010C 1206 00703 bcf PORTB,TXLINEPIN ; and transmit line as output
010D 3008 00704 movlw 0x08 ; set TMR0 as counter driven
Message[302]: Register in operand not in bank 0. Ensure that bank bits are correct.
010E 0081 00705 movwf OPTION_REG ; with internal clock
Message[302]: Register in operand not in bank 0. Ensure that bank bits are correct.
010F 1301 00706 bcf OPTION_REG,INTEDG
0110 1283 00707 bcf STATUS,RP0
0111 108B 00708 bcf INTCON,INTF
0112 160B 00709 bsf INTCON,INTE
0113 178B 00710 bsf INTCON,GIE
0114 0008 00711 return
00712
00713 ; #### InitWakeupLIN ############################################################
00714 ;
00715 ; This wakes up the bus by pulling the bus low for 7 bit times followed by
00716 ; a high stop bit. This would be used after the bus had been put to sleep,
00717 ; and the node needs to wake up the bus. One the bus has reawakened, the

2000 Microchip Technology Inc.


00718 ; master starts polling the slaves to find out why.
00719 ;
00720
0115 00721 InitWakeupLIN
0115 082A 00722 movf BITLENGTH,W
0116 1903 00723 btfsc STATUS,Z ; if there was no further communication
0117 2926 00724 goto InitWakeupEnd ; do not do this function
0118 3001 00725 movlw .1
0119 00AB 00726 movwf DATABLOCKLENGTH ; realize a one byte data block using
011A 3080 00727 movlw 0x80 ; the CRC reg as data container
011B 00B2 00728 movwf DATACRC
011C 3032 00729 movlw DATACRC ; initialize data pointer onto CRC

2000 Microchip Technology Inc.


011D 00B0 00730 movwf BUFFERPTR
011E 01A9 00731 clrf BITNBR ; and start transmission
011F 15AF 00732 bsf COMFLAGS,FTXDATA
00733
0120 0181 00734 clrf TMR0 ; do a delay before sending out the
00735 ; wakeup sequence
0121 30A0 00736 movlw 0xA0 ; set TMR0 int
0122 008B 00737 movwf INTCON
0123 19AF 00738 btfsc COMFLAGS,FTXDATA
0124 2923 00739 goto $-1
0125 13AF 00740 bcf COMFLAGS,FSLEEPMODE ; wait to end wakeup sequence
0126 00741 InitWakeupEnd
0126 0008 00742 return
00743

Preliminary
00744 ; #### CheckIdentifierByte ######################################################
00745 ;
00746 ; this function is called by interrupt after the synch break and synch byte
00747 ; is detected and the bitlength is calculated.
00748 ; The identifier byte is read from bus and at this point the byte will be
00749 ; checked if odd/even parity bis are correct, then extract the blocklength
00750 ; and ID number and in dependence of the ID the handler mode will be set.
00751 ;
00752 ;
0127 00753 DataBlockLengthTable ; decoder table for receive
0127 0782 00754 addwf PCL,F ; byte length
0128 3403 3403 3405 00755 DT 3,3,5,9 ; there is one byte more for the checksum
3409
00756 ; byte is at the end of the data array
00757
012C 00758 CheckIdentifierByte
012C 01AF 00759 clrf COMFLAGS ; clear all flags
012D 0831 00760 movf COMBUFFER,W ; get identifier field
012E 3A80 00761 xorlw 0x80 ; and test if there is a SLEEP command
012F 1903 00762 btfsc STATUS,Z
0130 29A0 00763 goto ActionBusSleep ; yes : break the function
AN729

DS00729A-page 25
00764
0131 00765 CheckEvenParityBit6 ; count ones for even parity
0131 01A9 00766 clrf BITNBR
0132 1831 00767 btfsc COMBUFFER,0
0133 0AA9 00768 incf BITNBR,F
0134 18B1 00769 btfsc COMBUFFER,1
0135 0AA9 00770 incf BITNBR,F
AN729

DS00729A-page 26
0136 1931 00771 btfsc COMBUFFER,2
0137 0AA9 00772 incf BITNBR,F
0138 1A31 00773 btfsc COMBUFFER,4
0139 0AA9 00774 incf BITNBR,F
00775
013A 1B31 00776 btfsc COMBUFFER,6 ; check bit6 contains the even
013B 0AA9 00777 incf BITNBR,F ; value
013C 1829 00778 btfsc BITNBR,0 ; if even then check odd parity bit
013D 294A 00779 goto SetParityError
013E 00780 CheckOddParityBit7 ; count ones for odd parity
013E 01A9 00781 clrf BITNBR ; and invert
013F 18B1 00782 btfsc COMBUFFER,1
0140 0AA9 00783 incf BITNBR,F
0141 19B1 00784 btfsc COMBUFFER,3
0142 0AA9 00785 incf BITNBR,F
0143 1A31 00786 btfsc COMBUFFER,4
0144 0AA9 00787 incf BITNBR,F
0145 1AB1 00788 btfsc COMBUFFER,5
0146 0AA9 00789 incf BITNBR,F
00790

Preliminary
0147 1FB1 00791 btfss COMBUFFER,7
0148 0AA9 00792 incf BITNBR,F ; if odd then split off
0149 1829 00793 btfsc BITNBR,0 ; the blocklength
014A 00794 SetParityError
014A 14AE 00795 bsf ERRORFLAGS,FIDPARITYERROR ; set parity error bit
00796 ; if there is an error
014B 00797 GetPreID
014B 0831 00798 movf COMBUFFER,W ; get the id number plus
014C 393F 00799 andlw 0x3F ; the blocklength subsets
014D 00AC 00800 movwf PREIDNUMBER ; and save the value
00801
014E 00802 DecodeBlockLength
014E 3001 00803 movlw high DataBlockLengthTable ; get address of decoder table
014F 008A 00804 movwf PCLATH
00805
0150 0E31 00806 swapf COMBUFFER,W ; switches bit3,4 into bit0,1
0151 3903 00807 andlw .3 ; kill the rest
0152 2127 00808 call DataBlockLengthTable ; and decode the result
0153 00AB 00809 movwf DATABLOCKLENGTH ; store the used blocklength
00810 ; including the checksum byte

2000 Microchip Technology Inc.


0154 01B2 00811 clrf DATACRC ; initialize the checksum
0155 01AE 00812 clrf ERRORFLAGS ; and error flag register
00813
0156 00814 DecodeIdNumber
0156 162F 00815 bsf COMFLAGS,FCOMDATA ; set communication flag
00816
0157 3001 00817 movlw HIGH DecodeIDTable ; initial the high program
0158 008A 00818 movwf PCLATH ; counter with table adress
00819
0159 0831 00820 movf COMBUFFER,W ; get the buffer value
015A 390F 00821 andlw .15
015B 00AD 00822 movwf IDNUMBER ; save ID number

2000 Microchip Technology Inc.


015C 00B1 00823 movwf COMBUFFER ; generate the jump width
015D 0DB1 00824 rlf COMBUFFER,F ; by multiplying id with
015E 0D31 00825 rlf COMBUFFER,W ; four and do the jump
015F 0782 00826 addwf PCL,F ; by manipulating the PCL
00827
00828 ; ---- DecodeIDTable ------------------------------------------------------------
00829 ;
00830 ; Decode table using the ID numbers
00831 ;
00832 ; This is the point where the user can decide how the slave will react on
00833 ; the decoded identifier number. Also he can decide where the received data
00834 ; will be stored or where the send data come from.
00835 ;
00836 ; Three modes are possible:

Preliminary
00837 ; MacroRsMode (ptr) -> read data from bus and save
00838 ; it in the provided buffer (ptr)
00839 ; MacroTxMode (ptr) -> send data out on bus from the
00840 ; provided buffer.
00841 ; MacroLstMode -> only monitor the bus
00842 ;
00843 ; In the monitoring mode the user has the possibility to use the value of
00844 ; the PREIDNUMBER to handle 64 commands without any data messages.
00845
0160 00846 DecodeIDTable
00847 MacroLstMode
0160 16AF M bsf COMFLAGS,FLISTENONLY ; indicates the receive mode
M ; without saving the received data
0161 0000 M nop ; this is necessary to have
0162 0000 M nop ; a correct jump table length
0163 3400 M retlw 0
00848 MacroTxMode ( BUTTONPRESSED1 ) ; ID1: Transmit the button press counts
0164 15AF M bsf COMFLAGS,FTXDATA ; indicates the transmission mode
0165 3033 M movlw ( BUTTONPRESSED1 ) ; get the wanted ram location
M ; where the data will read from
AN729

DS00729A-page 27
0166 00B0 M movwf BUFFERPTR ; and initialize the pointer
0167 3400 M retlw 0
00849 MacroLstMode
0168 16AF M bsf COMFLAGS,FLISTENONLY ; indicates the receive mode
M ; without saving the received data
0169 0000 M nop ; this is necessary to have
016A 0000 M nop ; a correct jump table length
016B 3400 M retlw 0
AN729

DS00729A-page 28
00850 MacroLstMode
016C 16AF M bsf COMFLAGS,FLISTENONLY ; indicates the receive mode
M ; without saving the received data
016D 0000 M nop ; this is necessary to have
016E 0000 M nop ; a correct jump table length
016F 3400 M retlw 0
00851 MacroRsMode ( COMPLED1 ) ; ID4: Receive LED counters
0170 152F M bsf COMFLAGS,FRSDATA ; indicates the receive mode
0171 303B M movlw ( COMPLED1 ) ; get the wanted ram location
M ; where the data will stored
0172 00B0 M movwf BUFFERPTR ; and initialize the pointer
0173 3400 M retlw 0
00852 MacroLstMode
0174 16AF M bsf COMFLAGS,FLISTENONLY ; indicates the receive mode
M ; without saving the received data
0175 0000 M nop ; this is necessary to have
0176 0000 M nop ; a correct jump table length
0177 3400 M retlw 0
00853 MacroLstMode
0178 16AF M bsf COMFLAGS,FLISTENONLY ; indicates the receive mode

Preliminary
M ; without saving the received data
0179 0000 M nop ; this is necessary to have
017A 0000 M nop ; a correct jump table length
017B 3400 M retlw 0
00854 MacroLstMode
017C 16AF M bsf COMFLAGS,FLISTENONLY ; indicates the receive mode
M ; without saving the received data
017D 0000 M nop ; this is necessary to have
017E 0000 M nop ; a correct jump table length
017F 3400 M retlw 0
00855 MacroLstMode
0180 16AF M bsf COMFLAGS,FLISTENONLY ; indicates the receive mode
M ; without saving the received data
0181 0000 M nop ; this is necessary to have
0182 0000 M nop ; a correct jump table length
0183 3400 M retlw 0
00856 MacroLstMode
0184 16AF M bsf COMFLAGS,FLISTENONLY ; indicates the receive mode
M ; without saving the received data
0185 0000 M nop ; this is necessary to have

2000 Microchip Technology Inc.


0186 0000 M nop ; a correct jump table length
0187 3400 M retlw 0
00857 MacroLstMode
0188 16AF M bsf COMFLAGS,FLISTENONLY ; indicates the receive mode
M ; without saving the received data
0189 0000 M nop ; this is necessary to have
018A 0000 M nop ; a correct jump table length
018B 3400 M retlw 0
00858 MacroLstMode
018C 16AF M bsf COMFLAGS,FLISTENONLY ; indicates the receive mode
M ; without saving the received data
018D 0000 M nop ; this is necessary to have

2000 Microchip Technology Inc.


018E 0000 M nop ; a correct jump table length
018F 3400 M retlw 0
00859 MacroLstMode
0190 16AF M bsf COMFLAGS,FLISTENONLY ; indicates the receive mode
M ; without saving the received data
0191 0000 M nop ; this is necessary to have
0192 0000 M nop ; a correct jump table length
0193 3400 M retlw 0
00860 MacroLstMode
0194 16AF M bsf COMFLAGS,FLISTENONLY ; indicates the receive mode
M ; without saving the received data
0195 0000 M nop ; this is necessary to have
0196 0000 M nop ; a correct jump table length
0197 3400 M retlw 0

Preliminary
00861 MacroLstMode
0198 16AF M bsf COMFLAGS,FLISTENONLY ; indicates the receive mode
M ; without saving the received data
0199 0000 M nop ; this is necessary to have
019A 0000 M nop ; a correct jump table length
019B 3400 M retlw 0
00862 MacroLstMode
019C 16AF M bsf COMFLAGS,FLISTENONLY ; indicates the receive mode
M ; without saving the received data
019D 0000 M nop ; this is necessary to have
019E 0000 M nop ; a correct jump table length
019F 3400 M retlw 0
00863
00864
00865 ; ---- ActionBusSleep -----------------------------------------------------------
00866 ;
00867 ; Arriving on this sequence the master will not longer talk to the
00868 ; slaves so he gives the command to hangup the line.
00869 ; After finishing the bus read the main task is able to activate
00870 ; the wakeup sequence to give the master the directive to reactivate
AN729

DS00729A-page 29
00871 ; the communication.
00872
01A0 00873 ActionBusSleep
01A0 17AF 00874 bsf COMFLAGS,FSLEEPMODE
01A1 3003 00875 movlw .3
01A2 00AB 00876 movwf DATABLOCKLENGTH ; decomp length control bits
01A3 3080 00877 movlw 0x80
01A4 00AD 00878 movwf IDNUMBER ; set identifier on sleep id
AN729

DS00729A-page 30
00879 MacroRsMode ( RSDATAFIELD ) ; save the two received bytes
01A5 152F M bsf COMFLAGS,FRSDATA ; indicates the receive mode
01A6 303B M movlw ( RSDATAFIELD ) ; get the wanted ram location
M ; where the data will stored
01A7 00B0 M movwf BUFFERPTR ; and initialize the pointer
01A8 3400 M retlw 0
00880
00881 ; #### MAIN #####################################################################
00882
01A9 00883 Main
00884
01A9 300A 00885 movlw .10
01AA 00C5 00886 movwf COMPERATOR ; after x counts set LED1&2 on
01AB 00C8 00887 movwf DEBOUNCECOUNTER
00888
01AC 01CA 00889 clrf EDGEDETECT
00890
01AD 1683 00891 bsf STATUS,RP0
01AE 301F 00892 movlw 0x1F ; set PORTB7..5 as output
01AF 0086 00893 movwf PORTB ; to manage LEDs

Preliminary
01B0 1283 00894 bcf STATUS,RP0
00895
01B1 2100 00896 call InitLinSlave ; initialize linbus functions
00897
01B2 00898 MainLoop
01B2 1F2F 00899 btfss COMFLAGS,FCOMPLETE ; message frame complete ?
01B3 29B7 00900 goto CheckLevel ; no -> do rest of main task
00901
01B4 132F 00902 bcf COMFLAGS,FCOMPLETE ; clear flag
01B5 3080 00903 movlw (1<<LED3) ; and toggle LED
01B6 0686 00904 xorwf PORTB,F
00905
01B7 00906 CheckLevel
01B7 0845 00907 movf COMPERATOR,W ; compare delimiter
01B8 023B 00908 subwf COMPLED1,W ; with first value
01B9 1C03 00909 btfss STATUS,C ; if not equal
01BA 29BE 00910 goto CheckNextLevel ; check next value
00911
01BB 01BB 00912 clrf COMPLED1 ; else manipulate value
01BC 3020 00913 movlw (1<<LED1) ; and toggle LED1

2000 Microchip Technology Inc.


01BD 0686 00914 xorwf PORTB,F
00915
01BE 00916 CheckNextLevel
01BE 0845 00917 movf COMPERATOR,W ; compare second value
01BF 023C 00918 subwf COMPLED2,W
01C0 1C03 00919 btfss STATUS,C
01C1 29C5 00920 goto TestButtons
00921
01C2 01BC 00922 clrf COMPLED2 ; and if equal
01C3 3040 00923 movlw (1<<LED2) ; toggle LED2
01C4 0686 00924 xorwf PORTB,F
00925

2000 Microchip Technology Inc.


01C5 00926 TestButtons
01C5 0BC8 00927 decfsz DEBOUNCECOUNTER,F
01C6 29B2 00928 goto MainLoop ; do the loop
00929
00930
01C7 3006 00931 movlw (1<<BUTTON1) | (1<<BUTTON2) ; maskout of the used
01C8 0506 00932 andwf PORTB,W ; portpins and save
01C9 00C9 00933 movwf COPYPORTB ; the result
00934
01CA 00935 CheckEdgeChange
01CA 064A 00936 xorwf EDGEDETECT,W ; check actual and last
01CB 0549 00937 andwf COPYPORTB,W ; value to detect any
01CC 1903 00938 btfsc STATUS,Z ; rising edge on input
01CD 29D7 00939 goto ButtomTestEnd ; nothing -> do the loop

Preliminary
00940
01CE 00C8 00941 movwf DEBOUNCECOUNTER ; save the pin who changed
00942
01CF 00943 RisingEdgeButtom1
01CF 3002 00944 movlw (1<<BUTTON1) ; mask of button1
01D0 0548 00945 andwf DEBOUNCECOUNTER,W ; buttom1 pressed ?
01D1 1D03 00946 btfss STATUS,Z
01D2 0AB3 00947 incf BUTTONPRESSED1,F ; yes : count the rising edge
00948
01D3 00949 RisingEdgeButtom2
01D3 3004 00950 movlw (1<<BUTTON2) ; mask of button2
01D4 0548 00951 andwf DEBOUNCECOUNTER,W ; button 2 pressed ?
01D5 1D03 00952 btfss STATUS,Z
01D6 0AB4 00953 incf BUTTONPRESSED2,F ; yes : count the rising edge
00954
01D7 00955 ButtomTestEnd
01D7 0849 00956 movf COPYPORTB,W ; save actual values to detect
01D8 00CA 00957 movwf EDGEDETECT ; the next rising edge
00958
01D9 300A 00959 movlw .10 ; reload the debounce
AN729

DS00729A-page 31
01DA 00C8 00960 movwf DEBOUNCECOUNTER
01DB 29B2 00961 goto MainLoop ; and do the loop again
00962
00963 end
MEMORY USAGE MAP (X = Used, - = Unused)

0000 : X---XXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX


0040 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
AN729

DS00729A-page 32
0080 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX

MPASM 02.30.09 Intermediate LINSLAVE.ASM 1-27-2000 9:57:59 PAGE 25

MEMORY USAGE MAP (X = Used, - = Unused)

00C0 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX


0100 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
0140 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
0180 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
01C0 : XXXXXXXXXXXXXXXX XXXXXXXXXXXX---- ---------------- ----------------
2000 : -------X-------- ---------------- ---------------- ----------------

All other memory blocks unused.

Program Memory Words Used: 473


Program Memory Words Free: 1575

Preliminary
2000 Microchip Technology Inc.
AN729
NOTES:

2000 Microchip Technology Inc. Preliminary DS00729A-page 33


Note the following details of the code protection feature on PICmicro MCUs.

The PICmicro family meets the specifications contained in the Microchip Data Sheet.
Microchip believes that its family of PICmicro microcontrollers is one of the most secure products 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 knowl-
edge, require using the PICmicro microcontroller in a manner outside the operating specifications contained in the data sheet.
The person doing so may be 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 product.
If you have any further questions about this matter, please contact the local sales office nearest to you.

Information contained in this publication regarding device Trademarks


applications and the like is intended through suggestion only
and may be superseded by updates. It is your responsibility to The Microchip name and logo, the Microchip logo, FilterLab,
ensure that your application meets with your specifications. KEELOQ, microID, MPLAB, PIC, PICmicro, PICMASTER,
No representation or warranty is given and no liability is PICSTART, PRO MATE, SEEVAL and The Embedded Control
assumed by Microchip Technology Incorporated with respect Solutions Company are registered trademarks of Microchip Tech-
to the accuracy or use of such information, or infringement of nology Incorporated in the U.S.A. and other countries.
patents or other intellectual property rights arising from such
dsPIC, ECONOMONITOR, FanSense, FlexROM, fuzzyLAB,
use or otherwise. Use of Microchips products as critical com-
In-Circuit Serial Programming, ICSP, ICEPIC, microPort,
ponents in life support systems is not authorized except with
Migratable Memory, MPASM, MPLIB, MPLINK, MPSIM,
express written approval by Microchip. No licenses are con-
MXDEV, PICC, PICDEM, PICDEM.net, rfPIC, Select Mode
veyed, implicitly or otherwise, under any intellectual property
and Total Endurance are trademarks of Microchip Technology
rights.
Incorporated in the U.S.A.

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.

2002, Microchip Technology Incorporated, Printed in the


U.S.A., All Rights Reserved.

Printed on recycled paper.

Microchip received QS-9000 quality system


certification for its worldwide headquarters,
design and wafer fabrication facilities in
Chandler and Tempe, Arizona in July 1999. The
Companys quality system processes and
procedures are QS-9000 compliant for its
PICmicro 8-bit MCUs, KEELOQ code hopping
devices, Serial EEPROMs and microperipheral
products. In addition, Microchips quality
system for the design and manufacture of
development systems is ISO 9001 certified.

2002 Microchip Technology Inc.


M
WORLDWIDE SALES AND SERVICE
AMERICAS ASIA/PACIFIC Japan
Microchip Technology Japan K.K.
Corporate Office Australia
Benex S-1 6F
2355 West Chandler Blvd. Microchip Technology Australia Pty Ltd
3-18-20, Shinyokohama
Chandler, AZ 85224-6199 Suite 22, 41 Rawson Street
Kohoku-Ku, Yokohama-shi
Tel: 480-792-7200 Fax: 480-792-7277 Epping 2121, NSW
Kanagawa, 222-0033, Japan
Technical Support: 480-792-7627 Australia
Web Address: http://www.microchip.com Tel: 61-2-9868-6733 Fax: 61-2-9868-6755 Tel: 81-45-471- 6166 Fax: 81-45-471-6122
Rocky Mountain China - Beijing Korea
2355 West Chandler Blvd. Microchip Technology Consulting (Shanghai) Microchip Technology Korea
Chandler, AZ 85224-6199 Co., Ltd., Beijing Liaison Office 168-1, Youngbo Bldg. 3 Floor
Tel: 480-792-7966 Fax: 480-792-7456 Unit 915 Samsung-Dong, Kangnam-Ku
Bei Hai Wan Tai Bldg. Seoul, Korea 135-882
Atlanta No. 6 Chaoyangmen Beidajie Tel: 82-2-554-7200 Fax: 82-2-558-5934
500 Sugar Mill Road, Suite 200B Beijing, 100027, No. China Singapore
Atlanta, GA 30350 Tel: 86-10-85282100 Fax: 86-10-85282104 Microchip Technology Singapore Pte Ltd.
Tel: 770-640-0034 Fax: 770-640-0307 200 Middle Road
China - Chengdu
Boston #07-02 Prime Centre
Microchip Technology Consulting (Shanghai)
2 Lan Drive, Suite 120 Singapore, 188980
Co., Ltd., Chengdu Liaison Office
Westford, MA 01886 Tel: 65-334-8870 Fax: 65-334-8850
Rm. 2401, 24th Floor,
Tel: 978-692-3848 Fax: 978-692-3821 Taiwan
Ming Xing Financial Tower
Chicago No. 88 TIDU Street Microchip Technology Taiwan
333 Pierce Road, Suite 180 Chengdu 610016, China 11F-3, No. 207
Itasca, IL 60143 Tel: 86-28-6766200 Fax: 86-28-6766599 Tung Hua North Road
Tel: 630-285-0071 Fax: 630-285-0075 Taipei, 105, Taiwan
China - Fuzhou
Dallas Tel: 886-2-2717-7175 Fax: 886-2-2545-0139
Microchip Technology Consulting (Shanghai)
4570 Westgrove Drive, Suite 160 Co., Ltd., Fuzhou Liaison Office
Addison, TX 75001 Unit 28F, World Trade Plaza
Tel: 972-818-7423 Fax: 972-818-2924 EUROPE
No. 71 Wusi Road
Detroit Fuzhou 350001, China Denmark
Tri-Atria Office Building Tel: 86-591-7503506 Fax: 86-591-7503521 Microchip Technology Nordic ApS
32255 Northwestern Highway, Suite 190 China - Shanghai Regus Business Centre
Farmington Hills, MI 48334 Microchip Technology Consulting (Shanghai) Lautrup hoj 1-3
Tel: 248-538-2250 Fax: 248-538-2260 Co., Ltd. Ballerup DK-2750 Denmark
Kokomo Room 701, Bldg. B Tel: 45 4420 9895 Fax: 45 4420 9910
2767 S. Albright Road Far East International Plaza France
Kokomo, Indiana 46902 No. 317 Xian Xia Road Microchip Technology SARL
Tel: 765-864-8360 Fax: 765-864-8387 Shanghai, 200051 Parc dActivite du Moulin de Massy
Los Angeles Tel: 86-21-6275-5700 Fax: 86-21-6275-5060 43 Rue du Saule Trapu
18201 Von Karman, Suite 1090 China - Shenzhen Batiment A - ler Etage
Irvine, CA 92612 91300 Massy, France
Microchip Technology Consulting (Shanghai)
Tel: 949-263-1888 Fax: 949-263-1338 Tel: 33-1-69-53-63-20 Fax: 33-1-69-30-90-79
Co., Ltd., Shenzhen Liaison Office
New York Rm. 1315, 13/F, Shenzhen Kerry Centre, Germany
150 Motor Parkway, Suite 202 Renminnan Lu Microchip Technology GmbH
Hauppauge, NY 11788 Shenzhen 518001, China Gustav-Heinemann Ring 125
Tel: 631-273-5305 Fax: 631-273-5335 Tel: 86-755-2350361 Fax: 86-755-2366086 D-81739 Munich, Germany
Tel: 49-89-627-144 0 Fax: 49-89-627-144-44
San Jose Hong Kong
Microchip Technology Inc. Microchip Technology Hongkong Ltd. Italy
2107 North First Street, Suite 590 Unit 901-6, Tower 2, Metroplaza Microchip Technology SRL
San Jose, CA 95131 223 Hing Fong Road Centro Direzionale Colleoni
Tel: 408-436-7950 Fax: 408-436-7955 Kwai Fong, N.T., Hong Kong Palazzo Taurus 1 V. Le Colleoni 1
Tel: 852-2401-1200 Fax: 852-2401-3431 20041 Agrate Brianza
Toronto
Milan, Italy
6285 Northam Drive, Suite 108 India Tel: 39-039-65791-1 Fax: 39-039-6899883
Mississauga, Ontario L4V 1X5, Canada Microchip Technology Inc.
Tel: 905-673-0699 Fax: 905-673-6509 India Liaison Office United Kingdom
Divyasree Chambers Arizona Microchip Technology Ltd.
1 Floor, Wing A (A3/A4) 505 Eskdale Road
No. 11, OShaugnessey Road Winnersh Triangle
Bangalore, 560 025, India Wokingham
Tel: 91-80-2290061 Fax: 91-80-2290062 Berkshire, England RG41 5TU
Tel: 44 118 921 5869 Fax: 44-118 921-5820

01/18/02

2002 Microchip Technology Inc.

You might also like