|
|
View previous topic :: View next topic |
Author |
Message |
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
#FUSES question [SOLVED] |
Posted: Mon Feb 27, 2017 12:22 pm |
|
|
Compiler: 5.026
Device: PIC24EP512GP806
Quick question on fuses.... Can you use #FUSES anywhere in the code to modify the behaviour of the MCU _at that point in the code_ ? Or is it the last #FUSES encountered used for the life of the program?
Like for instance, if I use #FUSES at the begining of my code with a bunch of fuses configured and somewhere along the way, inside a function, I call #FUSES again with different fuses.... What should I expect?
The reason I am asking is because I want to disable the watchdog timer when the MCU falls in sleep mode after I call a function I wrote.
In that function, I disable a bunch of interrupts and I do a bunch of other things but I also want to make sure that before I call < sleep( SLEEP_FULL ); >, I need to make sure that the WDT gets disabled because I don't want the MCU to revive itself upon expiry of the WDT.
The MCU can only wake-up upon external interrupts from the serial port or two input interrupt pins.
Many thanks,
Benoit
Last edited by benoitstjean on Mon Feb 27, 2017 9:43 pm; edited 1 time in total |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Mon Feb 27, 2017 1:02 pm |
|
|
A fuse is something that, as far as I know, can only be "burned" by an external programmer. Unless devices with the ability to write program memory can modify the fuse locations? In which case, if that's even possible, modifying them on the fly would be rather involved. You'd need to write the new value to that location and you might also need to program a whole page? |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Mon Feb 27, 2017 1:14 pm |
|
|
Ok, that would make sense.
So these are my fuses:
#fuses HS, PR, WDT, WINDIS, WPOSTS16, NOJTAG, NODEBUG, NOIESO
In my main C file, rght at the start, I do this:
setup_wdt( WDT_16S );
Then at some point in time after a pre-determined timer expires, I go in shutdown mode and when I call the shutdown function:
- I disable and clear a bunch of interrupts
- Stop the timers;
- Call <setup_wdt( WDT_OFF );> ;
- Disable perripheral power with <#byte PMDx = getenv("byte:PMDx")> followed by <PMDx = 0xFF> and do this from 1-8
- Then I call <sleep full>;
So far, the thing goes to sleep but automatically reboots after a few seconds and I call the <restart_cause();> function and keeps returning WATCHDOG TIMER.
Benoit |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Mon Feb 27, 2017 1:35 pm |
|
|
I know that there are some processors with an either/or fuse/no fuse WDT setup. If you use the WDT fuse, you don't have software control of the thing, which explains what you're seeing. You'll have to dig into the data sheet for that processor (or family reference manual) to see if the WDT can be only software controlled. If it can, you'll have to change to NOWDT and then assume software control of it in code. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Mon Feb 27, 2017 1:40 pm |
|
|
You always need to read the data sheet.
Like a lot of other chips, if the watchdog is enabled in the fuses, it cannot be turned off.
Page 143 in the sheet. Note at the bottom:
"2: If the FWDTEN Configuration bit is ‘1’ (unprogrammed), the WDT is always enabled, regardless of the SWDTEN bit setting."
To be able to disable the watchdog when you sleep, you need to turn the watchdog _off_ in the fuses. Then at the start of your code, enable it in software. You can then disable it in software before you sleep. |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Mon Feb 27, 2017 1:54 pm |
|
|
Hmm... So, I changed to this:
.h File:
#fuses HS, PR, NOWDT, WINDIS, WPOSTS16, NOJTAG, NODEBUG, NOIESO
.c file at the start:
Code: |
setup_wdt( WDT_16S | WDT_ON ); |
In my power management function after clearing all interrupts and other stuff:
Code: |
setup_wdt( WDT_OFF );
setup_oscillator( OSC_INTERNAL );
sleep( SLEEP_FULL );
|
This now seems to be working....
So, I guess that if I use the WDT fuse, it overrides the setup_wdt() function? So it means I have to use one or the other, either the fuse OR the functions? So if I use the fuse, then I cannot stop the WDT but if I use the functions, then I have more control?
And if I create a lock condition in my code at the moment with the above setup, the WDT kicks-in as expected. Otherwise, it goes to sleep and waits for my signal before restarting.
Ben |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Mon Feb 27, 2017 2:47 pm |
|
|
Yes.
The reason for the fuse, is that some code has the requirement that the watchdog cannot be turned off. The fuse ensures this. However means you can't use sleep, unless you accept that this will wake from the watchdog. |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Mon Feb 27, 2017 3:27 pm |
|
|
Hi TTelmah,
So from your reply, the code I posted just above where I disable the WDT fuse and use the setup_wdt( WDT_ON ) and WDT_OFF is the way to go, correct? Anyhow, that's what's currently happening - it works.
Thanks,
Benoit |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Mon Feb 27, 2017 3:34 pm |
|
|
Yes.
The setup_wdt function controls the SWDTEN (software watchdog enable) bit.
The fuse is the FWDTEN (fuse watchdog enable) bit.
With the fuse on, the software bit does not work. With it off, you have to enable and disable the watchdog when wanted. |
|
|
|
|
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
|