CRCModule
A module providing CRC routines for various uses.
Instructions for use provided in the module comments. Note the #option required when using the table versions of the code.
{ ***************************************************************************** * Name : CRC.BAS Swordfish MODULE * * Author : Thomas D. Estes * * Date : 12/31/2008 * * Version : 1.1 * * Notes : What in the world am I doing working on crc routines on * * : New Years eve? Get a life Tom! * ***************************************************************************** V1.0 12/31/2008 Dallas/Maxim DALcrc8SF, DALcrc8AL, DALcrc8LU Dallas/Maxim DALcrc16SF, DALcrc16AL, DALcrc16LU Sensirion SHTcrc8SF, SHTcrc8AL SMBus SMBcrc8SF, SMBcrc8LU V1.1 1/7/2009 adds Sensiron SHTcrc8LU SMBus SMBcrc8AL CCITT CCITTcrc16SF MODBUS MODBUScrc16SF CRC16 CRC16SF This module provides CRC calculations for various crc schemes. Several variations of each calculation are provided. A Swordfish version (always), a Swordfish encapsulated assembly language version (sometimes) and a table based SF version (sometimes) may be provided. In general the assembly language version is twice as fast as the Swordfish version. The table based versions are generally 4 times faster than the assembly version. These of course require large tables to be stored in program memory and operate a byte at a time rather than a bit at a time. Each call requires the data byte to be added to the crc and the starting or cumulative crc value. The function returns the crc. So you would want to call them by crc = CRC.xxxcrcxx(data_to_be_added,crc). That way crc continues to accumulate assuming that is what you want. Time to execute each routine is given in cpu clock ticks. The number includes instructions to start and stop the timer so the actual numbers are slightly smaller than those given. ************NOTE************NOTE*************NOTE*************NOTE************** Check your implementation carefully. Many schemes want the CRC to be initialized with certain registers or values. Some want the end result rotated, complemented, reversed or bytes swapped in 16 bit implementations. There are many input/output schemes so make sure to understand yours. Feel free to add other CRC schemes to it but when you do please increase the version by .1 and notify everyone by a message to the SF forum. } Module CRC Include "system.bas" //need to include an option to indicate the look up tables will be needed //more specifically which look up table is needed //without this the tables would be compiled into all crc code #option LUTable = None //assume no look up tables are to be loaded #if isoption(LUTable) And Not (LUTable in (None, DAL8, DAL16, SMB8, SHT8)) #error LUTable, "Invalid Option, LUTable must be None DAL8 DAL16 SHT8 SMB8" #endif #if LUTable = DAL8 Const DAL8Table(256) As Byte = ($00,$5E,$BC,$E2,$61,$3F,$DD,$83,$C2,$9C,$7E,$20,$A3,$FD,$1F,$41, $9D,$C3,$21,$7F,$FC,$A2,$40,$1E,$5F,$01,$E3,$BD,$3E,$60,$82,$DC, $23,$7D,$9F,$C1,$42,$1C,$FE,$A0,$E1,$BF,$5D,$03,$80,$DE,$3C,$62, $BE,$E0,$02,$5C,$DF,$81,$63,$3D,$7C,$22,$C0,$9E,$1D,$43,$A1,$FF, $46,$18,$FA,$A4,$27,$79,$9B,$C5,$84,$DA,$38,$66,$E5,$BB,$59,$07, $DB,$85,$67,$39,$BA,$E4,$06,$58,$19,$47,$A5,$FB,$78,$26,$C4,$9A, $65,$3B,$D9,$87,$04,$5A,$B8,$E6,$A7,$F9,$1B,$45,$C6,$98,$7A,$24, $F8,$A6,$44,$1A,$99,$C7,$25,$7B,$3A,$64,$86,$D8,$5B,$05,$E7,$B9, $8C,$D2,$30,$6E,$ED,$B3,$51,$0F,$4E,$10,$F2,$AC,$2F,$71,$93,$CD, $11,$4F,$AD,$F3,$70,$2E,$CC,$92,$D3,$8D,$6F,$31,$B2,$EC,$0E,$50, $AF,$F1,$13,$4D,$CE,$90,$72,$2C,$6D,$33,$D1,$8F,$0C,$52,$B0,$EE, $32,$6C,$8E,$D0,$53,$0D,$EF,$B1,$F0,$AE,$4C,$12,$91,$CF,$2D,$73, $CA,$94,$76,$28,$AB,$F5,$17,$49,$08,$56,$B4,$EA,$69,$37,$D5,$8B, $57,$09,$EB,$B5,$36,$68,$8A,$D4,$95,$CB,$29,$77,$F4,$AA,$48,$16, $E9,$B7,$55,$0B,$88,$D6,$34,$6A,$2B,$75,$97,$C9,$4A,$14,$F6,$A8, $74,$2A,$C8,$96,$15,$4B,$A9,$F7,$B6,$E8,$0A,$54,$D7,$89,$6B,$35) { ***************************************************************************** * Name : Function DALcrc8LU Dallas/Maxim CRC8 SF Look Up table * * Date : 12/31/2008 * * Version : 1.0 * * Notes : Requires 13 cpu clocks * * : Requires the 256 byte table DAL8Table be in program memory * ***************************************************************************** } Public Function DALcrc8LU(pDataByte As Byte,pCRC As Byte) As Byte pDataByte = pDataByte Xor pCRC Result = DAL8Table(pDataByte) End Function #elseif LUTable = DAL16 Const DAL16HiTable(256) As Byte = ($00,$C0,$C1,$01,$C3,$03,$02,$C2,$C6,$06,$07,$C7,$05,$C5,$C4,$04, $CC,$0C,$0D,$CD,$0F,$CF,$CE,$0E,$0A,$CA,$CB,$0B,$C9,$09,$08,$C8, $D8,$18,$19,$D9,$1B,$DB,$DA,$1A,$1E,$DE,$DF,$1F,$DD,$1D,$1C,$DC, $14,$D4,$D5,$15,$D7,$17,$16,$D6,$D2,$12,$13,$D3,$11,$D1,$D0,$10, $F0,$30,$31,$F1,$33,$F3,$F2,$32,$36,$F6,$F7,$37,$F5,$35,$34,$F4, $3C,$FC,$FD,$3D,$FF,$3F,$3E,$FE,$FA,$3A,$3B,$FB,$39,$F9,$F8,$38, $28,$E8,$E9,$29,$EB,$2B,$2A,$EA,$EE,$2E,$2F,$EF,$2D,$ED,$EC,$2C, $E4,$24,$25,$E5,$27,$E7,$E6,$26,$22,$E2,$E3,$23,$E1,$21,$20,$E0, $A0,$60,$61,$A1,$63,$A3,$A2,$62,$66,$A6,$A7,$67,$A5,$65,$64,$A4, $6C,$AC,$AD,$6D,$AF,$6F,$6E,$AE,$AA,$6A,$6B,$AB,$69,$A9,$A8,$68, $78,$B8,$B9,$79,$BB,$7B,$7A,$BA,$BE,$7E,$7F,$BF,$7D,$BD,$BC,$7C, $B4,$74,$75,$B5,$77,$B7,$B6,$76,$72,$B2,$B3,$73,$B1,$71,$70,$B0, $50,$90,$91,$51,$93,$53,$52,$92,$96,$56,$57,$97,$55,$95,$94,$54, $9C,$5C,$5D,$9D,$5F,$9F,$9E,$5E,$5A,$9A,$9B,$5B,$99,$59,$58,$98, $88,$48,$49,$89,$4B,$8B,$8A,$4A,$4E,$8E,$8F,$4F,$8D,$4D,$4C,$8C, $44,$84,$85,$45,$87,$47,$46,$86,$82,$42,$43,$83,$41,$81,$80,$40) Const DAL16LoTable(256) As Byte = ($00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$00,$C1,$81,$40, $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$01,$C0,$80,$41, $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$01,$C0,$80,$41, $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$00,$C1,$81,$40, $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$01,$C0,$80,$41, $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$00,$C1,$81,$40, $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$00,$C1,$81,$40, $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$01,$C0,$80,$41, $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$01,$C0,$80,$41, $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$00,$C1,$81,$40, $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$00,$C1,$81,$40, $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$01,$C0,$80,$41, $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$00,$C1,$81,$40, $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$01,$C0,$80,$41, $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$01,$C0,$80,$41, $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$00,$C1,$81,$40) { ***************************************************************************** * Name : Function Dalcrc16LU Dallas/Maxim CRC16 SF Look Up Table * * Date : 12/31/2008 * * Version : 1.0 * * Notes : Requires 27 cpu clocks * * : Requires 2 256 byte tables DAL16HiTable and DAL16LoTable * * : be in program memory * ***************************************************************************** } Public Function DALcrc16LU(pDataByte As Byte,pCRC As Word) As Word Dim CRCLo As Byte Dim CRCHi As Byte Dim OldCRCHi As Byte CRCLo = pCRC.byte0 CRCHi = pCRC.byte1 OldCRCHi = CRCHi pDataByte = pDataByte Xor CRClo CRCHi = DAL16HiTable(pDataByte) CRCLo = DAL16LoTable(pDataByte) CRCLo = CRCLo Xor OldCRCHi Result.byte0 = CRCLo Result.byte1 = CRCHi End Function #elseif LUTable = SMB8 Const SMB8Table(256) As Byte = ($00,$07,$0E,$09,$1C,$1B,$12,$15,$38,$3F,$36,$31,$24,$23,$2A,$2D, $70,$77,$7E,$79,$6C,$6B,$62,$65,$48,$4F,$46,$41,$54,$53,$5A,$5D, $E0,$E7,$EE,$E9,$FC,$FB,$F2,$F5,$D8,$DF,$D6,$D1,$C4,$C3,$CA,$CD, $90,$97,$9E,$99,$8C,$8B,$82,$85,$A8,$AF,$A6,$A1,$B4,$B3,$BA,$BD, $C7,$C0,$C9,$CE,$DB,$DC,$D5,$D2,$FF,$F8,$F1,$F6,$E3,$E4,$ED,$EA, $B7,$B0,$B9,$BE,$AB,$AC,$A5,$A2,$8F,$88,$81,$86,$93,$94,$9D,$9A, $27,$20,$29,$2E,$3B,$3C,$35,$32,$1F,$18,$11,$16,$03,$04,$0D,$0A, $57,$50,$59,$5E,$4B,$4C,$45,$42,$6F,$68,$61,$66,$73,$74,$7D,$7A, $89,$8E,$87,$80,$95,$92,$9B,$9C,$B1,$B6,$BF,$B8,$AD,$AA,$A3,$A4, $F9,$FE,$F7,$F0,$E5,$E2,$EB,$EC,$C1,$C6,$CF,$C8,$DD,$DA,$D3,$D4, $69,$6E,$67,$60,$75,$72,$7B,$7C,$51,$56,$5F,$58,$4D,$4A,$43,$44, $19,$1E,$17,$10,$05,$02,$0B,$0C,$21,$26,$2F,$28,$3D,$3A,$33,$34, $4E,$49,$40,$47,$52,$55,$5C,$5B,$76,$71,$78,$7F,$6A,$6D,$64,$63, $3E,$39,$30,$37,$22,$25,$2C,$2B,$06,$01,$08,$0F,$1A,$1D,$14,$13, $AE,$A9,$A0,$A7,$B2,$B5,$BC,$BB,$96,$91,$98,$9F,$8A,$8D,$84,$83, $DE,$D9,$D0,$D7,$C2,$C5,$CC,$CB,$E6,$E1,$E8,$EF,$FA,$FD,$F4,$F3) { ***************************************************************************** * Name : Function SMBcrc8LU SMBus CRC8 SF look up table * * Date : 12/31/2008 * * Version : 1.0 * * Notes : Requires 13 cpu clocks * * : Requires the 256 byte table SMB8Table be in program memory * ***************************************************************************** } Public Function SMBcrc8LU(pDataByte As Byte,PCRC As Byte) As Byte pDataByte = pDataByte Xor pCRC Result = SMB8Table(pDataByte) End Function #elseif LUTable = SHT8 Const SHT8Table(256) As Byte = ($00,$31,$62,$53,$C4,$F5,$A6,$97,$B9,$88,$DB,$EA,$7D,$4C,$1F,$2E, $43,$72,$21,$10,$87,$B6,$E5,$D4,$FA,$CB,$98,$A9,$3E,$0F,$5C,$6D, $86,$B7,$E4,$D5,$42,$73,$20,$11,$3F,$0E,$5D,$6C,$FB,$CA,$99,$A8, $C5,$F4,$A7,$96,$01,$30,$63,$52,$7C,$4D,$1E,$2F,$B8,$89,$DA,$EB, $3D,$0C,$5F,$6E,$F9,$C8,$9B,$AA,$84,$B5,$E6,$D7,$40,$71,$22,$13, $7E,$4F,$1C,$2D,$BA,$8B,$D8,$E9,$C7,$F6,$A5,$94,$03,$32,$61,$50, $BB,$8A,$D9,$E8,$7F,$4E,$1D,$2C,$02,$33,$60,$51,$C6,$F7,$A4,$95, $F8,$C9,$9A,$AB,$3C,$0D,$5E,$6F,$41,$70,$23,$12,$85,$B4,$E7,$D6, $7A,$4B,$18,$29,$BE,$8F,$DC,$ED,$C3,$F2,$A1,$90,$07,$36,$65,$54, $39,$08,$5B,$6A,$FD,$CC,$9F,$AE,$80,$B1,$E2,$D3,$44,$75,$26,$17, $FC,$CD,$9E,$AF,$38,$09,$5A,$6B,$45,$74,$27,$16,$81,$B0,$E3,$D2, $BF,$8E,$DD,$EC,$7B,$4A,$19,$28,$06,$37,$64,$55,$C2,$F3,$A0,$91, $47,$76,$25,$14,$83,$B2,$E1,$D0,$FE,$CF,$9C,$AD,$3A,$0B,$58,$69, $04,$35,$66,$57,$C0,$F1,$A2,$93,$BD,$8C,$DF,$EE,$79,$48,$1B,$2A, $C1,$F0,$A3,$92,$05,$34,$67,$56,$78,$49,$1A,$2B,$BC,$8D,$DE,$EF, $82,$B3,$E0,$D1,$46,$77,$24,$15,$3B,$0A,$59,$68,$FF,$CE,$9D,$AC) { ***************************************************************************** * Name : Function SHTcrc8LU Sensirion CRC8 SF look up table * * Date : 1/7/2009 * * Version : 1.0 * * Notes : Requires 13 cpu clocks * * : Requires the 256 byte table SHT8Table be in program memory * ***************************************************************************** } Public Function SHTcrc8LU(pDataByte As Byte,PCRC As Byte) As Byte pDataByte = pDataByte Xor pCRC Result = SHT8Table(pDataByte) End Function #endif { ***************************************************************************** * Name : Function SHTcrc8SF Sensirion CRC8 SwordFish * * Date : 12/31/2008 * * Version : 1.0 * * Notes : Requires a minimum 126 maximum 130 cpu clocks * * : * ***************************************************************************** } Public Function SHTcrcSF(pDataByte,pCRC As Byte) As Byte Dim BitNo As Byte Dim TestBit As Bit For BitNo = 0 To 7 TestBit = pCRC.7 Xor pDataByte.7 pDataByte = pDataByte << 1 If TestBit = 0 GoTo No_XOR pCRC = pCRC Xor $18 No_XOR: pCRC = pCRC << 1 pCRC.0 = TestBit Next Result = pCRC End Function { ***************************************************************************** * Name : Function SHTcrc8AL Sensirion CRC8 SF encapsulataed assembly * * Date : 12/31/2008 * * Version : 1.0 * * Notes : Requires a minimum 56 maximum 68 cpu clocks * * : * ***************************************************************************** } Public Function SHTcrcAL(pDataByte As D0,pCRC As D1) As Byte //D0 through D3 (or through D23 if needed) are system variables available //to assembly routines in subs or functions without concern for bank switching. //Include system.bas to access them. Dim BitNo As D2 Dim TempByte As D3 ASM MOVLW 8 MOVWF BitNo ;//Do this For all 8 bits of DataByte SHTCRCLOOP MOVF pCRC,0 ;//Put CRC into W XORWF pDataByte,0 ;//Xor CRC With TestByte MOVWF TempByte ;//Put results In TempByte RLCF TempByte,1 ;//Shift TempByte.7 into Carry Bit BTFSS STATUS,C ;//If Carry = 1, do polynomial Math GoTo SHTCRCSHIFT ;//Otherwise just Shift CRC And CRCByte MOVF pCRC,0 ;//Get latest copy of CRC XORLW 0x18 ;//Compliment feedback bits MOVWF pCRC ;//Keep a copy of results SHTCRCSHIFT RLCF pCRC,1 ;//Rotate CRC into carry RLCF pDataByte,1 ;//Rotate DataByte, carry shifts In but Not important DECFSZ BitNo,1 ;//Keep track of #times through loop GoTo SHTCRCLOOP ;//Go To Start If Not looped through the 8 bits End ASM Result = pCRC End Function { ***************************************************************************** * Name : Function DALcrc8SF Dallas/Maxim CRC8 SwordFish * * Date : 12/31/2008 * * Version : 1.0 * * Notes : Requires a minimum 126 maximum 130 cpu clocks * * : * ***************************************************************************** } Public Function DALcrc8SF(pDataByte,pCRC As Byte) As Byte Dim BitNo As Byte Dim TestBit As Bit For BitNo = 0 To 7 //Do for all 8 bits in data byte TestBit = pCRC.0 Xor pDataByte.0//XOR bit0 of data byte and crc pDataByte = pDataByte >> 1 //Position data byte for next bit test If TestBit = 0 GoTo DalShift //If test bit not set, just shift CRC pCRC = pCRC Xor $18 //If set, compliment feedback bits DalShift: //Shift right the CRC byte pCRC = pCRC >> 1 //CRC bit 0 to bit bucket pCRC.7 = TestBit //Test bit rotates into CRC bit 7 Next Result = pCRC End Function { ***************************************************************************** * Name : Function DALcrc8AL Dallas/Maxim CRC8 SF encapuslated assembly * * Date : 12/31/2008 * * Version : 1.0 * * Notes : Requires a minimum 56 maximum 68 cpu clocks * * : * ***************************************************************************** } Public Function DALcrc8AL(pDataByte As D0,pCRC As D1) As Byte Dim BitNo As D2 Dim TempByte As D3 ASM MOVLW 8 MOVWF BitNo ;//Do this For all 8 bits DALCRCLOOP MOVF pCRC,0 ;//Put CRC into W XORWF pDataByte,0 ;//Xor CRC With DataByte MOVWF TempByte ;//Put results in TempByte RRCF TempByte,1 ;//Shift TempByte.0 into Carry Bit BTFSS STATUS,C ;//If Carry = 1, account for feedback gates GoTo DALCRCSHIFT ;//Otherwise just shift CRC And TestByte MOVF pCRC,0 ;//Get latest copy of CRC XORLW 0x18 ;//Compliment feedback bits MOVWF pCRC ;//Keep a copy of results DALCRCSHIFT RRCF pCRC,1 ;//Rotate CRC incorporating carry RRCF pDataByte,1 ;//Rotate DataByte, carry shifts in but Not important DECFSZ BitNo,1 ;//Keep track of #times through loop GoTo DALCRCLOOP ;//Go To start If Not looped through the 8 bits End ASM Result = pCRC End Function { ***************************************************************************** * Name : Function DALcrc16SF Dallas/Maxim CRC16 Swordfish * * Date : 12/31/2008 * * Version : 1.0 * * Notes : Requires a minimum 133 maximum 201 cpu clocks * * : * ***************************************************************************** } Public Function DALcrc16SF(pDataByte As Byte,pCRC As Word) As Word Dim BitNo As Byte Dim TestBit As Bit For BitNo = 0 To 7 //do for all 8 bits in Data Byte TestBit = pDataByte.0 Xor pCRC.0 //XOR bit0 of Data Byte and Low CRC pDataByte = pDataByte >> 1 //position Data Byte for next bit test If TestBit = 0 GoTo Dal16Shift //if Test Bit not set, just shift CRC's pCRC.14 = pCRC.14 Xor 1 //if TestBit set, compliment bits 14 pCRC.1 = pCRC.1 Xor 1 //and 1 of CRC (feedback bits) Dal16Shift: pCRC = pCRC >> 1 //shift right the CRC word pCRC.15 = TestBit //replace bit 15 of CRC with TestBit Next Result = pCRC End Function { ***************************************************************************** * Name : Function DALcrc16AL Dallas/Maxim CRC16 SF encapsulated assembly* * Date : 12/31/2008 * * Version : 1.0 * * Notes : Requires a minimum 65 maximum 89 cpu clocks * * : * ***************************************************************************** } Public Function Access DALcrc16AL(pDataByte As Byte,pCRC As Word) As Word //couldn't use system variables here as pCRC needed to be passed as a word //hence use of Access instead Dim CRCLo As Byte Dim CRCHi As Byte Dim BitNo As Byte Dim TestByte As Byte CRCLo = pCRC.byte0 CRCHi = pCRC.byte1 ASM MOVLW 8 MOVWF BitNo ;//Do this For all 8 bits of CRCByte DAL16CRCLOOP MOVF CRCLo,0 ;//Put CRCLo into W XORWF pDataByte,0 ;//Xor CRCLo With CRCData MOVWF TestByte ;//Put results in TestByte RRCF TestByte,1 ;//Shift TestByte.0 into Carry Bit BTFSS STATUS,C ;//If Carry = 1, account For EXOR feedback gates GoTo DAL16CRCSHIFT ;//Otherwise just shift CRCs And CRCByte MOVF CRCHi,0 ;//Get latest copy of CRCHi XORLW 0x40 ;//Compliment CRCHi.6 MOVWF CRCHi ;//Keep a copy of results MOVF CRCLo,0 ;//Get latest copy of CRCL0 XORLW 0x02 ;//Compliment CRCLo.1 MOVWF CRCLo ;//Keep a copy of results DAL16CRCSHIFT RRCF CRCHi,1 ;//Rotate both CRCs As a Word, incorporate RRCF CRCLo,1 ;//c flag into CRCHi.7 RRCF pDataByte,1 ;//Shift remaining data bits right once DECFSZ BitNo,1 ;//Keep track of #times through loop GoTo DAL16CRCLOOP ;//Go To start If Not looped through the 8 bits End ASM Result.byte0 = CRCLo Result.byte1 = CRCHi End Function { ***************************************************************************** * Name : Function SMBcrc8SF SMBus CRC8 SwordFish * * Date : 12/31/2008 * * Version : 1.0 * * Notes : Requires a minimum 55 maximum 67 cpu clocks * * : * ***************************************************************************** } Public Function SMBcrc8SF(pDataByte As Byte,pCRC As Byte) As Byte Dim BitNo As Byte pDataByte = pDataByte Xor pCRC //xor new byte and old crc to get remainder + byte For BitNo = 0 To 7 //check all 8 bits If pDataByte.7 =1 Then //if bit 7 is a 1 pDataByte = pDataByte << 1 //shift it out pDataByte = pDataByte Xor $07 //then xor with the polynomial Else //if the bit is not a 1 pDataByte = pDataByte << 1 //just shift it out End If Next //check next bit Result = pDataByte End Function { ***************************************************************************** * Name : Function SMBcrc8AL Sensirion CRC8 SF encapuslated assembly * * Date : 1/7/2009 * * Version : 1.0 * * Notes : Requires a minimum 41 maximum 52 cpu clocks * * : * ***************************************************************************** } Public Function SMBcrc8AL(pDataByte As D0,pCRC As D1) As Byte Dim BitNo As D2 ASM MOVLW 8 MOVWF BitNo ;//Do this For all 8 bits MOVF pCRC,0 ;//CRC to W XORWF pDataByte,1 ;//Xor CRC With DataByte, result to DataByte SMBCRCLOOP BCF STATUS,0 ;//clear carry so zero will rotate in RLCF pDataByte,1 ;//rotate results to DataByte, Bit 7 is in carry BTFSS STATUS,0 ;//test bit 7 GoTo SMBCRCNOSHIFT ;//Otherwise just shift DataByte MOVF pDataByte,0 ;//get working copy XORLW 0x07 ;//Compliment feedback bits MOVWF pDataByte ;//Keep a copy of results SMBCRCNOSHIFT DECFSZ BitNo,1 ;//Keep track of #times through loop GoTo SMBCRCLOOP ;//Go To start If Not looped through the 8 bits End ASM Result = pDataByte End Function { ***************************************************************************** * Name : Function CCITTcrc16SF CCITT CRC16 Swordfish * * Date : 1/15/2009 * * Version : 1.0 * * Notes : Normally CRC is initialized to $FFFF * * : X.25, v.41, CDMA, Bluetooth, XMODEM, HDLC, PPP, IrDA, BACnet, * * : others? please add if you know * ***************************************************************************** } Public Function CCITTcrc16SF(pDataByte As Byte,pCRC As Word) As Word Dim TempWord As Word Dim Index As Byte TempWord = pDataByte << 8 pCRC = pCRC Xor TempWord For Index = 0 To 7 If pCRC.15 = 1 Then pCRC = (PCRC << 1) Xor $1021 Else pCRC = PCRC << 1 End If Next Result = pCRC End Function { ***************************************************************************** * Name : Function MODBUScrc16SF MODBUS CRC16 Swordfish * * Date : 1/15/2009 * * Version : 1.0 * * Notes : Normally CRC is initialized to $FFFF * * : * ***************************************************************************** } Public Function MODBUScrc16SF(pDataByte As Byte,pCRC As Word) As Word Dim TempWord As Word Dim Index As Byte TempWord = $00FF And pDataByte pCRC = pCRC Xor TempWord For Index = 0 To 7 If pCRC.0 = 1 Then pCRC = (pCRC >> 1) Xor $A001 Else pCRC = pCRC >> 1 End If Next Result = pCRC End Function { ***************************************************************************** * Name : Function CRC16SF CRC16 Swordfish * * Date : 1/15/2009 * * Version : 1.0 * * Notes : Normally CRC is initialized to $0 * * : IBM, SDLC, USB, others? please add if you know * ***************************************************************************** } Public Function CRC16SF(pDataByte As Byte,pCRC As Word) As Word Dim TempWord As Word Dim Index As Byte TempWord = $00FF And pDataByte pCRC = pCRC Xor TempWord For Index = 0 To 7 If pCRC.0 = 1 Then pCRC = (pCRC >> 1) Xor $A001 Else pCRC = pCRC >> 1 End If Next Result = pCRC End Function