|
|
View previous topic :: View next topic |
Author |
Message |
peterfreedom
Joined: 12 Sep 2003 Posts: 12 Location: Val-d'or, Quebec, Canada
|
RESTART_CAUSE NOT WORKING! |
Posted: Mon Mar 15, 2004 1:45 pm |
|
|
Hi! Again. I finally made the WatchDog Timer work. Thanks to PCM Programmer. I had to use my In Circuit Serial Programming device instead of my RS-232 Port with a Bootloader.
Here is my question. I'm trying to have the Restart_cause function to give me the real cause of the the Reset on the CPU. I tried the EX_wdt.c without success. I always have code 24 or Normal_Power_Up. I simplified the example to its simpliest form:
Code: | #byte status1 = 0x03
void main()
{
printf("Main Restart Cause = %x\r\n",status1);
setup_wdt(WDT_1152MS);
while(TRUE)
{
printf("While Restart Cause = %x\r\n",status1);
}
} |
This will give this on Hyperterminal:
While Restart Cause = 1f
While Restart Main Restart Cause = 1f
While Restart Cause = 1f
While Restart Cause = 1f
While Restart Cause = 1f
While Restart Cause = 1f
While Restart Cause = 1f
While Restart Cause = 1f
While Restart Cause = 1f
While Restart Cause = 1f
While Restart Cause = 1f
1F is the state of the Status Register and we can see that bit 3 and 4 are alway set to 1. That is a Normal_Power_Up condition. In no way I can get bit 4 to clear to 0 and have the number 8 cause WDT_Timeout. If I take a look at the .hex file generated by CCS I can see this:
Code: | void main()
.................... {
*
0064: MOVLW 57
0065: MOVWF 77
0066: MOVLW 20
0067: MOVWF 04
0068: CLRF 00
0069: INCF 04,F
006A: CLRWDT
006B: DECFSZ 77,F
006C: GOTO 068
006D: CLRF 78
006E: CLRF 79
006F: CLRF 7A
0070: CLRF 7B
0071: CLRF 7C
0072: CLRF 7D
0073: CLRF 7E
0074: MOVLW 50
0075: MOVWF 77
0076: MOVLW A0
0077: MOVWF 04
0078: CLRF 00
0079: INCF 04,F
007A: CLRWDT
007B: DECFSZ 77,F
007C: GOTO 078
007D: CLRF 20
007E: CLRF 04
007F: MOVLW 1F
0080: ANDWF 03,F
0081: MOVLW 06
0082: BSF 03.5
0083: MOVWF 1F
.................... printf("Main Restart Cause = %x\r\n",status1);
*
00A0: CLRF 36
00A1: MOVF 36,W
00A2: CALL 004 |
CCS insert a lot of Clear WDT before the Printf. Is there anyway to avoid this? I'm using a 16f877 with the latest version of CCS 3.181. |
|
|
RKnapp
Joined: 23 Feb 2004 Posts: 51
|
|
Posted: Mon Mar 15, 2004 2:03 pm |
|
|
Hey peterfreedom,
I had a problem with restart_cause() too. I can't tell if you're using the ICD-2 or the ICD-U40, but I am using ICD-U40 v1.23 on PIC18F8720 under CCS compiler v3.187 and no matter what, restart cause was always "normal power up."
I never did figure it out, but I discovered that when I used the ICD-U40 in "standalone" mode -- not in debugging mode -- then the very same code worked fine. You know, that little hammer & wrench mode on the "Debug Configure" tab. And sorry, for some reason I can't find my earlier thread on this, but give that a try.
If you figure out why it works this way, pls let me know.
Hope this helps,
Robert |
|
|
peterfreedom
Joined: 12 Sep 2003 Posts: 12 Location: Val-d'or, Quebec, Canada
|
Sorry, I'm not using any In Circuit Dubugger! |
Posted: Mon Mar 15, 2004 2:08 pm |
|
|
I'm not using any ICD at all. I'm using the serial Port or just leds on outputs to help understand the PIC.
Do you have any idea why CCS inserts that code in the main?
Thanks. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 15, 2004 2:14 pm |
|
|
I took the CCS test program, EX_WDT.C and modified it slightly
for my demo board, and it worked fine. I then modified it some
more, so it would display the value returned by restart_cause().
It displays either 0x18 for a normal power-up or 0x08 for a WDT reset.
I tested it with PCM vs. 3.184, and a 16F877.
Code: | #include <16F877.h>
#fuses XT, WDT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
void main()
{
char c;
c = restart_cause();
printf("c = %x ", c);
switch ( c )
{
case WDT_TIMEOUT:
{
printf("\r\nRestarted processor because of watchdog timeout!\r\n");
break;
}
case NORMAL_POWER_UP:
{
printf("\r\nNormal power up!\r\n");
break;
}
}
setup_wdt(WDT_2304MS);
while(TRUE)
{
restart_wdt();
printf("Hit any key to avoid a watchdog timeout.\r\n");
getc();
}
} |
|
|
|
peterfreedom
Joined: 12 Sep 2003 Posts: 12 Location: Val-d'or, Quebec, Canada
|
SAME RESULT |
Posted: Mon Mar 15, 2004 2:28 pm |
|
|
Here what appears on hyperterminal every 2.3 sec:
Code: | c = 18
Normal power up!
Hit any key to avoid a watchdog timeout.
c = 18
Normal power up!
Hit any key to avoid a watchdog timeout. |
Here is a part of the .hex file:
Code: | void main()
.................... {
*
00B7: MOVLW 57
00B8: MOVWF 77
00B9: MOVLW 20
00BA: MOVWF 04
00BB: CLRF 00
00BC: INCF 04,F
00BD: CLRWDT
00BE: DECFSZ 77,F
00BF: GOTO 0BB
00C0: CLRF 78
00C1: CLRF 79
00C2: CLRF 7A
00C3: CLRF 7B
00C4: CLRF 7C
00C5: CLRF 7D
00C6: CLRF 7E
00C7: MOVLW 50
00C8: MOVWF 77
00C9: MOVLW A0
00CA: MOVWF 04
00CB: CLRF 00
00CC: INCF 04,F
00CD: CLRWDT
00CE: DECFSZ 77,F
00CF: GOTO 0CB
00D0: CLRF 20
00D1: CLRF 04
00D2: MOVLW 1F
00D3: ANDWF 03,F
00D4: MOVLW 06
00D5: BSF 03.5
00D6: MOVWF 1F
.................... char c;
....................
.................... c = restart_cause();
*
00F3: MOVF 03,W
00F4: ANDLW 18
00F5: MOVWF 36
.................... printf("c = %x ", c);
00F6: CLRF 37
00F7: MOVF 37,W
00F8: CALL 004
00F9: INCF 37,F
00FA: MOVWF 77
00FB: MOVF 77,W
00FC: BTFSS 0C.4
00FD: GOTO 0FC
00FE: MOVWF 19
00FF: MOVLW 04
0100: SUBWF 37,W
0101: BTFSS 03.2
0102: GOTO 0F7
0103: MOVF 36,W
0104: MOVWF 38
0105: MOVLW 57
0106: MOVWF 39
0107: GOTO 092
0108: MOVLW 20
0109: BTFSS 0C.4
010A: GOTO 109
010B: MOVWF 19
010C: MOVLW 20
010D: BTFSS 0C.4
010E: GOTO 10D
010F: MOVWF 19
....................
.................... switch ( c )
.................... {
0110: MOVF 36,W
0111: MOVWF 77
0112: MOVLW 08
0113: SUBWF 77,W
0114: BTFSC 03.2
0115: GOTO 11B
0116: MOVLW 18
0117: SUBWF 77,W
0118: BTFSC 03.2
0119: GOTO 129
011A: GOTO 137
.................... case WDT_TIMEOUT:
.................... {
.................... printf("\r\nRestarted processor because of watchdog timeout!\r\n");
011B: CLRF 37 |
The CLWDT will set TO and PD in Status Register before it will be copied in the c variable. Does your compiler do the same thing? |
|
|
peterfreedom
Joined: 12 Sep 2003 Posts: 12 Location: Val-d'or, Quebec, Canada
|
|
Posted: Mon Mar 15, 2004 2:37 pm |
|
|
I just dowloaded latest version 3.187 without any good result. For your information. |
|
|
jds-pic
Joined: 17 Sep 2003 Posts: 205
|
|
Posted: Mon Mar 15, 2004 2:45 pm |
|
|
you must check restart_cause() BEFORE you touch ANY other registers... in fact, get the value and store it as your very first steps in main() -- BEFORE you do ANYTHING else...
Code: |
void main()
{
if ((restart_cause())==NORMAL_POWER_UP)
normal_powerup_flag=TRUE;
else
normal_powerup_flag=FALSE;
#include "sctl-reg.h" /* register and timing control defs */
restart_wdt();
sctl_startup(normal_powerup_flag);
<...>
|
the snippet above works exactly as it you think it should work. the example given by PCM programmer above operates the same way.
jds-pic
Last edited by jds-pic on Mon Mar 15, 2004 2:47 pm; edited 1 time in total |
|
|
Ttelmah Guest
|
|
Posted: Mon Mar 15, 2004 2:46 pm |
|
|
peterfreedom wrote: | I just dowloaded latest version 3.187 without any good result. For your information. |
I have used restart_cause without any problems. However there are some important things that should be applied.
The first is that restart_cause, in order to detect what has happened, has to set one bit in the processor. Because of this, it should only be called _once_. If a second call is made, it may see the bit that was changed by the first call. There is no point in calling restart_cause more than once, since any restart, will vector to the processors boot address.
The second, is that many of the initialisation processes carried out during a normal program start, may lead to changes in the returned status. Hence the call should be made a early as possible in the code.
The third thing is that the defines supplied for restart_cause, seem to miss some of the possible states...
The basic function though does work.
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 15, 2004 2:48 pm |
|
|
Well, I can see you're not using the code that I posted, verbatim,
because you've got ASM code in there that's generated by the
#zero_ram statement.
Are you using the plain PCM compiler, integrated in MPLAB, or are
you using some IDE (PCW ?) with a lot of extra options checked
on some setup screen ? ie., "Zero ram", "clear WDT", etc.
If so, go to the plain compiler. Use my code verbatim.
I tested it with PCM 3.181 and PCM 3.184. No problems. |
|
|
peterfreedom
Joined: 12 Sep 2003 Posts: 12 Location: Val-d'or, Quebec, Canada
|
I found the problem! |
Posted: Mon Mar 15, 2004 3:24 pm |
|
|
I was keeping some old declaration like #include "global.c" that was no more in use. Somewhere hidden in there was a #zero_ram declaration.
If you look at the CCS code above, you see right at the beginning of the program that it clears the RAM and , to prevent to reset on the WatchDog Timer, do a CLRWDT.
So thanks anyway all. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|