2015-03-04 09:29 AM
Hi all,
I'm using the STM32F205VBT on some boards I developed. Software development is done under Win7/x64 using Eclipse (4.4.1) with CDT (8.5.0), Toolchain is gcc 4.8.4. (arm-none-eabi). My Software Project is created with STM32CubeMX 4.6.0. and utilizes the HAL. Works fine so far, but the CRC peripheral is missing from the configuration tree in CubeMX, when building a configuration for the STM32F2xx family. CRC peripheral is supported for every other MCU family I tested, but is just missing for the one I'm using in this project. Is there anything I could do to include the HAL driver for the CRC peripheral into my STM32F205 project? Best regards, Thorsten #stm32f2xx #crc32 #gzip2015-03-10 06:08 AM
No one any idea?
2015-03-10 06:39 AM
Hello Thorsten,
This is an issue in MX 4.6. This should be fixed within next MX release. For now you will have to manually copy the CRC library files and create an init function such as:void MX_CRC_Init(void)
{hcrc.Instance = CRC;
HAL_CRC_Init(&hcrc);}
Best regards.2015-03-10 07:37 AM
ok, thank you!
As far as I get it, it should be sufficient to uncomment the Line#define HAL_CRC_MODULE_ENABLED
in the header filestm32f2xx_hal_conf.h
and add the init function you suggested. That init function was the missing link. I'll try this and will report later... Best regards, Thorsten2015-03-13 11:09 AM
O.K. finally I got it working!
The suggested init function was necessary, but not sufficient, there were some more things to do... To give other users a hand, here's what I did to get it running, step by step: 1. add the init function (and of course, call it from main() )void
MX_CRC_Init(
void
)
{
hcrc.Instance = CRC;
HAL_CRC_Init(&hcrc);
}
2. uncomment the line
#define HAL_CRC_MODULE_ENABLED
in the header filestm32f2xx_hal_conf.h
3. to get the CRC peripheral clock enabled (and disabled), the MspInit/MspDeInit functions for the CRC peripheral have to be added in the file stm32f2xx_hal_msp.c (Normally done by the STM32CubeMX software.)void
HAL_CRC_MspInit(CRC_HandleTypeDef* hcrc)
{
if
(hcrc->Instance==CRC)
{
/* USER CODE BEGIN CRC_MspInit 0 */
/* USER CODE END CRC_MspInit 0 */
/* Peripheral clock enable */
__CRC_CLK_ENABLE();
/* USER CODE BEGIN CRC_MspInit 1 */
/* USER CODE END CRC_MspInit 1 */
}
}
void
HAL_CRC_MspDeInit(CRC_HandleTypeDef* hcrc)
{
if
(hcrc->Instance==CRC)
{
/* USER CODE BEGIN CRC_MspDeInit 0 */
/* USER CODE END CRC_MspDeInit 0 */
/* Peripheral clock disable */
__CRC_CLK_DISABLE();
/* USER CODE BEGIN CRC_MspDeInit 1 */
/* USER CODE END CRC_MspDeInit 1 */
}
}
That's all you have to do, to use the CRC peripheral via HAL funtions.
Because I needed to calculate a Gzip / ZMODEM compatible CRC32 on a bytewise organized data stream, I had to write my own function. The the CRC unit only can calculate CRC on whole 32 bit data words, and it shifts the other way round ...
My crc function first tweaks the data written to the CRC peripheral by reversing bitorder of each 32-bit word and also reverses bitorder of the calculated CRC. At last, the CRC value has to be inverted bitwise.
To be able to calculate the CRC of data blocks with lengths not beeing a multiple of 4 byte, I added a small piece of extra software that calculates the CRC of the remaining bytes (at most 3).
Because at most 3 bytes are calculated by software this won't be a performance issue.
my crc function:
/**
* @brief Computes the 32-bit CRC of 8-bit data buffer independently
* of the previous CRC value.
* @param hcrc: CRC handle
* @param p_src: Pointer to the buffer containing the data to be computed
* @param size: size of the buffer to be computed, in bytes
* @retval 32-bit CRC, compatible with Gzip, PKZIP, WINRAR, ZMODEM etc.
*/
uint32_t crc32_calculate(CRC_HandleTypeDef *hcrc, uint8_t *p_src, uint32_t size)
{
uint32_t i;
uint32_t bit;
uint32_t crc32;
// Process Locked
__HAL_LOCK(hcrc);
// Change CRC peripheral state
hcrc->State = HAL_CRC_STATE_BUSY;
// Reset CRC Calculation Unit
__HAL_CRC_DR_RESET(hcrc);
// calculate number of complete 32-bit words
i = size >> 2;
// Enter complete 32-bit-data words to the CRC calculator
while
(i--)
{
// load 32 bit data word and reverse bitorder [.0] -> [0..31]
crc32 = __RBIT(*(uint32_t*)p_src);
// enter data into CRC calculator
hcrc->Instance->DR = crc32;
// set byte pointer to next 32 bit word
p_src += 4;
}
// Change CRC peripheral state
hcrc->State = HAL_CRC_STATE_READY;
// Process Unlocked
__HAL_UNLOCK(hcrc);
// read out calculated CRC and reverse bitorder
crc32 = __RBIT(hcrc->Instance->DR);
// get number of remaining data bytes (max 3)
i = size & 0x03;
// calculate CRC of remaining bytes by software
while
(i--)
{
crc32 ^= (uint32_t)(*p_src++);
for
(bit = 0; bit < 8; bit++)
{
if
(crc32 & 1)
{
// shift and XOR with CRC-polynomial
crc32 = (crc32 >> 1) ^ 0xEDB88320ul;
}
else
{
crc32 >>= 1;
}
}
}
// at last, calculated CRC value has to be inverted bitwise
crc32 = ~crc32;
// return calculated CRC32
return
crc32;
}
Best regards,
Thorsten
2015-03-26 08:43 AM
Addition:
just updated to CubeMX 4.7.0, now it works exactly as it should, no tweaking needed anymore. To the CubeMX Team: Thank you for fixing this! Nevertheless the crc function from my previous posting could be useful for other programmers who need to calculate Gzip/Zmodem compatible CRC32. Best regards, Thorsten2015-04-30 09:07 PM
Below, I'm not shouting - just trying to get noticed in the noise floor by ST.
IS THERE A FORMAL BUG REPORTING AND TRACKING MECHANISM FOR ST's HAL AND CUBEMX? SURELY THERE MUST BE!
This forum blog is just too informal for bug cures, for those of use involved in $$$$ projects. It could reject bug reports without a means to confirm and try to reproduce, or bugs that are just dumb.
2015-05-08 03:54 AM
Hmm, I don't get it ... What exactly is your problem?
Which .c files are missing in Cube 4.7? The aforementioned problems I had with 4.6 were completely solved with 4.7. Best regards, Thorsten