Comment configurer STM32 pour générer un CRC32 standard

J’essaie de générer le CRC avec le module matériel STM32L4. Je voudrais valider les fichiers fatfs, donc j’ai essentiellement des tableaux d’octets. J’utilise ce générateur de CRC.

Malheureusement, je n’arrive pas à comprendre comment configurer STM32L4 pour générer le même résultat. J’ai besoin de CRC32 et j’ai

configuration:

hcrc.Instance = CRC; /* The default polynomial is not used. It is required to defined it in CrcHandle.Init.GeneratingPolynomial*/ hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE; /* Set the value of the polynomial */ hcrc.Init.GeneratingPolynomial = 0x4C11DB7; //hcrc.Init.GeneratingPolynomial = 0xFB3EE248; hcrc.Init.CRCLength= CRC_POLYLENGTH_32B; /* The default init value is used */ /* The default init value is not used */ hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; /* User init value is used instead */ //hcrc.Init.InitValue = 0; hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; //hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE; /* The input data are inverted by word */ //hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_WORD; //hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE; hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; HAL_CRC_Init(&hcrc); 

essai:

 uint8_t test[] = {49,50,51,52}; uint32_t uwCRCValue = HAL_CRC_Calculate(&hcrc,(uint32_t *) test, 4); 

résultat: A695C4AA

Je n’ai plus d’idées. uint32_t test[] être uint32_t test[] et l’entrée est définie sur hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; Malheureusement, j’ai uint8_t

Utilisez le code suivant pour calculer cc32. CRC32 calculé par l’unité STM32 CRC n’est pas identique à notre CRC32 standard, il utilisait le big endian et ne sera pas XOR avec 0xFFFFFFFF.

 u32 CRC32_ForBytes(u8 *pData, u32 uLen); #define UNUSED(x) ((void)(x)) /** * @brief CRC functions */ #define __HAL_RCC_CRC_CLK_ENABLE() do { \ __IO uint32_t tmpreg; \ SET_BIT(RCC->AHBENR, RCC_AHBENR_CRCEN);\ /* Delay after an RCC peripheral clock enabling */\ tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_CRCEN);\ UNUSED(tmpreg); \ } while(0) #define __HAL_RCC_CRC_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_CRCEN)) #define CRC32_POLYNOMIAL ((u32)0xEDB88320) #define RCC_CRC_BIT ((u32)0x00001000) /** * @brief Calc CRC32 for data in bytes * @param pData Buffer pointer * @param uLen Buffer Length * @retval CRC32 Checksum */ u32 CRC32_ForBytes(u8 *pData,u32 uLen) { u32 uIndex= 0,uData = 0,i; uIndex = uLen >> 2; __HAL_RCC_CRC_CLK_ENABLE(); /* Reset CRC generator */ CRC_ResetDR(); while(uIndex--) { #ifdef USED_BIG_ENDIAN uData = __REV((u32*)pData); #else ((u8 *)&uData)[0] = pData[0]; ((u8 *)&uData)[1] = pData[1]; ((u8 *)&uData)[2] = pData[2]; ((u8 *)&uData)[3] = pData[3]; #endif pData += 4; uData = revbit(uData); CRC->DR = uData; } uData = revbit(CRC->DR); uIndex = uLen & 0x03; while(uIndex--) { uData ^= (u32)*pData++; for(i = 0;i < 8;i++) if (uData & 0x1) uData = (uData >> 1) ^ CRC32_POLYNOMIAL; else uData >>= 1; } __HAL_RCC_CRC_CLK_DISABLE(); return uData^0xFFFFFFFF; } static u32 revbit(u32 uData) { u32 uRevData = 0,uIndex = 0; uRevData |= ((uData >> uIndex) & 0x01); for(uIndex = 1;uIndex < 32;uIndex++) { uRevData <<= 1; uRevData |= ((uData >> uIndex) & 0x01); } return uRevData; } 

Calculez votre CRC32 comme ceci:

 u32 uwCRCValue = CRC32_ForBytes(&test, 4); 

En utilisant CubeMX, j’ai généré avec ces parameters:

 hcrc.Instance = CRC; hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE; hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE; hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; 

Calculez le CRC comme suit:

 uint32_t crc = HAL_CRC_Calculate(&hcrc, (uint32_t *)address, length); 

Et enfin inverser:

 crc = ~crc;