cancel
Showing results for 
Search instead for 
Did you mean: 

Can the STM32 CRC Peripheral be abused into doing CRC-24Q ? Or other 24-bit CRC? Or shortened bit width CRC?

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.

https://community.st.com/s/question/0D53W00001bIU55SAG/can-the-stm32-crc-peripheral-be-made-to-work-with-the-crc15can-polynomial

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
2 REPLIES 2

Related  https://community.st.com/t5/stm32-mcus-products/problem-w-setting-polynomial-for-crc/td-p/730403

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

4-bit, right shifting, x^4 + x^3 + 1

https://github.com/cturvey/RandomNinjaChef/blob/main/STM32_CRC4_9R.c

32-bit, right shifting, x^32 + x^30 + x^29 + x^28 + x^26 + x^20 + x^19 + x^17 + x^16 + x^15 + x^11 + x^10 + x^7 + x^6 + x^4 + x^2 + x^1 + 1

https://github.com/cturvey/RandomNinjaChef/blob/main/STM32_CRC32K.c

24-bit, left shifting, 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

https://github.com/cturvey/RandomNinjaChef/blob/main/STM32_CRC24Q.c

17-bit, left-shifting, x^17 + x^16 + x^14 + x^13 + x^11 + x^6 + x^4 + x^3 + x^1 + 1

https://github.com/cturvey/RandomNinjaChef/blob/main/STM32_CRC17CAN.c

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..