cancel
Showing results for 
Search instead for 
Did you mean: 

Is CRC-7 X7+X3+X0 supported by STM32L4R9

Kevlar700
Associate III

I shall just write a function in software but I would be interested to know if it is supported or not by the CRC peripheral hardware.

STM32 cube MX configurator does not allow you to choose X7 for the 7bit (8 term) polynomial described on page 21 of this datasheet?

It is also prevented by a length check on line 111 of stm32l4xx_hal_crc_ex.c

(case CRC_POLYLENGTH_7B)

"https://www.sciosense.com/wp-content/uploads/documents/SC-000897-DS-7-ENS210-Datasheet.pdf"

Thank You

5 REPLIES 5

Should support 7, 8, 16, 32-bits with proper incantations.

Demonstrably capable of 5 and 24-bit CRC with ingenuity. Depends a lot on how the data presents, and methods likely applicable for 3 thru 31-bit.

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

The 17-bit data pattern probably not helpful in this context

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

Yes, should work with HW, will need some clever initialization

/*
https://www.sciosense.com/wp-content/uploads/documents/SC-000897-DS-7-ENS210-Datasheet.pdf
*/
 
//                     7654 3211
// Polynomial       0b 1000 1001 ~ x^7+x^3+x^0
//                  0x 8    9
 
#define CRC7WIDTH   7     // 7 bits CRC has polynomial of 7th order (has 8 terms)
#define CRC7POLY    0x89  // The 8 coefficients of the polynomial
#define CRC7IVEC    0x7F  // Initial vector has all 7 bits high
#define CRC7MASK    ((1UL<<CRC7WIDTH)-1)
 
// Payload data
#define DATA7WIDTH  17
#define DATA7MASK   ((1UL<<DATA7WIDTH)-1) // 0b 1 1111 1111 1111 1111
#define DATA7MSB    (1UL<<(DATA7WIDTH-1)) // 0b 1 0000 0000 0000 0000
 
// Compute the CRC-7 of ‘val’ (should only have 17 bits)
uint32_t crc7(uint32_t val)
{
  // Setup polynomial
  uint32_t pol = CRC7POLY;
 
  // Loop variable (indicates which bit to test, start with highest)
  uint32_t bit = DATA7MSB;
 
  // Align polynomial with data
  pol = pol << (DATA7WIDTH-CRC7WIDTH-1);
 
  // Make room for CRC value
  val = val << CRC7WIDTH;
  bit = bit << CRC7WIDTH;
  pol = pol << CRC7WIDTH;
 
  // Insert initial vector
  val |= CRC7IVEC;
 
  // Apply division until all bits done
  while(bit & (DATA7MASK << CRC7WIDTH))
  {
    if (bit & val) val ^= pol;
 
    bit >>= 1;
    pol >>= 1;
  }
 
  return(val);
}

Simplified

uint32_t crc7_test(uint32_t data) // ENS210 - sourcer32@gmail.com
{
  int i;
  uint32_t crc = ((data & 0x1FFFF) << 7) + 0x7F; // awkward initialization
 
  for(i=0; i<17; i++)
  {
    if (crc & 0x800000) // 24-bit aligned
      crc = (crc << 1) ^ (0x89 << 17); // align polynomial 24-7
    else
      crc <<= 1;
  }
 
  crc = (crc >> 17) & 0x7F; // shouldn't need masking
 
  return(crc);
}

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

Mechanics for 32-bit implementation, ingesting 17-bit as singular word

uint32_t crc7_test32(uint32_t data) // ENS210 - EMU32HW - sourcer32@gmail.com
{
  int i = 32;// width of crc
  uint32_t init = 0x00000000; // yes, zero
  uint32_t poly = (0x89 << (32 - 7)); // left align 32-bit
  uint32_t crc;
 
  data = (data & 0x1FFFF); // mask data word, or only 17-bits, right aligned
 
  crc = data ^ init; // apply
 
  while(i--)
  {
    if (crc & 0x80000000) // high order 32-bit
      crc = (crc << 1) ^ poly;
    else
      crc <<= 1; // left shifting
  }
 
  crc = ((crc >> (32 - 7)) ^ 0x7F); // align, masked by left constraints, invert
 
  return(crc);
} // sourcer32@gmail.com

Could probably make the 7-bit HW work too, Initialize at ZERO, and INVERT output

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

Quick Parallel Version 7-bit CRC of 17-bit word

//******************************************************************************
 
uint32_t crc7_quick(uint32_t data) // CRC-7 ENS210 - sourcer32@gmail.com
{
  static const uint32_t crctbl5[] = { // Polynomial 0x89 x^7+x^3+x^0
    0x00000000,0x12000000,0x24000000,0x36000000,0x48000000,0x5A000000,// 0x00
    0x6C000000,0x7E000000,0x90000000,0x82000000,0xB4000000,0xA6000000,// 0x05
    0xD8000000,0xCA000000,0xFC000000,0xEE000000,0x32000000,0x20000000,// 0x0B
    0x16000000,0x04000000,0x7A000000,0x68000000,0x5E000000,0x4C000000,// 0x11
    0xA2000000,0xB0000000,0x86000000,0x94000000,0xEA000000,0xF8000000,// 0x17
    0xCE000000,0xDC000000 };
 
  uint32_t crc = data << (32 - 17); // left aligned
 
  // 17 vis 3 rounds of 5 (15), 1 round of 2
 
  crc = (crc << 5) ^ crctbl5[crc >> (32 - 5)];
  crc = (crc << 5) ^ crctbl5[crc >> (32 - 5)];
  crc = (crc << 5) ^ crctbl5[crc >> (32 - 5)];
 
  crc = (crc << 2) ^ crctbl5[crc >> (32 - 2)];
 
  return(~crc >> (32 - 7)); // inverted, left aligned, 7-bit
} // sourcer32@gmail.com
 
//******************************************************************************

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