|
|
View previous topic :: View next topic |
Author |
Message |
starfire151
Joined: 01 Apr 2007 Posts: 195
|
PIC18F26K22 and sleep mode |
Posted: Sat May 05, 2012 10:12 am |
|
|
I'm using the PCWHD V4.132 compiler.
I have an application I would like to run on a PIC18F26K22 platform that normally uses the internal oscillator at 4MHz and also uses the sleep mode. I want the watchdog timer and an external interrupt to be able to wake the platform from sleep. I planned the watchdog to wake at the longest period (WDT32768 postscaler for a wakeup period of about 2.18 minutes) with the external interrupt (EXT0) waking immediately.
I got the baseline program working with the internal oscillator at 4MHz successfully. I used the #FUSES INTRC_IO for the internal oscillator. I also selected the #FUSES NOPLLEN.
From a test program I developed for the PIC18LF2620 platform using sleep mode, watchdog timers, and external interrupts, I also included the #FUSES NOWDT and then use the proram statements setup_wdt(WDT_ON) and setup_wdt(WDT_OFF) to control when I want the watchdog to be enabled or disabled. I would put the device into sleep and then wake it with either the watchdog timing out or the external interrupt. A flag set in the EXT0 ISR told me what the wake source was. I could then do some background task, clean up, and then return to sleep until the next wakeup. This worked well on the 2620 platform but not so much when I tried to migrate it to the K22 platform. When I include the #FUSES NOWDT in the K22 program, I never see a watchdog timeout. The external interrupt works but I don't see the watchdog. I have tried several postscaler values but none appear to work. When I don't include the #FUSES NOWDT and selected a postscaler value, the watchdog DOES work but the setup_wdt(WDT_OFF) doesn't stop it from running in the background.
I noticed in the datasheet for the K22 that the WDT is coming from the internal oscillator LFINTOSC source.
Is there an issue with using the internal oscillator for normal program operation but also using the watchdog timer to wake from sleep?
If anyone has done this, how did you set up your fuses to use the internal oscillator for normal program operation while including the watchdog postscaler and allowing programmatic control over the watchdog running by allowing setup_wdt(WDT_ON) and setup_wdt(WDT_OFF)?
Thanks for any help. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19536
|
|
Posted: Sat May 05, 2012 12:41 pm |
|
|
Your problem is not with the oscillator selection, or with the fuses, but with the different types of 'sleep'. On these low power PIC's, there are different 'levels' of sleep. The lowest (the default), _stops_ all the oscillators for the lowest possible power consumption - including the LFINTOSC.
If you look at table 3-1 in the data sheet, it shows the modes. You are starting in 'PRI_RUN', and switching to 'sleep' (top two entries in the table). You will see that the CPU is off, _and_ the peripherals are off - this includes the WDT. You need instead to be switching to 'PRI_IDLE', where the peripherals are left running.
This is controlled by the 'setup_oscillator' command, and the setting 'OSC_IDLE_MODE' in this. If you enable this _before_ selecting 'sleep', the peripheral oscillator is left running.
The normal operation, is to switch everything to the low speed oscillator as well, then turn it back up when you wake.
So:
Code: |
setup_oscillator(OSC_31250 | OSC_IDLE_MODE);
sleep();
delay_cycles(1); //This is prefetched when you sleep - NOP
setup_oscillator(OSC_4MHZ); //Back up to full speed
|
Setting the idle mode 'bit' is the critical part.
Best Wishes |
|
|
starfire151
Joined: 01 Apr 2007 Posts: 195
|
|
Posted: Sat May 05, 2012 1:04 pm |
|
|
Excellent! Thanks very much.
I will try that out. |
|
|
starfire151
Joined: 01 Apr 2007 Posts: 195
|
|
Posted: Sun May 06, 2012 9:59 am |
|
|
FYI: follow-on test results ---
I found there was a fuse for the PIC18F26K22 to specify the software as the source of turning the watchdog timer on and off (WDT_SW). With my PIC18LF2620 testbed, I used #FUSES NOWDT and then enabled and disabled the watchdog with setup_wdt(WDT_ON) and setup_wdt(WDT_OFF). When I used the #FUSES WDT_SW with the K22, the software was able to control the watchdog with the setup_wdt() commands. I didn't have to use the setup_oscillator() statements at all. When I coded it up in my testbed, it worked perfectly. I only call the setup_oscillator(OSC_PLL_OFF | OSC_4MHZ) statement once at the start of program operation. After I do my normal background operations, I call sleep(). After the period of time defined in the #FUSES WDTxxx (where xxx is the postscaler multiplier of 4ms) the next statement after the sleep() command is executed. I was able to code the setup_wdt(WDT_OFF) and do background operations lasting longer than the watchdog period so I know the watchdog was disabled.
Thanks, again, for your help with this. |
|
|
|
|
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
|