2026-04-06 7:42 AM - edited 2026-04-06 7:43 AM
Hi,
I’m working with the STM32H7S7L86H and using the SAES peripheral to encrypt and decrypt data stored in an SPI flash.
I currently have the peripheral working correctly using HAL functions in polling mode. I also managed to get it working with interrupt mode, including proper input/output callbacks.
However, I would like to use DMA to offload the CPU, but I haven’t been able to find any HAL-based examples for SAES with DMA. When I try to use DMA, the transfer does not seem to complete and no callback is triggered.
Could you help me understand how to properly configure SAES with DMA using HAL, or point me to a working example?
void HAL_CRYP_MspInit(CRYP_HandleTypeDef* hcryp)
{
if(hcryp->Instance==SAES)
{
/* USER CODE BEGIN SAES_MspInit 0 */
/* USER CODE END SAES_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SAES_CLK_ENABLE();
/* SAES DMA Init */
/* GPDMA1_REQUEST_SAES_OUT Init */
handle_GPDMA1_Channel13.Instance = GPDMA1_Channel13;
handle_GPDMA1_Channel13.Init.Request = GPDMA1_REQUEST_SAES_OUT;
handle_GPDMA1_Channel13.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
handle_GPDMA1_Channel13.Init.Direction = DMA_PERIPH_TO_MEMORY;
handle_GPDMA1_Channel13.Init.SrcInc = DMA_SINC_FIXED;
handle_GPDMA1_Channel13.Init.DestInc = DMA_DINC_INCREMENTED;
handle_GPDMA1_Channel13.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
handle_GPDMA1_Channel13.Init.DestDataWidth = DMA_SRC_DATAWIDTH_WORD;
handle_GPDMA1_Channel13.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
handle_GPDMA1_Channel13.Init.SrcBurstLength = 1;
handle_GPDMA1_Channel13.Init.DestBurstLength = 1;
handle_GPDMA1_Channel13.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
handle_GPDMA1_Channel13.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
handle_GPDMA1_Channel13.Init.Mode = DMA_NORMAL;
if (HAL_DMA_Init(&handle_GPDMA1_Channel13) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hcryp, hdmaout, handle_GPDMA1_Channel13);
if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel13, DMA_CHANNEL_NPRIV) != HAL_OK)
{
Error_Handler();
}
/* GPDMA1_REQUEST_SAES_IN Init */
handle_GPDMA1_Channel12.Instance = GPDMA1_Channel12;
handle_GPDMA1_Channel12.Init.Request = GPDMA1_REQUEST_SAES_IN;
handle_GPDMA1_Channel12.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
handle_GPDMA1_Channel12.Init.Direction = DMA_MEMORY_TO_PERIPH;
handle_GPDMA1_Channel12.Init.SrcInc = DMA_DINC_INCREMENTED;
handle_GPDMA1_Channel12.Init.DestInc = DMA_SINC_FIXED;
handle_GPDMA1_Channel12.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
handle_GPDMA1_Channel12.Init.DestDataWidth = DMA_SRC_DATAWIDTH_WORD;
handle_GPDMA1_Channel12.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
handle_GPDMA1_Channel12.Init.SrcBurstLength = 1;
handle_GPDMA1_Channel12.Init.DestBurstLength = 1;
handle_GPDMA1_Channel12.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
handle_GPDMA1_Channel12.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
handle_GPDMA1_Channel12.Init.Mode = DMA_NORMAL;
if (HAL_DMA_Init(&handle_GPDMA1_Channel12) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hcryp, hdmain, handle_GPDMA1_Channel12);
if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel12, DMA_CHANNEL_NPRIV) != HAL_OK)
{
Error_Handler();
}
/* SAES interrupt Init */
HAL_NVIC_SetPriority(SAES_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(SAES_IRQn);
/* USER CODE BEGIN SAES_MspInit 1 */
/* USER CODE END SAES_MspInit 1 */
}
}
uint8_t config_crypt_AES_CTR(){
hcryp.Instance = SAES;
hcryp.Init.DataType = CRYP_DATATYPE_8B;
hcryp.Init.KeySize = CRYP_KEYSIZE_256B;
hcryp.Init.pKey = (uint32_t *)AESKey;
hcryp.Init.pInitVect = iv_buf;
hcryp.Init.Algorithm = CRYP_AES_CTR;
hcryp.Init.Header = (uint32_t *)HeaderSAES;
hcryp.Init.HeaderSize = 0;
hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
hcryp.Init.HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_WORD;
hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
hcryp.Init.KeyMode = CRYP_KEYMODE_NORMAL;
hcryp.Init.KeySelect = CRYP_KEYSEL_NORMAL;
if (HAL_CRYP_Init(&hcryp) != HAL_OK)
{
return 0;
}
return 1;
}