LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

CRC-16 Calculation from C code

Solved!
Go to solution

Hello,

I am unable to recreate a CRC vi to calculate the checksum. The procedure mentions calculation as follows:-

The polynomial is 0x8005. The initial register value should be 0x0000. After the last bit of the
Count and packet has been transmitted, the internal CRC Register should have a value that matches that in the
block. The first Checksum byte transmitted (N-2) is the most-significant byte of the CRC value, and the last byte
of the block is the least-significant byte of the CRC.

I used the attached VI and configured as mentioned. The results are wrong:-

Some of the correct results are below:

Input: 0702000000 | CRC:1E2D

Input: 0730000000 | CRC:035D

 

Also available C Code:

/** \This function calculates a 16-bit CRC.
* \param[in] count number of bytes in data buffer
* \param[in] data pointer to data
* \param[out] crc pointer to calculated CRC (high byte at crc[0])
*/
void CalculateCrc(uint8_t length, uint8_t *data, uint8_t *crc)
{
uint8_t counter;
uint8_t crcLow = 0, crcHigh = 0, crcCarry;
uint8_t polyLow = 0x05, polyHigh = 0x80;
uint8_t shiftRegister;
uint8_t dataBit, crcBit;
for (counter = 0; counter < length; counter++) {
for (shiftRegister = 0x80; shiftRegister > 0x00; shiftRegister >>= 1) {
dataBit = (data[counter] & shiftRegister) ? 1 : 0;
crcBit = crcHigh >> 7;
// Shift CRC to the left by 1.
crcCarry = crcLow >> 7;
crcLow <<= 1;
crcHigh <<= 1;
crcHigh |= crcCarry;
if ((dataBit ^ crcBit) != 0) {
crcLow ^= polyLow;
crcHigh ^= polyHigh;
}
}
}
crc[0] = crcHigh;
crc[1] = crcLow;
}

0 Kudos
Message 1 of 4
(10,117 Views)
Solution
Accepted by dipu2689

I'm even questioning the C code you gave us.  Based on what I am finding, that shouldn't work either based on your supplied CRC examples.  Anyways, here is a working setup.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 2 of 4
(10,065 Views)

Thanks crossrulz.

 

This works perfectly!

The code is taken directly from the Atmel Crypto IC datasheet

http://www.atmel.com/Images/Atmel-8760-CryptoAuth-ATAES132-Datasheet.pdf

I lost 2 whole days trying to create a vi from the code. 

 

Thanks again!

 

 

0 Kudos
Message 3 of 4
(10,034 Views)

@dipu2689 wrote:

The code is taken directly from the Atmel Crypto IC datasheet


Yep, that C code would not work with your example data.  It worked exactly as I would expect with the sample data in the Atmel datasheet.

 

So you just learned something important about CRCs: There are a TON of variations.  You cannot just say "16-bit with this polynomial".  Just in my "standard" CRC library (a VI for 8, 16, and 32 bit each), I have parameters for the polynomial, Starting CRC, Final XOR (common for inverting the final CRC), and 2 for which direction to shift the CRC and the data bits.  And then there are some that do not follow that format and have an XOR with the data and CRC before the bit shifting even starts (like the VI you initially attached).


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 4 of 4
(10,018 Views)