STM32F7 CRC unit: is behavior of bit reversal settings on 16- and 8-bit data sizes intentional?
If LL_CRC_INDATA_REVERSE_WORD is set and 8-bit data is provided via LL_CRC_FeedData8(), the resulting CRC is not what is expected. It appears the combination of word-reversal and byte-submission mangles the submitted data in some way, when I had expected it to fall back to byte reversal.
The datasheet does not indicate this is a concern, and the HAL code freely mixes word, half-word, and byte sizes, giving results that do not match third party calculators when dealing with data that isn't a multiple of 4 bytes in length. For example, these three all give correct results (22C644CD):
uint8_t data8[8] = {0x1F, 0x52, 0x41, 0x9C, 0xB6, 0xAF, 0, 0};
uint16_t * data16 = (uint16_t *)data8;
uint32_t * data32 = (uint32_t *)data8;
LL_CRC_SetInputDataReverseMode(CRC, LL_CRC_INDATA_REVERSE_BYTE);
LL_CRC_ResetCRCCalculationUnit(CRC);
LL_CRC_FeedData8(CRC, data8[0]);
LL_CRC_FeedData8(CRC, data8[1]);
LL_CRC_FeedData8(CRC, data8[2]);
LL_CRC_FeedData8(CRC, data8[3]);
LL_CRC_FeedData8(CRC, data8[4]);
LL_CRC_FeedData8(CRC, data8[5]);
crc = ~LL_CRC_ReadData32(CRC);
printf("rev by byte: %08lX\n", crc);
LL_CRC_ResetCRCCalculationUnit(CRC);
LL_CRC_SetInputDataReverseMode(CRC, LL_CRC_INDATA_REVERSE_WORD);
LL_CRC_FeedData32(CRC, data32[0]);
LL_CRC_SetInputDataReverseMode(CRC, LL_CRC_INDATA_REVERSE_HALFWORD);
LL_CRC_FeedData16(CRC, data16[2]);
crc = ~LL_CRC_ReadData32(CRC);
printf("rev by word/halfword: %08lX\n", crc);
LL_CRC_ResetCRCCalculationUnit(CRC);
LL_CRC_SetInputDataReverseMode(CRC, LL_CRC_INDATA_REVERSE_WORD);
LL_CRC_FeedData32(CRC, data32[0]);
LL_CRC_SetInputDataReverseMode(CRC, LL_CRC_INDATA_REVERSE_BYTE);
LL_CRC_FeedData8(CRC, data8[4]);
LL_CRC_FeedData8(CRC, data8[5]);
crc = ~LL_CRC_ReadData32(CRC);
printf("rev by word/byte: %08lX\n", crc);
The HAL code does the equivalent of this, which gives incorrect results (B1C2A1A3):
LL_CRC_ResetCRCCalculationUnit(CRC);
LL_CRC_SetInputDataReverseMode(CRC, LL_CRC_INDATA_REVERSE_WORD);
LL_CRC_FeedData32(CRC, data32[0]);
LL_CRC_FeedData8(CRC, data8[4]);
LL_CRC_FeedData8(CRC, data8[5]);
crc = ~LL_CRC_ReadData32(CRC);
printf("rev by word: %08lX\n", crc);
LL_CRC_INDATA_REVERSE_NONE only gives the correct results if the bytes are reversed before sending to the CRC hardware. The HAL code appears to be quite broken when handling bytes: CRC_Handle_8()'s byte ordering requires bit reversal on input, but its mixing of data sizes without changing the reversal settings requires unreversed input.
