View previous topic :: View next topic |
Author |
Message |
Marco27293
Joined: 09 May 2020 Posts: 126
|
PIC18F47J53 CCS C Compiler 5.090 Sleep vs Deep Sleep |
Posted: Sat Dec 12, 2020 3:35 am |
|
|
Hi,
I have a very well working firmware using deep sleep in order to minimize consumes.
In past projects I used external interrupt 0 hardware connected to PIN_B0 to successfully exit DS.
Unfortunately, my new hw needs to be waked-up by an external interrupt mapped on PIN_C1 pin (e.g. INT_EXT1), so I cannot exit DS anymore.
I would like to use Slepp mode, but I have a couple of questions:
1) Is it possible to exit Sleep using INT_EXT1 or INT_RTC (triggered by a previously set rtc_alarm)? if yes which register bits I need to clear/set ? (I know in asm I can do:
BCF IDLEN
BSF GIE
BCF INT1IF
BSF INT1IE
BSF DSEN
SLEEP
but what about INT_RTC ?
2) What are the mainly differences between Sleep and DS modes regarding power consumption ? In DS I reduce consumes up to 15uA, which is the best
could I got with Sleep mode?
Regards,
Marco |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9294 Location: Greensville,Ontario
|
|
Posted: Sat Dec 12, 2020 6:26 am |
|
|
Though I don't use that PIC, I dled and read the datasheet.
Section 4.5.0 says that ANY interupt will 'wakeup' the PIC from 'sleep' mode.
I didn't read about the power vs sleep modes though. Generally speaking ,reducing power involves turning off all unecessary peripherals,setting I/O pins and using high value pullups.
To me anything less than 10ma IS 'low power'....
Jay |
|
|
Marco27293
Joined: 09 May 2020 Posts: 126
|
|
Posted: Sat Dec 12, 2020 8:18 am |
|
|
I need a more detailed reply.
Which bits I need to set/clear before sleep in order to enable INT_RTC on RTC alarm during sleep?
For my application there is an enormous difference between few uA and few mA power consume (actually we're speaking of a x1000 factor!!)
Please give me a detailed feedback,
Marco |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9294 Location: Greensville,Ontario
|
|
Posted: Sat Dec 12, 2020 8:28 am |
|
|
You should read the CCS manual, have a look at some of the examples they supply as I don't use your PIC though the overall process is the same I mainly use the PIC18F46K22 series with an external RTC.
Using the internal RTC would simply need to enable that interrupt and cut a ISR. Similar process as coding for any interrupt. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1362
|
|
Posted: Sat Dec 12, 2020 9:04 am |
|
|
15uA seems really high to me for deep sleep. Most of my PIC24 chips draw 100's of nA in deep sleep. At the end of your datasheet is a section called "Electrical Characteristics". It will tell you the expected current values based on your configuration.
As far as how interrupts are setup for sleep. There really isn't anything special that needs to be done to have them work in sleep mode. They just do. So if you turn on the EXT1 functionality (on PIC24's it is usually via #pin_select, but I don't know your chip), then the interrupt will automatically wake it from sleep and set the IF bit for that interrupt. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19619
|
|
Posted: Sat Dec 12, 2020 9:23 am |
|
|
Understand that a 'wake' from deep sleep involves a reboot of the chip.
It does a POR when you wake from this mode. You have to reprogram
all of your RAM variables etc.. All data is lost when you use deep sleep.
From the data sheet:
Quote: |
Because VDDCORE could fall below the SRAM retention
voltage while in Deep Sleep mode, SRAM data could
be lost in Deep Sleep. Exiting Deep Sleep mode
causes a POR; as a result, most Special Function
Registers will reset to their default POR values.
Applications needing to save a small amount of data
throughout a Deep Sleep cycle can save the data to the
general purpose DSGPR0 and DSGPR1 registers. The
contents of these registers are preserved while the
device is in Deep Sleep, and will remain valid throughout
an entire Deep Sleep entry and wake-up sequence
|
You have to rewrite your code so that it tests for the restart cause,
and restores all the values you require when you wake. All the
peripherals that were not kept awake, also have to be reprogrammed.
Basically the chip is 'off' when in deep sleep mode, except for the
specific peripherals that can be kept awake. INT0, the RTCC, the ULPWU
pin and possibly the BOR & the WDT.
You can get extremely close to the power consumption of the deep sleep
mode using normal sleep. The difference (for a 3.3v supply) is about the
12uA drawn by the internal regulator. From normal sleep any interrupt
can be used to wake, and your values are all retained. If you are talking
mA of consumption, then you are not switching something off properly
before going to sleep.
Set up properly, in deep sleep the chip will draw about 200nA.
Standard sleep about 12uA. |
|
|
Marco27293
Joined: 09 May 2020 Posts: 126
|
|
Posted: Sun Dec 13, 2020 11:56 am |
|
|
Hi,
I'm actually have problems to enter in sleep mode:
setup_wdt(WDT_OFF); // disabilito WDT
while(RTCSYNC);
#asm
BSF REGSLP
BCF IDLEN
BCF GIE
BCF DSEN
SLEEP
#endasm
It seems after few seconds that the code resumes to be processed from the subsequent instructions after the above code... Why?
How can I fix?
The weird thing is that deep sleep works perfectly:
setup_wdt(WDT_OFF);
while(RTCSYNC);
#asm
BSF DSWDTEN
BSF REGSLP
BCF IDLEN
BCF GIE
BSF DSEN
SLEEP
#endasm |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19619
|
|
Posted: Sun Dec 13, 2020 12:17 pm |
|
|
Use the compilers sleep instructions.
However the wake up, suggests that you have something left running
that is waking the chip. A timer, interrupt etc. |
|
|
Marco27293
Joined: 09 May 2020 Posts: 126
|
|
Posted: Sun Dec 13, 2020 12:27 pm |
|
|
Interrupt are disabled (BCF GIE).
Timers are disabled.
Only RTCC works.
If I use sleep(); like suggested by the compiler nothing changes...
Please, help me, I do not know what could be the problem...
I repeat, Deep sleep is working, BUT I need sleep mode. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Dec 13, 2020 1:03 pm |
|
|
Marco27293 wrote: | If I use sleep(); like suggested by the compiler nothing changes...
Please, help me, I do not know what could be the problem...
|
Post a small but complete test program that uses the sleep() function.
The program should be compilable. Don't post code fragments. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19619
|
|
Posted: Sun Dec 13, 2020 1:17 pm |
|
|
Disabling GIE, will still allow interrupts to wake the chip. In fact it'll not go to
sleep if any of the 'wake source' interrupt flags is set. I suspect this is your
problem.
You have to clear all the interrupts before you try to sleep. Remember
though that some interrupts cannot be cleared without the event being cleared. |
|
|
Marco27293
Joined: 09 May 2020 Posts: 126
|
|
Posted: Sun Dec 13, 2020 1:57 pm |
|
|
Hi Ttelmah,
I cleared all interrupts previously enabled with clear_interrupt(level);
I also disable timer1 and turn off timer0.
It does NOT fix the sleep issue, code exits sleep after few seconds... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19619
|
|
Posted: Mon Dec 14, 2020 1:23 am |
|
|
As I already pointed out, some interrupts have to be serviced, or they
cannot be cleared. INT_RDA is an example of this. You cannot clear
INT_RDA, you have to read the character.
However 'after a few seconds', says that something is waking the chip
Obvious one is watchdog. You do understand that if the watchdog is
enabled in hardware, it cannot be turned off in software. You can only
disable in software, if the watchdog is enabled in software not by the
hardware fuses.
Something is waking your chip. You need to work out 'what'. |
|
|
Marco27293
Joined: 09 May 2020 Posts: 126
|
|
Posted: Mon Dec 14, 2020 2:45 am |
|
|
Hi,
these are my fuses:
#FUSES RTCOSC_INT
#FUSES WDT,WDT1024
#FUSES DSWDT,DSWDTOSC_INT
#FUSES DSWDT_=12
#FUSES NOPROTECT
#FUSES NOIOL1WAY
I think watch dog could be the problem. I need while main code runs, but I need to turn-off it during sleep, I've already tried via software with:
setup_wdt(WDT_OFF);
How can I fix this weird situation ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19619
|
|
Posted: Mon Dec 14, 2020 3:46 am |
|
|
Disable the watchdog in your fuse.
Then enable the watchdog at the start of the code with setup_wdt.
If you look at the watchdog fuse in the data sheet:
Quote: |
bit 0 WDTEN: Watchdog Timer Enable bit
1 = WDT is enabled
0 = WDT is disabled (control is placed on the SWDTEN bit)
|
If you look at the SWDTEN bit there is a note:
Quote: |
This bit has no effect if the Configuration bit, WDTEN, is enabled.
|
The point is that setting it 'on' in the fuses removes control from the
SWDTEN bit. If you turn it off in the fuses, it then becomes software
controllable.. |
|
|
|