2025-09-10 7:46 PM
I’m working on a project that involves reading audio samples from ADF1 and storing them in an internal RAM buffer using the GPDMA. The GPDMA is configured using Linked Lists in circular mode. An interrupt is generated when the buffer is half-full and full. The STM32 should remain in STOP1 mode while the buffer is filled, and wake up when either of the two interrupts occur.
Note that FatFs is also used to write the buffered data to an SD card through the SDMMC interface.
I have this all working perfectly on my custom STM32U575 pcb, but only when I put the STM32 into sleep mode. It does not work in STOPMODE1. The interrupts never occur and the device never wakes from STOPMODE1. What am I missing? How can I make this work? I’ve looked for existing example code using GPDMA and STOP1, but have come up empty. See below for CUBEMX configuration and code:
Most of my code is in the main() function:
int main(void)
{
FRESULT ReturnResult;
FIL MyFile;
int numberOfWrites = 16;
HAL_Init();
SystemPower_Config();
SystemClock_Config();
MX_GPDMA1_Init();
__HAL_LINKDMA(&AdfHandle0, hdma, handle_GPDMA1_Channel11);
MX_GPIO_Init();
MX_ADF1_Init();
MX_ICACHE_Init();
MX_SDMMC1_SD_Init();
HAL_DBGMCU_EnableDBGStopMode();
FATFS_LinkDriver(&SD_Driver, SD_Path);
ReturnResult = f_mount(&SDDISKFatFs, (TCHAR const*)SD_Path, 1);
if(ReturnResult != FR_OK)
{
Error_Handler();
}
ReturnResult = f_open(&MyFile, "NewAudio1.raw", FA_CREATE_ALWAYS | FA_WRITE);
if(ReturnResult != FR_OK)
{
Error_Handler();
}
MX_MDFQueue_Config();
/* Link SAI queue to DMA channel */
HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel11, &MDFQueue);
MDF_DMAConfig();
if (HAL_MDF_AcqStart_DMA(&AdfHandle0, &AdfFilterConfig0, &DMAConfig) != HAL_OK)
{
Error_Handler();
}
HAL_PWREx_ConfigSRDDomain(PWR_SRD_DOMAIN_RUN);
while (1)
{
HAL_SuspendTick();
//HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); //<- THIS WORKS
__HAL_RCC_PWR_CLK_ENABLE();
HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI); //<- THIS DOES NOT WORK
HAL_ResumeTick();
if(DmaRecHalfBuffCplt == 1)
{
FatFsResult = f_write(&MyFile, &RecBuff[0], (UINT)((REC_BUFF_SIZE_DIV2 - 1) * 2), (void *)&byteswritten);
if(FatFsResult != FR_OK)
{
Error();
}
DmaRecHalfBuffCplt = 0;
}
if(DmaRecBuffCplt == 1)
{
FatFsResult = f_write(&MyFile, &RecBuff[REC_BUFF_SIZE_DIV2], (UINT)(REC_BUFF_SIZE_DIV2 * 2), (void *)&byteswritten);
if(FatFsResult != FR_OK)
{
Error();
}
numberOfWrites--;
DmaRecBuffCplt = 0;
}
if(numberOfWrites == 0)
{
HAL_MDF_AcqStop_DMA(&AdfHandle0);
f_close(&MyFile);
break;
}
}
HAL_MDF_DeInit(&AdfHandle0);
MX_GPDMA1_DeInit();
while (1)
{
}
}
Below is my HAL_MDF_MspInit() function with some additional function calls in the user code area that I'd hoped would allow GPDMA to run in STOP1:
void HAL_MDF_MspInit(MDF_HandleTypeDef* hmdf)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
if(IS_ADF_INSTANCE(hmdf->Instance))
{
/* USER CODE BEGIN ADF1_MspInit 0 */
__HAL_RCC_ADF1_CLK_SLEEP_ENABLE();
__HAL_RCC_GPDMA1_CLK_SLEEP_ENABLE();
__HAL_RCC_LPGPIO1_CLK_SLEEP_ENABLE();
__HAL_RCC_SRAM1_CLK_SLEEP_ENABLE();
__HAL_RCC_MSIKSTOP_ENABLE();
HAL_PWREx_EnableVddIO2();
HAL_PWREx_EnableVddA();
/* USER CODE END ADF1_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADF1;
PeriphClkInit.Adf1ClockSelection = RCC_ADF1CLKSOURCE_MSIK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/* Peripheral clock enable */
__HAL_RCC_ADF1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**ADF1 GPIO Configuration
PB3 (JTDO/TRACESWO) ------> ADF1_CCK0
PB4 (NJTRST) ------> ADF1_SDI0
*/
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF3_ADF1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* ADF1 interrupt Init */
HAL_NVIC_SetPriority(ADF1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADF1_IRQn);
/* USER CODE BEGIN ADF1_MspInit 1 */
/* USER CODE END ADF1_MspInit 1 */
}
}
2025-09-14 6:45 PM
I'll try again... Anyone out there have an idea on how to get GPDMA and STOP1 working?
I was able to get this code working with LPDMA and STOP2 by learning from the "ADF_AudioSoundDetector" example that ST provides. However, due to some of the limitations of LPDMA and STOP2, I suspect my application might be more power efficient in STOP1 with GPDMA. I cant seem to find any similar example code for GPDMA and STOP1 however
The following is a screenshot of the Clock Configuration screen from CubeMX in case that offers any clues as to what I might be doing wrong
2025-09-29 1:32 AM
Hello @coppercrimp
Thanks a lot for your detailed and pertinent questions.
Regarding your issue I have remarked in your current code, the function call:
HAL_DBGMCU_EnableDBGStopMode();
enables debug during STOP mode. While this is useful for debugging, it prevents the CPU core from fully entering low-power STOP1 mode because the core remains gated and the MCU operates in a low-power emulation mode instead of true STOP mode.
HAL_DBGMCU_EnableDBGStopMode();
Please feel free to respond and confirm whether this resolves your request or not.
Best regards,
Haifa.
2025-10-05 6:06 PM
Hi Haifa,
Thank you for responding to my question. And thank you for bringing the issue with HAL_DBGMCU_EnableDBGStopMode() to my attention. I wish I could say that this was the problem, but unfortunately it is not. My program still does not exit from stop mode1 as stated in my original post.
I am able to confirm that the following registers are set to '1' as suggested on page 504 of the RM0456 reference manual:
Also, I'd like to ask: is the following instruction required for STOP1?
HAL_PWREx_ConfigSRDDomain(PWR_SRD_DOMAIN_RUN);
I don't think the Smart Run Domain is used in STOP1, but I'm not completely sure
Are there any other suggestions I might try?
Best regards
2025-10-12 3:10 PM
I wanted to try bumping this to the top of the list again. It seems strange that there is so little information available on GPDMA in stop mode 1
2025-10-13 12:01 AM
Hello @coppercrimp
Given the issues you are experiencing with GPDMA1 interrupts not occurring and the STM32U5 not waking up from STOPMODE1, could you please try using the LPBAM utility in your application?
LPBAM enables peripherals like ADF1 and GPDMA1 to operate autonomously and perform DMA transfers while the MCU remains in STOPMODE1 mode, which should help maintain buffer filling and generate the necessary wake-up interrupts without CPU intervention.
You can find typical examples on our GitHub repository at the following link:
Please test your setup with LPBAM configured and let us know if this resolves the problem.