Post Go back to editing

Watchdog reset event from NMI ISR on BF518

Hi,

If I set the watchdog timer to generate a non-maskable interrupt (NMI), then a watchdog event occurs sending the program counter into the NMI interrupt service routine (ISR), then, from within this ISR, change the settings of the watchdog timer such that it has a new count value, the count starts over, and it will generate a reset event (rather than another NMI event) if it expires again?  If the watchdog timer expires in this NMI, again, will it force the reset?

In my application, I use the watchdog timer to generate an NMI if it expires.  Within the NMI ISR, I use the SPI port (using a polling method) to write current context parameters (the values of vital program control variables) to an external EEPROM, then I generate a software reset with the raise(1) function. I am concerned in this scenario that the processor may hang somehow while waiting for a write to complete to the EEPROM.  I would like to re-use the watchdog timer to avoid this possible scenario and force the reset, even if the context parameters weren't saved to EEPROM, correctly. This is preferred to just hanging in an infinite loop.

Thanks,

David

  • Hi Phil,

    It says in HRM about the WDRO bit: It can be cleared only by writing a “1” to the bit when the watchdog has been disabled first. Could you try with that sequence, in your ISR?

    Regards

    Prasanth.

  • the watchdog does not re-arm itself once it has gone off.  software must restart the counter.  so if you arent reloading the value in your NMI, it isnt going to go off.

    once the watchdog expires, the peripheral doesnt care how you re-program it.  so you could reconfigure it to trigger a software reset and have things work just fine.

    you didnt say what Blackfin variant you're using, but on many, "raise 1" does not perform a software reset.  it only resets the core -- the system (i.e. peripherals) are not reset.

  • I am currently using a BF518. In the future, I hope to use the same code for the BF512.

    From: Mike Frysinger analog@sgaur.hosted.jivesoftware.com

    Sent: Thursday, March 18, 2010 11:19 AM

    To: Parkinson, David E.

    Subject: New message: "Watchdog reset event from NMI ISR on BF518"

    Analog Devices EngineerZone<https://ez.analog.com/index.jspa>

    Watchdog reset event from NMI ISR on BF518

    reply from Mike Frysinger<https://ez.analog.com/people/vapier> in Blackfin Processors - View the full discussion<https://ez.analog.com/message/8273#8273

  • the BF51x bootrom should take care of the system reset for you when you issue a core reset via 'raise 1', so you shouldnt have to worry about it there

  • Hi David (and Mike),

    I am working on this now and wrote the code below. The NMI occurs as expected and I wind up in the NMI handler; but, instead of then returning to main, I end up in _register_handler_ex. I've not worked with NMI handling previously, and so have some debug and learning ahead. I won't return to this effort till later today so I'm posting the code as you might find this interesting. Talk soon. -Phil

    -----------------------------------------------------------------------------------------------------------------------------

    //PLL is (25MHz * 16 = 400 MHZ) at power up, SCLK is /5 so SCLK =80 MHz

    #define WDOGPERIOD 0x00200000  //26.2 ms

    volatile unsigned short temp_reg;

    EX_NMI_HANDLER(nmi_isr);

    int main( void )
    {

    temp_reg = *pSWRST;
    if (temp_reg & RESET_WDOG)
    {
           printf("SW reset generated by watchdog \n");
    }

    register_handler(ik_nmi, nmi_isr);

    *pWDOG_CNT = WDOGPERIOD;    //PLL is 25MHz * 16 at power up, SCLK is /5 so SCLK =80 MHz
    *pWDOG_CTL = WDEN | WDEV_NMI;

    while(1){
    asm("nop;");
    asm("nop;");
    asm("nop;");
    }

    }

    EX_NMI_HANDLER(nmi_isr)
    {

    *pWDOG_CTL = WDDIS;

    asm("nop;");
    asm("nop;");
    asm("nop;");

    }

  • Phil,

    I agree with Prasanth.  To disable the watchdog, you need to clear the WDRO bit along with the WDDIS.  Also, I've found that it's helpful to put a couple of ssync()s before writing to the WD control register.  So, something like this in your NMI:

    ssync();
    ssync();
    /* Clear the watchdog expired bit */

      *pWDOG_CTL = WDRO | WDDIS;

    Also, if you are trying to run this on the emulator, it won't work. The HRM says its disabled when in "emulation mode".  Dunno what it does on the simulator.  Also, at the end of your NMI isr, if you want to reset everything, you need another instruction, like "raise(1)".

  • Hi David,

    At present I am not trying to re-enable the watchdog nor cause the reset. Sorry if that was not clear. I want to clear the NMI condition and am not sure how to do that.

    Prasanth,

    Do you have an example of a NMI ISR handler?

    Thanks,

    Phil

  • I tried implementing this method on hardware.  It seems to work fine. Thanks all for the advice.

    The NMI ISR I have is basically:

    EX_NMI_HANDLER(WatchdogTimerIsr)
    {

        *pWDOG_CTL =  WDDIS;

       ssync();
       ssync();
      
       /* Clear the watchdog expired bit */
       *pWDOG_CTL = WDRO | WDDIS;

       /* Setup WDT interrupt for forced reset in-case something goes awry in
          this ISR         */
       ssync();
       ssync();  
      
       *pWDOG_CNT = MY_WATCHDOG_COUNT


       *pWDOG_CTL = WDEN;   
       /* WDEV(1:0)  = 00 generate reset event
        *            = 01 generate nmi (use WDEV_NMI)
        *            = 10 generate gp interrupt (use WDEV_GPI)
        *            = 11 disable event generation
        *
        * WDEN(7:0)  = 0xAD counter disabled
        *            = all other values, counter is enabled
        *            = WDEN constant, counter enabled
        *            = WDDIS constant, counter disabled
        *
        * WDRO - W1C = 0 watchdog timer has not expired
        *            = 1 watchdog timer has expired
        */

    /*temp code to force 2nd watchdog timeout */
       for(;;) { asm("nop;"); asm("nop;"); }
    /* end temp */

    /* insert code to write to context to EEPROM or whatever else needs to happen */

         /* Change the BCODE fields of the SYSCR register so
        * that the processor will undergo a full reboot. */
       *pSYSCR = *pSYSCR | BCODE_ALLBOOT;

       /* Wait for MMR write to complete. */
       ssync();
       ssync();

       /* Found the ssync() calls were not enough and had
        * to put this delay in.  Didn't try minimizing the
        * delay so its possible a much shorter delay
        * would work.   */
       DELAY_MSECS(100);

    /* Cause a processor reset */
       raise(1);

  • Hi David,

    I am glad you are up and running. I had the idea you might want to return from the NMI without resetting for the case where the EEPROM is written correctly.

    So - sorry for my confusion on that.

    Thanks. -Phil