Low-power sleep

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, 

 

I'm using an UC3 to schedule the startup of various onboard hardware. To do this I need to put the CPU in a low-power wait state for a given period of time. 1ms+-20% will be more than enough precision. 

 

Is there a convenient way to do this? In my code this will be the first routine to run after boot-up, while the CPU has very little internal hardware fired up, and way before the task switcher is started. 

 

Background: The board uses one shared current limiting power switch which is always on. During a fault it will limit to a predefined constant current and set a FAULT pin accordingly. My plan is to power the CPU from a big cap, which is fed from a diode, all the while monitoring the FAULT pin. While polling the FAULT pin I will enable one load at a time. I expect the current limiter to go into limiting multiple times, but can't let that take down the CPU. To do this the CPU should consume as little current as possible in order to run for a longer time from the cap. 

 

 

Thanks,

Børge

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Putting the processor to sleep is easy via the SLEEP n instruction (where n is your required mode), but ;
1) Which sleep-mode ? (there are at least 5).
2) After a reset the processor will use the default system clock which is the onboard 115 kHz oscillator.


To pick a sleep mode you will need to look at the datasheets where there is ;
a) Electrical Characteristics which has a Power consumption section from where you can get the actual current.
b) Power Manager section which describes the sleep modes and what interrupt(s) will wake the processor from a mode.


Your 'after-reset' code has to configure a wake-up source (eg a timer) and then issue the SLEEP n.


You did not specify which processor you are using, so, using the UC3Bxxx with a 60 MHz clock as an example, you need a maximum of 18.5 mA in Active mode and 7.3 mA in Idle mode.
If you put your "big cap" directly on the processor VDDIN and assume that a 0.3 V drop is acceptable, then for a 1 mS sustain-time the required capacitance is about 60 uF.
(It is better if you put the capacitor upstream of the regulator that supplies VDDIN but you will need to increase the capacitance).
To me, for that amount of sustain time I wouldn't bother with sleeping the processor but would simply use a "big cap".

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Mike, 

 

Thanks a lot for your help! I'm using the AT32UC3A3256. 

 

This code will run right after reset, while clocks are still slow. Do you know if there is existing C code for this, or would I have to write that from scratch? The code I write here will be open sourced. 

 

 

Best,

Børge

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This seems to me to be a special requirement, therefore I doubt that there will be existing code available.
The simplest software technique would be to use the RTC timer, running from the RCSYS clock and with WAKEUP mode enabled.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, thanks!

 

Børge

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have found both a SLEEP() macro and the function pm_configure_clocks() in the code base. Unfortunately, it doesn't seem that the 115kHz RC oscillator is a valid choice on UC3A3. 

 

According to the datasheet the 115kHz RC can't feed the Real-time counter, only an external 32kHz osc can. But other parts of the datasheet says it can. Confusing.  Both external oscillators are busy. I'm running a 12MHz crystal on one which could serve as a timer input. I was hoping to run the deep sleep mode only on the 115kHz RC, but that doesn't seem to be straightforward. 

 

I'll keep searching.

 

 

Børge

 

Last Edited: Tue. Jul 31, 2018 - 01:39 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The ASF pm_configure_clocks() is written for OSC0 only, (I do not know why).


Where did you find "According to the datasheet the 115kHz RC can't feed the Real-time counter ..." ???


There is no "deep sleep" mode, there is a "deep stop" mode but be aware that starting (or restarting) the external oscillators will require time.


RTC

Quote:
8.4.2 Clocks
The RTC can use the system RC oscillator as clock source. ...

...

8.6.1 Control Register
Name: CTRL
...
• CLK32: 32 KHz Oscillator Select
1: The RTC uses the 32 KHz oscillator as clock source.
0: The RTC uses the RC oscillator as clock source.

The "RC oscillator" is also known as the "slow clock" or "RCSYS".
The ASF has an RTC 'driver' to control the RTC module.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Whey, we have working code!

 

Not yet tested on oscilloscope and ampmeter, but seemingly very close to desired 1Hz blink rate. 

 

Børge

 

#define RTC_COUNTER_FREQ	115000			// Nominal frequency of Real Time Counter in Hz

void mobo_rtc_waken(volatile avr32_rtc_t *rtc, uint8_t enable) {
	while (rtc_is_busy(rtc));
	if (enable)
		rtc->ctrl |= AVR32_RTC_WAKE_EN_MASK;		// Set waken
	else
		rtc->ctrl &= ~AVR32_RTC_WAKE_EN_MASK;		// Clear waken
}

void mobo_sleep_rtc_ms(uint16_t time_ms) {
	mobo_rtc_waken(&AVR32_RTC, 0);				// Clear waken before sleeping
	rtc_init(&AVR32_RTC, RTC_OSC_RC, 0);			// RC clock at 115kHz, clear RTC
	rtc_disable_interrupt(&AVR32_RTC);			// For good measure
	rtc_set_top_value(&AVR32_RTC, RTC_COUNTER_FREQ / 2000 * time_ms);	// Counter reset after time_ms ms, accounting for prescaler set to 0 two lines up
	mobo_rtc_waken(&AVR32_RTC, 1);				// Set waken before sleeping
	rtc_enable(&AVR32_RTC);
	SLEEP(AVR32_PM_SMODE_DEEP_STOP);			// Disable all but RC clock
}

while (1) {
	mobo_sleep_rtc_ms(500);
	<led on>
	mobo_sleep_rtc_ms(500);
	<led off>
}

 

Last Edited: Wed. Aug 1, 2018 - 12:06 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

... above code must replace /1000 by /2000 to acount for prescaler causing freq/=2^(n+1) where n=0

 

Timed it for 30s and it was spot on.

 

Last Edited: Wed. Aug 1, 2018 - 12:05 PM