View previous topic :: View next topic |
Author |
Message |
hmmpic
Joined: 09 Mar 2010 Posts: 314 Location: Denmark
|
restart_cause? Values |
Posted: Fri Nov 10, 2017 10:45 am |
|
|
CCS_IDE:5066
PIC: 16f1825
The function restart_cause() return me a 0x3F but that is not an existing value for my chip?
I think it is a:
BROWNOUT_RESTART it is defined as 0x3E
Any hints? |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Fri Nov 10, 2017 10:57 am |
|
|
You'll have to search through the device's header file as well as the assembly to see how the compiler is "assembling" the restart cause code. From page 79 of the datasheet, the various bits which dictate the restart causes are scattered over the PCON and STATUS registers. It could be that CCS made a mistake.
If you do find a mistake, let them know. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Fri Nov 10, 2017 11:23 am |
|
|
It is actually brownout. There is one bit (POR), which is listed as 'undefined' in this state. It actually depends on just how low the voltage gets. If it gets low enough, the RAM contents start to fail, and this bit can go to '1'....
If the brownout voltage is set higher you get 0x3E all the time, but at the lowest setting, you can sometimes get 0x3F. |
|
|
guy
Joined: 21 Oct 2005 Posts: 297
|
same issue, different chip |
Posted: Tue Nov 14, 2017 1:08 am |
|
|
PIC16LF18855
Compiler version 5.075
I get a restart_cause of 0x32F from a device in the field that got reset somehow. The header contains
Quote: | #define NORMAL_POWER_UP 0x33C
#define BROWNOUT_RESTART 0x33E
#define MCLR_FROM_SLEEP 0x237
#define WDT_TIMEOUT 0x12F
#define WDT_FROM_SLEEP 0x03F
#define INTERRUPT_FROM_SLEEP 0x23F
#define MCLR_FROM_RUN 0x337
#define RESET_INSTRUCTION 0x33B
#define STACK_OVERFLOW 0x3BF
#define STACK_UNDERFLOW 0x37F
#define WDT_WINDOW_VIOLATION 0x31F |
Any ideas about the restart cause parsing? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Tue Nov 14, 2017 2:00 am |
|
|
OK.
The top byte is the bits TO and PD (rotated from the status register).
The low byte is the PCON0 register, except if there has been a POR, it clears the BOR bit. The call also resets the status bits high.
So your pattern is TO and PD both high, and WDTWV RMCLR RI POR BOR all high, with just RWDT low.
Now that means we are looking at the patterns in the sheet that have TO and PD both high or both unchanged for the reset, and something else dropping the RWDT bit first. The only event that drops RWDT, and does not immediately cause a reset, is a watchdog from sleep.
You have had a watchdog timeout, in sleep, which you have not tested for, _followed_ by a brownout reset (which leaves the RWDT bit unchanged).
In fact the original poster here could have had a similar behaviour. If you are using restart_cause it is vital to always call it again after any event that can change the 'cause' bits. So if using sleep, you should call it after waking, if you want the actual cause to be right when the chip does restart. |
|
|
guy
Joined: 21 Oct 2005 Posts: 297
|
|
Posted: Tue Nov 14, 2017 3:49 am |
|
|
Wow! I need a moment here...
Although I don't doubt your explanation Ttelmah I'm having a hard time facing the meaning of this:
A brownout reset is unlikely since I see batteries at 3V. Could be that during startup there was a short bounce with the batteries which caused a voltage glitch and together with the input capacitors caused a quick brownout.
WDT and sleep are both used but the combination is weird:
The chip has T1OSC running a 32KHz crystal causing the chip to wake up every 1 second (by programming a starting value into TMR1). WDT is set to >2sec and reset before sleep. So a restart during sleep means crystal failure (assuming the code is ok). |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Tue Nov 14, 2017 4:16 am |
|
|
What you need to start by doing, is reading 'restart_cause()' immediately after you wake from sleep (actually one instruction after - remember the nop needed after the sleep). This will then clear the watchdog bit, which may be why you are getting the odd result from restart_cause at the start of the code.
If the status at this point does say 'Watchdog from sleep', then you need to start looking at whether something silly is happening like the timer clock getting turned off....
With this done, the restart_cause at the beginning, will then reflect 'why' the chip has really reset, so should tell you what is wrong. If it still says 'brownout', then you at least know where to start looking.
It does sound as if the RTC clock may have stopped, then it woke on the watchdog, and then perhaps because the clock wasn't running ended up doing a reset. Have you got the fuse STVREN set?. If not then you could get the pattern you are showing by having had the watchdog wake from sleep, and then the stack overflow because the clock is not running, and if it pulled perhaps an address 0 from the stack, it ended up at the reset, without any of the status bits being changed. |
|
|
guy
Joined: 21 Oct 2005 Posts: 297
|
|
Posted: Tue Nov 14, 2017 4:45 am |
|
|
I am not referring to STVREN in the code.
I recently moved from the old MPLAB to PCW IDE - is there an easy way to find out a. the default setting of the fuse, b. what is defined in my specific hex file? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Tue Nov 14, 2017 5:30 am |
|
|
You should always be enabling STVREN. Otherwise if the stack overflows/underflows the code can go anywhere, resulting in chaos.
Look at the end of the list file. This shows the fuse settings being used.
The only times not to use STVREN, is if you are writing your own code to trap/handle this, or if you are deliberately overrunning the stack to allow you to push a specific return address or extract the addresses from it. |
|
|
guy
Joined: 21 Oct 2005 Posts: 297
|
|
Posted: Tue Nov 14, 2017 6:41 am |
|
|
Quote: | Configuration Fuses:
Word 1: 3FEC NOEXTOSC RSTOSC_HFINTRC NOCLKOUT CKS FCMEN
Word 2: 3F1C NOMCLR PUT LPBOR NOBROWNOUT BORV24 ZCDDIS PPS1WAY STVREN NODEBUG
Word 3: 3FEB WDT65536 WDT WDTWIN_SW WDTCLK_SW
Word 4: 1FFF NOWRT SCANE NOLVP
Word 5: 3FFC PROTECT CPD |
It seems to be enabled by default. I will bear your tip in mind though. Thanks! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Tue Nov 14, 2017 8:12 am |
|
|
Ok. The default on the later compilers is to leave all fuses in their 'erased' state unless specified. This rules out a stack over/underflow as being what happens after the watchdog, since these would have the higher bits set in the PCON0 register.
Try the read after waking from sleep and see if anything changes. |
|
|
guy
Joined: 21 Oct 2005 Posts: 297
|
|
Posted: Tue Nov 14, 2017 10:39 am |
|
|
Not so easy - it's out in the field and the error cannot be easily recreated... But thanks anyway. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Tue Nov 14, 2017 11:48 am |
|
|
A 'one off' could be as nasty as a cosmic ray hit.
If you are re-designing the code in the future you should add the restart_cause read to help in the future.
There are potentially hundreds of possible patterns. The hardware is meant to only give certain combinations, but an EMI event, or a particle hit can always give otherwise impossible events. |
|
|
jv13159
Joined: 08 Mar 2018 Posts: 1
|
PIC16F15325 0x73F = restart_cause() |
Posted: Fri Mar 09, 2018 7:00 am |
|
|
I have the same problem on the PIC16F15325. My configuration bits are set as follows:
Code: |
#fuses NOWDT,NOPROTECT,NOMCLR,NOBROWNOUT,NODEBUG,NOCLKOUT,NOEXTOSC,RSTOSC_HFINTRC,FCMEN,NOPUT,STVREN,SAF,ZCDDIS,WRTC,NOLPBOR
|
Here is the PIC header code for the function:
Code: |
////////////////////////////////////////////////////////////////// Control
// Control Functions: RESET_CPU(), SLEEP(), RESTART_CAUSE()
// Prototypes:
_bif int16 restart_cause(void);
_bif void reset_cpu(void);
_bif void sleep(void);
// Constants returned from RESTART_CAUSE() are:
#define NORMAL_POWER_UP 0x73C
#define BROWNOUT_RESTART 0x73E
#define MCLR_FROM_SLEEP 0x637
#define WDT_TIMEOUT 0x52F
#define WDT_FROM_SLEEP 0x43F
#define INTERRUPT_FROM_SLEEP 0x63F
#define MCLR_FROM_RUN 0x737
#define RESET_INSTRUCTION 0x33B
#define STACK_OVERFLOW 0x7BF
#define STACK_UNDERFLOW 0x77F
#define WDT_WINDOW_VIOLATION 0x71F
#define MEMORY_VIOLATION 0x33F
|
Every restart is giving me the same 0x73F code regardless if I power the circuit from the supply or the ICD3 debugger. I have another project that uses the same PIC and seems to get the correct reset code on start up. I am thinking it has something to do with the slew rate of the start up but I have no way of telling yet.
Was this issue ever resolved? _________________ Blah blah blah |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Fri Mar 09, 2018 9:19 am |
|
|
That would make a lot of sense. They do have a specification of 0.05V/mSec as the minimum Vdd slew rate to guarantee a proper POR signal. Assuming a linear supply rise, this means 1/16th second for a 3v supply. They do talk about the BOR re-arming, but don't give details, but it might well be that the BOR bit can be triggered before the chip has actually exited it's POR state, which then leaves you with a hybrid of a POR & a brownout.... |
|
|
|