This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

watchdog not working in 87c520

A strange situation where an internal watchdog reset implementation seems not to work on the 87c520 target while it does work ok when using the Ceibo ICE.

Seems like the reset occurs but unclear where the PC jumps to because the SW does not restart properly but rather stays "stuck" (we know it enters the if (status) passage). With the ICE the program does start ok.

What we do is enable the watchdog timer in the program. In the interrupt handler (ISR 12) depending on some status, we enable the reset itself. All this occurs, but then for the target the program does not go into running normally.

Any ideas?
Thanks,
Baruch



if ( status ) //
{
TA = 0xAA ; //Accessing timed access in order to start the watchdog timer
TA = 0x55 ; //
EWT = 1 ; // Enable WatchDog timer reset

TA = 0xAA; //Accessing timed access in order to start the watchdog timer
TA = 0x55; //
WDIF = 0 ; // watch dog flag clear
}

else
{
TA = 0xAA; //Accessing timed access in order to start the watchdog timer
TA = 0x55; //
WDIF = 0 ; // watch dog flag clear

TA = 0xAA ; //Accessing timed access in order to start the watchdog timer
TA = 0x55 ; //
RWT = 1 ; // Restart Watchdog timer

}

  • Hi,
    first of all - do you read Errata about this MCU? There are alot of problems include bad execution of program from 0x0000 after watchdog reset.
    Seems, the problem is that your software executes any MOVX instruction due watchdog reset as it said in Errata. Really, EWT does not implement momentarely reset but just enables it after about 512 cycles. So your software goes into watchdog ISR then enables reset and comes back to main execution where (probably) there is a MOVX instruction(s). All you need to do is modify ISR something like:

    if ( status ) //
    {
    EA=0;         // disable all interrupts
    
    TA = 0xAA ; //Accessing timed access in order to start the watchdog timer
    TA = 0x55 ; //
    EWT = 1 ; // Enable WatchDog timer reset
    
    TA = 0xAA; //Accessing timed access in order to start the watchdog timer
    TA = 0x55; //
    WDIF = 0 ; // watch dog flag clear
    
    // stop rest program execution
    dead_loop:
    goto dead_loop;
    }
    
    This way stops execution of next commands and so watchdog will restart MCU due JMP command that is correct.

    Good days!

  • rather than a goto:

    for( ;; );

  • aha, I always know that C-programmers do not like goto ((=
    well, then use while(1);

    Good days!

  • Thanks. We were happy for few moments till tested - doesn;t work yet. Also read the Erratas.
    Our version is A15. Its Errata does not include this problem. Still we have just tried the dead loop as well as inserting LCall at address 0, but no success yet.

  • I am sure you want to hear the next chapter.
    We are in the process of tracing it down as follows.

    In our applicaiton, first the EPROM code is executed. It takes a "little" time to complete. Then it loads and turns to the flash.

    When a WD expires in the flash code and the reset is enabled and occurs, the app jumps to the EPROM start point. But then it gets stuck, because as we believe, the EWT or equivalent remains enabled and the WDCON timer is switched to its minimal value, so that a WD reset is continuosly triggered inside the EPROM code. At the moment there is no EWT reset/disable in the beginning of the EPROM code. There is also no WD interrupt handler there.

    A quote:
    "If the device contains internal program memory, the default power-on reset state of EWT is determined by the Watchdog Default POR State bit (WDPOR) located in the System Control Byte or a mask option. This bit is unaffected by all other resets."

    Assuming that the last sentence in the quote ("This bit...") refers to the EWT bit, not the WDPOR bit which the whole paragraphs speaks about, then this conforms the cause.

    We are now trying to comfirm that this is the case.

    So assuming we confirm this, my next question is-
    after such WD reset, can the app be forced to jump to the flash 0 and run from there rather than to the EPROM 0?
    We know of the 87c520 pin that allows control over that, but the question is how to do that by SW only. I believe the ROMSIZE gets reseted too and can;t be used for this purpose.

    Thanks,
    Baruch

  • Hi,
    yes, any reset (either watchdog or external RES pin) set SFRs to their default values except POR flag(s).
    Why do you just not control this flag at first program steps? For example: at first codes just check POR value:
    - if POR=1 then it is first power-on: you do configure flash, make POR=0 by software and wait till watchdog resets MCU;
    - if it is =0 then you make on-chip ROM size equ 0 kb and next instructuon will be fetched from external flash. It is simple.

    Good days!

  • Of course. The normal resolution would be to handle the POR and/or the WTRF (WDCON.2) for the watchdog reset flag at the beginning of the EPROM code.
    For various practical reasons we would have liked to avoid modifying the EPROM code, but it seems that we will have to take this course.

    Thanks again,
    Baruch

  • void main ()
    {
    // disable WDT hardware reset.
    // if wdt ever fires,
    // the initialization
    // and the prom checksum could not
    // complete before wdt fired again,
    // staying there forever, so disable
    // wdt till checksum over.

    // disable WDT hardware reset
    EA = 0; // disable all interrupts
    TA = 0xaa;
    TA = 0x55;
    WDCON = WDCON & ~EWT_;


    other initialization here

    then just before main loop

    // initialize WATCH Dog Timer
    // set WDT for 56.889MS...18.432mhz cry
    // see page 116 in dallasbook
    CKCON |= WD0_;
    CKCON &= ~WD1_;

    // Enable hardware reset
    // if Watch Dog Timer expires
    EA = 0; // disable interrupts
    TA = 0xaa;
    TA = 0x55;
    WDCON = WDCON | EWT_; // Enable WDT

    EA = 1; // enable interrupts

    // MAIN LOOP
    do
    {

    //Watch Dog Timer Reset
    EA = 0; // disable interrupts !!
    // if any interrupt occurs during
    // the following 3 instructions
    // the wdt will not be reset
    // so disable interrupts
    TA = 0xaa;
    TA = 0x55;
    WDCON = WDCON | RWT_; //reset wdt
    EA = 1; // enable all interrupts!!

    other main loop things

    }while(1);

    } // end of main