CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

PIC24E restart_cause() returns unknown cause 16 (0x10)

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
benoitstjean



Joined: 30 Oct 2007
Posts: 539
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PIC24E restart_cause() returns unknown cause 16 (0x10)
PostPosted: Fri Dec 15, 2017 9:42 am     Reply with quote

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
benoitstjean



Joined: 30 Oct 2007
Posts: 539
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Fri Dec 15, 2017 9:50 am     Reply with quote

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
Ttelmah



Joined: 11 Mar 2010
Posts: 19186

View user's profile Send private message

PostPosted: Fri Dec 15, 2017 1:23 pm     Reply with quote

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'.
benoitstjean



Joined: 30 Oct 2007
Posts: 539
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Fri Dec 15, 2017 1:25 pm     Reply with quote

Ohhh.... I see what you mean. Ok, I'll work something out.

Thanks.

Benoit
Ttelmah



Joined: 11 Mar 2010
Posts: 19186

View user's profile Send private message

PostPosted: Fri Dec 15, 2017 1:38 pm     Reply with quote

If you want to test the WDTO bit, just test it.
Code:

#BIT WDTO=getenv("BIT:WDTO")


     if (WDTO)   //will test the WDTO bit
benoitstjean



Joined: 30 Oct 2007
Posts: 539
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Wed Feb 21, 2018 9:54 am     Reply with quote

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
Ttelmah



Joined: 11 Mar 2010
Posts: 19186

View user's profile Send private message

PostPosted: Wed Feb 21, 2018 11:21 am     Reply with quote

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.
benoitstjean



Joined: 30 Oct 2007
Posts: 539
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Wed Feb 21, 2018 12:55 pm     Reply with quote

Where does the debugger come from? I'm not using a debugger.

I'm printing to a serial console.
Ttelmah



Joined: 11 Mar 2010
Posts: 19186

View user's profile Send private message

PostPosted: Wed Feb 21, 2018 1:12 pm     Reply with quote

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.
benoitstjean



Joined: 30 Oct 2007
Posts: 539
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Wed Feb 21, 2018 1:20 pm     Reply with quote

#build ( stack=1024 )
Ttelmah



Joined: 11 Mar 2010
Posts: 19186

View user's profile Send private message

PostPosted: Wed Feb 21, 2018 1:53 pm     Reply with quote

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.
benoitstjean



Joined: 30 Oct 2007
Posts: 539
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Wed Feb 21, 2018 2:01 pm     Reply with quote

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
benoitstjean



Joined: 30 Oct 2007
Posts: 539
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Thu Feb 22, 2018 6:57 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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