Electronic – STM32F4: WWDG interrupt fires as soon as it’s enabled

interruptsmicrocontrollerstm32stm32f4watchdog

I'm doing some coding on an STM32F411 board, used the CubeMX & HAL Libraries for laziness.

I'm trying to get the windowed watchdog (WWDG) up & running, and doing the very basic version (non interrupting) works as expected using this sequence of setting up (straight from the HAL/CubeMX):

/* Reset of all peripherals, Initialises the Flash interface and the Systick. */
HAL_Init();

/* Configure the system clock */
SystemClock_Config();

/* Initialise all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
MX_I2C1_Init();
MX_IWDG_Init();
MX_TIM1_Init();
MX_USART6_UART_Init(); 
MX_USB_OTG_FS_USB_Init();

MX_WWDG_Init(); // Window == count == 0x7F
HAL_WWDG_Refresh(&hwwdg, 0x7F);
HAL_WWDG_Start(&hwwdg);

while(1)
{
    //main loop stuff
}

This works as expected (I will narrow the window later), but if I change the code to use the "early wakeup" interrupt function (EWIF) – again, all auto-generated from CubeMX – it instantly fires the interrupt:

/* Reset of all peripherals, Initialises the Flash interface and the Systick. */
HAL_Init();

/* Configure the system clock */
SystemClock_Config();

/* Initialise all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
MX_I2C1_Init();
MX_IWDG_Init();
MX_TIM1_Init();
MX_USART6_UART_Init(); 
MX_USB_OTG_FS_USB_Init();

MX_WWDG_Init(); // Window == count == 0x7F
HAL_WWDG_Refresh(&hwwdg, 0x7F);
HAL_WWDG_Start_IT(&hwwdg);

while(1)
{
    //main loop stuff
}

The MX_WWDG_Init(); call in this case includes the lines to set NVIC / enable IRQ but is otherwise identical:

void HAL_WWDG_MspInit(WWDG_HandleTypeDef* hwwdg)
{

  if(hwwdg->Instance==WWDG)
  {
  /* USER CODE BEGIN WWDG_MspInit 0 */

  /* USER CODE END WWDG_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_WWDG_CLK_ENABLE();

    /* Peripheral interrupt init */
   HAL_NVIC_SetPriority(WWDG_IRQn, 0, 0);
   HAL_NVIC_EnableIRQ(WWDG_IRQn);
  /* USER CODE BEGIN WWDG_MspInit 1 */

  /* USER CODE END WWDG_MspInit 1 */
  }
}

I tried adding __HAL_WWDG_CLEAR_FLAG(hwwdg, WWDG_FLAG_EWIF); just before the __HAL_WWDG_ENABLE_IT(hwwdg, WWDG_IT_EWI); call in HAL_WWDG_Start_IT(&hwwdg); but it makes no difference.

What have I missed here?

Best Answer

You have to clear both IWDG_SR.EWIF and NVIC pending flag for IWDG interrupt before enabling it:

WWDG->SR = 0;
NVIC_ClearPendingIRQ(WWDG_IRQn);
NVIC_EnableIRQ(WWDG_IRQn);
Related Topic