View previous topic :: View next topic |
Author |
Message |
legion
Joined: 10 Oct 2007 Posts: 23
|
PRISD bit and SLEEP() |
Posted: Tue Apr 07, 2015 6:21 am |
|
|
Funny how there's this bit in OSCON2 for 18F2X/4XK22 that nobody seems to talk about :-)
I'm trying to put the PIC into the lowest possible power sleep mode. I've got IDLEN=0 in OSCON so it sleeps not idles when the SLEEP instruction is executed.
But my XTAL is still oscillating during sleep()
In the datasheet I found PRISD in OSCON2: Primary Oscillator Drive Circuit Shutdown bit, which is set during sleep() should it be cleared? I tried clearing it before the sleep() call but ti didn't seem to do anything.
How do we get the XTAL OSC to shutdown when sleep() is called? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19557
|
|
Posted: Tue Apr 07, 2015 7:38 am |
|
|
Show us the CCS code you are using to try to sleep.
Are you sure the chip is actually sleeping?. Something like an interrupt triggered, which is preventing sleep being entered.
Remember you can't stop the oscillator while you are using it.
It should stop on it's own if sleep is being properly entered, but if you want to stop the oscillator, the sequence is:
Code: |
#bit PRISD=getenv("BIT:PRISD")
//put chip to sleep to wake on INT_EXT
setup_oscillator(OSC_31250 | OSC_INTRC | OSC_IDLE_MODE); //switch to internal LP oscillator
PRISD=0; //stop the main oscillator before sleeping
ext_int_edge(H_TO_L);
enable_interrupts(INT_EXT);
clear_interrupt(INT_EXT);
sleep(SLEEP_FULL);
delay_cycles(1); //ensure NOP as next instruction
//now restart the primary oscillator
PRISD=1;
do {
state=setup_oscillator(OSC_NORMAL);
} while(state!=4); //and wait for it to stabilise
//Get here when awake
//do something
delay_ms(100);
|
|
|
|
legion
Joined: 10 Oct 2007 Posts: 23
|
|
Posted: Tue Apr 07, 2015 9:16 am |
|
|
Thanks Ttelmah. If I compile this:
Code: | #include <18F46K22.h>
//8 MHZ XTAL
#fuses HSH,NOFCMEN,MCLR,WDT256,WDT,PUT,PROTECT,NOBROWNOUT,NOLVP,NOCPD,NOWRT,PLLEN
#use delay(clock=64000000)
void main(){
do {
sleep(); //sleep for 256*4mS before WDT times out
delay_cycles(1); //NOP
}
while(TRUE);
}
|
I can see it oscillate on the scope all the time. My naive expectation is for it to stop the osc. during sleep. The reality is that it can't do this.
By experiment, if I put a 10mS delay in the loop it does indeed shut down for a second then oscillate for roughly 10ms. Obviously the clock is unstable for a while after restarting and it seems to defeat the ability to go back to sleep altogether. It makes no difference how long the WDT period is set to - it just doesn't ever shut down the clock.
Your test for clock stability takes over 2 Seconds to complete - but in my application even 10ms is too long. I need it to sleep for 4 Secs. then wake and check a radio in as short a time as possible before sleeping again. Hopefully in less than 10ms. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19557
|
|
Posted: Tue Apr 07, 2015 9:28 am |
|
|
That is one problem of crystal oscillators.....
Big advantage of using the internal oscillator.
However your time is exceptional, which suggests there is something preventing your crystal starting as it should.
A crystal should start and stabilise in perhaps 700clock cycles.
Things that would cause problems:
Overdriving the crystal. This is suggested strongly by the long time it is taking to stabilise. Add a series resistor. Perhaps 200R.
Lack of bias. You can often get a crystal to start better by adding a little resistance across the crystal (perhaps 1M5R).
Badly incorrect loading. If for instance the loading capacitance is much too high, this can slow startup.
Wrong drive. If (for instance) you use HS to drive a low frequency crystal, it'll often give odd harmonics and not stabilise.
Poor smoothing on the processor can also give slow stabilisation.
You are selecting HSH. This is recommended for 16MHz crystals, so you are overdriving. HSM for 8MHz..... |
|
|
legion
Joined: 10 Oct 2007 Posts: 23
|
|
Posted: Tue Apr 07, 2015 10:06 am |
|
|
So I'm actually using an 8MHz resonator which I called an XTAL for some unknown reason. Unfortunately HSH is the lowest power setting I can get it running on.
I like the idea of using the stability check to optimize the drive level though, must remember to use this in the future! |
|
|
legion
Joined: 10 Oct 2007 Posts: 23
|
|
Posted: Tue Apr 07, 2015 11:07 am |
|
|
This sounds like what I need:
Quote: | 2.12 Two-Speed Clock Start-up Mode
Two-Speed Start-up mode provides additional power
savings by minimizing the latency between external
oscillator start-up and code execution. In applications
that make heavy use of the Sleep mode, Two-Speed
Start-up will remove the external oscillator start-up
time from the time spent awake and can reduce the
overall power consumption of the device. |
I tried it out expecting to see the resonator begin spooling up then cut out when the sleep() was executed. I got quite excited when I saw the resonator active for just 1ms - although I had to add a delay_us(200) after sleep() to get it to shut down properly when put to sleep.
But then I tried it without setting IESO in the fuses (the bit that enables two-speed start-up) and it behaves exactly the same. The datasheet says to set IESO, SCS=00 in OSCON (i.e. use FOSC fuse settings) but as far as I can tell it has no advantage over waiting 200us for the resonator to struggle into action, execute my code then successfully enter sleep. |
|
|
legion
Joined: 10 Oct 2007 Posts: 23
|
|
Posted: Tue Apr 07, 2015 11:55 am |
|
|
OK, so NOIESO has to be asserted in the fuses to disable two-speed startup which by default is on. That's why I could see no difference. Blush.
Well, at least now my app can wake, do its business and wait on OSTS to see when the osc. has switched over. This is when it's safe to execute another sleep() |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19557
|
|
Posted: Tue Apr 07, 2015 1:30 pm |
|
|
Why do you actually need the crystal?.
Unless you are doing something that is timing critical, just use the faster internal oscillator. It's accurate enough for 99% of applications. Unless your resonator is a high accuracy device it may well not be much if any better than the internal oscillator, and as you have already found your resonator device unfortunately is very slow to start. If you need the higher accuracy, then try a real crystal, not the ceramic resonator. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Apr 08, 2015 2:36 am |
|
|
How and when are you checking the oscillator?
It would not surprise me in the least that the PIC would not fully sleep in debug - its got to respond to the debugger. So unless its release mode compiled and running on actual system hardware, I wouldn't expect the PIC to turn off the oscillator in debug.
As you probably know, the crystal oscillator takes a long time to start up and stabilise. I have heard that, if anything, its even worse when driving resonators. The internal RC oscillators are, they say, much faster to start/restart. Crystal drive also takes considerable power.
Quote: | Funny how there's this bit in OSCON2 for 18F2X/4XK22 that nobody seems to talk about :-) |
There's no conspiracy of silence or anything like that. CCS C users rarely have to talk about SFR bits at all. That's one of the great things about CCS C - most of the bit fiddling is dealt with behind the scenes by the compiler, allowing us to write simpler, more generic and portable C code, instead of C code that emulates and looks like assembler and is specific to particular processors. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19557
|
|
Posted: Wed Apr 08, 2015 3:00 am |
|
|
All very true.
Lets add one important thing here. My code waits for the oscillator to be stable. This is taking your resonator an absolute age (looks like at least 1000* longer than it should). Now until it is stable, there is not point in using it. After all if you have it because you want 'accuracy', then if it is not stable, it is not doing what you want. The standard code waits 1000 clock cycles for the device to be stable, and this is the delay you are seeing without my test, but in your case the oscillator just is not stable at this time, so using it is basically pointless.
The internal RC oscillator is just a charge discharge system, rather than a resonator based system, and basically starts instantly (uSecs).
I suspect your resonator has a particularly bad startup characteristic...
It's not a problem, waiting for the oscillator to stabilise, if you can do 'non timing critical tasks at this point, and it you are only waking every few seconds. However it sounds as if you are trying to start at quite short intervals, and if so, then if you do need accuracy, the first thing to do is try a crystal. Another suggestion is to try something like a MAX7377 to generate your clock, but this is little if any better than the internal RC oscillator. This takes about 40uSec to switch to the high speed clock. |
|
|
|