0
\$\begingroup\$

Im trying to understand how Independent watchdog really works and i wrote a piece of code that runs on STM32F411VE Eval board. I believe i have configured the Watchdog Timer correctly according to Reference manual.

The Independent WDOG Timer is configured with Internal LSI with a frequency of 32KHz and a pre-scaler of 64. The counter is set to 256. So if the Reload counter is not loaded within 0.5 seconds, the MCU should be reset. Is my understanding wrong?

What i dont understand is, the watchdog reset comes way too late than expected (5-6 seconds) if the counter value is not reloaded. I fail to understand why. Here's my Code.

//Initialise Independent Watchdog
void init_independent_wdog(void){

 IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
 if(!IS_BIT_SET(IWDG->SR,0)){
      IWDG_SetPrescaler(IWDG_Prescaler_64);
 }
 //Set counter value to 256
 if(!IS_BIT_SET(IWDG->SR,1)){
       IWDG_SetReload(0x0100);
 }
 IWDG_Enable();
}

int main(void)
{
   SystemInit();
   SysTick_Init();

   //Initialize On-board LED GPIOs
   init_led_gpios();

   //Initialize On-board USART
   init_usart6_gpio();
   init_usart6_comm_module();

  //Initialize External Interrupt Button
  init_exti_struct();
  enable_exti_irq();

  //Initialize Independent WDOG
  init_independent_wdog();
  USART_TX_string("Hello1\n\r");

  while (1);      
 }


 //Interrupt triggered when User Button at PA0 is pressed
 void EXTI0_IRQHandler(void)
 {
    if (EXTI_GetITStatus(EXTI_Line0) != RESET)
    {
        GPIO_ToggleBits(GPIOD, GPIO_Pin_15);
        IWDG_ReloadCounter();
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
  }
\$\endgroup\$
1
\$\begingroup\$

Your init-function is probably not doing what you want.

Currently you only call the set functions if the bits are in a certain state. What you want to do is wait until the bit is in the correct state and then execute the set function.


Wrong guess:

So my guess is that the second statement is never executed and the reload register stays at the standard value of 4095 which would result in a ~8 s timeout (RC oscillator can vary quite a bit, so 6 s is in the range of what's possible).


Correct guess:

The reference manual states this:

When the independent watchdog is started by writing the value 0xCCCC in the Key register (IWDG_KR), the counter starts counting down from the reset value of 0xFFF. When it reaches the end of count value (0x000) a reset signal is generated (IWDG reset).

Whenever the key value 0xAAAA is written in the IWDG_KR register, the IWDG_RLR value is reloaded in the counter and the watchdog reset is prevented.

So the first time the watchdog will start counting down from 0xFFF which results in a time of around 8 seconds with a divider of 64 in place. To prevent that, we have to "reload" the value right after enabling the watchdog.

So try this (also corrected the waiting for the bits):

//Initialize Independent Watchdog
void init_independent_wdog(void){

    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
    while(IS_BIT_SET(IWDG->SR,0))
    {
        // wait for PVU bit reset
    }
    IWDG_SetPrescaler(IWDG_Prescaler_64);

    //Set counter value
    while(IS_BIT_SET(IWDG->SR,1))
    {
        // wait for RVU bit reset
    }

    IWDG_SetReload(256);

    IWDG_Enable();
    IWDG_ReloadCounter(); // load the wanted value
}
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Calling IWDG_ReloadCounter after IWDG_enable worked. Now I'm getting a reset every 0.5 second as expected. You interpreted the wording correctly because 0xFFF would explain the reset every 8 seconds. Thanks a lot. :) \$\endgroup\$ – Abel Tom Mar 18 at 13:15
  • 1
    \$\begingroup\$ @AbelTom thank you for the testing, so now I am certain how it works and we both learned something :-) And possibly more people in the future. \$\endgroup\$ – Arsenal Mar 18 at 14:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.