cancel
Showing results for 
Search instead for 
Did you mean: 

Question regarding implementation of HAL_PWR_EnterSTOPMode() and other low-power routines in F1 HAL

carmine
Associate II
Posted on May 14, 2016 at 11:12

Hi,

I'm experiencing a really obscure issue on an STM32F103 using the latest CubeF1 HAL, and I suspect that it's related to the way the WFI instruction is called.

My scenario is a little bit complex. My code runs with FreeRTOS, but under certain conditions I can suspend the tick generation and place the MCU in STOP mode using the

HAL_PWR_EnterSTOPMode()

with WFI instruction. The EXTI controller is configured so that PC13 is the wake up pin. The problem I've is that when the MCU wakes up, it immediately generates an hardfault, which doesn't give me useful information.

The code works perfectly on other STM32 families (especially F0 and L4). Digging in this issue, I realized that the

HAL_PWR_EnterSTOPMode()

doesn't follow what ARM says about the right calling sequence of WFI instruction, as stated here:

http://infocenter.arm.com/help/topic/com.arm.doc.dai0321a/BIHICBGB.html

So, I've modified the function in this way:

void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry) {

/* Check the parameters */

assert_param(IS_PWR_REGULATOR(Regulator));

assert_param(IS_PWR_STOP_ENTRY(STOPEntry));

/* Clear PDDS bit in PWR register to specify entering in STOP mode when CPU enter in Deepsleep */

CLEAR_BIT(PWR->CR, PWR_CR_PDDS);

/* Select the voltage regulator mode by setting LPDS bit in PWR register according to Regulator parameter value */

MODIFY_REG(PWR->CR, PWR_CR_LPDS, Regulator);

/* Set SLEEPDEEP bit of Cortex System Control Register */

SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));

/* Select Stop mode entry --------------------------------------------------*/

if(STOPEntry == PWR_STOPENTRY_WFI)

{

/* Request Wait For Interrupt */

__DSB(); //Added by me

__WFI();

__ISB();//Added by me

}

else

{

/* Request Wait For Event */

__SEV();

PWR_OverloadWfe(); /* WFE redefine locally */

PWR_OverloadWfe(); /* WFE redefine locally */

}

/* Reset SLEEPDEEP bit of Cortex System Control Register */

CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));

}

With this modification, the code works well and the MCU exists from STOP mode correctly.

Does someone know more about this? Can ST engineers explain why the

HAL_PWR_EnterSTOPMode()

isn't implemented in the way suggested by ARM?

Thanks

1 REPLY 1
Amel NASRI
ST Employee
Posted on June 01, 2016 at 17:39

Hi cnoviello,

To more understand the issue and start our investigation, I would like to know:

1- is the same issue faced if you don't use FreeRTOS?

2- do you confirm that the SAME application runs successfully with F0 and F4? (ARM restriction is applicable for Cortex M3/M4/M0, so why only with M3 problem is faced?, we need to understand this)

3- were you able to identify the hardfault root cause before applying the workaround?

Thanks.

-Mayla-

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.