2023-12-13 02:55 AM
Hi!
I am using an STM32MP153 and am working on implementing the STOP mode functionality for my application. The MCU shall wake up on a falling edge on pin PI8. The pin PG15 has an interrupt attached to it for another functionality. Before going into stop mode, I must disable the PG15 interrupt for applicational reasons. Going into stop mode and waking up works fine unless I disable the interrupt on PG15. If going to stop mode fails, the power consumption is approx. 830mW and I cannot wake up the system on pin PI8. I cannot explain this behaviour, does anyone have an idea? Thanks a lot!
Here are snippets of my code:
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GYRO1_INT1_GPIO_Port, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI8_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI8_IRQn);
// (Set up interrupt for PG15...)
// disable EXTI interrupt for Port G, Pin 15
dioConfigStruct_st.Alternate = 0;
dioConfigStruct_st.Mode = GPIO_MODE_IT_OFF;
dioConfigStruct_st.Pin = GPIO_PIN_15;
dioConfigStruct_st.Pull = GPIO_NOPULL;
dioConfigStruct_st.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_ClearPortExti(GPIOG, &dioConfigStruct_st); // If I comment out this line, going to Stop mode works
// go to Stop mode...
/* (C)STOP protection mechanism
* Only the IT with the highest priority (0 value) can interrupt.
* RCC_WAKEUP_IRQn IT is intended to have the highest priority and to be the
* only one IT having this value
* RCC_WAKEUP_IRQn is generated only when RCC is completely resumed from CSTOP
*/
__set_BASEPRI((RCC_WAKEUP_IRQ_PRIO + 1) << (8 - __NVIC_PRIO_BITS));
/* Back up clock context */
rccBackupClocks();
/* Clear the Low Power MCU flags before going into CSTOP */
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_STOP);
HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);
/* ... STOP mode ... */
/* Leaving CStop mode */
/* Test if system was on STOP mode */
if (__HAL_PWR_GET_FLAG(PWR_FLAG_STOP) == 1U)
{
/* Clear the Low Power MCU flags */
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_STOP);
}
/* Restore clocks */
ASSERT_THAT(rccRestoreClocks() == HAL_OK, "Restore Clocks failed!");
/* All level of ITs can interrupt */
__set_BASEPRI(0U);
// Enter 'systemctl suspend' in the Linux console
2023-12-14 03:00 AM
Hi @tinova-1
maybe PG15 related interrupt get fired during de-validation sequence if not done in right order.
Could you please share the code behind:
HAL_GPIO_ClearPortExti(GPIOG, &dioConfigStruct_st);
as this is seems not part of STM32MP1xx_HAL_Driver deliveries.
To go further, maybe dump and compare GPIOI, GPIOG and EXTI registers in both successful and failing cases (just before going to Stop).
Regards.
2023-12-14 06:54 AM
Hi @PatrickF
thank you very much for your quick response.
Find the function code here:
void HAL_GPIO_ClearPortExti(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
{
uint32_t position;
uint32_t ioposition;
uint32_t iocurrent;
uint32_t temp;
/* Configure the port pins */
for (position = 0; position < GPIO_NUMBER; position++)
{
/* Get the IO position */
ioposition = 1 << position;
/* Get the current IO position */
iocurrent = (uint32_t) (GPIO_Init->Pin) & ioposition;
if (iocurrent == ioposition)
{
/*--------------------- EXTI Mode Configuration ------------------------*/
/* Configure the External Interrupt or event for the current IO */
if ((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE)
{
temp = EXTI->EXTICR[position >> 2];
temp &= (((uint32_t) 0xFF) << (8 * (position & 0x03)));
if (temp == ((uint32_t) (GPIO_GET_INDEX(GPIOx)) << (8 * (position & 0x03))))
{
/* Clear EXTI line configuration for Current CPU */
EXTI_C2->IMR1 &= ~((uint32_t) iocurrent);
EXTI_C2->EMR1 &= ~((uint32_t) iocurrent);
/* Clear Rising Falling edge configuration */
EXTI->RTSR1 &= ~((uint32_t) iocurrent);
EXTI->FTSR1 &= ~((uint32_t) iocurrent);
/* Configure the External Interrupt or event for the current IO */
temp = ((uint32_t) 0xFF) << (8 * (position & 0x03));
EXTI->EXTICR[position >> 2] &= ~temp;
}
}
}
}
}
The registers before before the fail, shortly before calling 'EnterStopMode()':
EXTI_RTSR1 0x00002228
EXTI_FTSR1 0x00000100
EXTI_SWIER1 0x00000000
EXTI_RPR1 0x00000000
EXTI_FPR1 0x00000000
EXTI_TZENR1 0x00000000
EXTI_RTSR2 0x00000000
EXTI_FTSR2 0x00000000
EXTI_SWIER2 0x00000000
EXTI_RPR2 0x00000000
EXTI_FPR2 0x00000000
EXTI_TZENR2 0x00000000
EXTI_RTSR3 0x00000010
EXTI_FTSR3 0x00000000
EXTI_SWIER3 0x00000000
EXTI_RPR3 0x00000000
EXTI_FPR3 0x00000000
EXTI_TZENR3 0x00000000
EXTI_EXTICR1 0x08000000
EXTI_EXTICR2 0x00000700
EXTI_EXTICR3 0x00000108
EXTI_EXTICR4 0x00000700
EXTI_IMR1 0x41080000
EXTI_EMR1 0x00000000
EXTI_IMR2 0x20801000
EXTI_EMR2 0x00000000
EXTI_IMR3 0x00000050
EXTI_EMR3 0x00000000
EXTI_C2IMR1 0x00002328
EXTI_C2EMR1 0x00000000
EXTI_C2IMR2 0x00000000
EXTI_C2EMR2 0x00000000
EXTI_C2IMR3 0x00000000
EXTI_C2EMR3 0x00000000
EXTI_HWCFGR13 0x00000000
EXTI_HWCFGR12 0x1FC02200
EXTI_HWCFGR11 0x050EFFFF
EXTI_HWCFGR10 0x00000000
EXTI_HWCFGR9 0x00000000
EXTI_HWCFGR8 0x00000000
EXTI_HWCFGR7 0x00000004
EXTI_HWCFGR6 0x00000000
EXTI_HWCFGR5 0x000EFFFF
EXTI_HWCFGR4 0x00000616
EXTI_HWCFGR3 0x00000000
EXTI_HWCFGR2 0x0001FFFF
EXTI_HWCFGR1 0x000B214B
EXTI_VERR 0x00000030
EXTI_IPIDR 0x000E0001
EXTI_SIDR 0xA3C5DD01
GPIOG_MODER 0x2B9BF65F
GPIOG_OTYPER 0x00008000
GPIOG_OSPEEDR 0x2B04C200
GPIOG_PUPDR 0x80200080
GPIOG_IDR 0x00000A04
GPIOG_ODR 0x00000004
GPIOG_BSRR 0x00000000
GPIOG_LCKR 0x00000000
GPIOG_AFRL 0x700B0000
GPIOG_AFRH 0x0BB760C0
GPIOG_BRR 0x00000000
GPIOG_HWCFGR10 0x00001240
GPIOG_HWCFGR9 0x0000FFFF
GPIOG_HWCFGR8 0xFFFFFFFF
GPIOG_HWCFGR7 0xFFFFFFFF
GPIOG_HWCFGR6 0xFFFFFFFF
GPIOG_HWCFGR5 0x00000000
GPIOG_HWCFGR4 0x00000000
GPIOG_HWCFGR3 0x00000000
GPIOG_HWCFGR2 0x00000000
GPIOG_HWCFGR1 0x00000000
GPIOG_HWCFGR0 0x00000000
GPIOG_VERR 0x00000040
GPIOG_IPIDR 0x000F0003
GPIOG_SIDR 0xA3C5DD01
GPIOI_MODER 0xFFFC773D
GPIOI_OTYPER 0x00000108
GPIOI_OSPEEDR 0x00000014
GPIOI_PUPDR 0x00008880
GPIOI_IDR 0x00000000
GPIOI_ODR 0x00000000
GPIOI_BSRR 0x00000000
GPIOI_LCKR 0x00000000
GPIOI_AFRL 0x00000000
GPIOI_AFRH 0x00000000
GPIOI_BRR 0x00000000
GPIOI_HWCFGR10 0x00001240
GPIOI_HWCFGR9 0x0000FFFF
GPIOI_HWCFGR8 0xFFFFFFFF
GPIOI_HWCFGR7 0xFFFFFFFF
GPIOI_HWCFGR6 0xFFFFFFFF
GPIOI_HWCFGR5 0x00000000
GPIOI_HWCFGR4 0x00000000
GPIOI_HWCFGR3 0x00000000
GPIOI_HWCFGR2 0x00000000
GPIOI_HWCFGR1 0x00000000
GPIOI_HWCFGR0 0x00000000
GPIOI_VERR 0x00000040
GPIOI_IPIDR 0x000F0003
GPIOI_SIDR 0xA3C5DD01
And these are the registers before it works:
EXTI_RTSR1 0x0000A228
EXTI_FTSR1 0x00000100
EXTI_SWIER1 0x00000000
EXTI_RPR1 0x00008000
EXTI_FPR1 0x00000000
EXTI_TZENR1 0x00000000
EXTI_RTSR2 0x00000000
EXTI_FTSR2 0x00000000
EXTI_SWIER2 0x00000000
EXTI_RPR2 0x00000000
EXTI_FPR2 0x00000000
EXTI_TZENR2 0x00000000
EXTI_RTSR3 0x00000010
EXTI_FTSR3 0x00000000
EXTI_SWIER3 0x00000000
EXTI_RPR3 0x00000000
EXTI_FPR3 0x00000000
EXTI_TZENR3 0x00000000
EXTI_EXTICR1 0x08000000
EXTI_EXTICR2 0x00000700
EXTI_EXTICR3 0x00000108
EXTI_EXTICR4 0x06000700
EXTI_IMR1 0x41080000
EXTI_EMR1 0x00000000
EXTI_IMR2 0x20801000
EXTI_EMR2 0x00000000
EXTI_IMR3 0x00000050
EXTI_EMR3 0x00000000
EXTI_C2IMR1 0x0000A328
EXTI_C2EMR1 0x00000000
EXTI_C2IMR2 0x00000000
EXTI_C2EMR2 0x00000000
EXTI_C2IMR3 0x00000000
EXTI_C2EMR3 0x00000000
EXTI_HWCFGR13 0x00000000
EXTI_HWCFGR12 0x1FC02200
EXTI_HWCFGR11 0x050EFFFF
EXTI_HWCFGR10 0x00000000
EXTI_HWCFGR9 0x00000000
EXTI_HWCFGR8 0x00000000
EXTI_HWCFGR7 0x00000004
EXTI_HWCFGR6 0x00000000
EXTI_HWCFGR5 0x000EFFFF
EXTI_HWCFGR4 0x00000616
EXTI_HWCFGR3 0x00000000
EXTI_HWCFGR2 0x0001FFFF
EXTI_HWCFGR1 0x000B214B
EXTI_VERR 0x00000030
EXTI_IPIDR 0x000E0001
EXTI_SIDR 0xA3C5DD01
GPIOG_MODER 0x2B9BF65F
GPIOG_OTYPER 0x00008000
GPIOG_OSPEEDR 0x2B04C200
GPIOG_PUPDR 0x80200080
GPIOG_IDR 0x00008A24
GPIOG_ODR 0x00000024
GPIOG_BSRR 0x00000000
GPIOG_LCKR 0x00000000
GPIOG_AFRL 0x700B0000
GPIOG_AFRH 0x0BB760C0
GPIOG_BRR 0x00000000
GPIOG_HWCFGR10 0x00001240
GPIOG_HWCFGR9 0x0000FFFF
GPIOG_HWCFGR8 0xFFFFFFFF
GPIOG_HWCFGR7 0xFFFFFFFF
GPIOG_HWCFGR6 0xFFFFFFFF
GPIOG_HWCFGR5 0x00000000
GPIOG_HWCFGR4 0x00000000
GPIOG_HWCFGR3 0x00000000
GPIOG_HWCFGR2 0x00000000
GPIOG_HWCFGR1 0x00000000
GPIOG_HWCFGR0 0x00000000
GPIOG_VERR 0x00000040
GPIOG_IPIDR 0x000F0003
GPIOG_SIDR 0xA3C5DD01
GPIOI_MODER 0xFFFC773D
GPIOI_OTYPER 0x00000108
GPIOI_OSPEEDR 0x00000014
GPIOI_PUPDR 0x00008880
GPIOI_IDR 0x00000000
GPIOI_ODR 0x00000000
GPIOI_BSRR 0x00000000
GPIOI_LCKR 0x00000000
GPIOI_AFRL 0x00000000
GPIOI_AFRH 0x00000000
GPIOI_BRR 0x00000000
GPIOI_HWCFGR10 0x00001240
GPIOI_HWCFGR9 0x0000FFFF
GPIOI_HWCFGR8 0xFFFFFFFF
GPIOI_HWCFGR7 0xFFFFFFFF
GPIOI_HWCFGR6 0xFFFFFFFF
GPIOI_HWCFGR5 0x00000000
GPIOI_HWCFGR4 0x00000000
GPIOI_HWCFGR3 0x00000000
GPIOI_HWCFGR2 0x00000000
GPIOI_HWCFGR1 0x00000000
GPIOI_HWCFGR0 0x00000000
GPIOI_VERR 0x00000040
GPIOI_IPIDR 0x000F0003
GPIOI_SIDR 0xA3C5DD01
2023-12-14 07:54 AM
Seems PG15 pin is different : 1 (fail) and 0 (works). So maybe you have something different elsewhere (PG5 is also different, but maybe expected).
When it works, there is a EXTI[15] rising interrupt pending, maybe still present for wakeup but masked when it fails. try to add HAL_EXTI_ClearPending() at the beginning or HAL_GPIO_ClearPortExti().
I see also pull-down on PG15 (GPIO15_PUPDR[31:30] = 0b10) whereas you define NOPULL, so something weird too (GYRO1_INT1_GPIO_Port value ?).
If PG15 changed from 0 to 1 before, maybe there is interrupt pending in NVIC, could try HAL_NVIC_ClearPendingIRQ()
Hope it's helps.
Regards.
2023-12-15 04:06 AM
Hi @PatrickF
I used HAL_EXTI_ClearPending() and HAL_NVIC_ClearPendingIRQ() but the behaviour was the same. Attached, you can find two files with the NVIC registers too.
2023-12-18 02:05 AM
In the "pass" dump, there is EXTI15 (likely from PG15) interrupt pending and enabled (position 127, GICD_ISPENDR3[31] and GICD_ISENABLER3[31]).
Pending bit is 0 on the "fail" dump.
Probably something to dig into as I would have expected vice-versa (fail when interrupt is pending).
If an interrupt is present at the output of the NVIC to the Cortex-M core, the core will skip the WFI instruction, so not going in low power (even if interrupt handling is disabled in the core by bits F and/or I).
I let you debug your SW and settings by deep diving as there is not much more I could do by just looking at code portion and dumps.
Regards.