CRC Generating and Checking: Example 1: Modulo-2 Calculation
CRC Generating and Checking: Example 1: Modulo-2 Calculation
CRC Generating and Checking: Example 1: Modulo-2 Calculation
EXAMPLE 1:
MODULO-2 CALCULATION
1001100101
INTRODUCTION
This application note describes the Cyclic Redundancy Check (CRC) theory and implementation. The CRC check is used to detect errors in a message. Two implementations are shown: Table driven CRC calculation Loop driven CRC calculation This application describes the implementation of the CRC-16 polynomial. However, there are several formats for the implementation of CRC such as CRC-CCITT, CRC-32 or other polynomials. CRC is a common method for detecting errors in transmitted messages or stored data. The CRC is a very powerful, but easily implemented technique to obtain data reliability.
XOR =
0100110111 1101010010
XOR-Function
X1 0 0 1 1
X2 0 1 0 1
Y 0 1 1 0
THEORY OF OPERATION
The theory of a CRC calculation is straight forward. The data is treated by the CRC algorithm as a binary number. This number is divided by another binary number called the polynomial. The rest of the division is the CRC checksum, which is appended to the transmitted message. The receiver divides the message (including the calculated CRC), by the same polynomial the transmitter used. If the result of this division is zero, then the transmission was successful. However, if the result is not equal to zero, an error occurred during the transmission. The CRC-16 polynomial is shown in Equation 1. The polynomial can be translated into a binary value, because the divisor is viewed as a polynomial with binary coefficients. For example, the CRC-16 polynomial translates to 1000000000000101b. All coefficients, like x2 or x15, are represented by a logical 1 in the binary value. The division uses the Modulo-2 arithmetic. Modulo-2 calculation is simply realized by XORing two numbers.
Example Calculation
In this example calculation, the message is two bytes long. In general, the message can have any length in bytes. Before we can start calculating the CRC value 1, the message has to be augmented by n-bits, where n is the length of the polynomial. The CRC-16 polynomial has a length of 16-bits, therefore, 16-bits have to be augmented to the original message. In this example calculation, the polynomial has a length of 3-bits, therefore, the message has to be extended by three zeros at the end. An example calculation for a CRC is shown in Example 1. The reverse calculation is shown in Example 2.
Preliminary
DS00730A-page 1
AN730
EXAMPLE 2: CALCULATION FOR GENERATING A CRC
Message = 110101 Polynomial = 101
11010100 : 101=111 01 101 111 101 100 101 110 101 110 101 11 Quotient (has no function in CRC calculation)
EXAMPLE 3:
11010111 : 101=111 01 101 111 101 100 101 111 101 101 101 00 Quotient
DS00730A-page 2
Preliminary
AN730
FIGURE 1: HARDWARE CRC-16 GENERATOR
Flip-Flops
x16
x15
x2
x0
Data
FIGURE 2:
CRC_HIGH
CRC_LOW 0 7 0 7
CRC_BUFF
Preliminary
DS00730A-page 3
AN730
LOOP DRIVEN CRC IMPLEMENTATION
This section describes the loop driven CRC implementation. This implementation is derived from the hardware implementation shown in Figure 1. The program for the loop driven CRC generation and CRC checking is shown in Appendix A.
CRC Generation
The CRC at the table driven implementation is generated by reading a precomputed value out of a table and XOR, the result with the low and high byte of the CRC shift registers. In the first step, the registers, CRC_BUFF, CRC_HIGH and CRC_LOW, are initialized with the first three bytes of data. After that, the value in CRC_BUFF is used as an offset to get the value for the precomputed CRC value out of the look-up table. Since the CRC-16 is 16 bits long, the look-up table is split up into two separate look-up tables. One for the high byte of the CRC register and one for the low byte of the CRC register (see Figure 3). The result from the look-up table of the high byte is XORed to the content of the CRC_HIGH register. The result for the low byte is XORed to the content of CRC_LOW. The results are stored back in CRC_LOW. The next step is that the content from CRC_HIGH is shifted into CRC_BUFF and the content from CRC_LOW is shifted into the register, CRC_HIGH. Then the register, CRC_LOW, is loaded with the new data byte. This process repeats for all data bytes. At the end of the CRC generation, the message has to be appended by 16 zeros. The 16 zeros are treated like the data bytes. After the calculation is done, the content of the registers, CRC_HIGH and CRC_LOW, are appended to the message.
CRC Generation
The implementation of a loop driven CRC generation is shown in Figure 2. In the first step the registers, CRC_HIGH and CRC_LOW, are initialized with the first two bytes of data. CRC_BUFF is loaded with the third byte of data. After that, the MSb of CRC_BUFF is shifted into the LSb of CRC_LOW and the MSb of CRC_LOW is shifted into the LSb of CRC_HIGH. The MSb of CRC_HIGH, which is now stored in the Carry flag, is tested to see if it is set. If the bit is set, the registers, CRC_HIGH and CRC_LOW, will be XORed with the CRC-16 polynomial. If the bit is not set, the next bit from CRC_BUFF will be shifted into the LSb of CRC_LOW. This process is repeated until all data from CRC_BUFF is shifted into CRC_LOW. After this, CRC_BUFF is loaded with the next data byte. Then all data bytes are processed, and 16 zeros are appended to the message. The registers, CRC_HIGH and CRC_LOW, contain the calculated CRC value. The message can have any length. In this application note, the CRC value for 8 data bytes is calculated.
CRC Checking
The CRC check uses the same technique as the CRC generation, with the only difference being that zeros are not appended to the message.
CRC Checking
The CRC check uses the same technique as the CRC generation, with the difference being that zeros are not appended to the message.
COMPARISON
Table 1 shows a comparison between the loop driven implementation and the table driven implementation. For the calculation, 8 data bytes were used.
TABLE 1:
Implementation
DS00730A-page 4
Preliminary
AN730
ADVANTAGES OF CRC VS. SIMPLE SUM TECHNIQUES
The CRC generation has many advantages over simple sum techniques or parity check. CRC error correction allows detection of: 1. 2. 3. single bit errors double bit errors bundled bit errors (bits next to each other)
A parity bit check detects only single bit errors. The CRC error correction is mostly used where large data packages are transmitted, for example, in local area networks such as Ethernet.
References
Ross N. Williams - A Painless Guide to CRC Error Detection Algorithms Donald E. Knuth - The Art of Computer Programming, Volume 2, Addisson Wesley
Preliminary
DS00730A-page 5
AN730
FIGURE 3:
7
+ 7 0 TABLE_HIGH 0 0 7
+ TABLE_LOW 0
0xFF
0xFF
DS00730A-page 6
Preliminary
APPENDIX A:
Preliminary
DS00730A-page 7
00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
*********************************************************************************************** * Title : CRC16 calculation * * Author : Thomas Schmidt * * Date : 15.04.1999 * * Revision : 0.4 * * Last Modified : 15.04.1999 * * Core : 12-bit, 14-bit (12-bit core tested) * * Peripherals used: none * * Registers used : * * Modifications : crc16_01.asm Checksum check was added * * crc16_03.asm Number of data bytes was increased from 2 to 8 bytes * * crc16_04.asm added revers CRC * Description : * * * * This module calculates the checksum for the CRC16 polynom. The CRC16 polynome is defined * * as x16+x15+x2+x0. The calculation is done by bitwise checking. The algorithm is designed * * for a two byte wide message. The algorithm can easily be modified for longer messages. The * * only thing what has to be done is to check after the low byte is shifted into the high byte * * that the low byte is loaded with a new data byte. The number of iteration has to be adjusted* * to the number of extra bytes in the data message. The number is calculated as follows: * * n=16+x*messagebits. For example if the message is 4 bytes long the number of iterations is * * n=16+16bits. The extra iterations have to be done because the message is extended with 16 *
AN730
AN730
DS00730A-page 8
Preliminary
01FF 01FF
0A00
0003 0004
0C10 0024
0005
0910
* * 00024 ; *********************************************************************************************** 00025 00026 00027 LIST P=16C54B, r=hex 00028 00029 #include p16c5x.inc 00001 LIST 00002 ; P16C5X.INC Standard Header File, Version 4.00 Microchip Technology, Inc. 00313 LIST 00030 00031 #define PolynomLow b00000101 ; low byte of polynome 00032 #define PolynomHigh b10000000 ; high byte of polynome 00033 #define PolynomLength 0x10 ; 16-bit polynome length 00034 #define DataLength 0x09 ; Data length in Bits 00035 #define Iterations 0x08 ; number of iterations for CRC calculation 00036 00037 cblock 0x07 00038 CRC_HIGH ; CRC shift registers 00039 CRC_LOW ; second CRC shift register 00040 CRC_BUFF ; CRC buffer register 00041 BITS ; number of data bits 00042 DATABYTES ; number of bytes of data 00043 TEMP ; temporary register 00044 endc 00045 00046 ORG 0x1ff 00047 goto Begin 00048 00049 00050 00051 ORG 0x00 00052 Begin movlw 0x10 ; Data for CRC generation 00053 movwf FSR ; Set point to begin of data block 00054 movlw 0xAA ; data 00055 00056 00057 ; initialization what has to be done before CRC16 routine can be 00058 ; called. The FSR register contains the pointer to the first byte of 00059 ; data and the register DATABYTES contains the number of data bytes 00060 ; of the message. 00061 movlw 0x10 ; set pointer to first data location 00062 movwf FSR ; initialize FSR register 00063 00064 Main call CRC16Generate ; calculate CRC16 value 00065
0006 0007 0008 0009 000A 000B 000C 000D 000E Stop goto Stop ; do forever
; append CRC to message incf FSR, f movf CRC_HIGH, w movwf INDF incf FSR, f movf CRC_LOW, w movwf INDF movlw 0x10 movwf FSR call CRC16Restore ; ; ; ; ; ; ; ; ; point to position behind last data byte copy CRC_HIGH data into w-register copy CRC_HIGH behing last data byte point to next location copy CRC_LOW data into w-register copy data into next location set pointer to first data location initialize FSR register restore CRC16 value
2000 Microchip Technology Inc. CRC16Generate ; ******************************************************************************* ; * Title: CRC16 calculation * ; * Input parameter: Pointer to first data byte (pointer in FSR register) * ; * Number of data bytes stored in register DATABYTES * ; * Output: CRC result stored in CRC_HIGH and CRC_LOW * ; ******************************************************************************* call CRC16Init ; initialize registers movlw 0x03 ; initialize TEMP register with 2 movwf TEMP ; move 0x02 into TEMP call decfsz goto CRC16Engine DATABYTES, f Reload ; Calculate CRC16 for one byte ; Decrement the number of data bytes by one ; reload CRC_BUFF register with new data byte NextCRC16 AppendZeros decfsz goto retlw clrf movlw movwf incf goto TEMP, f AppendZeros 0x00 CRC_BUFF Iterations BITS DATABYTES, f NextCRC16 ; ; ; ; ; ; ; ; decrement TEMP register Append zeros to message return to main append data with zeros initialize BITS register with 0x08 increment data bytes last iteration Reload ; Reload CRC buffer register with new data word. incf FSR, f ; point to next data byte movf INDF, w ; copy data into w-register movwf CRC_BUFF ; move data into CRC_BUFF register movlw Iterations ; initialize register BITS with 8 movwf BITS ; move 8 into register BITS goto NextCRC16 ; calculate next CRC ; *******************************************************************************
000F
0A0F
Preliminary
00066 00067 00068 00069 00070 00071 00072 00073 00074 00075 00076 00077 00078 00079 00080 00081 00082 00083 00084 00085 00086 00087 00088 00089 00090 00091 00092 00093 00094 00095 00096 00097 00098 00099 00100 00101 00102 00103 00104 00105 00106 00107 00108 00109 00110 00111 00112
AN730
DS00730A-page 9
AN730
DS00730A-page 10
CRC16Restore NextCRCRestore ; Decrement the number of data bytes by one ; reload CRC_BUFF register with new data byte call decfsz goto CRC16Engine DATABYTES, f ReloadRestore ; check movf btfss goto movf btfss goto retlw CRCError retlw 0x01 ; return to main with error code 1 if CRC_HIGH and CRC_LOW equal to zero CRC_HIGH, f ; copy CRC_HIGH onto itself STATUS, Z ; is content zero? CRCError ; no, CRC error occured CRC_LOW, f ; copy CRC_LOW register onto itself STATUS, Z ; is content zero? CRCError ; no, CRC error occured 0x00 ; return to main (0= no error) ReloadRestore ; Reload CRC buffer register with new data word. incf FSR, f ; point to next data byte movf INDF, w ; copy data into w-register movwf CRC_BUFF ; move data into CRC_BUFF register movlw Iterations ; initialize register BITS with 8 movwf BITS ; move 8 into register BITS goto NextCRCRestore ; calculate next CRC CRC16Init ; ******************************************************************************* ; * Titel: CRC16 Initialization * ; * Input: Pointer to first data byte in FSR register * ; * Output: none * ; ******************************************************************************* movf INDF, w ; copy data into W-register movwf CRC_HIGH ; copy w-register into CRC_HIGH register incf FSR, f ; set pointer to next location movf INDF, w ; copy data into w-register movwf incf movf CRC_LOW FSR, f INDF, w ; copy w-register into CRC_LOW ; set pointer to next location ; copy next data into w-register
; * Titel: Restore CRC function * ; * Input: Pointer to first data byte in FSR register * ; * Output: w=0 CRC was restore sucessfull * ; * w=1 CRC was not restored sucessfull * ; ******************************************************************************* call CRC16Init ; initialize CRC registers movlw 0x02 ; add offset to DATABYTES addwf DATABYTES, f ; add offset to register DATABYTES
Preliminary
0031
0801
00113 00114 00115 00116 00117 00118 00119 00120 00121 00122 00123 00124 00125 00126 00127 00128 00129 00130 00131 00132 00133 00134 00135 00136 00137 00138 00139 00140 00141 00142 00143 00144 00145 00146 00147 00148 00149 00150 00151 00152 00153 00154 00155
2000 Microchip Technology Inc. ; ******************************************************************************* ; * Titel: CRC16 Engine * ; * Input: Pointer to first data byte in FSR register * ; * Output: none * ; ******************************************************************************* bcf STATUS, C ; clear carry flag rlf CRC_BUFF, f ; shift bit7 of CRC_BUFF into carry flag rlf CRC_LOW, f ; shift bit7 of CRC_LOW into carry flag ; and shift 0 into bit7 of CRC_LOW rlf CRC_HIGH, f ; rotate carry flag into bit0 of CRC_HIGH ; and rotate bit7 of CRC_HIGH into carry ; flag btfss STATUS, C ; is carry flag set? goto NextBitEngine ; carry flag is clear there next rotation movlw PolynomHigh ; carry flag is set therefore XOR CRCSHIFT ; registers xorwf CRC_HIGH, f ; XOR CRC_HIGH register movlw PolynomLow ; load w-register with low byte of polynom xorwf CRC_LOW, f ; XOR CRC_LOW register decfsz BITS, f ; do for all bits goto CRC16Engine ; calculate CRC for next bit retlw 0x00 ; return from Subroutine END 85 427 0 suppressed 0 suppressed
0046
0800
; ; ; ; ; ; ; ; ;
copy data into CRC buffer register initialize register BITs with length of polynome for iteration copy number of data bytes into register DataBytes decrement three from the number of data bytes, because three register are now initialized return from subroutine
004A
0367
Preliminary
00159 00160 00161 00162 00163 00164 00165 00166 00167 00168 00169 00170 00171 00172 00173 00174 00175 00176 CRC16Engine 00177 00178 00179 00180 00181 00182 00183 00184 00185 00186 00187 00188 00189 00190 NextBitEngine 00191 00192 00193 00194
AN730
DS00730A-page 11
0 0 reported, 0 reported,
APPENDIX B:
AN730
DS00730A-page 12
00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021
00000007 00000008
*********************************************************************************************** * Title : CRC16 calculation table driven implementation * * Author : Thomas Schmidt * * Date : 22.03.1999 * * Revision : 0.1 * * Last Modified : 15.04.1999 * * Core : 12-bit, 14-bit (12-bit core tested) * * Peripherals used: none * * Registers used : * * Modifications : crctab01.asm: first program CRC generation * * Description : * * * * This module calculates the checksum for the CRC16 polynom. The CRC16 polynome is defined * * as x16+x15+x2+x0. The calculation is done by bitwise checking. The algorithm is designed * * for a two byte wide message. The algorithm can easily be modified for longer messages. The * * only thing what has to be done is to check after the low byte is shifted into the high byte * * that the low byte is loaded with a new data byte. The number of iteration has to be adjusted* * to the number of extra bytes in the data message. The number is calculated as follows: * * n=16+x*messagebits. For example if the message is 4 bytes long the number of iterations is * * n=16+16bits. The extra iterations have to be done because the message is extended with 16 * * zeros at the end of the message. * * 00022 ; *********************************************************************************************** 00023 00024 LIST P=16C58B, r=hex 00025 00026 #include p16c5x.inc 00001 LIST 00002 ; P16C5X.INC Standard Header File, Version 4.00 Microchip Technology, Inc. 00313 LIST 00027 00028 #define DataLength 0x09 ; length of data field 00029 #define LastTableElementHigh 0x2 ; last table element of high byte 00030 #define LastTableElementLow 0x2 ; last table element of low byte 00031 00032 cblock 0x07 00033 CRC_LOW ; low byte of CRC register 00034 CRC_HIGH ; high byte of CRC register
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
Preliminary
2000 Microchip Technology Inc.
0A00
2000 Microchip Technology Inc. ; initialization what has to be done before CRC16 routine can be ; called. The FSR register contains the pointer to the first byte of ; data and the register DATABYTES contains the number of data bytes ; of the message. movlw 0x10 ; set pointer to first data location movwf FSR ; initialize FSR register Main call CRC16Generate ; calculate CRC16 value TestPoint Stop movf movwf incf movf movwf movlw movwf call goto CRC_HIGH, w INDF FSR, f CRC_LOW, w INDF 0x10 FSR CRC16Restore Stop ; ; ; ; ; ; ; ; ; copy CRC_HIGH data into w-register copy CRC_HIGH behing last data byte point to next location copy CRC_LOW data into w-register copy data into next location set pointer to first data location initialize FSR register Restore CRC do forever CRC16Generate ; ******************************************************************************* ; * Title: CRC16 Table driven calculation * ; * Input parameter: Pointer to first data byte (pointer in FSR register) * ; * Number of data bytes stored in register DATABYTES * ; * Output: CRC result stored in CRC_HIGH and CRC_LOW * ; ******************************************************************************* call CRC16Init ; initialize CRC registers movlw 0x03 ; initialize TEMP register movwf TEMP ; with 0x02 NextValueGen ; check if last CRC_BUFF points to last element in table. These elements ; cannot be read from the look up table, because they are beyond the ; program memory page. movf CRC_BUFF, w ; load CRC_BUFF into w-register xorlw 0xff ; check if content equals to 0xff btfss STATUS, Z ; is result from XOR = 0? goto CalculateCRC ; no, calculate CRC
0000 0000
0000 0001
0C10 0024
0002
090C
Preliminary
AN730
DS00730A-page 13
00035 00036 00037 00038 00039 00040 00041 00042 00043 00044 00045 00046 00047 00048 00049 00050 00051 00052 00053 00054 00055 00056 00057 00058 00059 00060 00061 00062 00063 00064 00065 00066 00067 00068 00069 00070 00071 00072 00073 00074 00075 00076 00077 00078 00079 00080 00081
; ; ; ; ;
yes, get XOR with get last XOR with goto end
last table element for high byte high byte table element for low byte low byte of loop
AN730
DS00730A-page 14
DecDATABYTES movf bcf bsf call xorwf movf bsf bcf call xorwf bcf bcf decfsz goto CRC_BUFF, w STATUS, PA1 STATUS, PA0 CRC16TableHigh CRC_HIGH,f CRC_BUFF, w STATUS, PA1 STATUS, PA0 CRC16TableLow CRC_LOW,f STATUS, PA0 STATUS, PA1 DATABYTES, f ReloadGen ; ; ; ; ; ; ; ; ; ; ; ; ; ; copy high byte of CRC into w-register select page 1 select page 1 get value for high byte XOR table element with high byte get value for low byte select page 2 select page 2 get value out of table XOR with low byte select page 0 select page 0 decrement data bytes reload values AppendZeros decfsz goto retlw movf movwf movf movwf clrf incf goto call goto Reload NextValueGen TEMP, f AppendZeros 0x00 CRC_HIGH, w CRC_BUFF CRC_LOW,w CRC_HIGH CRC_LOW DATABYTES, f NextValueGen ; ; ; ; ; ; ; ; ; ; append two bytes with zeros append zeros to message (do twice) return to main copy high byte into w-register and from there to CRC_BUFF Copy low byte into w-register and from there into CRC_HIGH and from there into CRC_LOW increment for additonal iteration calculate CRC for next byte ; reload registers ; calculate next CRC value ReloadGen Reload ; ******************************************************************************* ; * Titel: Reload CRC_HIGH, CRC_LOW and CRC_BUFF register * ; * Input: Pointer to next data byte in FSR register * ; * Output: * ; ******************************************************************************* movf CRC_HIGH, w ; copy high byte into w-register movwf CRC_BUFF ; and from there to CRC_BUFF movf CRC_LOW,w ; Copy low byte into w-register movwf CRC_HIGH ; and from there into CRC_HIGH movf INDF, w ; copy next data into w-register movwf CRC_LOW ; and from there into CRC_LOW incf FSR, f ; point to next data byte
0018 0019 001A 001B 001C 001D 001E 001F 0020 0021 0022 0023 0024 0025
0209 04C3 05A3 0900 01A8 0209 05C3 04A3 0900 01A7 04A3 04C3 02EA 0A30
Preliminary
0026 0027 0028 0029 002A 002B 002C 002D 002E 002F
02EB 0A29 0800 0208 0029 0207 0028 0067 02AA 0A0F
0030 0031
0932 0A0F
00082 00083 00084 00085 00086 00087 00088 00089 00090 00091 00092 00093 00094 00095 00096 00097 00098 00099 00100 00101 00102 00103 00104 00105 00106 00107 00108 00109 00110 00111 00112 00113 00114 00115 00116 00117 00118 00119 00120 00121 00122 00123 00124 00125 00126 00127 00128
0039
0800
retlw
0x00
2000 Microchip Technology Inc. CRC16Restore ; ******************************************************************************* ; * Titel: Restore CRC function * ; * Input: Pointer to first data byte in FSR register * ; * Output: w=0 CRC was restore sucessfull * ; * w=1 CRC was not restored sucessfull * ; ******************************************************************************* call CRC16Init ; initialize CRC registers movlw 0x02 ; add two onto addwf DATABYTES, f ; register DATABYTES NextValueRes ; check if last CRC_BUFF points to last element in table. These elements ; cannot be read from the look up table, because they are beyond the ; program memory page. movf CRC_BUFF, w ; load CRC_BUFF into w-register xorlw 0xff ; check if content equals to 0xff btfss STATUS, Z ; is result from XOR = 0? goto CalculateCRCRes ; no, calculate CRC movlw LastTableElementHigh ; yes, get last table element for high byte xorwf CRC_HIGH, f ; XOR with high byte movlw LastTableElementLow ; get last table element for low byte xorwf CRC_LOW, f ; XOR with low byte goto DecDATABYTESRes ; goto end of loop CRC_BUFF, w STATUS, PA1 STATUS, PA0 CRC16TableHigh CRC_HIGH,f CRC_BUFF, w STATUS, PA1 STATUS, PA0 CRC16TableLow CRC_LOW,f STATUS, PA0 STATUS, PA1 DATABYTES, f ReloadRes ; ; ; ; ; ; ; ; ; ; ; ; ; ; copy high byte of CRC into w-register select page 1 select page 1 get value for high byte XOR table element with high byte get value for low byte select page 2 select page 2 get value out of table XOR with low byte select page 0 select page 0 decrement data bytes calculate next CRC16 value CalculateCRCRes movf bcf bsf call xorwf movf bsf bcf call xorwf DecDATABYTESRes bcf bcf decfsz goto ; check movf btfss goto movf btfss if CRC_HIGH and CRC_LOW equal to zero CRC_HIGH, f ; copy CRC_HIGH onto itself STATUS, Z ; is content zero? CRCError ; no, CRC error occured CRC_LOW, f ; copy CRC_LOW register onto itself STATUS, Z ; is content zero?
Preliminary
0046 0047 0048 0049 004A 004B 004C 004D 004E 004F 0050 0051 0052 0053
0209 04C3 05A3 0900 01A8 0209 05C3 04A3 0900 01A7 04A3 04C3 02EA 0A5C
AN730
DS00730A-page 15
00129 00130 00131 00132 00133 00134 00135 00136 00137 00138 00139 00140 00141 00142 00143 00144 00145 00146 00147 00148 00149 00150 00151 00152 00153 00154 00155 00156 00157 00158 00159 00160 00161 00162 00163 00164 00165 00166 00167 00168 00169 00170 00171 00172 00173 00174 00175
0059 005A CRCError ReloadRes call goto Reload NextValueRes ; reload register ; calculate next value retlw 0x01 ; return to main with error code 1
0A5B 0800
goto retlw
CRCError 0x00
005B
0801
AN730
DS00730A-page 16
CRC16Init ; ******************************************************************************* ; * Titel: CRC16 Initialization * ; * Input: Pointer to first data byte in FSR register * ; * Output: none * ; ******************************************************************************* movf INDF, w ; copy data into W-register movwf CRC_BUFF ; copy w-register into CRC_BUFF register incf FSR, f ; set pointer to next location movf INDF, w ; copy data into W-register movwf CRC_HIGH ; copy w-register into CRC_HIGH register incf FSR, f ; set pointer to next location movf INDF, w ; copy data into w-register movwf CRC_LOW ; copy w-register into CRC_LOW incf FSR, f ; point to next location movlw DataLength ; copy number of data bytes movwf DATABYTES ; into register DataBytes movlw 0x03 ; decrement three from the number subwf DATABYTES, f ; of data bytes, because three register ; are now initialized retlw 0x00 ; return from subroutine CRC16TableHigh ; ******************************************************************************* ; * Titel: CRC16 Table for High byte * ; * Input: Pointer to table element in w-register * ; * Output: look-up value in w-register * ; ******************************************************************************* org 0x200 addwf PCL, f ; add to low byte of PC dt 0, 0x80, 0x80, 0 dt dt dt dt 0, 0x80, 0x80, 0x80, 0, 0, 0x80, 0, 0, 0, 0x80, 0, 0x80 0x80 0 0x80
005C 005D
0932 0A3D
005E 005F 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A
0200 0029 02A4 0200 0028 02A4 0200 0027 02A4 0C09 002A 0C03 00AA
Preliminary
006B
0800
00176 00177 00178 00179 00180 00181 00182 00183 00184 00185 00186 00187 00188 00189 00190 00191 00192 00193 00194 00195 00196 00197 00198 00199 00200 00201 00202 00203 00204 00205 00206 00207 00208 00209 00210 00211 00212 0880 0880 00213
0205
0209
020D
0211
01E2 0800 0800 0880 0880 0880 0880 0800 0800 0880 0880
0215 dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt 0x81, 0x81, 0x1, 0x81, 0x1, 0x1, 0x81, 0x81, 0x1, 0x1, 0x81, 0x1, 0x81, 0x1, 0x81, 0x1, 0x1, 0x1, 0x81, 0x81, 0x1, 0x1, 0x81, 0x1, 0x1, 0x81, 0x81, 0x81, 0x1, 0x1, 0x81 0x1 0x81 0x81 0x1 0x1 0x81 0x81 0x1 0x81 0x1, 0x81, 0x81, 0x1 0x1, 0x81, 0x81, 0x1 0x81, 0x1, 0x1, 0x81 0, 0x80, 0x80, 0 0x80, 0, 0, 0x80 0x80, 0, 0, 0x80 0, 0x80, 0x80, 0 0x80, 0, 0, 0x80 0, 0x80, 0x80, 0 0, 0x80, 0x80, 0 0x80, 0, 0, 0x80 0x80, 0, 0, 0x80 0, 0x80, 0x80, 0
dt
0,
0x80,
0x80,
0219
021D
0221
0225
0229
022D
0231
0235
0239
023D
0241
0245
Preliminary
0249
024D
0251
0255
0259
025D
0261
0265
0269
026D
AN730
DS00730A-page 17
0271
0800 0800 0800 0800 0880 0880 0880 0880 0800 0800 0800 0800 0880 0880 0800 0800 0880 0880 0880 0880 0800 0800 0881 0881 0801 0801 0801 0801 0881 0881 0801 0801 0881 0881 0881 0881 0801 0801 0801 0801 0881 0881 0881 0881 0801 0801 0881
0275 dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt 0x82, 0x82, 0x2, 0x2, 0x83, 0x3, 0x82, 0x2, 0x2, 0x82, 0x3, 0x83, 0x3, 0x83, 0x83, 0x83, 0x3, 0x82, 0x2, 0x2, 0x82, 0x83, 0x3, 0x3, 0x3, 0x83, 0x83, 0x3 0x83 0x3 0x3 0x83 0x2 0x82 0x82 0x2 0x83, 0x3, 0x3, 0x83 0x83, 0x3, 0x3, 0x83 0x3, 0x83, 0x83, 0x3 0x3, 0x83, 0x83, 0x3 0x83, 0x3, 0x3, 0x83 0x83, 0x3, 0x3, 0x83 0x3, 0x83, 0x83, 0x3 0x83, 0x3, 0x3, 0x83 0x3, 0x83, 0x83, 0x3 0x3, 0x83, 0x83, 0x3 0x83, 0x3, 0x3, 0x83 0x81, 0x1, 0x1, 0x81 0x1, 0x81, 0x81, 0x1
dt
0x1,
0x81,
0x81,
0x1
0279
AN730
027D
DS00730A-page 18
0281
0285
0289
028D
0291
0295
0299
029D
02A1
Preliminary
02A5
02A9
02AD
02B1
02B5
02B9
02BD
02C1
02C5
02C9
02CD
0881 0801 0801 0801 0801 0881 0881 0883 0883 0803 0803 0803 0803 0883 0883 0803 0803 0883 0883 0883 0883 0803 0803 0803 0803 0883 0883 0883 0883 0803 0803 0883 0883 0803 0803 0803 0803 0883 0883 0802 0802 0882 0882 0882 0882 0802 0802
02D1 dt dt dt dt dt dt dt dt dt dt dt 0x2, 0x82, 0x82 0x82, 0x2, 0x2, 0x82 0x82, 0x2, 0x2, 0x82 0x2, 0x82, 0x82, 0x2 0x82, 0x2, 0x2, 0x82 0x2, 0x82, 0x82, 0x2 0x2, 0x82, 0x82, 0x2 0x82, 0x2, 0x2, 0x82 0x82, 0x2, 0x2, 0x82 0x2, 0x82, 0x82, 0x2 0x2, 0x82, 0x82, 0x2
dt
0x82,
0x2,
0x2,
0x82
02D5
02D9
02DD
02E1
2000 Microchip Technology Inc. ; ******************************************************************************* ; * Titel: CRC16 Table for low byte * ; * Input: Pointer to table element in w-register * ; * Output: look-up value in w-register * ; ******************************************************************************* org 0x400 addwf PCL, f ; add to low byte of PC dt 0, 0x5, 0xf, 0xa dt dt dt dt dt dt dt 0x63, 0x78, 0x50, 0x4b, 0x28, 0x33, 0x36, 0x2d, 0x66, 0x7d, 0x55, 0x4e, 0x1b, 0x1e, 0x14, 0x3c, 0x27, 0x6c, 0x77, 0x5f, 0x44, 0x11 0x39 0x22 0x69 0x72 0x5a 0x41
02E5
02E9
02ED
02F1
02F5
02F9
Preliminary
02FD
0882 0882 0802 0802 0802 0802 0882 0882 0882 0882 0802 0802 0802 0802 0882 0882 0802 0802 0882 0882 0882 0882 0802
0405
0409
040D
0411
0415
0419
AN730
DS00730A-page 19
041D
0882 0882 00276 00277 00278 00279 00280 00281 00282 00283 01E2 00284 CRC16TableLow 0800 0805 080F 00285 080A 081B 081E 0814 00286 0811 0833 0836 083C 00287 0839 0828 082D 0827 00288 0822 0863 0866 086C 00289 0869 0878 087D 0877 00290 0872 0850 0855 085F 00291 085A 084B 084E 0844 00292
0421 dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt 0x23, 0x38, 0x10, 0x68, 0x73, 0x76, 0x6d, 0x26, 0x3d, 0x15, 0x5b, 0x5e, 0x40, 0x45, 0x4f, 0x54, 0x7c, 0x67, 0x2c, 0x37, 0x1f, 0xc8, 0xcd, 0xc7, 0xd3, 0xd6, 0xdc, 0xd9 0xc2 0x4a 0x51 0x79 0x62 0x29 0x32 0x1a 0xfb, 0xfe, 0xf4, 0xf1 0xe0, 0xe5, 0xef, 0xea 0xab, 0xae, 0xa4, 0xa1 0xb0, 0xb5, 0xbf, 0xba 0x98, 0x9d, 0x97, 0x92 0x83, 0x86, 0x8c, 0x89 0x88, 0x8d, 0x87, 0x82 0x93, 0x96, 0x9c, 0x99 0xbb, 0xbe, 0xb4, 0xb1 0xa0, 0xa5, 0xaf, 0xaa 0xeb, 0xee, 0xe4, 0xe1 0xf0, 0xf5, 0xff, 0xfa 0xd8, 0xdd, 0xd7, 0xd2
dt
0xc3,
0xc6,
0xcc,
0xc9
0425
AN730
0429
DS00730A-page 20
042D
0431
0435
0439
043D
0441
0445
0449
044D
Preliminary
0451
0455
0459
045D
0461
0465
0469
046D
0471
0475
0479
0841 08C3 08C9 08D8 08D2 08F0 08FA 08EB 08E1 08A0 08AA 08BB 08B1 0893 0899 0888 0882 0883 0889 0898 0892 08B0 08BA 08AB 08A1 08E0 08EA 08FB 08F1 08D3 08D9 08C8 08C2 0840 084A 085B 0851 0873 0879 0868 0862 0823 0829 0838 0832 0810 081A
047D dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt dt 0xa8, 0xe3, 0xf8, 0xd0, 0xb3, 0x9b, 0x9e, 0xb6, 0xad, 0xe6, 0xfd, 0xd5, 0x80, 0x85, 0x8b, 0x8e, 0x84, 0x8f, 0x94, 0xbc, 0xa7, 0xec, 0xf7, 0xdf, 0x90, 0x95, 0x9f, 0xb8, 0xbd, 0xb7, 0xb2 0x9a 0x81 0x8a 0x91 0xb9 0xa2 0xe9 0xf2 0xda 0xa3, 0xa6, 0xac, 0xa9 0xe8, 0xed, 0xe7, 0xe2 0xf3, 0xf6, 0xfc, 0xf9 0xdb, 0xde, 0xd4, 0xd1 0xc0, 0xc5, 0xcf, 0xca 0x48, 0x4d, 0x47, 0x42 0x53, 0x56, 0x5c, 0x59 0x7b, 0x7e, 0x74, 0x71 0x60, 0x65, 0x6f, 0x6a 0x2b, 0x2e, 0x24, 0x21 0x30, 0x35, 0x3f, 0x3a 0x18, 0x1d, 0x17, 0x12 0x3, 0x6, 0xc, 0x9
dt
0xb,
0xe,
0x4,
0x1
0481
0485
0489
048D
0491
0495
0499
049D
04A1
04A5
04A9
04AD
Preliminary
04B1
04B5
04B9
04BD
04C1
04C5
04C9
04CD
04D1
04D5
AN730
DS00730A-page 21
04D9
080B 0801 0803 0809 0818 0812 0830 083A 082B 0821 0860 086A 087B 0871 0853 0859 0848 0842 08C0 08CA 08DB 08D1 08F3 08F9 08E8 08E2 08A3 08A9 08B8 08B2 0890 089A 088B 0881 0880 088A 089B 0891 08B3 08B9 08A8 08A2 08E3 08E9 08F8 08F2 08D0
04DD dt dt dt dt dt dt dt dt END 621 1427 0x8, 0xd, 0x7 0x13, 0x16, 0x1c, 0x19 0x3b, 0x3e, 0x34, 0x31 0x20, 0x25, 0x2f, 0x2a 0x6b, 0x6e, 0x64, 0x61 0x70, 0x75, 0x7f, 0x7a 0x58, 0x5d, 0x57, 0x52 0x43, 0x46, 0x4c, 0x49
dt
0xcb,
0xce,
0xc4,
0xc1
04E1
AN730
04E5
DS00730A-page 22
0 suppressed 0 suppressed
04E9
04ED
04F1
04F5
04F9
04FD
08DA 08CB 08C1 0843 0849 0858 0852 0870 087A 086B 0861 0820 082A 083B 0831 0813 0819 0808
Preliminary
0 0 reported, 5 reported,
AN730
NOTES:
Preliminary
DS00730A-page 23
AMERICAS (continued)
Toronto
Microchip Technology Inc. 5925 Airport Road, Suite 200 Mississauga, Ontario L4V 1W1, Canada Tel: 905-405-6279 Fax: 905-405-6253
ASIA/PACIFIC (continued)
Singapore
Microchip Technology Singapore Pte Ltd. 200 Middle Road #07-02 Prime Centre Singapore, 188980 Tel: 65-334-8870 Fax: 65-334-8850
ASIA/PACIFIC
China - Beijing
Microchip Technology, Beijing Unit 915, 6 Chaoyangmen Bei Dajie Dong Erhuan Road, Dongcheng District New China Hong Kong Manhattan Building Beijing, 100027, P.R.C. Tel: 86-10-85282100 Fax: 86-10-85282104
Taiwan
Microchip Technology Taiwan 10F-1C 207 Tung Hua North Road Taipei, Taiwan Tel: 886-2-2717-7175 Fax: 886-2-2545-0139
Atlanta
Microchip Technology Inc. 500 Sugar Mill Road, Suite 200B Atlanta, GA 30350 Tel: 770-640-0034 Fax: 770-640-0307
Boston
Microchip Technology Inc. 5 Mount Royal Avenue Marlborough, MA 01752 Tel: 508-480-9990 Fax: 508-480-8575
EUROPE
Denmark
Microchip Technology Denmark ApS Regus Business Centre Lautrup hoj 1-3 Ballerup DK-2750 Denmark Tel: 45 4420 9895 Fax: 45 4420 9910
China - Shanghai
Microchip Technology Unit B701, Far East International Plaza, No. 317, Xianxia Road Shanghai, 200051, P.R.C. Tel: 86-21-6275-5700 Fax: 86-21-6275-5060
Chicago
Microchip Technology Inc. 333 Pierce Road, Suite 180 Itasca, IL 60143 Tel: 630-285-0071 Fax: 630-285-0075
Hong Kong
Microchip Asia Pacific Unit 2101, Tower 2 Metroplaza 223 Hing Fong Road Kwai Fong, N.T., Hong Kong Tel: 852-2-401-1200 Fax: 852-2-401-3431
France
Arizona Microchip Technology SARL Parc dActivite 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
Dallas
Microchip Technology Inc. 4570 Westgrove Drive, Suite 160 Addison, TX 75248 Tel: 972-818-7423 Fax: 972-818-2924
India
Microchip Technology Inc. India Liaison Office No. 6, Legacy, Convent Road Bangalore, 560 025, India Tel: 91-80-229-0061 Fax: 91-80-229-0062
Germany
Arizona Microchip Technology GmbH Gustav-Heinemann-Ring 125 D-81739 Mnchen, Germany Tel: 49-89-627-144 0 Fax: 49-89-627-144-44
Dayton
Microchip Technology Inc. Two Prestige Place, Suite 150 Miamisburg, OH 45342 Tel: 937-291-1654 Fax: 937-291-9175
Italy
Arizona Microchip Technology SRL Centro Direzionale Colleoni Palazzo Taurus 1 V. Le Colleoni 1 20041 Agrate Brianza Milan, Italy Tel: 39-039-65791-1 Fax: 39-039-6899883
Detroit
Microchip Technology Inc. Tri-Atria Office Building 32255 Northwestern Highway, Suite 190 Farmington Hills, MI 48334 Tel: 248-538-2250 Fax: 248-538-2260
Japan
Microchip Technology Intl. Inc. 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
Los Angeles
Microchip Technology Inc. 18201 Von Karman, Suite 1090 Irvine, CA 92612 Tel: 949-263-1888 Fax: 949-263-1338
United Kingdom
Arizona Microchip Technology Ltd. 505 Eskdale Road Winnersh Triangle Wokingham Berkshire, England RG41 5TU Tel: 44 118 921 5858 Fax: 44-118 921-5835
03/23/00
Korea
Microchip Technology Korea 168-1, Youngbo Bldg. 3 Floor Samsung-Dong, Kangnam-Ku Seoul, Korea Tel: 82-2-554-7200 Fax: 82-2-558-5934
New York
Microchip Technology Inc. 150 Motor Parkway, Suite 202 Hauppauge, NY 11788 Tel: 631-273-5305 Fax: 631-273-5335
San Jose
Microchip Technology Inc. 2107 North First Street, Suite 590 San Jose, CA 95131 Tel: 408-436-7950 Fax: 408-436-7955
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.
All rights reserved. 2000 Microchip Technology Incorporated. Printed in the USA. 5/00
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 Microchips 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, except as maybe explicitly expressed herein, under any intellectual property rights. The Microchip logo and name are registered trademarks of Microchip Technology Inc. in the U.S.A. and other countries. All rights reserved. All other trademarks mentioned herein are the property of their respective companies.
DS00730A-page 24