Problem calculating CRC32 with DMA (STM32U585)
Hello,
perhaps someone here has an idea what's going wrong:
I wrote a small program with cube ide to calculate a crc32 (standard polynom 0x4c11db7). It took me some time, but now I get the same result when using HAL_CRC_generate and 'manually' feeding the CRC module.
Then I tried to feed the CRC module via DMA (GPDMA, channel 0), and then it becomes a little bit weird:
if the length of data is 1 to 3 bytes, all three methods calculate the same crc.
But if the length is >= 4, the crc generated via dma differs.
Attached is the main.c, but the interesting code of initializing the crc module and the dma channel is listed below...
Thanks,
Gunter
/*
* Method 3: CRC module via DMA
*/
/* init crc module */
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;
if (HAL_CRC_Init(&hcrc) != HAL_OK)
{
Error_Handler();
}
/* init gpdma channel 0 */
__HAL_RCC_GPDMA1_CLK_ENABLE();
handle_GPDMA1_Channel0.Instance = GPDMA1_Channel0;
handle_GPDMA1_Channel0.Init.Request = DMA_REQUEST_SW;
handle_GPDMA1_Channel0.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
handle_GPDMA1_Channel0.Init.Direction = DMA_MEMORY_TO_MEMORY;
handle_GPDMA1_Channel0.Init.SrcInc = DMA_SINC_INCREMENTED;
handle_GPDMA1_Channel0.Init.DestInc = DMA_DINC_FIXED;
handle_GPDMA1_Channel0.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
handle_GPDMA1_Channel0.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
handle_GPDMA1_Channel0.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
handle_GPDMA1_Channel0.Init.SrcBurstLength = 1;
handle_GPDMA1_Channel0.Init.DestBurstLength = 1;
handle_GPDMA1_Channel0.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
handle_GPDMA1_Channel0.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
handle_GPDMA1_Channel0.Init.Mode = DMA_NORMAL;
if (HAL_DMA_Init(&handle_GPDMA1_Channel0) != HAL_OK)
{
Error_Handler();
}
if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel0, DMA_CHANNEL_NPRIV) != HAL_OK)
{
Error_Handler();
}
__HAL_CRC_DR_RESET(&hcrc);
HAL_DMA_Start(&handle_GPDMA1_Channel0, (uint32_t)&testdata[0], (uint32_t)&CRC->DR, crclen);
crc_dma = hcrc.Instance->DR ^ 0xFFFFFFFFu;
if ( (crc_HAL != crc_man) || (crc_HAL != crc_dma) )
{
while (1)
