avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] Watch Dog Timer problems


From: John Wicking
Subject: [avr-gcc-list] Watch Dog Timer problems
Date: Fri, 11 Apr 2008 09:09:08 +1000
User-agent: Mozilla Thunderbird 1.0 (Windows/20041206)

Problem with WatchDog timer

I had some code which used the Watchdog timer and worked fine.  My code is now not operating correctly.  I can set up the code so the WatchDog timer is turned off.  Then I call a function where it is initialized and wait for the processor to reset.

The code I am using is on a AT90USB1287 with code based on the HOST CDC demo application.  My memory sizes look ok and the Stack pointer is around 0x20FF which looks right.  I am using 21,114 bytes of program memory and 4679 bytes of RAM.

Here is the code I use to test it

// Watchdog timer routines
// These routines are used to test the operation

void die()
    {
    // Procedure to restart the system via the Watchdog timer
    U8 wdt_reg;
#if RELEASE==1
    goto Die_Loop;                        // The Watchdog is on!
#endif
// It must be in debug mode
    cli();                                // Turn off the global interrupt (Timing critical)
    wdt_reset();                        // Reset it
    Wdt_clear_flag();                    // Clear the flag
    Wdt_change_enable();                // We are going to change the setting
    Wdt_enable_1s();                    // Wait one second
Die_Loop:
    // Turn all the LEDS on
    Led0_on();
    Led1_on();
    Led2_on();
    Led3_on();
// Check that the WDT interrupt was not enabled
    wdt_reg=WDTCSR;                        // Read it
    if(wdt_reg&(1<<WDIE))Led0_off();    // Turn it off
    
Die_Loop1:
    goto Die_Loop1;                        // Loop and die
    }

In the Release mode the LEDs all turn on and it waits for one second and then it tries to Reset

I thought it may have been a problem with the Watch Dog timer interrupt being turned on but I check for that by turning off one LED which does not happened.

The process is running after this but it has not done a full reset. I monitor it by loking at messages from the serial port.  If I cycle the power it restarts correctly. I cannot reset it with the JTag MkII

If I replaced the call to the die() with a with a Soft Reset (jmp 0x0000), it works fine.

Here is teh code from the Reset vector to the main().

+00000000:   940C0280    JMP     0x00000280       Jump
+00000002:   940C029F    JMP     0x0000029F       Jump
+00000004:   940C029F    JMP     0x0000029F       Jump
+00000006:   940C029F    JMP     0x0000029F       Jump

and then at 0x280

 
+00000280:   2411        CLR     R1               Clear Register
+00000281:   BE1F        OUT     0x3F,R1          Out to I/O location
+00000282:   EFCF        SER     R28              Set Register
+00000283:   E2D0        LDI     R29,0x20         Load immediate
+00000284:   BFDE        OUT     0x3E,R29         Out to I/O location
+00000285:   BFCD        OUT     0x3D,R28         Out to I/O location
+00000286:   E011        LDI     R17,0x01         Load immediate
+00000287:   E0A0        LDI     R26,0x00         Load immediate
+00000288:   E0B1        LDI     R27,0x01         Load immediate
+00000289:   E9EE        LDI     R30,0x9E         Load immediate
+0000028A:   E6FD        LDI     R31,0x6D         Load immediate
+0000028B:   E000        LDI     R16,0x00         Load immediate
+0000028C:   BF0B        OUT     0x3B,R16         Out to I/O location
+0000028D:   C002        RJMP    PC+0x0003        Relative jump
+0000028E:   9007        ELPM    R0,Z+            Extended load program memory and postincrement
+0000028F:   920D        ST      X+,R0            Store indirect and postincrement
+00000290:   33A4        CPI     R26,0x34         Compare with immediate
+00000291:   07B1        CPC     R27,R17          Compare with carry
+00000292:   F7D9        BRNE    PC-0x04          Branch if not equal
+00000293:   E113        LDI     R17,0x13         Load immediate
+00000294:   E3A4        LDI     R26,0x34         Load immediate
+00000295:   E0B1        LDI     R27,0x01         Load immediate
+00000296:   C001        RJMP    PC+0x0002        Relative jump
+00000297:   921D        ST      X+,R1            Store indirect and postincrement
+00000298:   34A7        CPI     R26,0x47         Compare with immediate
+00000299:   07B1        CPC     R27,R17          Compare with carry
+0000029A:   F7E1        BRNE    PC-0x03          Branch if not equal
+0000029B:   940E03F5    CALL    0x000003F5       Call subroutine
 

and then at 0x 03F5 which is the call to main.

+000003F5:   94F8        CLI                      Global Interrupt Disable
71:                   my_MCUSR=MCUSR;                                               // Read the register
+000003F6:   B794        IN      R25,0x34         In from I/O location
72:                   MCUSR=0;                                                     // Clear all the flags
+000003F7:   BE14        OUT     0x34,R1          Out to I/O location
73:                   wdt_reset();                                          // Pets the Watchdog timer fast
+000003F8:   95A8        WDR                      Watchdog reset
76:                   my_reg=WDTCSR;                                         // Get it
+000003F9:   91800060    LDS     R24,0x0060       Load direct from data space
77:                   my_reg|=(1<<WDIF);                          // Set the interrupt flag bit
+000003FB:   6880        ORI     R24,0x80         Logical OR with immediate
78:                   WDTCSR=my_reg;                                         // Clear it by writing one to it!
+000003FC:   93800060    STS     0x0060,R24       Store direct to data space
81:                   if(my_MCUSR&(1<<WDRF))flags|=(1<<WDT_RS_FLG);    // Set the flag from the copy

 If I set a breakpoint in the disassembled codeor the main code after the Reset vector  and it never seems to reach it.

Thanks for any comments.

Regards

John


reply via email to

[Prev in Thread] Current Thread [Next in Thread]