Skip to main content
Visitor II
December 13, 2023
Question

Stop mode does not work as expected

  • December 13, 2023
  • 4 replies
  • 3084 views

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

 

 

    This topic has been closed for replies.

    4 replies

    Technical Moderator
    December 14, 2023

    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.

     

    tinova-1Author
    Visitor II
    December 14, 2023

    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
    Technical Moderator
    December 14, 2023

    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.

    tinova-1Author
    Visitor II
    December 15, 2023

    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.

    Technical Moderator
    December 18, 2023

    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.