Столкнулся с некорректной реализацией подсчета CRC в stm32l0xx_hal_crc.c
Пришлось копнуть поглубже. Кому интересно моё решение, спрашивайте, напишу подробнее.
Вот что в итоге получилось для CRC16 с полиномом 0xA001 (для CRC32 придется слегка подправить):
#include <stdint.h>
#include "stm32l0xx.h"
#include "core_cm0plus.h"
#include "stm32l0xx_hal.h"
extern CRC_HandleTypeDef hcrc;
void MB_CRC_Init(void)
{
hcrc.Instance = CRC;
hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE;
hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE;
hcrc.Init.GeneratingPolynomial = 0x8005;
hcrc.Init.CRCLength = CRC_POLYLENGTH_16B;
hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_WORD;
hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLED;
hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
HAL_CRC_Init(&hcrc);
}
uint16_t usMBCRC16(uint8_t* pBuffer, uint32_t size)
{
hcrc.Instance->CR |= CRC_CR_RESET;
while (size > 3)
{
*(uint32_t volatile*) (&hcrc.Instance->DR) = *(uint32_t*)pBuffer;
pBuffer += 4;
size -= 4;
}
if (size != 0)
{
if (size == 1)
{
*(uint8_t volatile*) (&hcrc.Instance->DR) = *pBuffer;
}
else if (size == 2)
{
*(uint16_t volatile*) (&hcrc.Instance->DR) = *(uint16_t*)pBuffer;
}
else if (size == 3)
{
*(uint16_t volatile*) (&hcrc.Instance->DR) = *(uint16_t*)pBuffer;
pBuffer += 2;
*(uint8_t volatile*) (&hcrc.Instance->DR) = *pBuffer;
}
}
return (*(uint16_t volatile*) (&hcrc.Instance->DR));
}