cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H747: CM4 stalls when CM7 (D1 Domain) enters DStop mode (Tickless Idle)

Patryk_Kucia
Associate III

Hi everyone,

I am working on a dual-core project using the STM32H747XI. I am implementing a custom Tickless Idle mode in FreeRTOS on the Cortex-M7 (CM7) core using LPTIM1 as the wakeup source.

I’m facing a specific issue regarding the interaction between D1 and D2 domains:

The Scenario:

  • CM4 is running a continuous task (intended to stay active).

  • CM7 enters low-power mode via vPortSuppressTicksAndSleep.

  • If I use HAL_PWR_EnterSLEEPMode(), everything works perfectly—CM4 keeps running, and CM7 wakes up as expected.

  • If I switch to HAL_PWREx_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI, PWR_D1_DOMAIN), the CM4 core seems to "die" or freeze as soon as CM7 enters the DStop state.

Is it physically possible for CM4 to continue executing code if the D1 domain is in DStop (CM4 is using only LPTIM1 on D3 and timers on D2)?

Code snippet used on CM7:

_weak void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) {
	// Generated when configUSE_TICKLESS_IDLE == 2.
	// Function called in tasks.c (in portTASK_FUNCTION).
	// TO BE COMPLETED or TO BE REPLACED by a user one, overriding that weak one.
	uint32_t ulReloadValue, ulCompleteTickPeriods;
	TickType_t xModifiableIdleTime;
	if (xExpectedIdleTime > 0xFFFF) {
		xModifiableIdleTime = 0xFFFF;
	} else {
		xModifiableIdleTime = xExpectedIdleTime;
	}
//	HAL_GPIO_WritePin(LED_1_GPIO_Port, LED_1_Pin, GPIO_PIN_SET);
	HAL_SuspendTick();
	HAL_TIM_Base_Stop_IT(&htim13);
	__disable_irq();
	if (eTaskConfirmSleepModeStatus() == eAbortSleep) {
		__enable_irq();
		HAL_ResumeTick();
	} else {
		ulReloadValue = xModifiableIdleTime - 1;
		if (HAL_LPTIM_TimeOut_Start_IT(&hlptim1, 0xFFFF, ulReloadValue)
				!= HAL_OK) {
			__enable_irq();
			HAL_ResumeTick();
			return;
		}
		(void) SysTick->CTRL;
		SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;	//oznacza zapis 1 do tego bitu.
		__DSB();
		__ISB();
		 HAL_PWREx_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI, PWR_D1_DOMAIN);
	uint32_t ulCountValue = HAL_LPTIM_ReadCounter(&hlptim1);
		HAL_LPTIM_TimeOut_Stop_IT(&hlptim1);
		if (ulCountValue > xModifiableIdleTime) {
			ulCompleteTickPeriods = xModifiableIdleTime;
		} else {
			ulCompleteTickPeriods = ulCountValue;
		}
		ulHighFrequencyTimerTicks += (ulCompleteTickPeriods * 1000UL);
		vTaskStepTick(ulCompleteTickPeriods);
		__enable_irq();
		HAL_ResumeTick();
		HAL_TIM_Base_Start_IT(&htim13);

 

6 REPLIES 6
TDK
Super User

> Is it physically possible for CM4 to continue executing code if the D1 domain is in DStop

Yes, it's physically possible as long as CPU2 doesn't use anything in the D1 domain.

TDK_0-1775936413689.png

I suggest creating a new project where you only look at this aspect and try getting that to run. It's possible your application is using something else that you're missing.

If you feel a post has answered your question, please click "Accept as Solution".

Thanks for the insight. I have a follow-up question regarding the memory architecture:

My CPU2 (CM4) is currently executing code directly from Flash memory (mapped at 0x08100000), while its stack and data are in D2-domain RAM (0x10000000).

Since the Flash memory controller is physically located within the D1 domain, does entering DStop on D1 effectively cut off the Flash clock or power for the entire system?

If so, does this mean that CPU2 (running in D2) is physically blocked from fetching instructions the moment D1 enters DStop, even if the D2 domain itself remains in DRun? I suspect this 'hidden' dependency on the D1 bus matrix is what's causing my CM4 to stall, as it works fine in Sleep mode (where the D1 bus remains active).

I’ve also observed that if D1 is in RUN/SLEEP mode, then D2 does not properly enter or operate in STOP mode.

 

image.png

I’ve also observed that if D1 is in RUN/SLEEP mode, then D2 does not properly enter or operate in STOP mode.

image.png

Patryk_Kucia
Associate III

It looks like the issue is related to LPTIM2 being located in the D3 domain.

In my setup:

  • When I use LPTIM2 as the wake-up source for CM7 or CM4, STOP mode behaves incorrectly
  • However, when I switch to LPTIM1, i can manage to put corresponding core to sleep.
    So how can i force LPTIM2 to run normally?

Hello @Patryk_Kucia 

According to the RM table 59, D3 peripherals can remain clocked in STOP mode if autonomous mode is enabled (LPTIM2AMEN = 1) and its kernel clock source is a low-power clock that remains active in D3Stop, i.e. LSE or LSI.
If LPTIM2 is clocked from PCLK/PLL or AMEN is not set, it will not run in STOP.

Saket_Om_0-1776072515601.png

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om