CRC’s are normally 2 or 4 bytes, whereas a Checksum is a single byte that is computed by adding together the value of each character in a buffer. The high 8 bits are thrown away leaving an 8 byte checksum.
Instead of simply adding the values together, some implementations Exclusive OR the values, which offers slightly better error correction.
The following function can be used to compute a Checksum and with a slight modification, an XOR Checksum. This example uses a CSTRING as the source of data since it is assumed you will be working with data received from the Serial Port.
Prototype:
GetChecksum(*CSTRING),BYTE
Procedure:
GetChecksum FUNCTION(RStr)
Cnt SHORT
StrLen SHORT
Tally SHORT
ChkSum BYTE
CODE
Tally = 0
StrLen = Len(Clip(RStr))
! Tally up the Checksum
! Comment Out or Remove the Line inside
! the Loop that you do not need.
Loop Cnt = 1 to StrLen
! Compute a Regular Checksum
Tally += Val(RStr[Cnt])
! Compute an Exclusive OR Checksum
Tally = BXOR(Val(RStr[Cnt]),Tally)
End
ChkSum = Tally ! Checksum = lower 8 bits
Return(ChkSum) CLACom’s 16 bit CRC function utilizes the CRC-CCITT calculation (also known as the “Xmodem CRC”). This is the function that is used to calculate a CRC for the Xmodem and Ymodem File transfers in CLACom. The Polynomial is:
x16 + x12 + x5 + 1
If your application requires the CRC-16 calculation that uses a Polynomial of:
x16 + x15 + x2 + 1
a file containing the Clarion code that calculates this CRC is available in the Private Download area for CLACom (the same place where you download the latest updates from).
If your application does use the CRC-CCITT Polynomial and GetCrc16() seems to be returning the wrong value, you may need to reverse the Bytes in the return value from GetCRC16(). There is no standard as to how the 2 bytes of the CRC are sent (or received). Some implementations send the Low order Byte first and some send the High order Byte first.
For the string 'TEXT', GetCRC16() returns 54512 or D4F0 hex. Reverse the Bytes and you have F0D4 hex or 61652.
Example Code to reverse the Bytes.
CRC16 USHORT CRCVal USHORT CRCStr CSTRING(256)
CRCStr = 'TEST'
CRC16 = GetCRC16(CRCStr, 4)
! Reverse the Bytes
CRCVal = BSHIFT(CRC16, 8) + BSHIFT(CRC16,-8)
If you need access to the individual Bytes then use a GROUP as shown below.
CRCGRP GROUP
LoByte BYTE
HiByte BYTE
END
CRC16 USHORT,OVER(CRCGRP) CRCVal USHORT CRCStr CSTRING(256)
CRCStr = 'TEST'
CRC16 = GetCRC16(CRCStr, 4)
! To reverse the bytes using the above GROUP
CRCVal = BSHIFT(CRCGRP.LoByte,8) + CRCGRP.HiByte
