2022-06-08 03:08 PM
Ok, well I'm going to answer my own question, Yes.
This stems from an earlier conversation about doing CRC15 or CRC-15-CAN, where I had postulated that it probably could, and I then subsequently proof-of-concepted that idea, and then started pondering other uses.
The hardware implementation provides for 7, 8, 16 and 32-bit modes of operation, but for byte-wise and left-shifting, we can use the high-order portion of the register to carry the residual and apply the polynomial. We have to shift the initial values and polynomial in to the left most portion of the selected word size, and the right most, least significant side is zero'd, and finally when you recover the computed value, realign that into the expected bit width. For checking a CRC, you typically run the value through itself, and it drops to zero, as it perfectly divides into the polynomial.
CRC-24Q (Qualcomm) polynomial typically quoted as 0x864CFB or 0x1864CFB
x^24+ x^23+ x^18+ x^17+ x^14+ x^11+ x^10+ x^7+ x^6+ x^5+ x^4+ x^3+ x+1
//******************************************************************************
// Copyright (C) 2022 Clive Turvey (aka Tesla DeLorean, sourcer32@gmail.com)
// All Rights Reserved
void Crc24Test(void) // sourcer32@gmail.com
{
uint8_t test1[] = { 0x01,0x02,0x03,0x04,0x05,0x06 }; // 0xBC7E06
uint8_t test2[] = { 0x11,0x22,0x33,0x44,0x55,0x66 }; // 0xD686A9
uint8_t rtcm3testpattern[] = // Packet of known veracity
{ 0xD3,0x00,0x13,0x3E,0xD7,0xD3,0x02,0x02,0x98,0x0E,0xDE,
0xEF,0x34,0xB4,0xBD,0x62,0xAC,0x09,0x41,0x98,0x6F,0x33,
0x36,0x0B,0x98 }; // Should be zero when pulled thru polynomial
/* CRC handler declaration */
CRC_HandleTypeDef CrcHandle = {0};
/* CRC Peripheral clock enable */
__HAL_RCC_CRC_CLK_ENABLE();
/*##-1- Configure the CRC peripheral #######################################*/
CrcHandle.Instance = CRC;
/* The default polynomial is not used. It is required to defined it in CrcHandle.Init.GeneratingPolynomial*/
CrcHandle.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE;
/* Set the value of the polynomial */
CrcHandle.Init.GeneratingPolynomial = (0x864CFB << 8); // 24-bit CRC24Q used for SBAS and RTCM3
/* The user-defined generating polynomial generates a 32-bit long CRC */
CrcHandle.Init.CRCLength = CRC_POLYLENGTH_32B; // Actually 24-bit we use the high order bits
/* The default init value is not used, want zero */
CrcHandle.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE;
/* The used-defined initialization value */
CrcHandle.Init.InitValue = 0;
/* The input data are not inverted */
CrcHandle.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
/* The output data are not inverted */
CrcHandle.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
/* The input data are 8-bit long, ie digested byte-wise */
CrcHandle.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
if (HAL_CRC_Init(&CrcHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler(__FILE__, __LINE__);
}
printf("CRC24Q %06X TEST1 BC7E06?\n", HAL_CRC_Calculate(&CrcHandle, (uint32_t *)test1, sizeof(test1)) >> 8); // Get high-order 24-bit computation
printf("CRC24Q %06X TEST2 D686A9?\n", HAL_CRC_Calculate(&CrcHandle, (uint32_t *)test2, sizeof(test2)) >> 8); // Get high-order 24-bit computation
printf("CRC24Q %08X RTCM3 CHECK Zero?\n", HAL_CRC_Calculate(&CrcHandle, (uint32_t *)rtcm3testpattern, sizeof(rtcm3testpattern)));
printf("CRC24Q %06X RTCM3 COMPUTE 360B98?\n", HAL_CRC_Calculate(&CrcHandle, (uint32_t *)rtcm3testpattern, sizeof(rtcm3testpattern) - 3) >> 8);
}
//******************************************************************************
CRC24Q BC7E06 TEST1 BC7E06?
CRC24Q D686A9 TEST2 D686A9?
CRC24Q 00000000 RTCM3 CHECK Zero?
CRC24Q 360B98 RTCM3 COMPUTE 360B98?
https://github.com/cturvey/RandomNinjaChef/blob/main/RTCM3Test.c
2024-10-11 01:32 PM
Related https://community.st.com/t5/stm32-mcus-products/problem-w-setting-polynomial-for-crc/td-p/730403