cancel
Showing results for 
Search instead for 
Did you mean: 

IWDG in STOP2

IHlot.1
Associate II

I'm using MCU STM32WB55CE. The issue is the following:

after putting MCU in STOP mode it looks like IWDG still running and reset the MCU.

Option byte: 0x3B79F1AA, means bit IWDG_STDBY and IWDG_STOP clear.

I'm using SEGGER J-Link for debugging. Ble stack version: 1.13.3

IWDG init:

void InitWatchDog()
{    
    FLASH_OBProgramInitTypeDef obInit;
    HAL_FLASHEx_OBGetConfig(&obInit);
    HAL_StatusTypeDef status = 0;
 
    if ( (obInit.UserConfig & OB_USER_IWDG_STOP) !=  OB_IWDG_STOP_FREEZE
            || (obInit.UserConfig & OB_USER_IWDG_STDBY) != OB_IWDG_STDBY_FREEZE )
    {
        status = HAL_FLASH_Unlock();
        if (status)
        {
            assert(false);
        }
        status = HAL_FLASH_OB_Unlock();
        if (status)
        {
            assert(false);
        }
 
        FLASH_OBProgramInitTypeDef OBInit =
        {
            .OptionType = OPTIONBYTE_USER,
            .UserType = OB_USER_IWDG_STOP | OB_USER_IWDG_STDBY,
            .UserConfig = OB_IWDG_STOP_FREEZE | OB_IWDG_STDBY_FREEZE,
        };
        status = HAL_FLASHEx_OBProgram(&OBInit);
        if (status)
        {
            assert(false);
        }
 
        HAL_FLASH_OB_Launch();
        HAL_FLASH_OB_Lock();
        HAL_FLASH_Lock();
    }
 
    InternalWatchdog.Instance = IWDG;
    InternalWatchdog.Init.Prescaler = IWDG_PRESCALER_256;
    InternalWatchdog.Init.Window = 4095;
    InternalWatchdog.Init.Reload = 4095;
    if (HAL_IWDG_Init(&InternalWatchdog) != HAL_OK)
    {
        assert(false);
    }
}

Put MCU in sleep mode:

void EnterStopMode(void)
{
    LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
 
    HAL_SuspendTick();
 
    HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
 
    HAL_ResumeTick();
}

7 REPLIES 7
Mvill.17
Associate III

Hi

I'm working with STM32L0 and have the same problem: the uC enters the STOP mode and the IDWG reset the system though I config the watchdog hardware and clear IWDG_STOP in the option byte.

Why do they put this bit in the option byes if it the watchdog doesn't freeze in STOP?

Bye

IHlot.1
Associate II

This IWDG issue is odd, i've tried several solution suggested on this forum, but none of it help me.

I'm not sure as for the second core (M0) which is responsible for Ble stack.

Is it possible that core M0 won't allow MCu goes in to STOP mode?

I used the following macro for this :

LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);

but not 100% sure.

Remy ISSALYS
ST Employee

Hello,

You have the right configuration for the following option bytes:

  • IWDGSTOP = 0 : Independent watchdog counter frozen in Stop mode
  • IWDGSW = 1 : Software independent watchdog

It seems that you are not entering in stop mode as it should be done, I suggest you to

have a look on BLE_HeartRate example available in STM32CubeWB package which allow to go in stop mode using low power manager. In addition, when CPU2 is running, you shall not use LL_C2 command like the following: LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);

For debugging purpose, according to reference manual RM0434, there is a bit to configure in order to debug with IWDG:

When the CPU1 enters Debug mode (core halted), the IWDG counter either continues to work normally or stops, depending on the configuration of the corresponding bit in debug freeze register.

See DBG_IWDG_STOP: IWDG stop in CPU1 debug

  • 0: Normal operation. IWDG continues to operate while CPU1 is in debug mode
  • 1: Stop in debug. IWDG is frozen while CPU1 is in debug mode

Best Regards

The guys are not asking for stopping IWDG in debug mode, which is a different feature. They are asking for stopping IWDG in low-power Stop mode.

Piranha
Chief II

By the way, in the code you posted in this topic, the line 8 must be after the line 11.

Piranha
Chief II

As you took the code from my article, did you define the NDEBUG for a non-debug build and tested that build?

Maybe you are entering the Standby mode from ISR (interrupt service routine)?

rene_e
Associate

Hi, even if this thread is kinda old, it's the one which came up during my search for a solution. And finally found one, as you can see below (it's working code). The major issue I had was the difference between the mask to use for the USERConfig (i.e. FLASH_OPTR_IWDG_SW) and the mask/userType to use for the flash programming itself (i.e. OB_USER_IWDG_SW). Once this was fixed, the code was working and the watchdog does not trigger if the program is in Stop-Mode (HAL_PWR_EnterSTOPMode (PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);). The same can be done for Standby mode, use FLASH_OPTR_IWDG_STDBY and OB_USER_IWDG_STDBY instead. But thanks for pointing in the right direction.

Best regards, Rene

void MX_IWDG_Init(void)
{

  /* USER CODE BEGIN IWDG_Init 0 */
	// copied and adapted from
	// https://community.st.com/t5/stm32-mcus-wireless/iwdg-in-stop2/td-p/95317
	FLASH_OBProgramInitTypeDef obInit;
	HAL_FLASHEx_OBGetConfig(&obInit);

	if ( (obInit.USERConfig & FLASH_OPTR_IWDG_SW) !=  OB_IWDG_SW
			|| (obInit.USERConfig & FLASH_OPTR_IWDG_STOP) != OB_IWDG_STOP_FREEZE )
	{
		if (HAL_FLASH_Unlock() != HAL_OK)
		{
		    Error_Handler();
		}
		if (HAL_FLASH_OB_Unlock() != HAL_OK)
		{
		    Error_Handler();
		}

		obInit.OptionType = OPTIONBYTE_USER;
		obInit.USERType = OB_USER_IWDG_SW | OB_USER_IWDG_STOP;
		obInit.USERConfig = OB_IWDG_SW | OB_IWDG_STOP_FREEZE;
		if (HAL_FLASHEx_OBProgram(&obInit) != HAL_OK)
		{
		    Error_Handler();
		}

		HAL_FLASH_OB_Launch(); // this causes system reset
		HAL_FLASH_OB_Lock();
		HAL_FLASH_Lock();
	}
  /* USER CODE END IWDG_Init 0 */

  /* USER CODE BEGIN IWDG_Init 1 */

  /* USER CODE END IWDG_Init 1 */
  hiwdg.Instance = IWDG;
  hiwdg.Init.Prescaler = IWDG_PRESCALER_256;
  hiwdg.Init.Window = 4095;
  hiwdg.Init.Reload = 4095;
  if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN IWDG_Init 2 */

  /* USER CODE END IWDG_Init 2 */

}