summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2011-05-20 01:35:49 -0700
committerKeith Packard <keithp@keithp.com>2011-05-20 01:35:49 -0700
commitd67df9a6dc76ba52f32fa4c0b141825b97a2fbc8 (patch)
tree02fc0fed6c08ad54afe2a1ed9161132fb2f91d88
parent92fcfc2e8e5a9cb789c8d4be36d38c1a73ddd413 (diff)
src-avr: Add 'sleep_cpu' to reduce power usage while idle
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--src-avr/ao_task.c22
-rw-r--r--src-avr/ao_timer.c3
-rw-r--r--src-avr/avr.h1
3 files changed, 9 insertions, 17 deletions
diff --git a/src-avr/ao_task.c b/src-avr/ao_task.c
index 83f12e2b..51467133 100644
--- a/src-avr/ao_task.c
+++ b/src-avr/ao_task.c
@@ -102,19 +102,6 @@ ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *nam
ao_init_stack(task, start);
}
-void
-ao_show_task_from(void)
-{
-// if (ao_cur_task)
-// printf("switching from %s\n", ao_cur_task->name);
-}
-
-void
-ao_show_task_to(void)
-{
-// printf("switching to %s\n", ao_cur_task->name);
-}
-
/* Task switching function. This must not use any stack variables */
void
ao_yield(void) __naked
@@ -187,7 +174,6 @@ ao_yield(void) __naked
SP = AO_STACK_START - 1;
#endif
- ao_show_task_from();
/* Find a task to run. If there isn't any runnable task,
* this loop will run forever, which is just fine
*/
@@ -211,10 +197,11 @@ ao_yield(void) __naked
break;
}
-#ifdef AVR
-#else
/* Enter lower power mode when there isn't anything to do */
if (ao_next_task_index == ao_cur_task_index)
+#ifdef AVR
+ sleep_cpu();
+#else
PCON = PCON_IDLE;
#endif
}
@@ -225,7 +212,6 @@ ao_yield(void) __naked
uint8_t sp_l, sp_h;
sp_l = (uint16_t) ao_cur_task->sp;
sp_h = ((uint16_t) ao_cur_task->sp) >> 8;
- ao_show_task_to();
cli();
asm("out __SP_H__,%0" : : "r" (sp_h) );
asm("out __SP_L__,%0" : : "r" (sp_l) );
@@ -291,9 +277,11 @@ ao_yield(void) __naked
uint8_t
ao_sleep(__xdata void *wchan)
{
+ cli();
__critical {
ao_cur_task->wchan = wchan;
}
+ sei();
ao_yield();
ao_cur_task->alarm = 0;
if (ao_cur_task->wchan) {
diff --git a/src-avr/ao_timer.c b/src-avr/ao_timer.c
index cc48dd2a..f0918a7d 100644
--- a/src-avr/ao_timer.c
+++ b/src-avr/ao_timer.c
@@ -162,6 +162,9 @@ ao_clock_init(void)
PLLCSR |= (1 << PLLE);
while (!(PLLCSR & (1 << PLOCK)))
;
+
+ set_sleep_mode(SLEEP_MODE_IDLE);
+ sleep_enable();
#else
/* Switch system clock to crystal oscilator */
CLKCON = (CLKCON & ~CLKCON_OSC_MASK) | (CLKCON_OSC_XTAL);
diff --git a/src-avr/avr.h b/src-avr/avr.h
index 8c9c7bd7..9811a07f 100644
--- a/src-avr/avr.h
+++ b/src-avr/avr.h
@@ -21,6 +21,7 @@
#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
+#include <avr/sleep.h>
#if TEENSY
#define F_CPU 16000000UL // 16 MHz