cancel
Showing results for 
Search instead for 
Did you mean: 

Blinking LED based on IWDG counter

stenasc
Senior
Posted on June 15, 2013 at 13:38

Hi,

In our system, our main code loop repeats every 12 seconds and refreshs the watchdog counter. When refreshing the counter, I toggle an LED. The only problem is the blink period. I would lke the watchdog running LED indicator to blink every one second instead of every twelve seconds. I was hoping I could do this using the IWDG count value (use a particular bit of this counter to toggle LED) but from reading the spec it looks as if I don't have access to this counter. Anyone know a way around this or alternatively is there some way of accessing the counter that I don't know?

Many Thanks

Bob

9 REPLIES 9
Posted on June 15, 2013 at 13:55

You can change the prescaler and reload registers to set the period you desire within functional limitations.

The counter operates in the 3V domain, not the 1.25V domain, and is not accessable. It signals the core with a Terminal Count, and can be suspended by Debugger settings.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
stenasc
Senior
Posted on June 15, 2013 at 15:21

Thanks Clive.

One funny I have noticed is that when an interrupt happens the IWDG->RLR register is reset to 0xFFF and the board resets. My code is as follows...Anything silly I'm doing?

Bob

static void Watchdog_Config(void)

{    

      // LSI clock is 40KHz. We want a watchdog timeout of 20 secs and we are

      // going to use a prescaler value of 256.

      // Therefore 40000 * 20 = 256 * reload value

      // 800000 / 256 = 3125 = 0xC35....this gives us a 20 sec

      // watchdog timeout period

    

    RCC_LSICmd( ENABLE );   // enable low speed internal clock used by watchdog

    while (IWDG->SR & 0x3); // wait for previous update operations to complete

    IWDG->KR = 0x5555;      // Enable independent watchdog register access

    IWDG->PR = 0x7;         // (bits 2 to 0 = 111) prescaler set to device by 256 (min 6.4ms, max 26214.4ms)

    IWDG->RLR = 0xC35;      // reload value (0xFFF max)

    IWDG->KR = 0xCCCC;      // start the watchdog       

}

void Call_Watchdog(void)

{

       IWDG->KR = 0xAAAA;

       LEDToggle(LED_GREEN);

}

Posted on June 15, 2013 at 16:12

The examples tend to reload prior to enabling.

What interrupts, what happens in them? Do they work properly absent the watchdog?

In terms of signs of life, you could have another timer use one-shot mode, but this would keep going even if foreground code was stuck in a while() loop.

You could also toggle a GPIO when you kick the watchdog.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
stenasc
Senior
Posted on June 17, 2013 at 12:19

Hi Clive,

I had to ditch the standard IWDG because I couldn't set the timeout period long enough for some of the routines.(initialization(1 minute) and web upload (approx 5 minutes)) and I cannot disable the IWDG once it has started. I created my own basic count down counter which is triggered by a 10 sec timer. It counts down every 10 secs. However when I simulate a code hang by entering an infinite loop, no interrupts occur and the watchdog counter doesn't decrement and therefore never resets.

Timer priority is set to 1.

Is there a way around this?

Regards

Bob

       while(1)   //Cause infinite loop to make watchdog timeout

         {

         }

Posted on June 17, 2013 at 13:54

Is the while() loop in an interrupt routine?

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
stenasc
Senior
Posted on June 17, 2013 at 16:16

Yes...part of USART1_IRQHandler

Posted on June 17, 2013 at 16:45

Yes...part of USART1_IRQHandler

Then you'll need to pay attention to the preemption levels assigned to the TIM vs USART interrupts in the NVIC

I don't use watchdogs to network based transfers, but rather have those routines watch a time counter (millisecond), and exit out cleanly when some specific time-outs expire.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
stenasc
Senior
Posted on June 17, 2013 at 18:57

Hi Clive,

I'm using stm32f051 and there doesn't seem to be the following command to set the preemption priority.....NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority.

error:  #136: struct ''<unnamed>'' has no field ''NVIC_IRQChannelPreemptionPriority''

USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

        

  USART_InitStructure.USART_BaudRate = 9600;

  USART_InitStructure.USART_WordLength = USART_WordLength_8b;

  USART_InitStructure.USART_StopBits = USART_StopBits_1;

  USART_InitStructure.USART_Parity = USART_Parity_No;

  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  COMInit(COM1, &USART_InitStructure);

                

  // USART2 IRQ Channel configuration

  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

        

 // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;        

//  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        

        

  NVIC_InitStructure.NVIC_IRQChannelPriority = 3;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

As in the above, I set the priority to 3 but it still locked up. Not sure how to work my way round this one.

Bob
Posted on June 17, 2013 at 19:16

Yeah, I'm not actively using STM32F0 devices, and haven't waded too deep into the M0 documentation.

Generally, I would avoid doing things in interrupt service routines that would lead them to get stuck in this fashion, preferring them to drop through and exit quickly.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..