32-Bit Programmable Cyclic Redundancy Check (CRC) HIGHLIGHTS This section of the manual contains the following major topics: 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 Introduction ....................................................................................................................... 2 Module Overview .............................................................................................................. 3 CRC Registers .................................................................................................................. 4 CRC Engine .................................................................................................................... 10 Control Logic................................................................................................................... 11 Advantages of Programmable CRC Module ................................................................... 20 Application of CRC Module............................................................................................. 20 Operation in Power Save Modes .................................................................................... 31 Register Maps ................................................................................................................. 32 Related Application Notes............................................................................................... 33 Revision History .............................................................................................................. 34 © 2009-2013 Microchip Technology Inc. DS30009729B-page 1 dsPIC33/PIC24 Family Reference Manual 1.0 INTRODUCTION The 32-bit programmable Cyclic Redundancy Check (CRC) module in dsPIC33/PIC24 devices is a software configurable CRC checksum generator. The checksum is a unique number associated with a message, or a particular block of data, containing several bytes. Whether it is a data packet for communication, or a block of data stored in memory, a piece of information, such as checksum helps to validate it before processing. The simplest way to calculate a checksum is to add together all the data bytes present in the message. However, this method of checksum calculation fails badly when the message is modified by inverting or swapping groups of bytes. Also, it fails when null bytes are added anywhere in the message. The CRC is a more complicated, but robust, error checking algorithm. The main idea behind the CRC algorithm is to treat a message as a binary bit stream and divide it by a fixed binary number. The remainder from this division is considered as the checksum. Like in division, the CRC calculation is also an iterative process. The only difference is that these operations are done on modulo arithmetic, based on mod 2. For example, division is replaced with the XOR operation (i.e., subtraction without carry). The CRC algorithm uses the term, polynomial, to perform all of its calculations. The divisor, dividend and remainder that are represented by numbers are termed as: polynomials with binary coefficients. For example, the number, 25h (11001), is represented as: Equation 1-1: (1 * x4) + (1 * x3) + (0 * x2) + (0 * x1) + (1 * x0) or x4 + x3 + x0 In order to perform the CRC calculation, a suitable divisor is first selected. This divisor is called the generator polynomial. Since CRC is used to detect errors, a suitable generator polynomial of a suitable length needs to be chosen for a given application, as each polynomial has different error detection capabilities. Some polynomials are widely used for many applications, but the error detecting capabilities of any particular polynomial are beyond the scope of this reference section. The CRC calculation is an iterative process and consumes considerable CPU bandwidth when implemented in software. The software configurable CRC hardware module in dsPIC33/PIC24 devices facilitates a fast CRC checksum calculation with minimal software overhead. The programmable CRC generator provides a hardware implemented method of quickly generating checksums for various communication and security applications. It provides the following features: • • • • • DS30009729B-page 2 User-programmable CRC polynomial equation, up to 32 bits Programmable shift direction (little or big endian) Independent data and polynomial lengths Configurable interrupt output Data FIFO © 2009-2013 Microchip Technology Inc. 32-Bit Programmable Cyclic Redundancy Check (CRC) 2.0 MODULE OVERVIEW The programmable CRC generator module in dsPIC33/PIC24 devices can be broadly classified into two parts: the control logic and the CRC engine. The control logic incorporates a register interface, FIFO, interrupt generator and CRC engine interface. The CRC engine incorporates a CRC calculator, which is implemented using a serial shifter with XOR function. A simplified block diagram is shown in Figure 2-1. Figure 2-1: Simplified Block Diagram of the Programmable CRC Generator CRCWDATH CRCWDATL Variable FIFO (4x32, 8x16 or 16x8) FIFO Empty Event CRCISEL 2 * FCY Shift Clock 1 Shift Buffer 0 0 1 LENDIAN CRC Shift Engine CRCWDATH © 2009-2013 Microchip Technology Inc. Set CRCIF Shift Complete Event CRCWDATL DS30009729B-page 3 dsPIC33/PIC24 Family Reference Manual 3.0 CRC REGISTERS Different registers associated with the CRC module are described in detail in this section. There are eight registers in this module. These are mapped to the data RAM space as Special Function Registers (SFRs) in dsPIC33/PIC24 devices: • • • • • • • • CRCCON1 (CRC Control Register 1) CRCCON2 (CRC Control Register 2) CRCXORL (CRC XOR Low Register) CRCXORH (CRC XOR High Register) CRCDATL (CRC Data Low Register) CRCDATH (CRC Data High Register) CRCWDATL (CRC Shift Low Register) CRCWDATH (CRC Shift High Register) The CRCCON1 (Register 3-1) and CRCCON2 (Register 3-2) registers control the operation of the module and configure various settings. The CRCXORL/H registers (Register 3-3 and Register 3-4) select the polynomial terms to be used in the CRC equation. The CRCDATL/H and CRCWDATL/H registers are each register pairs that serve as buffers for the double-word input data and CRC processed output, respectively. DS30009729B-page 4 © 2009-2013 Microchip Technology Inc. 32-Bit Programmable Cyclic Redundancy Check (CRC) Register 3-1: CRCCON1: CRC Control Register 1 R/W-0 U-0 R/W-0 R-0 R-0 R-0 R-0 R-0 CRCEN — CSIDL VWORD4 VWORD3 VWORD2 VWORD1 VWORD0 bit 15 bit 8 R-0 R-1 R/W-0 R/W-0 R/W-0 U-0 U-0 U-0 CRCFUL CRCMPT CRCISEL CRCGO LENDIAN — — — bit 7 bit 0 Legend: R = Readable bit W = Writable bit U = Unimplemented bit, read as ‘0’ -n = Value at POR ‘1’ = Bit is set ‘0’ = Bit is cleared x = Bit is unknown bit 15 CRCEN: CRC Enable bit 1 = Enables module 0 = Disables module bit 14 Unimplemented: Read as ‘0’ bit 13 CSIDL: CRC Stop in Idle Mode bit 1 = Discontinues module operation when device enters Idle mode 0 = Continues module operation in Idle mode bit 12-8 VWORD<4:0>: Counter Value bits Indicates the number of valid words in the FIFO. Has a maximum value of 16 when DWIDTH<4:0> 7 (data words, 8-bit-wide or less). Has a maximum value of 8 when DWIDTH<4:0> 15(data words from 9 to 16-bit-wide). Has a maximum value of 4 when DWIDTH<4:0> 31 (data words from 17 to 32-bit-wide). bit 7 CRCFUL: CRC FIFO Full bit 1 = FIFO is full 0 = FIFO is not full bit 6 CRCMPT: CRC FIFO Empty bit 1 = FIFO is empty 0 = FIFO is not empty bit 5 CRCISEL: CRC Interrupt Selection bit 1 = Interrupt on FIFO empty; final word of data is still shifted through CRC 0 = Interrupt on shift complete (FIFO is empty and no data is shifted from the shift buffer) bit 4 CRCGO: Start CRC bit 1 = Start CRC serial shifter; clearing the bit aborts shifting 0 = CRC serial shifter is turned off bit 3 LENDIAN: Data Word Little Endian Configuration bit 1 = Data word is shifted into the CRC, starting with the LSb (little endian); reflected input data 0 = Data word is shifted into the CRC, starting with the MSb (big endian); non-reflected input data bit 2-0 Unimplemented: Read as ‘0’ © 2009-2013 Microchip Technology Inc. DS30009729B-page 5 dsPIC33/PIC24 Family Reference Manual Register 3-2: CRCCON2: CRC Control Register 2 U-0 U-0 U-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 — — — DWIDTH4 DWIDTH3 DWIDTH2 DWIDTH1 DWIDTH0 bit 15 bit 8 U-0 U-0 U-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 — — — PLEN4 PLEN3 PLEN2 PLEN1 PLEN0 bit 7 bit 0 Legend: R = Readable bit W = Writable bit U = Unimplemented bit, read as ‘0’ -n = Value at POR ‘1’ = Bit is set ‘0’ = Bit is cleared bit 15-13 Unimplemented: Read as ‘0’ bit 12-8 DWIDTH<4:0>: Data Word Width Configuration bits Configures the width of the data word (Data Word Width – 1). bit 7-5 Unimplemented: Read as ‘0’ bit 4-0 PLEN<4:0>: Polynomial Length Configuration bits Configures the length of the polynomial (Polynomial Length – 1). DS30009729B-page 6 x = Bit is unknown © 2009-2013 Microchip Technology Inc. 32-Bit Programmable Cyclic Redundancy Check (CRC) Register 3-3: CRCXORL: CRC XOR Low Register R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 X15 X14 X13 X12 X11 X10 X9 X8 bit 15 bit 8 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 U-0 X7 X6 X5 X4 X3 X2 X1 — bit 7 bit 0 Legend: R = Readable bit W = Writable bit U = Unimplemented bit, read as ‘0’ -n = Value at POR ‘1’ = Bit is set ‘0’ = Bit is cleared bit 15-1 X<15:1>: XOR of Polynomial Term xn Enable bits bit 0 Unimplemented: Read as ‘0’ Register 3-4: x = Bit is unknown CRCXORH: CRC XOR High Register R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 X31 X30 X29 X28 X27 X26 X25 X24 bit 15 bit 8 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 X23 X22 X21 X20 X19 X18 X17 X16 bit 7 bit 0 Legend: R = Readable bit W = Writable bit U = Unimplemented bit, read as ‘0’ -n = Value at POR ‘1’ = Bit is set ‘0’ = Bit is cleared bit 15-0 x = Bit is unknown X<31:16>: XOR of Polynomial Term xn Enable bits © 2009-2013 Microchip Technology Inc. DS30009729B-page 7 dsPIC33/PIC24 Family Reference Manual Register 3-5: CRCDATL: CRC Data Low Register R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 DATA15 DATA14 DATA13 DATA12 DATA11 DATA10 DATA9 DATA8 bit 15 bit 8 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 DATA7 DATA6 DATA5 DATA4 DATA3 DATA2 DATA1 DATA0 bit 7 bit 0 Legend: R = Readable bit W = Writable bit U = Unimplemented bit, read as ‘0’ -n = Value at POR ‘1’ = Bit is set ‘0’ = Bit is cleared bit 15-0 x = Bit is unknown DATA<15:0>: CRC Input Data bits Writing to this register fills the FIFO; reading from this register returns ‘0’. Register 3-6: CRCDATH: CRC Data High Register R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 DATA31 DATA30 DATA29 DATA28 DATA27 DATA26 DATA25 DATA24 bit 15 bit 8 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 DATA23 DATA22 DATA21 DATA20 DATA19 DATA18 DATA17 DATA16 bit 7 bit 0 Legend: R = Readable bit W = Writable bit U = Unimplemented bit, read as ‘0’ -n = Value at POR ‘1’ = Bit is set ‘0’ = Bit is cleared bit 15-0 x = Bit is unknown DATA<31:16>: CRC Input Data bits Writing to this register fills the FIFO; reading from this register returns ‘0’. DS30009729B-page 8 © 2009-2013 Microchip Technology Inc. 32-Bit Programmable Cyclic Redundancy Check (CRC) Register 3-7: CRCWDATL: CRC Shift Low Register R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 SDATA15 SDATA14 SDATA13 SDATA12 SDATA11 SDATA10 SDATA9 SDATA8 bit 15 bit 8 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 SDATA7 SDATA6 SDATA5 SDATA4 SDATA3 SDATA2 SDATA1 SDATA0 bit 7 bit 0 Legend: R = Readable bit W = Writable bit U = Unimplemented bit, read as ‘0’ -n = Value at POR ‘1’ = Bit is set ‘0’ = Bit is cleared bit 15-0 x = Bit is unknown SDATA<15:0>: CRC Shift Register bits Writing to this register writes to the CRC Shift register through the CRC write bus. Reading from this register reads the CRC read bus. Register 3-8: CRCWDATH: CRC Shift High Register R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 SDATA31 SDATA30 SDATA29 SDATA28 SDATA27 SDATA26 SDATA25 SDATA24 bit 15 bit 8 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 SDATA23 SDATA22 SDATA21 SDATA20 SDATA19 SDATA18 SDATA17 SDATA16 bit 7 bit 0 Legend: R = Readable bit W = Writable bit U = Unimplemented bit, read as ‘0’ -n = Value at POR ‘1’ = Bit is set ‘0’ = Bit is cleared bit 15-0 x = Bit is unknown DATA<31:16>: CRC Shift Register bits Writing to this register writes to the CRC Shift register through the CRC write bus. Reading from this register reads the CRC read bus. © 2009-2013 Microchip Technology Inc. DS30009729B-page 9 dsPIC33/PIC24 Family Reference Manual 4.0 CRC ENGINE 4.1 Generic CRC Engine The CRC engine is a serial shifting CRC calculator with feedforward and feedback points, configurable though multiplexer settings. A simple version of the CRC shift engine is shown in Figure 4-1. The CRC algorithm uses a simplified form of arithmetic process, using the XOR operation instead of binary division. The coefficients of the generator polynomial are programmed with the CRCXORL<15:1> and CRCXORH<31:16> bits. Writing a ‘1’ into a location enables XORing of that element in the polynomial. The length of the polynomial is programmed using the PLEN<4:0> bits in the CRCCON2 register (CRCCON2<4:0>). The PLEN<4:0> value signals the length of the polynomial and switches a multiplexer to indicate the tap from which the feedback originated. The result of the CRC calculation is obtained by reading the holding registers through the CRC read bus. A direct write path to the CRC Shift registers is also provided through the CRC write bus. This path is accessed by the CPU through the CRCWDATL and CRCWDATH registers. Figure 4-1: CRC Shift Engine Detail CRCWDATH CRCWDATL Read/Write Bus X(0)(1) Shift Buffer Data Note 1: 2: X(1) Bit 0 X(2) Bit 1 X(n) Bit 2 Bit n(2) Each XOR stage of the shift engine is programmable. See text for details. Polynomial Length n is determined by (PLEN<4:0> + 1). DS30009729B-page 10 © 2009-2013 Microchip Technology Inc. 32-Bit Programmable Cyclic Redundancy Check (CRC) 5.0 CONTROL LOGIC 5.1 Polynomial Interface The CRC module can be programmed for CRC polynomials of up to the 32nd order, using up to 32 bits. Polynomial length, which reflects the highest exponent in the equation, is selected by the PLEN<4:0> bits (CRCCON2<4:0>). The CRCXORL and CRCXORH registers control which exponent terms are included in the equation. Setting a particular bit includes that exponent term in the equation functionally; this includes an XOR operation on the corresponding bit in the CRC engine. Clearing the bit disables the XOR. For example, consider two CRC polynomials, one a 16-bit equation and the other a 32-bit equation: Equation 5-1: x16 + x12 + x5 + 1 and x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 To program this polynomial into the CRC generator, set the register bits as shown in Table 5-1. Table 5-1: CRC Setup Examples for 16 and 32-Bit Polynomials Bit Values CRC Control Bits 16-Bit Polynomial 32-Bit Polynomial PLEN<4:0> 01111 11111 X<31:16> 0000 0000 0000 0000 0000 0100 1100 0001 X<15:1> 0001 0000 0010 000x 0001 1101 1011 011x Note that the appropriate positions are set to ‘1’ to indicate that they are used in the equation (e.g., X26 and X23). The 0 bit required by the equation is always XORed; thus, X0 is a don’t care. The Most Significant bit (MSb) of the polynomial does not affect the calculation and can be set to zero. 5.2 Data Interface The module accommodates user-defined input data width for calculating CRC. Input data width can be configured to any value, between 1 and 32 bits, using the DWIDTH<4:0> bits (CRCCON2<12:8>). The input data is fed to the CRCDATL and CRCDATH registers. Depending upon the configuration of the DWIDTH<4:0> bits, the width of the CRCDATL and CRCDATH registers is configured. For data width less than, or equal to, 16 bits, only the CRCDATL register has to be used and any writes to the CRCDATH register will be ignored. For data width greater than 16 bits, both the CRCDATL and CRCDATH registers should be used. The user must write the lower 16 bits (word) into the CRCDATL register first and then the upper bits into the CRCDATH register. Note: For data width less than, or equal to, 8 bits, the user should feed the input data through byte operations into the CRCDATL register. © 2009-2013 Microchip Technology Inc. DS30009729B-page 11 dsPIC33/PIC24 Family Reference Manual 5.3 Data Shift Direction The LENDIAN bit (CRCCON1<3>) is used to control the shift direction. By default, the CRC module will shift data through the engine, MSb first (LENDIAN = 0). Setting LENDIAN to ‘1’ causes the CRC module to shift data, LSb first. This setting allows better integration with various communication schemes and removes the overhead of reversing the bit order in software. Note that this only changes the direction the data is shifted into the engine. The result of the CRC calculation will still be a normal CRC result, not a reverse CRC result. The PIC24 and dsPIC33 are little endian devices. When the CRC module is configured for the big endian (LENDIAN = 0), the input data bytes and words must be swapped in the application code before loading them into the CRCDAT registers. 5.4 FIFO The module incorporates a FIFO that works with a variable data width. The data width is defined by the DWIDTH<4:0> bits (CRCCON2<12:8>). It can be configured to any value, between 1 and 32 bits. The logic associated with the FIFO contains a 5-bit counter, called VWORD (VWORD<4:0> or CRCCON1<12:8>). The value in the VWORD<4:0> bits indicates the number of new data elements in the FIFO. The FIFO is: • 16-word deep when DWIDTH<4:0> 7 (data words, 8-bit-wide or less) • 8-word deep when DWIDTH<4:0> 15 (data words from 9 to 16-bit-wide) • 4-word deep when DWIDTH<4:0> 31 (data words from 17 to 32-bit-wide) The data for which the CRC is to be calculated must first be written into the FIFO by the CPU using the CRCDAT registers. Reading the CRCDAT registers always returns zero. Filling the FIFO with Less Than or Equal to 8-Bit Data: With an 8-bit or less data word width setting, the FIFO increments on a write to either the lower or the upper byte of the CRCDATL register. The smallest data element that can be written into the FIFO is 1 byte. When a single 16-bit word is loaded into the CRCDATL register, the lower byte is written into the FIFO first and the higher byte is written next. For example, if DWIDTH<4:0> is five, then the size of the data is DWIDTH<4:0> + 1 or six. The data is written as a whole byte; the two unused upper bits are ignored by the module. Once the data byte is written into the CRCDATL register, the value of the VWORD<4:0> bits (CRCCON1< 12:8>) increments by one. Filling the FIFO with Greater Than 8-Bit and Less Than/Equal to 16-Bit Data: With greater than 8-bit, and less than or equal to a 16-bit data word width setting, the FIFO is loaded on a write to the CRCDATL register. Any write to the CRCDATH register will be ignored. The value of the VWORD<4:0> bits is incremented for every write to the CRCDATL register. Filling the FIFO with Greater Than 16 and Less Than 32-Bit Data: When the data width is greater than 16 bits, any write to the CRCDATH register increments the VWORD<4:0> bits by one. Writing the lower word into the CRCDATL register must be done before writing the upper word into the CRCDATH register. To accommodate the, MSb first shift method (LENDIAN = 0), byte and word swapping must be done in software when filling the FIFO. Pictorial descriptions of FIFO for different data widths are shown in the Figure 5-1, Figure 5-2 and Figure 5-3. Note: Ensure that the new data is not written into the CRCDATL and CRCDATH registers when the CRCFUL bit is set; if the new data is written, it will be ignored. When all shifts are done (the FIFO is empty and the CRC shift engine is Idle), it is possible to change the FIFO width (DWIDTH<4:0> bits) without any information loss or CRC result damage. DS30009729B-page 12 © 2009-2013 Microchip Technology Inc. 32-Bit Programmable Cyclic Redundancy Check (CRC) Filling the FIFO Word Width 8 Bits Figure 5-1: Initial Conditions: W1 W2 W3 W4 W5 W6 = = = = = = Code Executed to Fill the FIFO: MOV.W MOV.W MOV.B MOV.B MOV.B MOV.B 0x0201 0x0403 0x0005 0x0006 0x0007 0x0008 W1, W2, W3, W4, W5, W6, CRCDATL CRCDATL CRCDATL CRCDATL CRCDATL CRCDATL ; ; ; ; ; ; low low low low low low byte byte byte byte byte byte is written first, then high byte is written first, then high byte only only only only Resulting FIFO: Figure 5-2: Write Location Value W6L 7 0x08 W5L 6 0x07 W4L 5 0x06 W3L 4 0x05 W2H 3 0x04 W2L 2 0x03 W1H 1 0x02 W1L 0 0x01 Filling the FIFO Word Width > 8 Bits and 16 Bits Initial Conditions: W1 W2 W3 W4 = = = = Code Executed to Fill the FIFO: MOV.W MOV.B MOV.W MOV.W 0x0A01 0x0B02 0x0C03 0x0D04 W1, W2, W3, W4, CRCDATL CRCDATL CRCDATL CRCDATL ; ; ; ; word low byte word word Resulting FIFO: Note 1: Figure 5-3: Write Location Value W4 3 0x0D04 W3 2 0x0C03 W2L 1 0x-02(1) W1 0 0x0A01 Values of “-” indicates that the FIFO contains stale data from previous operations due to the way in which it was filled. Filling the FIFO Word Width > 16 Bits and 32 Bits Initial Conditions: W1 = 0x0A01 W2 = 0x0B02 W3 = 0x0C03 W4 = 0x0D04 Code Executed to Fill the FIFO: MOV.W W1, CRCDATL MOV.W W2, CRCDATH MOV.W W3, CRCDATL MOV.W W4, CRCDATH ; ; ; ; low word high word, write to FIFO occurs here low word high word, write to FIFO occurs here Word Width > 16 Bits and 32 Bits: © 2009-2013 Microchip Technology Inc. Write Location Value W4, W3 1 0x0D040C03 W2, W1 0 0x0B020A01 DS30009729B-page 13 dsPIC33/PIC24 Family Reference Manual 5.5 CRC Engine Interface 5.5.1 FIFO TO CRC SHIFT ENGINE To start moving the data from the FIFO to the CRC shift buffer, the CRCGO bit (CRCCON1<4>) must be set. The serial shifter starts shifting data from the shift buffer to the CRC shift engine, starting from the MSb first for LENDIAN = 0, and LSb first for LENDIAN = 1, when CRCGO = 1 and the value of VWORD<4:0> is greater than zero. If the CRCFUL bit was set earlier, then it is cleared when the VWORDx bits decrement by one. The VWORD<4:0> bits decrement by one when a FIFO location is moved to the shift buffer. The serial shifter continues shifting until the VWORD<4:0> bits reach zero, at which point, the CRCMPT bit becomes set to indicate that the FIFO is empty. If the CRCGO bit is reset manually during CRC calculation, then the CRC shift engine will stop calculating until the CRCGO bit is set. The application can write into the FIFO while the shift operation is in progress. The CRCFUL bit should be monitored. If the CRCFUL bit is not set, another word can be written into the FIFO. At least one instruction cycle must pass after a write to the CRCDAT registers, before a read of the valid value of the VWORD<4:0> bits. When the VWORD<4:0> bits reach the maximum value for the configured value of the DWIDTH<4:0> bits, the CRCFUL bit becomes set. When the VWORDx bits reach zero, the CRCMPT bit becomes set. The FIFO is emptied and the VWORD<4:0> bits are set to ‘00000’ whenever CRCEN is ‘0’. The frequency of the CRC shift clock is twice that of the CPU instruction clock cycle, thus making this hardware shifting process faster than a software shifter. This means that for a given data width, it takes half that number of instructions for each word to complete the calculation. For example, it takes 16 cycles to calculate the CRC for a single word of 32-bit data. 5.5.2 NUMBER OF INSTRUCTION CYCLES TO SHIFT DATA The data from FIFO goes to the shift buffer. It takes 2 instruction cycles to start moving the data words from FIFO to the shift buffer. The data from the shift buffer is then shifted to the CRC shift engine. For a given value of the DWIDTH<4:0> bits, it will take (DWIDTH<4:0> + 1)/2 instruction cycles to completely move the data from the shift buffer to the CRC shift engine. For example, if DWIDTH<4:0> = 5, then the data length is 6 bits (DWIDTH<4:0> + 1) and 3 cycles are required to shift the data. In this case, only 6 bits of a byte are shifted out. The two MSbs of each byte are don’t care bits. Similarly, for a 12-bit polynomial selection, the Most Significant 4 bits of each word are ignored. 5.5.3 CRC INITIAL VALUE The direct write path to the CRC Shift registers is provided through the CRC write bus. This path is accessed by the CPU through the CRCWDATL and CRCWDATH registers. These registers can be loaded with a desired CRC initial value prior to the start of the calculations. The CRC initial value must be in non-direct form. The non-direct form is a value for which the CRC is equal to the desired CRC initial value (direct initial value). For example, if the application uses CRC-32 polynomial, 0x04C11DB7, and must start the calculations from the CRC direct initial value, 0xFFFFFFFF, then the non-direct value, 0x46AF6449, must be loaded in the CRCWDATL and CRCWDATH registers (the CRC of this non-direct value, 0x46AF6449, is 0xFFFFFFFF). When the non-direct initial value is written into the shift engine using the CRCWDAT registers, it will be converted by the CRC module to the direct initial value after (PLEN<4:0> + 1)/2 instruction cycles. Note: The write to CRCWDAT registers clears/resets the Shift Buffer. Usually the CRC calculation starts from the same initial value every time. In this case, the non-direct initial value can be found just once and then can be defined as a constant in the application code. Note: DS30009729B-page 14 The CRC non-direct initial value of zero is zero. © 2009-2013 Microchip Technology Inc. 32-Bit Programmable Cyclic Redundancy Check (CRC) Example 5-1 shows a possible software routine to get the non-direct initial value from the direct initial value. Example 5-1: unsigned unsigned unsigned unsigned { unsigned unsigned unsigned Software Routine to Calculate the Non-Direct Initial Value long long long char CalculateNonDirectSeed( seed, polynomial, polynomialOrder) char char long lsb; i; msbmask; // direct CRC initial value // polynomial // polynomial order msbmask = ((unsigned long)1)<<(polynomialOrder-1); for (i=0; i<polynomialOrder; i++) { lsb = seed & 1; if (lsb) seed ^= polynomial; seed >>= 1; if (lsb) seed |= msbmask; } return } seed; // return the non-direct CRC initial value The CRC module can be used to get the non-direct initial value. To do this, the following steps should be completed: 1. 2. 3. 4. 5. 6. 7. 8. Enable the CRC module (CRCEN = 1) and shifts (CRCGO = 1). Shift the polynomial value right by one. Reverse the bit order of the shifted polynomial value. Write this result in the CRCXOR registers. Set data width and polynomial length (DWIDTH<4:0> and PLEN<4:0> bits) to the polynomial order (length). Reverse the bit order of the desired direct initial value. Write the reversed initial value in CRCWDAT registers. Write a dummy data to the CRCDAT registers and wait 2 instruction cycles to move the data from the FIFO to the shift buffer, and (PLEN<4:0> + 1)/2 instruction cycles to shift out the result; OR Clear the CRC Interrupt Selection bit (CRCISEL = 0) to get the interrupt when shifts from the shift buffer are done, clear CRC interrupt flag, write a dummy data in the CRCDAT registers and wait for the CRC interrupt flag to set. 9. Read the value from CRCWDAT registers. 10. Reverse the bit order of the read result; it will give the final non-direct initial value. © 2009-2013 Microchip Technology Inc. DS30009729B-page 15 dsPIC33/PIC24 Family Reference Manual Example 5-2 explains the steps described above. Example 5-2: Routine to Calculate the Non-Direct Initial Value Using the CRC Module unsigned long unsigned char CalculateNonDirectSeed(unsigned long seed, unsigned long polynomial, polynomialOrder) // // // // direct CRC initial value polynomial polynomial order (valid values are 8, 16, 32 bits) // // // // // enable CRC interrupt when all shifts are done data width polynomial length start CRC calculation { CRCCON1 = 0; CRCCON2 = 0; CRCCON1bits.CRCEN CRCCON1bits.CRCISEL CRCCON2bits.DWIDTH CRCCON2bits.PLEN CRCCON1bits.CRCGO = = = = = 1; 0; polynomialOrder-1; polynomialOrder-1; 1; polynomial >>= 1; // shift the polynomial right polynomial = ReverseBitOrder(polynomial, polynomialOrder); // // CRCXORL = (unsigned short)(polynomial&0x0000FFFF); // CRCXORH = (unsigned short)(polynomial>>16); seed = ReverseBitOrder(seed, polynomialOrder); // CRCWDATL = (unsigned short)(seed&0x0000FFFF); // CRCWDATH = (unsigned short)(seed>>16); _CRCIF = 0; switch(polynomialOrder) reverse bits order of the polynomial set the reversed polynomial reverse bits order of the seed value set seed value // clear interrupt flag // load dummy data to shift out the // seed result { case 8: *((unsigned char*)&CRCDATL) = 0; while(!_CRCIF); seed = CRCWDATL&0x00ff; case 16: CRCDATL = 0; while(!_CRCIF); seed = CRCWDATL; break; case 32: // load long CRCDATL = 0; CRCDATH = 0; while(!_CRCIF); seed = ((unsigned long)CRCWDATH<<16)|CRCWDATL; break; default: ; // load byte // wait until shifts are done // read reversed seed // load short // wait until shifts are done // read reversed seed // wait for shifts are done // read reversed seed } seed = ReverseBitOrder(seed, polynomialOrder); return seed; // reverse the bit order to get the // non-direct seed // return the non-direct CRC initial value } DS30009729B-page 16 © 2009-2013 Microchip Technology Inc. 32-Bit Programmable Cyclic Redundancy Check (CRC) Example 5-2: Routine to Calculate the Non-Direct Initial Value Using the CRC Module (Continued) // WHERE THE FUNCTION TO REVERSE THE BIT ORDER CAN BE unsigned long ReverseBitOrder(unsigned long data, unsigned char numberOfBits) { unsigned unsigned unsigned unsigned long long long char // input data // width of the input data, // valid values are 8,16,32 bits maskint = 0; maskout = 0; result = 0; i; switch(numberOfBits) { case 8: maskin = 0x80; maskout = 0x01; break; case 16: maskin = 0x8000; maskout = 0x0001; break; case 32: maskin = 0x80000000; maskout = 0x00000001; break; default: ; } for(i=0; i<numberOfBits; i++) { if(data&maskin){ result |= maskout; } maskint >>= 1; maskout <<= 1; } return result; } To continue calculations of the full data message in the applications where the intermediate CRC sums must be read in the middle of the calculations, the non-direct value must be calculated and set to the CRCWDAT registers again. In this case, the CRC direct initial value will be an intermediate CRC result read. © 2009-2013 Microchip Technology Inc. DS30009729B-page 17 dsPIC33/PIC24 Family Reference Manual 5.5.4 CRC RESULT The CRC module requires extra (PLEN<4:0> + 1)/2 instruction cycles to finish the calculations. To generate these additional cycles, the dummy data, with the width equal to the polynomial order (length), must be loaded into the CRCDAT registers. After the shifts are finished, the final CRC result can be read from the CRCWDAT registers (the CRCWDAT registers provide the direct access to the CRC Shift register). After all data is loaded into the CRC module, the following steps should be done to get the final CRC result. If the data width (DWIDTH<4:0> bits) is more than the polynomial length (PLEN<4:0> bits): 1. 2. 3. 4. 5. 6. 7. Wait for the data FIFO to empty (CRCMPT bit is set). Wait (DWIDTH<4:0> + 1)/2 instruction cycles to make sure that shifts from the shift buffer are finished. Change the data width to the polynomial length (DWIDTH<4:0> = PLEN<4:0>). Write one dummy data word to the CRCDAT registers. Wait 2 instruction cycles to move the data from the FIFO to the shift buffer and (PLEN<4:0> + 1)/2 instruction cycles to shift out the result; OR Clear the CRC Interrupt Selection bit (CRCISEL = 0) to get the interrupt when all shifts are done. Clear the CRC interrupt flag. Write dummy data in the CRCDAT registers and wait until the CRC interrupt flag is set. Read the final CRC result from the CRCWDAT registers. Restore the data width (DWIDTH<4:0> bits) for further calculations (OPTIONAL). If the data width (DWIDTH<4:0> bits) is equal to, or less than, the polynomial length (PLEN<4:0> bits), the procedure to get the result can be different: 1. 2. 3. 4. 5. 6. 7. Clear the CRC Interrupt Selection bit (CRCISEL = 0) to get the interrupt when all shifts are done. Suspend the calculation by setting CRCGO = 0. Clear the CRC interrupt flag. Write the dummy data with the total data length equal to the polynomial length in the CRCDAT registers. Resume the calculation by setting CRCGO = 1. Wait until the CRC interrupt flag is set. Read the final CRC result from the CRCWDAT registers. When the CRC result is achieved, the CRC non-direct initial value should be written again into the CRCWDAT registers to clear/reset the shift buffer from the previously loaded dummy data to start a new calculation. DS30009729B-page 18 © 2009-2013 Microchip Technology Inc. 32-Bit Programmable Cyclic Redundancy Check (CRC) Example 5-3 shows the steps described above for the polynomial orders of 8, 16 and 32 bits. Example 5-3: Routine to Get the Final CRC Result unsigned long unsigned char { unsigned long GetCRC(unsigned char polynomialOrder, currentDataWidth) // valid values are 8,16,32 // valid values are 8,16,32 crc = 0; while(!CRCCON1bits.CRCMPT); // wait until data FIFO is empty asm volatile ("repeat %0\n nop" : : "r"(currentDataWidth>>1)); // // CRCCON2bits.DWIDTH = polynomialOrder-1; // // CRCCON1bits.CRCISEL = 0; // _CRCIF = 0; wait until previous data shifts are done set data width to polynomial length interrupt when all shifts are done // clear interrupt flag switch(polynomialOrder) { case 8: *((unsigned char*)&CRCDATL) = 0; while(!_CRCIF); crc = CRCWDATL&0x00ff; break; case 16: CRCDATL = 0; while(!_CRCIF); crc = CRCWDATL; break; case 32: CRCDATL = 0; CRCDATH = 0; while(!_CRCIF); crc = ((unsigned long)CRCWDATH<<16)|CRCWDATL; break; default: ; } CRCCON2bits.DWIDTH = currentDataWidth-1; return crc; // // // // polynomial length is 8 bits load byte wait until shifts are done get crc // // // // polynomial length is 16 bits load short wait until shifts are done get crc // polynomial length is 32 bits // load long // wait until shifts are done // get crc // restore data width for further // calculations // return the final CRC value } 5.6 Interrupt Operation The module generates an interrupt that is configurable by the user for either of the two conditions. If CRCISEL is ‘1’, an interrupt is generated when the VWORD<4:0> bits make a transition from a value of ‘1’ to ‘0’. If CRCISEL is ‘0’, an interrupt will be generated when the FIFO is empty and shifts from the shift buffer are finished. The table in Section 9.0 “Register Maps” details the Interrupt register associated with the CRC module. For more details on interrupts and interrupt priority settings, refer to the “Interrupts” section in the “dsPIC33/PIC24 Family Reference Manual”. © 2009-2013 Microchip Technology Inc. DS30009729B-page 19 dsPIC33/PIC24 Family Reference Manual 6.0 ADVANTAGES OF PROGRAMMABLE CRC MODULE The CRC algorithm is straightforward to implement in software. However, it requires considerable CPU bandwidth to implement the basic requirements, such as shift, bit test and XOR. Moreover, CRC calculation is an iterative process and additional software overhead for data transfer instructions puts enormous burden on the MIPS requirement of a microcontroller. The CRC engine in the dsPIC33/PIC24 devices calculates the CRC checksum without CPU intervention; moreover, it is much faster than the software implementation. The CRC engine consumes only half of an instruction cycle per bit for its calculation as the frequency of the CRC shift clock is twice that of the dsPIC33/PIC24 instruction clock cycle. For example, the CRC hardware engine takes only about 64 instruction cycles to calculate a CRC checksum on a message that is 128 bits (16x8) long. If the same calculation is implemented in software, it will consume more than a thousand instruction cycles, even for an optimized piece of code. 7.0 APPLICATION OF CRC MODULE Calculating a CRC is a robust error checking algorithm in digital communication for messages containing several bytes or words. After calculation, the checksum is appended to the message and transmitted to the receiving station. The receiver calculates the checksum with the received message to verify the data integrity. 7.1 Variations The 32-bit programmable CRC module of the dsPIC33/PIC24 devices can be programmed to shift out either the MSb or LSb first. MSb first is a popular implementation as employed in XMODEM protocol. In one of the variations (CCITT protocol) for CRC calculation, the LSb is shifted out first. Discussions on all the variations are beyond the scope of this document, but several variations of CRC can be implemented using the 32-bit programmable CRC module in dsPIC33/PIC24 devices. The choice of the polynomial length, and the polynomial itself, are application dependent. Polynomial lengths of 5, 7, 8, 10, 12, 16 and 32 are normally used in various standard implementations. The following sections explain the recommended step-by-step procedure for CRC calculation. Users can decide whether zeros, or any other values, need to be appended to the message stream. Depending on the application, the user may decide whether any value needs to be appended at all. 7.2 Typical Operation To use the module for a typical CRC calculation: 1. 2. 3. 4. 5. 6. 7. DS30009729B-page 20 Set the CRCEN bit to enable the module. Configure the module for desired operation: a) Program the desired polynomial using the CRCXOR registers and PLEN<4:0> bits. b) Configure the data width and shift direction using the DWIDTH<4:0> and LENDIAN bits. Set the CRCGO bit to start the calculations. Set the desired CRC non-direct initial value by writing to the CRCWDAT registers. Load all data into the FIFO by writing to the CRCDAT registers as space becomes available (the CRCFUL bit must be zero before the next data loading). Wait until the data FIFO is empty (CRCMPT bit is set). Read the CRC result as described in Section 5.5.4 “CRC Result”. © 2009-2013 Microchip Technology Inc. 32-Bit Programmable Cyclic Redundancy Check (CRC) Example 7-1, Example 7-2, Example 7-3, Example 7-4 and Example 7-5 provide examples for different combinations between polynomial length, data width and shift direction. Example 7-1: 8-Bit Polynomial with 32-Bit Data Width When MSb is Shifted First (CRC SMBus) // ASCII bytes "12345678" unsigned char __attribute__((aligned(2))) message[] = {'1','2','3','4','5','6','7','8'}; volatile volatile unsigned char crcResultCRCSMBUS = 0; int main (void) { unsigned short* pointer; unsigned short length; unsigned short data_high; unsigned short data_low; //////////////////////////////////////////////////////////////////////////////// // standard CRC-SMBUS //////////////////////////////////////////////////////////////////////////////// #define #define CRCSMBUS_POLYNOMIAL CRCSMBUS_SEED_VALUE ((unsigned short)0x0007) ((unsigned short)0x0000) // non-direct of 0x00 CRCCON1 = 0; CRCCON2 = 0; CRCCON1bits.CRCEN CRCCON1bits.LENDIAN CRCCON1bits.CRCISEL CRCCON2bits.DWIDTH CRCCON2bits.PLEN CRCCON1bits.CRCGO = = = = = = 1; 0; 0; 32-1; 8-1; 1; // // // // // // enable CRC big endian interrupt when all shifts are done 32-bit data width 8-bit polynomial order start CRC calculation CRCXORL = CRCSMBUS_POLYNOMIAL; CRCXORH = 0; // set polynomial CRCWDATL = CRCSMBUS_SEED_VALUE; CRCWDATH = 0; // set initial value pointer = (unsigned short*)message; length = sizeof(message)/sizeof(unsigned long); while(length--) { // calculate CRC © 2009-2013 Microchip Technology Inc. DS30009729B-page 21 dsPIC33/PIC24 Family Reference Manual Example 7-1: 8-Bit Polynomial with 32-Bit Data Width When MSb is Shifted First (CRC SMBus) (Continued) while(CRCCON1bits.CRCFUL); data_low = *pointer++; data_high = *pointer++; // wait if FIFO is full // load from little endian volatile ("swap %0" : "+r"(data_low)); // swap bytes for big endian volatile ("swap %0" : "+r"(data_high)); asm asm CRCDATL = data_high; CRCDATH = data_low; // 32-bit word access to FIFO // swap 16-bit words for big endian } while(!CRCCON1bits.CRCMPT); // wait until FIFO is empty asm // wait until previous data shifts are done // 16 cycles maximum for 32-bit data width volatile ("repeat #16-#2\n nop"); CRCCON2bits.DWIDTH = 8-1; // 8-bit // switch data width to polynomial length _CRCIF = 0; // clear the interrupt flag // dummy data to shift out the CRC result *((unsigned char*)&CRCDATL) = 0; // byte access to FIFO while(!_CRCIF); crcResultCRCSMBUS = CRCWDATL&0x00ff; // wait until shifts are done // get CRC result (must be 0xC7) while(1); return 1; } DS30009729B-page 22 © 2009-2013 Microchip Technology Inc. 32-Bit Programmable Cyclic Redundancy Check (CRC) Example 7-2: 16-Bit Polynomial with 16-Bit Data Width When LSb is Shifted First (CRC 16) // ASCII bytes "87654321" volatile unsigned short message[] = {0x3738,0x3536,0x3334,0x3132}; volatile unsigned int main { unsigned unsigned unsigned (void) short* short short short crcResultCRC16 = 0; pointer; length; data; //////////////////////////////////////////////////////////////////////////////// // standard CRC-16 //////////////////////////////////////////////////////////////////////////////// #define CRC16_POLYNOMIAL ((unsigned short)0x8005) #define CRC16_SEED_VALUE ((unsigned short)0x0000) // non-direct of 0x0000 CRCCON1 = 0; CRCCON2 = 0; CRCCON1bits.CRCEN CRCCON1bits.CRCISEL CRCCON1bits.LENDIAN CRCCON2bits.DWIDTH CRCCON2bits.PLEN CRCCON1bits.CRCGO = = = = = = 1; 0; 1; 16-1; 16-1; 1; // // // // // // enable CRC interrupt when all shifts are done little endian 16-bit data width 16-bit polynomial order start CRC calculation CRCXORL = CRC16_POLYNOMIAL; CRCXORH = 0; // set polynomial CRCWDATL = CRC16_SEED_VALUE; CRCWDATH = 0; // set initial value pointer = (unsigned short*)message; lengthr = sizeof(message)/sizeof(unsigned short); // calculate CRC while(length--) { while(CRCCON1bits.CRCFUL); // wait if FIFO is full data = *pointer++; // load data CRCDATL = data; // 16-bit word access to FIFO while(CRCCON1bits.CRCFUL); // wait if FIFO is full } © 2009-2013 Microchip Technology Inc. DS30009729B-page 23 dsPIC33/PIC24 Family Reference Manual Example 7-2: 16-Bit Polynomial with 16-Bit Data Width When LSb is Shifted First (CRC 16) (Continued) CRCCON1bits.CRCGO = 0; // suspend CRC calculation to clear interrupt flag _CRCIFt = 0; // clear interrupt flag CRCDATL = 0; // load dummy data to shift out the CRC result // data width must be equal to polynomial length CRCCON1bits.CRCGO = 1; // resume CRC calculation while(!_CRCIF); // wait until shifts are done crcResultCRC16 = CRCWDATL; // get CRC result (must be 0xE716) while(1); return 1; } DS30009729B-page 24 © 2009-2013 Microchip Technology Inc. 32-Bit Programmable Cyclic Redundancy Check (CRC) Example 7-3: 16-Bit Polynomial with 16-Bit Data Width When MSb is Shifted First (CRC CCITT) // ASCII bytes "87654321" volatile unsigned short message[] = {0x3738,0x3536,0x3334,0x3132}; volatile unsigned short crcResultCRCCCITT = 0; int main { unsigned unsigned unsigned (void) short* short short pointer; length; data; //////////////////////////////////////////////////////////////////////////////// // standard CRC-CCITT //////////////////////////////////////////////////////////////////////////////// #define CRCCCITT_POLYNOMIAL ((unsigned short)0x1021) #define CRCCCITT_SEED_VALUE ((unsigned short)0x84CF) // non-direct of 0xffff CRCCON1 = 0; CRCCON2 = 0; CRCCON1bits.CRCEN CRCCON1bits.CRCISEL CRCCON1bits.LENDIAN CRCCON2bits.DWIDTH CRCCON2bits.PLEN CRCCON1bits.CRCGO = = = = = = 1; 0; 0; 16-1; 16-1; 1; // // // // // // enable CRC interrupt when all shifts are done big endian 16-bit data width 16-bit polynomial order start CRC calculation CRCXORL = CRCCCITT_POLYNOMIAL; CRCXORH = 0; // set polynomial CRCWDATL = CRCCCITT_SEED_VALUE; CRCWDATH = 0; // set initial value pointer = (unsigned short*)message; lengthr = sizeof(message)/sizeof(unsigned short); // calculate CRC while(length--) { while(CRCCON1bits.CRCFUL); // wait if FIFO is full data = *pointer++; // load data asm // swap bytes for big endian volatile ("swap %0" : "+r"(data)); © 2009-2013 Microchip Technology Inc. DS30009729B-page 25 dsPIC33/PIC24 Family Reference Manual Example 7-3: 16-Bit Polynomial with 16-Bit Data Width When MSb is Shifted First (CRC CCITT) (Continued) CRCDATL = data; } // 16 bit word access to FIFO while(CRCCON1bits.CRCFUL); // wait if FIFO is full CRCCON1bits.CRCGO = 0; // suspend CRC calculation to clear interrupt flag _CRCIF = 0; // clear interrupt flag CRCDATL = 0; // load dummy data to shift out the CRC result // data width must be equal to polynomial length CRCCON1bits.CRCGO = 1; // resume CRC calculation while(!_CRCIF); // wait until shifts are done crcResultCRCCCITT = CRCWDATL; // get CRC result (must be 0x9B4D) while(1); return 1; } DS30009729B-page 26 © 2009-2013 Microchip Technology Inc. 32-Bit Programmable Cyclic Redundancy Check (CRC) Example 7-4: 32-Bit Polynomial with 32-Bit Data Width When LSb is Shifted First (CRC 32) // ASCII bytes "12345678" char __attribute__((aligned(4))) message[] = {'1','2','3','4','5','6','7','8'}; volatile unsigned // function to reverse the bit order (OPTIONAL) unsigned long ReverseBitOrder(unsigned long data); volatile unsigned long crcResultCRC32 = 0; int main(void) { unsigned short* pointer; unsigned short length; //////////////////////////////////////////////////////////////////////////////// // standard CRC-32 //////////////////////////////////////////////////////////////////////////////// #define CRC32_POLYNOMIAL ((unsigned long)0x04C11DB7) #define CRC32_SEED_VALUE ((unsigned long)0x46AF6449) // non-direct of 0xffffffff CRCCON1 = 0; CRCCON2 = 0; CRCCON1bits.CRCEN CRCCON1bits.CRCISEL CRCCON1bits.LENDIAN CRCCON2bits.DWIDTH CRCCON2bits.PLEN CRCCON1bits.CRCGO = = = = = = 1; 0; 1; 32-1; 32-1; 1; // // // // // // enable CRC interrupt when all shifts are done little endian 32-bit data width 32-bit polynomial order start CRC calculation CRCXORL = CRC32_POLYNOMIAL&0x0000ffff; CRCXORH = CRC32_POLYNOMIAL>>16; // set polynomial CRCWDATL = CRC32_SEED_VALUE&0x0000ffff; CRCWDATH = CRC32_SEED_VALUE>>16; // set initial value pointer = (unsigned short*)message; lengthr = sizeof(message)/sizeof(unsigned long); while(length--) { // calculate CRC while(CRCCON1bits.CRCFUL); // wait if FIFO is full CRCDATL = *pointer++; CRCDATH = *pointer++; // 32-bit word access to FIFO // must be written first // must be written last } while(CRCCON1bits.CRCFUL); © 2009-2013 Microchip Technology Inc. // wait if FIFO is full DS30009729B-page 27 dsPIC33/PIC24 Family Reference Manual Example 7-4: 32-Bit Polynomial with 32-Bit Data Width When LSb is Shifted First (CRC 32) (Continued) CRCCON1bits.CRCGO = 0; // suspend CRC calculation to clear interrupt flag _CRCIF = 0; // clear interrupt flag CRCDATL = 0; CRCDATH = 0; // dummy data to shift out the CRC result CRCCON1bits.CRCGO = 1; // resume CRC calculation while(!_CRCIF); // wait until shifts are done crcResultCRC32 = ((unsigned long)CRCWDATH<<16)|CRCWDATL; // get the final CRC result crcResultCRC32 = ~ReverseBitOrder(crcResultCRC32); // OPTIONAL // reverse CRC value bit order and // invert (must be 0x9AE0DAAF) while(1); return 1; } unsigned { unsigned unsigned unsigned unsigned long ReverseBitOrder(unsigned long data) long long long char maskin; maskout; result = 0; i; maskin = 0x80000000; maskout = 0x00000001; for(i=0; i<32; i++) { if(data&maskin){ result |= maskout; } maskint >>= 1; maskout <<= 1; } return result; } DS30009729B-page 28 © 2009-2013 Microchip Technology Inc. 32-Bit Programmable Cyclic Redundancy Check (CRC) Example 7-5: 32-Bit Polynomial with Switched Data Width When MSb is Shifted First // ASCII bytes "12345678" volatile unsigned long message1[] = {0x34333231,0x38373635}; // ASCII bytes "123" volatile unsigned char message2[] = {'1','2','3'}; volatile crcResultCRC32 = 0; unsigned long int main(void) { unsigned char* unsigned short* unsigned short #define #define pointer8; pointer16; length; CRC32_POLYNOMIAL CRC32_SEED_VALUE ((unsigned long)0x04C11DB7) ((unsigned long)0x46AF6449) // non-direct of 0xffffffff CRCCON1 = 0; CRCCON2 = 0; CRCCON1bits.CRCEN CRCCON1bits.LENDIAN CRCCON2bits.DWIDTH CRCCON2bits.PLEN CRCCON1bits.CRCGO = = = = = 1; 1; 32-1; 32-1; 1; // // // // // enable CRC little endian 32-bit data width 32-bit polynomial order start CRC calculation CRCXORL = CRC32_POLYNOMIAL&0x0000ffff; CRCXORH = CRC32_POLYNOMIAL>>16; // set polynomial CRCWDATL = CRC32_SEED_VALUE&0x0000ffff; CRCWDATH = CRC32_SEED_VALUE>>16; // set initial value pointer16 = (unsigned short*)message1; lengthttt = sizeof(message1)/sizeof(unsigned long); while(length--) { // calculate CRC while(CRCCON1bits.CRCFUL); © 2009-2013 Microchip Technology Inc. // wait if FIFO is full DS30009729B-page 29 dsPIC33/PIC24 Family Reference Manual Example 7-5: 32-Bit Polynomial with Switched Data Width When MSb is Shifted First (Continued) CRCDATL = *pointer16++; CRCDATH = *pointer16++; // 32-bit word access to FIFO // must be written first // must be written last } while(!CRCCON1bits.CRCMPT); // wait until previous // data shifts are done // wait until FIFO is empty asm // 16 cycles maximum for 32-bit data volatile ("repeat #16-#2\n nop"); CRCCON2bits.DWIDTH = 8-1; // switch the data width to 8-bit pointer8 = (unsigned char*)message2; // calculate CRC lengthtt = sizeof(message2)/sizeof(unsigned char); while(length--) { while(CRCCON1bits.CRCFUL); // wait if FIFO is full *((unsigned char*)&CRCDATL) = *pointer8++; // byte access to FIFO } while(!CRCCON1bits.CRCMPT); asm volatile ("repeat #4-#2\n nop"); CRCCON2bits.DWIDTH = 32-1; CRCDATL = 0; CRCDATH = 0; asm volatile // wait until FIFO is empty // wait until previous data shifts are done // 4 cycles maximum for 8-bit data // switch the data width to polynomial length // 32-bit // dummy data to shift out the CRC result ("repeat #2+#16-#2\n nop"); // // // // delay 2 cycles to move data from FIFO to shift buffer and 16 cycles for 32-bit word to shift out the final result crcResultCRC32 = ((unsigned long)CRCWDATH<<16)|CRCWDATL; // get the final CRC result // (must be0xE092727E) while(1); return 1; } DS30009729B-page 30 © 2009-2013 Microchip Technology Inc. 32-Bit Programmable Cyclic Redundancy Check (CRC) 8.0 OPERATION IN POWER SAVE MODES 8.1 Sleep Mode If Sleep mode is entered while the module is operating, the module is suspended in its current state until clock execution resumes. 8.2 Idle Mode To continue full module operation in Idle mode, the CSIDL bit must be cleared prior to entry into the mode. If CSIDL = 1, the module behaves the same way as it does in Sleep mode; pending interrupt events will be passed on, even though the module clocks are not available. © 2009-2013 Microchip Technology Inc. DS30009729B-page 31 REGISTER MAPS A summary of the Special Function Registers associated with the dsPIC33/PIC24 32-Bit Programmable Cyclic Redundancy Check (CRC) module is provided in Table 9-1. Table 9-1: File Name Special Function Registers Associated with the Programmable CRC Module(1) Bit 15 Bit 14 Bit 13 Bit 12 Bit 11 Bit 10 Bit 9 Bit 8 Bit 7 Bit 6 Bit 5 Bit 3 Bit 2 Bit 1 Bit 0 All Resets 0040 CRCCON1 CRCEN — CSIDL VWORD4 VWORD3 VWORD2 VWORD1 VWORD0 CRCFUL CRCGO LENDIAN — — — CRCCON2 — — — DWIDTH4 DWIDTH3 DWIDTH2 DWIDTH1 DWIDTH0 — — — PLEN4 PLEN3 PLEN2 PLEN1 PLEN0 0000 CRCXORL X15 X14 X13 X7 X6 X5 X4 X3 X2 X1 — 0000 X12 X11 X10 X9 X8 CRCMPT CRCISEL Bit 4 CRCXORH X31 X30 X29 X28 X27 X26 X25 X24 X23 X22 X21 X20 X19 X18 X17 X16 0000 CRCDATL DATA15 DATA14 DATA13 DATA12 DATA11 DATA10 DATA9 DATA8 DATA7 DATA6 DATA5 DATA4 DATA3 DATA2 DATA1 DATA0 0000 CRCDATH DATA31 DATA30 DATA29 DATA28 DATA27 DATA26 DATA25 DATA24 DATA23 DATA22 DATA21 DATA20 DATA19 DATA18 DATA17 DATA16 0000 SDATA6 SDATA5 SDATA4 SDATA3 SDATA2 SDATA1 SDATA0 0000 SDATA21 SDATA20 SDATA19 SDATA18 SDATA17 SDATA16 0000 CRCWDATL SDATA15 SDATA14 SDATA13 SDATA12 SDATA11 SDATA10 SDATA9 SDATA8 SDATA7 CRCWDATH SDATA31 SDATA30 SDATA29 SDATA28 SDATA27 SDATA26 SDATA25 SDATA24 SDATA23 SDATA22 IFS4 — — — — — — — — — — — — CRCIF U2ERIF U1ERIF — 0000 IEC4 — — — — — — — — — — — — CRCIE U2ERIE U1ERIE — 0000 IPC16 — CRCIP2 CRCIP1 CRCIP0 — U2ERIP2 U2ERIP1 U2ERIP0 — U1ERIP2 U1ERIP1 U1ERIP0 — — — — 4440 Legend: — = unimplemented, read as ‘0’. Shaded bits are not used in the operation of the programmable CRC module. Note 1: Refer to the specific device data sheet for memory map details. dsPIC33/PIC24 Family Reference Manual DS30009729B-page 32 9.0 © 2009-2013 Microchip Technology Inc. 32-Bit Programmable Cyclic Redundancy Check (CRC) 10.0 RELATED APPLICATION NOTES This section lists application notes that are related to this section of the manual. These application notes may not be written specifically for the dsPIC33/PIC24 device family, but the concepts are pertinent and could be used with modification and possible limitations. The current application notes related to the 32-Bit Programmable Cyclic Redundancy Check (CRC) are: Title Application Note # No related application notes at this time. Note: Please visit the Microchip web site (www.microchip.com) for additional application notes and code examples for the dsPIC33/PIC24 family of devices. © 2009-2013 Microchip Technology Inc. DS30009729B-page 33 dsPIC33/PIC24 Family Reference Manual 11.0 REVISION HISTORY Revision A (April 2009) This is the initial released revision of this document. Revision B (August 2013) This revision includes the following changes: • Changed the document name from PIC24F Family Reference Manual to dsPIC33/PIC24 Family Reference Manual. • Revised description of CRCISEL in Register 3-1. • Added additional information to Section 5.3 “Data Shift Direction”. • Added additional information to Section 5.4 “FIFO”. • Made corrections to Figure 5-1, Figure 5-2 and Figure 5-3. • Revised Section 5.5 “CRC Engine Interface”. • Revised Section 5.6 “Interrupt Operation” and added code examples. • Revised Section 7.2 “Typical Operation” and added code examples. • Minor grammatical corrections throughout the document. DS30009729B-page 34 © 2009-2013 Microchip Technology Inc. Note the following details of the code protection feature on Microchip devices: • Microchip products meet the specification contained in their particular Microchip Data Sheet. • Microchip believes that its family of products is one of the most secure families of its kind on the market today, when used in the intended manner and under normal conditions. • There are dishonest and possibly illegal methods used to breach the code protection feature. All of these methods, to our knowledge, require using the Microchip products in a manner outside the operating specifications contained in Microchip’s Data Sheets. Most likely, the person doing so is engaged in theft of intellectual property. • Microchip is willing to work with the customer who is concerned about the integrity of their code. • Neither Microchip nor any other semiconductor manufacturer can guarantee the security of their code. Code protection does not mean that we are guaranteeing the product as “unbreakable.” Code protection is constantly evolving. We at Microchip are committed to continuously improving the code protection features of our products. Attempts to break Microchip’s code protection feature may be a violation of the Digital Millennium Copyright Act. If such acts allow unauthorized access to your software or other copyrighted work, you may have a right to sue for relief under that Act. Information contained in this publication regarding device applications and the like is provided only for your convenience and may be superseded by updates. It is your responsibility to ensure that your application meets with your specifications. MICROCHIP MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND WHETHER EXPRESS OR IMPLIED, WRITTEN OR ORAL, STATUTORY OR OTHERWISE, RELATED TO THE INFORMATION, INCLUDING BUT NOT LIMITED TO ITS CONDITION, QUALITY, PERFORMANCE, MERCHANTABILITY OR FITNESS FOR PURPOSE. Microchip disclaims all liability arising from this information and its use. Use of Microchip devices in life support and/or safety applications is entirely at the buyer’s risk, and the buyer agrees to defend, indemnify and hold harmless Microchip from any and all damages, claims, suits, or expenses resulting from such use. No licenses are conveyed, implicitly or otherwise, under any Microchip intellectual property rights. Trademarks The Microchip name and logo, the Microchip logo, dsPIC, FlashFlex, KEELOQ, KEELOQ logo, MPLAB, PIC, PICmicro, PICSTART, PIC32 logo, rfPIC, SST, SST Logo, SuperFlash and UNI/O are registered trademarks of Microchip Technology Incorporated in the U.S.A. and other countries. FilterLab, Hampshire, HI-TECH C, Linear Active Thermistor, MTP, SEEVAL and The Embedded Control Solutions Company are registered trademarks of Microchip Technology Incorporated in the U.S.A. Silicon Storage Technology is a registered trademark of Microchip Technology Inc. in other countries. Analog-for-the-Digital Age, Application Maestro, BodyCom, chipKIT, chipKIT logo, CodeGuard, dsPICDEM, dsPICDEM.net, dsPICworks, dsSPEAK, ECAN, ECONOMONITOR, FanSense, HI-TIDE, In-Circuit Serial Programming, ICSP, Mindi, MiWi, MPASM, MPF, MPLAB Certified logo, MPLIB, MPLINK, mTouch, Omniscient Code Generation, PICC, PICC-18, PICDEM, PICDEM.net, PICkit, PICtail, REAL ICE, rfLAB, Select Mode, SQI, Serial Quad I/O, Total Endurance, TSHARC, UniWinDriver, WiperLock, ZENA and Z-Scale are trademarks of Microchip Technology Incorporated in the U.S.A. and other countries. SQTP is a service mark of Microchip Technology Incorporated in the U.S.A. GestIC and ULPP are registered trademarks of Microchip Technology Germany II GmbH & Co. KG, a subsidiary of Microchip Technology Inc., in other countries. All other trademarks mentioned herein are property of their respective companies. © 2009-2013, Microchip Technology Incorporated, Printed in the U.S.A., All Rights Reserved. Printed on recycled paper. ISBN: 978-1-62077-400-7 QUALITY MANAGEMENT SYSTEM CERTIFIED BY DNV == ISO/TS 16949 == 2009-2013 Microchip Technology Inc. Microchip received ISO/TS-16949:2009 certification for its worldwide headquarters, design and wafer fabrication facilities in Chandler and Tempe, Arizona; Gresham, Oregon and design centers in California and India. The Company’s quality system processes and procedures are for its PIC® MCUs and dsPIC® DSCs, KEELOQ® code hopping devices, Serial EEPROMs, microperipherals, nonvolatile memory and analog products. In addition, Microchip’s quality system for the design and manufacture of development systems is ISO 9001:2000 certified. DS30009729B-page 35 Worldwide Sales and Service AMERICAS ASIA/PACIFIC ASIA/PACIFIC EUROPE Corporate Office 2355 West Chandler Blvd. Chandler, AZ 85224-6199 Tel: 480-792-7200 Fax: 480-792-7277 Technical Support: http://www.microchip.com/ support Web Address: www.microchip.com Asia Pacific Office Suites 3707-14, 37th Floor Tower 6, The Gateway Harbour City, Kowloon Hong Kong Tel: 852-2401-1200 Fax: 852-2401-3431 India - Bangalore Tel: 91-80-3090-4444 Fax: 91-80-3090-4123 India - New Delhi Tel: 91-11-4160-8631 Fax: 91-11-4160-8632 Austria - Wels Tel: 43-7242-2244-39 Fax: 43-7242-2244-393 Denmark - Copenhagen Tel: 45-4450-2828 Fax: 45-4485-2829 India - Pune Tel: 91-20-2566-1512 Fax: 91-20-2566-1513 France - Paris Tel: 33-1-69-53-63-20 Fax: 33-1-69-30-90-79 Japan - Osaka Tel: 81-6-6152-7160 Fax: 81-6-6152-9310 Germany - Munich Tel: 49-89-627-144-0 Fax: 49-89-627-144-44 Atlanta Duluth, GA Tel: 678-957-9614 Fax: 678-957-1455 Boston Westborough, MA Tel: 774-760-0087 Fax: 774-760-0088 Chicago Itasca, IL Tel: 630-285-0071 Fax: 630-285-0075 Cleveland Independence, OH Tel: 216-447-0464 Fax: 216-447-0643 Dallas Addison, TX Tel: 972-818-7423 Fax: 972-818-2924 Detroit Farmington Hills, MI Tel: 248-538-2250 Fax: 248-538-2260 Indianapolis Noblesville, IN Tel: 317-773-8323 Fax: 317-773-5453 Los Angeles Mission Viejo, CA Tel: 949-462-9523 Fax: 949-462-9608 Santa Clara Santa Clara, CA Tel: 408-961-6444 Fax: 408-961-6445 Toronto Mississauga, Ontario, Canada Tel: 905-673-0699 Fax: 905-673-6509 Australia - Sydney Tel: 61-2-9868-6733 Fax: 61-2-9868-6755 China - Beijing Tel: 86-10-8569-7000 Fax: 86-10-8528-2104 China - Chengdu Tel: 86-28-8665-5511 Fax: 86-28-8665-7889 China - Chongqing Tel: 86-23-8980-9588 Fax: 86-23-8980-9500 Netherlands - Drunen Tel: 31-416-690399 Fax: 31-416-690340 Korea - Daegu Tel: 82-53-744-4301 Fax: 82-53-744-4302 Spain - Madrid Tel: 34-91-708-08-90 Fax: 34-91-708-08-91 China - Hangzhou Tel: 86-571-2819-3187 Fax: 86-571-2819-3189 Korea - Seoul Tel: 82-2-554-7200 Fax: 82-2-558-5932 or 82-2-558-5934 China - Hong Kong SAR Tel: 852-2943-5100 Fax: 852-2401-3431 Malaysia - Kuala Lumpur Tel: 60-3-6201-9857 Fax: 60-3-6201-9859 China - Nanjing Tel: 86-25-8473-2460 Fax: 86-25-8473-2470 Malaysia - Penang Tel: 60-4-227-8870 Fax: 60-4-227-4068 China - Qingdao Tel: 86-532-8502-7355 Fax: 86-532-8502-7205 Philippines - Manila Tel: 63-2-634-9065 Fax: 63-2-634-9069 China - Shanghai Tel: 86-21-5407-5533 Fax: 86-21-5407-5066 Singapore Tel: 65-6334-8870 Fax: 65-6334-8850 China - Shenyang Tel: 86-24-2334-2829 Fax: 86-24-2334-2393 Taiwan - Hsin Chu Tel: 886-3-5778-366 Fax: 886-3-5770-955 China - Shenzhen Tel: 86-755-8864-2200 Fax: 86-755-8203-1760 Taiwan - Kaohsiung Tel: 886-7-213-7828 Fax: 886-7-330-9305 China - Wuhan Tel: 86-27-5980-5300 Fax: 86-27-5980-5118 Taiwan - Taipei Tel: 886-2-2508-8600 Fax: 886-2-2508-0102 China - Xian Tel: 86-29-8833-7252 Fax: 86-29-8833-7256 Thailand - Bangkok Tel: 66-2-694-1351 Fax: 66-2-694-1350 UK - Wokingham Tel: 44-118-921-5869 Fax: 44-118-921-5820 China - Xiamen Tel: 86-592-2388138 Fax: 86-592-2388130 China - Zhuhai Tel: 86-756-3210040 Fax: 86-756-3210049 DS30009729B-page 36 Italy - Milan Tel: 39-0331-742611 Fax: 39-0331-466781 Japan - Tokyo Tel: 81-3-6880- 3770 Fax: 81-3-6880-3771 11/29/12 2009-2013 Microchip Technology Inc.