cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F429 WFI w/ interrupt disabled

alessandro morniroli
Associate III
Posted on February 07, 2018 at 09:47

Hi,

I'm developing on a custom board with STM32F429. I need to use stop mode for power consumption. We have some external interrupt (e.g. interrupt from accelerometer) we use to wakeup from stop mode.

Wake up is working fine, but the problem is that exiting from stop mode, HSI oscillator is automatically used. I need to reconfigure the PLL prior to executing the interrupt handler that woke up the MCU. I enter stop mode in my idle task as soon as it's possible. 

My first solution was to enter stop mode with global interrupt disabled, in order to reconfigure PLL in idle task and then restoring global interrupt and execute the interrupt handler that woke up the MCU. But it's not working: MCU remains in stop mode no matter what.

I used this apporach in the past using a Kinetis MCU (cortex M4) from NXP and it was working fine.

Am I missing something?
4 REPLIES 4
Tilen MAJERLE
ST Employee
Posted on February 07, 2018 at 11:47

Hello

alessandro.morniroli

‌,

please provide here more info about:

  • How do you know that MCU is still in STOP mode?
  • Do you see the same behavior in case of SLEEP mode?

Best regards,

Tilen

Posted on February 07, 2018 at 14:57

Hi Tilen,

I know the MCU is still in stop because I turn on a led as soon as it exits from stop mode (but the led remain off).

I managed to exit from stop mode with global interrupt disabled, starting from a blank project

__disable_irq ();
HAL_PWR_EnterSTOPMode (PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
ledPowerOn ();
__enable_irq ();�?�?�?�?�?�?�?�?

ledPowerOn is executed before the interrupt handler that woke up the MCU (this is correct, and this is what I want).

I think the problem is that in my project, I'm using FreeRTOS, and instead of __disable_irq ()

__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
{
 __ASM volatile ('cpsid i' : : : 'memory');
}�?�?�?�?

I'm using the FreeRTOS macro vPortEnterCritical ()

#define configPRIO_BITS 4
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY \
 ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See https://community.st.com/external-link.jspa?url=http%3A%2F%2Fwww.FreeRTOS.org%2FRTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY \
 ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
{
uint32_t ulNewBASEPRI;
__asm volatile
 (
 ' mov %0, %1 
' \
 ' msr basepri, %0 
' \
 ' isb 
' \
 ' dsb 
' \
 :'=r' (ulNewBASEPRI) : 'i' ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
 );
}

void vPortEnterCritical( void )
{
 portDISABLE_INTERRUPTS();
 uxCriticalNesting++;
/* This is not the interrupt safe version of the enter critical function so
 assert() if it is being called from an interrupt context. Only API
 functions that end in 'FromISR' can be used in an interrupt. Only assert if
 the critical nesting count is 1 to protect against recursive calls if the
 assert function also uses a critical section. */
 if( uxCriticalNesting == 1 )
 {
 configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
 }
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

I think it's something in basepri setting that is preventing interrupt to trigger and to exit from stop mode.

Posted on February 07, 2018 at 15:35

Hello

alessandro.morniroli

‌,

FreeRTOS might not always disable interrupts when entering critical section.

Please check URL below with some informations.

To force interrupt disable, use __disable_irq function

https://www.freertos.org/RTOS-Cortex-M3-M4.html

Do you use tickless sleep mode inside idle thread?

Best regards,

Tilen

Posted on May 09, 2018 at 12:22

Hi Tilen,

no I haven't used tickless sleep mode.

Best regards,

Alessandro Morniroli