cancel
Showing results for 
Search instead for 
Did you mean: 

Stop mode does not work as expected

tinova-1
Associate II

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

 

 

5 REPLIES 5
PatrickF
ST Employee

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.

 

In order 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.
tinova-1
Associate II

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
PatrickF
ST Employee

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.

In order 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.
tinova-1
Associate II

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.

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.

In order 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.