![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
PIC24E restart_cause() returns unknown cause 16 (0x10) |
Posted: Fri Dec 15, 2017 9:42 am |
|
|
Compiler: 5.026
Device: PIC24EP512GP806
In the device header file, these are the listed cause values for <restart_cause()>:
Code: |
#define RESTART_POWER_UP 0
#define RESTART_BROWNOUT 1
#define RESTART_WATCHDOG 4
#define RESTART_SOFTWARE 6
#define RESTART_MCLR 7
#define RESTART_ILLEGAL_OP 14
#define RESTART_TRAP_CONFLICT 15
|
In my code, the MCU goes to sleep after 1 minute. When it returns from sleep, the first thing I do is check the restart_cause() flag and it returns 16 (0x10). This is not listed in the device header file.
What can it be?
I'll check the MCU docs but in the meantime, if someone has a good answer, then it would be appreciated!
Thanks!
Ben |
|
![](templates/subSilver/images/spacer.gif) |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
|
Posted: Fri Dec 15, 2017 9:50 am |
|
|
So in the MCU docs <http://ww1.microchip.com/downloads/en/DeviceDoc/S8.pdf> register <Register 8-1: RCON: Reset Control Register>, it seems that restart cause 16 (0x10) is 'Watchdog Time-out Flag bit':
bit 4 WDTO: Watchdog Time-out Flag bit
1 = WDT time-out has occurred
0 = WDT time-out has not occurred
But the unit did not wake-up via a WDT timeout, it woke-up via an external interrupt on EXT 0 while it was sleeping.
So my question is why isn't it returning 0x80 instead since bit 3 is:
bit 3 SLEEP: Wake-up from Sleep Flag bit
1 = Device has been in Sleep mode
0 = Device has not been in Sleep mode
Thanks!
Ben |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Fri Dec 15, 2017 1:23 pm |
|
|
Restart_cause, only works at the start of the code, when the processor has 'restarted'. Calling it anywhere else, is not guaranteed to give a genuine reason.
It sounds as if you are calling it after the processor has waken from sleep, not 'restarted'. |
|
![](templates/subSilver/images/spacer.gif) |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
|
Posted: Fri Dec 15, 2017 1:25 pm |
|
|
Ohhh.... I see what you mean. Ok, I'll work something out.
Thanks.
Benoit |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Fri Dec 15, 2017 1:38 pm |
|
|
If you want to test the WDTO bit, just test it.
Code: |
#BIT WDTO=getenv("BIT:WDTO")
if (WDTO) //will test the WDTO bit
|
|
|
![](templates/subSilver/images/spacer.gif) |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
|
Posted: Wed Feb 21, 2018 9:54 am |
|
|
Back to this issue, I may have caught the "Unknown cause" interrupt and it seems that it is caused by SWDTEN.
At the very begining of the code when it starts, I print the registers below. What has happened is that my MCU rebooted all of a sudden and the SWDTEN bit was set to '1'. This is with the following code:
#fuses HS, PR, NOWDT, WINDIS, WPOSTS16, NOJTAG, NODEBUG, NOIESO
Then in my code, I do the following:
Code: |
main()
{
Error.InternalRestartCode = restart_cause();
#BIT POR=getenv("BIT:POR")
#BIT BOR=getenv("BIT:BOR")
#BIT IDLE=getenv("BIT:IDLE")
#BIT SLEEP=getenv("BIT:SLEEP")
#BIT WDTO=getenv("BIT:WDTO")
#BIT SWDTEN=getenv("BIT:SWDTEN")
#BIT SWR=getenv("BIT:SWR")
#BIT EXTR=getenv("BIT:EXTR")
#BIT VREGS=getenv("BIT:VREGS")
#BIT CM=getenv("BIT:CM")
#BIT VREGSF=getenv("BIT:VREGSF")
#BIT SBOREN=getenv("BIT:SBOREN")
#BIT IOPUWR=getenv("BIT:IOPUWR")
#BIT TRAPR=getenv("BIT:TRAPR")
fprintf( SERIAL, "\n\r\n\rStart -> TRAPR: %u, IOPUWR: %u, SBOREN: %u, VREGSF: %u, CM: %u, VREGS: %u, EXTR: %u, SWR: %u, SWDTEN: %u, WDTO: %u, SLEEP: %u, IDLE: %u, BOR: %u, POR: %u", TRAPR, IOPUWR, SBOREN, VREGSF, CM, VREGS, EXTR, SWR, SWDTEN, WDTO, SLEEP, IDLE, BOR, POR );
setup_wdt( WDT_16S | WDT_ON ); <---- Should it be called here?
// Rest of the code from here.
} |
Does it matter where setup_wdt() is called?
Should I move it at the very very begining?
And in the MCP docs under SWDTEN:
SWDTEN: Software Enable/Disable of WDT bit(3)
1 = WDT is enabled
0 = WDT is disabled
3: If the FWDTEN Configuration bit is ‘1’ (unprogrammed), the WDT is always enabled, regardless of the SWDTEN bit setting.
Maybe someone can shed some light as to what I am doing wrong and what is the appropriate action to correct this?
Everytime I power-up the unit, the SWDTEN bit is always 0. But when this unexpected reboot occured, it was set to '1'.
Thanks,
Benoit |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Wed Feb 21, 2018 11:21 am |
|
|
How are you testing this?.
You do realise you can not enable the watchdog, if you are using a debugger?.
The chip will crash if you enable the watchdog, and have the chip in debug mode. The debug executive can't work with the watchdog enabled. |
|
![](templates/subSilver/images/spacer.gif) |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
|
Posted: Wed Feb 21, 2018 12:55 pm |
|
|
Where does the debugger come from? I'm not using a debugger.
I'm printing to a serial console. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Wed Feb 21, 2018 1:12 pm |
|
|
I just 'wondered'....
It was a possibility.
Debuggers will prevent the watchdog fuse being set, but can't stop one from setting the SWDTEN bit, and it gives exactly your symptoms.
As another possibility, what stack size have you got selected?. The stack on PIC24/30/33's is used for data as well as simple call/return information, and a stack overflow, unless you have added a trap, would cause a reset. Printf instructions use a lot of stack space, and your print instruction is large enough that this could be happening, especially on a relatively early V5 compiler as you mention (CCS doubled the default size only a few versions later).
#BUILD (STACK=384)
I'd suggest as worth a try. |
|
![](templates/subSilver/images/spacer.gif) |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
|
Posted: Wed Feb 21, 2018 1:20 pm |
|
|
#build ( stack=1024 ) |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Wed Feb 21, 2018 1:53 pm |
|
|
All we actually know, is that SWDTEN is enabled when the problem happens. Doesn't mean this is the 'cause'.
Things that can cause you to get to the restart, with a flag pattern that isn't recognised, are problems like an interrupt that doesn't have a handler present, or a jump to the start of memory. |
|
![](templates/subSilver/images/spacer.gif) |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
|
Posted: Wed Feb 21, 2018 2:01 pm |
|
|
All righty. Problem is it is very rare so I don't know how / what causes it.
The worst case scenario is that it resets the unit. But since it's very rare, I don't really mind.
Thanks,
Ben |
|
![](templates/subSilver/images/spacer.gif) |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
|
Posted: Thu Feb 22, 2018 6:57 am |
|
|
UPDATE:
An explanation from CCS support:
-------------------------------------
The only ways that it should be able to return 16 for restart_cause() is if it was called twice in software, or if something caused the program to jump to a point that caused restart_cause() get called again without it being an actual reset of the device. A call to goto_address(0); is an example of how the second way could occur. I would check that you don't have multiple calls to restart_cause() in your code, one example that I've personally run into is that I had a call to restart_cause() in a standalone bootloader and then call it again in my application.
-------------------------------------
I looked in my code and the only two places I call restart_cause() is at the beginning of the main():
Code: | void main()
{
delay_ms( 250 );
// Enable watchdog timer
setup_wdt( WDT_16S | WDT_ON );
// Get MCU's internal last restart cause
Error.InternalRestartCode = restart_cause();
// rest of code here
} |
...and after the delay_cycles(100) following sleep( SLEEP_FULL ):
Code: | // Sleep NOW
sleep( SLEEP_FULL );
// Wake-up from sleep
delay_cycles(100);
// Get MCU's internal last restart cause
Error.InternalRestartCode = restart_cause(); |
I'll post more if CCS replies to this.
Benoit |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|