cstm32crc32stm32l152

How to calulate CRC of 1 byte using stm32l1 CRC unit


I'm trying to calculate the CRC of a one byte data input using the CRC calculation unit of the stm32l152.
The CRC unit accepts only 32Bit inputs. I was able to get it calculate the CRC for a 32Bit data input, but now I'm struggling to get it to work for a byte data input.

My test input data is 0x20 and I expect as output 0xD62B0954
CRC parameter: polynom 0x04C11DB7, init-val: 0xFFFFFFFF

How can I solve this, I'm running out of ideas?

Sample code for the 32 bit data:

CRC->DR = u32Input`  
u32Crc = CRC->DR;

I've also found this code snippet, to calculate the CRC byte-wise, but the output is different.

static uint32_t crc32_step(uint32_t crc, uint8_t data)
{
    crc = ~crc ^ data;
    CRC->DR = (~CRC->DR) ^ __RBIT(~(crc << 24));
    return (crc >> 8) ^ ~__RBIT(CRC->DR);
}

I get the following output using the code above with a provided crc of 0xFFFFFFFF: 0xC491DF37

I don't really understand what the crc32_step function does, but I'm not even sure if this is the right direction to go. I would greatly appreciate any hints or ideas.


Solution

  • The CRC being calculated appears to be a CRC-32/MPEG2. Here is some simple code in C to calculate it:

    #include <stddef.h>
    #include <stdint.h>
    
    uint32_t crc32mpeg2(uint32_t crc, void const *mem, size_t len) {
        unsigned char const *data = mem;
        if (data == NULL)
            return 0xffffffff;
        while (len--) {
            crc ^= (uint32_t)(*data++) << 24;
            for (unsigned k = 0; k < 8; k++)
                crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
        }
        return crc;
    }
    

    The routine is called with NULL for mem to get the initial CRC value. So it would be used like this:

    #include <stdio.h>
    
    int main(void) {
        unsigned char data[1] = { 0x20 };
        uint32_t crc = crc32mpeg2(0, NULL, 0);
        crc = crc32mpeg2(crc, data, 1);
        printf("%08x\n", crc);
        return 0;
    }
    

    The output is:

    d62b0954