AnsweredAssumed Answered

IWDG STM32F303

Question asked by Red5 on Feb 7, 2014
I didn't see a formal way to log bugs against the standard peripheral library, so I figured I would at least submit a note here.  The header file (stm32f30x_iwdg.h) for the IWDG in the standard peripheral library for the stm32f3 series has an error in the definition of the status register flags.  The definitions given are:
/** @defgroup IWDG_Flag
  * @{
  */
 
#define IWDG_FLAG_PVU               ((uint16_t)0x0001)
#define IWDG_FLAG_RVU               ((uint16_t)0x0002)
#define IWDG_FLAG_WVU               ((uint16_t)0x0002)
#define IS_IWDG_FLAG(FLAG) (((FLAG) == IWDG_FLAG_PVU) || ((FLAG) == IWDG_FLAG_RVU)  || \
                            ((FLAG) == IWDG_FLAG_WVU))

The definition for the WVU bit is wrong.  It should be 0x0004.

Also, the reference manual gives the following sequence for configuring the IWDG when window mode is not used:

When the window option it is not used, the IWDG can be configured as follows:
1. Enable register access by writing 0x0000 5555 in the IWDG_KR register.
2. Write the IWDG prescaler by programming IWDG_PR from 0 to 7.
3. Write the reload register (IWDG_RLR).
4. Wait for the registers to be updated (IWDG_SR = 0x0000 0000).
5. Refresh the counter value with IWDG_RLR (IWDG_KR = 0x0000 AAAA).
6. Enable the IWDG by writing 0x0000 CCCC in the IWDG_KR.


When I implement it following these instructions, it hangs at step 4.  The only way I can get it to pass the test in step 4 is to move step 6 to step 1 or use the option bytes to hardware enable the IWDG at power-up.  In other words, the IWDG must be enabled for the status register to clear the bits.

The code hangs when I run this sequence:
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
IWDG_SetPrescaler(IWDG_Prescaler_16);
IWDG_SetReload(0x0FFF);
while( IWDG_GetFlagStatus(IWDG_FLAG_PVU | IWDG_FLAG_RVU | IWDG_FLAG_WVU) == SET );
IWDG_ReloadCounter();
IWDG_Enable();

The code runs fine when I run this sequence:
IWDG_Enable();
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
IWDG_SetPrescaler(IWDG_Prescaler_16);
IWDG_SetReload(0x0FFF);
while( IWDG_GetFlagStatus(IWDG_FLAG_PVU | IWDG_FLAG_RVU | IWDG_FLAG_WVU) == SET );
IWDG_ReloadCounter();

This post is mostly just to let people know what I ran into, but I would like to hear from you if you see something I've done wrong.

Outcomes