CRCModule
SwordfishUser.CRCModule History
Hide minor edits - Show changes to output
Changed line 11 from:
* Version : 1.0 *
to:
* Version : 1.1 *
Changed lines 15-17 from:
Dallas/Maxim CRC8 & CRC16, Sensirion8, and SMBus8
to:
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.
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.
Added lines 45-50:
************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.
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.
Changed lines 63-64 from:
#if isoption(LUTable) And Not (LUTable in (None, DAL8, DAL16, SMB8))
#error LUTable, "Invalid Option, LUTable must be None DAL8 DAL16or SMB8"
#error LUTable, "Invalid Option, LUTable must be None DAL8 DAL16
to:
#if isoption(LUTable) And Not (LUTable in (None, DAL8, DAL16, SMB8, SHT8))
#error LUTable, "Invalid Option, LUTable must be None DAL8 DAL16 SHT8 SMB8"
#error LUTable, "Invalid Option, LUTable must be None DAL8 DAL16 SHT8 SMB8"
Changed lines 190-191 from:
#endif
to:
#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)
Changed lines 211-212 from:
* Name : Function SHTcrcSF Sensirion CRC8 SwordFish *
* Date : 12/31/2008 *
*
to:
* Name : Function SHTcrc8LU Sensirion CRC8 SF look up table *
* Date : 1/7/2009 *
* Date : 1/7/2009 *
Changed lines 214-215 from:
* Notes : Requires a minimum 126 maximum 130 cpu clocks *
* : *
*
to:
* Notes : Requires 13 cpu clocks *
* : Requires the 256 byte table SHT8Table be in program memory *
* : Requires the 256 byte table SHT8Table be in program memory *
Added lines 218-233:
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 *
* : *
*****************************************************************************
}
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 *
* : *
*****************************************************************************
}
Changed line 251 from:
* Name : Function SHTcrcAL Sensirion CRC8 SF encapsulataed assembly *
to:
* Name : Function SHTcrc8AL Sensirion CRC8 SF encapsulataed assembly *
Changed line 325 from:
MOVWF BitNo ;//Do this For all 8 bits of CRCByte
to:
MOVWF BitNo ;//Do this For all 8 bits
Added lines 437-542:
{
*****************************************************************************
* 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
Added lines 1-388:
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.
=code [=
{
*****************************************************************************
* Name : CRC.BAS Swordfish MODULE *
* Author : Thomas D. Estes *
* Date : 12/31/2008 *
* Version : 1.0 *
* Notes : What in the world am I doing working on crc routines on *
* : New Years eve? Get a life Tom! *
*****************************************************************************
This module provides CRC calculations for various crc schemes including
Dallas/Maxim CRC8 & CRC16, Sensirion8, and SMBus8.
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.
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))
#error LUTable, "Invalid Option, LUTable must be None DAL8 DAL16 or 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
#endif
{
*****************************************************************************
* Name : Function SHTcrcSF 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 SHTcrcAL 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 of CRCByte
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
=]
Instructions for use provided in the module comments. Note the #option required when using the table versions of the code.
=code [=
{
*****************************************************************************
* Name : CRC.BAS Swordfish MODULE *
* Author : Thomas D. Estes *
* Date : 12/31/2008 *
* Version : 1.0 *
* Notes : What in the world am I doing working on crc routines on *
* : New Years eve? Get a life Tom! *
*****************************************************************************
This module provides CRC calculations for various crc schemes including
Dallas/Maxim CRC8 & CRC16, Sensirion8, and SMBus8.
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.
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))
#error LUTable, "Invalid Option, LUTable must be None DAL8 DAL16 or 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
#endif
{
*****************************************************************************
* Name : Function SHTcrcSF 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 SHTcrcAL 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 of CRCByte
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
=]