2017-01-12 12:10 PM
This CRC is used by an I2C peripheral and documented at
Can this CRC be duplicated using the CRC IP on the STM32F7? The HAL library defaults to X^4 + X^2 + X^1 and I seem unable to change that (and it states that the exponents must be less than 8.) I tried substituting the code for the polynomial above (0x131) and the HAL initialization code rejected it.
Is this a shortcoming of the library or a limit of the H/W?
Code to init the CRC produced by Cube is:
/* CRC init function */
static void MX_CRC_Init(void){hcrc.Instance = CRC;
hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE; hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE; hcrc.Init.GeneratingPolynomial = 0x7; hcrc.Init.CRCLength = CRC_POLYLENGTH_8B; hcrc.Init.InitValue = 65535; hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; if (HAL_CRC_Init(&hcrc) != HAL_OK) { Error_Handler(); }}
(Hmmm not sure I've got this code formatting thing right.)
(Hmmm.2 - two CRC posts in one day!)
#crcSolved! Go to Solution.
2017-01-12 12:15 PM
Would be 0x31, the high order bit is inferred. Initial value is zero.
2017-01-12 12:15 PM
Would be 0x31, the high order bit is inferred. Initial value is zero.
2017-01-12 01:29 PM
Yes, that works - Thanks!
Cube accepts X5+X4+X0 as the polynomial and it generates the desired result.
I should add that the other thing I needed to change was the initial value to 0xFF in the model code. I don't know if it was done differently with a different devide (I'm working with a different Sensiron sensor) or if it was an oversight in the example code, but that was necessary to get the correct results for the data read from the Sensiron humidity/temperature sensor. (Or perhaps it was misapplication of the code.) I made a similar change in the CRC IP configuration.
thanks,
hank
2017-01-12 01:43 PM
//****************************************************************************
// CRC x8 + x5 + x4 + 1 Sensirion
// http://www.sensirion.co.jp/fileadmin/user_upload/customers/sensirion/Dokumente/GasFlow/Sensirion_Gas_Flow_SFM3000_CRC_Checksum.pdf
// Implementation Copyright (C) 2017 sourcer32@gmail.com All Rights Reserved
//****************************************************************************
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char uint8_t;
#define POLY 0x31 // Polynomial x8 + x5 + x4 + 1, left shifting
//****************************************************************************
uint8_t Slow_CRC_Cal8Bits(uint8_t crc, size_t Size, uint8_t *Buffer)
{
int i;
while(Size--)
{
crc = crc ^ *Buffer++;
for(i=0; i<8; i++)
{
if (crc & 0x80)
crc = (crc << 1) ^ POLY;
else
crc = (crc << 1);
}
}
return(crc);
}
//****************************************************************************
uint8_t Quick_CRC_Cal8Bits(uint8_t crc, size_t Size, uint8_t *Buffer)
{
static const uint8_t CrcTable[] = { // Sensirion 8-bit CRC x8+x5+x4+1
0x00,0x31,0x62,0x53,0xC4,0xF5,0xA6,0x97, // 0x31 nibble table - sourcer32@gmail.com
0xB9,0x88,0xDB,0xEA,0x7D,0x4C,0x1F,0x2E };
while(Size--)
{
crc = crc ^ *Buffer++; // Apply data byte
crc = (crc << 4) ^ CrcTable[(crc >> 4) & 0xF]; // Apply CRC 4-bit at a time, 2 rounds
crc = (crc << 4) ^ CrcTable[(crc >> 4) & 0xF];
}
return(crc);
}
//****************************************************************************
uint8_t Fast_CRC_Cal8Bits(uint8_t crc, size_t Size, uint8_t *Buffer)
{
static const uint8_t CrcTable[] = { // Sensirion 8-bit CRC x8+x5+x4+1
0x00,0x31,0x62,0x53,0xC4,0xF5,0xA6,0x97, // 0x31 byte table - sourcer32@gmail.com
0xB9,0x88,0xDB,0xEA,0x7D,0x4C,0x1F,0x2E,
0x43,0x72,0x21,0x10,0x87,0xB6,0xE5,0xD4,
0xFA,0xCB,0x98,0xA9,0x3E,0x0F,0x5C,0x6D,
0x86,0xB7,0xE4,0xD5,0x42,0x73,0x20,0x11,
0x3F,0x0E,0x5D,0x6C,0xFB,0xCA,0x99,0xA8,
0xC5,0xF4,0xA7,0x96,0x01,0x30,0x63,0x52,
0x7C,0x4D,0x1E,0x2F,0xB8,0x89,0xDA,0xEB,
0x3D,0x0C,0x5F,0x6E,0xF9,0xC8,0x9B,0xAA,
0x84,0xB5,0xE6,0xD7,0x40,0x71,0x22,0x13,
0x7E,0x4F,0x1C,0x2D,0xBA,0x8B,0xD8,0xE9,
0xC7,0xF6,0xA5,0x94,0x03,0x32,0x61,0x50,
0xBB,0x8A,0xD9,0xE8,0x7F,0x4E,0x1D,0x2C,
0x02,0x33,0x60,0x51,0xC6,0xF7,0xA4,0x95,
0xF8,0xC9,0x9A,0xAB,0x3C,0x0D,0x5E,0x6F,
0x41,0x70,0x23,0x12,0x85,0xB4,0xE7,0xD6,
0x7A,0x4B,0x18,0x29,0xBE,0x8F,0xDC,0xED,
0xC3,0xF2,0xA1,0x90,0x07,0x36,0x65,0x54,
0x39,0x08,0x5B,0x6A,0xFD,0xCC,0x9F,0xAE,
0x80,0xB1,0xE2,0xD3,0x44,0x75,0x26,0x17,
0xFC,0xCD,0x9E,0xAF,0x38,0x09,0x5A,0x6B,
0x45,0x74,0x27,0x16,0x81,0xB0,0xE3,0xD2,
0xBF,0x8E,0xDD,0xEC,0x7B,0x4A,0x19,0x28,
0x06,0x37,0x64,0x55,0xC2,0xF3,0xA0,0x91,
0x47,0x76,0x25,0x14,0x83,0xB2,0xE1,0xD0,
0xFE,0xCF,0x9C,0xAD,0x3A,0x0B,0x58,0x69,
0x04,0x35,0x66,0x57,0xC0,0xF1,0xA2,0x93,
0xBD,0x8C,0xDF,0xEE,0x79,0x48,0x1B,0x2A,
0xC1,0xF0,0xA3,0x92,0x05,0x34,0x67,0x56,
0x78,0x49,0x1A,0x2B,0xBC,0x8D,0xDE,0xEF,
0x82,0xB3,0xE0,0xD1,0x46,0x77,0x24,0x15,
0x3B,0x0A,0x59,0x68,0xFF,0xCE,0x9D,0xAC };
while(Size--)
{
crc = crc ^ *Buffer++; // Apply data byte
crc = CrcTable[crc & 0xFF]; // Apply CRC 8-bits at a time
}
return(crc);
}
//****************************************************************************
int main(int argc, char **argv)
{
uint8_t crc;
uint8_t test[2] = { 0x87,0x01 }; // 0xBC
printf('crc=%02X Slow
', Slow_CRC_Cal8Bits(0x00, sizeof(test), test));
printf('crc=%02X Quick
', Quick_CRC_Cal8Bits(0x00, sizeof(test), test));
printf('crc=%02X Fast
', Fast_CRC_Cal8Bits(0x00, sizeof(test), test));
return(1);
}
//****************************************************************************
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?