The power-saving SLEEP patch by Simon Elén.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3259 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Björn Stenberg 2003-02-14 09:44:34 +00:00
parent 84706a4188
commit c4d8d970f6
15 changed files with 101 additions and 31 deletions

View file

@ -1376,3 +1376,8 @@ id: LANG_RECORDING_SIZE
desc: Display of recorded file size
eng: "Size:"
new:
id: LANG_CPU_SLEEP
desc: in system_settings_menu()
eng: "Power Saving"
new:

View file

@ -103,12 +103,12 @@ void init(void)
font_init();
show_logo();
set_irq_level(0);
#ifdef DEBUG
debug_init();
#else
serial_setup();
#endif
set_irq_level(0);
i2c_init();

View file

@ -180,8 +180,7 @@ bool recording_screen(void)
while(!done)
{
yield();
button = button_get(false);
button = button_get_w_tmo(HZ / peak_meter_fps);
switch(button)
{
case BUTTON_OFF:

View file

@ -21,6 +21,7 @@
#include <stdio.h>
#include "config.h"
#include "kernel.h"
#include "thread.h"
#include "settings.h"
#include "disk.h"
#include "panic.h"
@ -102,7 +103,7 @@ offset abs
0x23 0x37 <rec. left gain (bit 0-3)>
0x24 0x38 <rec. right gain (bit 0-3)>
0x25 0x39 <disk poweroff flag (bit 0), MP3 buffer margin (bit 1-3),
Trickle charge flag (bit 4)>
Trickle charge flag (bit 4), CPU sleep flag (bit 5)>
0x26 0x40 <runtime low byte>
0x27 0x41 <runtime high byte>
0x28 0x42 <topruntime low byte>
@ -350,7 +351,8 @@ int settings_save( void )
config_block[0x25] = (unsigned char)
((global_settings.disk_poweroff & 1) |
((global_settings.buffer_margin & 7) << 1) |
((global_settings.trickle_charge & 1) << 4));
((global_settings.trickle_charge & 1) << 4) |
((global_settings.cpu_sleep & 1) << 5));
{
static long lasttime = 0;
@ -513,6 +515,8 @@ void settings_apply(void)
global_settings.lang_file);
lang_load(buf);
}
cpu_sleep(global_settings.cpu_sleep);
}
/*
@ -636,6 +640,7 @@ void settings_load(void)
global_settings.disk_poweroff = config_block[0x25] & 1;
global_settings.buffer_margin = (config_block[0x25] >> 1) & 7;
global_settings.trickle_charge = (config_block[0x25] >> 4) & 1;
global_settings.cpu_sleep = (config_block[0x25] >> 5) & 1;
}
if (config_block[0x27] != 0xff)
@ -881,6 +886,7 @@ void settings_reset(void) {
global_settings.lang_file[0] = 0;
global_settings.runtime = 0;
global_settings.topruntime = 0;
global_settings.cpu_sleep = true;
}

View file

@ -147,6 +147,8 @@ struct user_settings
int bidir_limit; /* bidir scroll length limit */
int scroll_delay; /* delay (in 1/10s) before starting scroll */
int scroll_step; /* pixels to advance per update */
bool cpu_sleep; /* Use sleep instruction when idle? */
};
/* prototypes */

View file

@ -27,6 +27,7 @@
#include "mpeg.h"
#include "button.h"
#include "kernel.h"
#include "thread.h"
#include "sprintf.h"
#include "settings.h"
#include "settings_menu.h"
@ -539,6 +540,13 @@ static bool poweroff(void)
}
#endif
static bool cpu_sleep_set(void)
{
bool result = set_bool(str(LANG_CPU_SLEEP), &global_settings.cpu_sleep);
cpu_sleep(global_settings.cpu_sleep);
return result;
}
static bool buffer_margin(void)
{
return set_int(str(LANG_MP3BUFFER_MARGIN), "s",
@ -731,6 +739,7 @@ static bool system_settings_menu(void)
#ifdef HAVE_ATA_POWER_OFF
{ str(LANG_POWEROFF), poweroff },
#endif
{ str(LANG_CPU_SLEEP), cpu_sleep_set },
#ifndef SIMULATOR
{ str(LANG_BATTERY_CAPACITY), battery_capacity },
#endif

View file

@ -111,7 +111,8 @@ static int wait_for_bsy(void)
{
int timeout = current_tick + HZ*10;
while (TIME_BEFORE(current_tick, timeout) && (ATA_ALT_STATUS & STATUS_BSY))
yield();
sleep_thread();
wake_up_thread();
if (TIME_BEFORE(current_tick, timeout))
return 1;
@ -131,7 +132,8 @@ static int wait_for_rdy(void)
while (TIME_BEFORE(current_tick, timeout) &&
!(ATA_ALT_STATUS & STATUS_RDY))
yield();
sleep_thread();
wake_up_thread();
if (TIME_BEFORE(current_tick, timeout))
return STATUS_RDY;

View file

@ -163,19 +163,8 @@ int button_get(bool block)
int button_get_w_tmo(int ticks)
{
struct event ev;
unsigned int timeout = current_tick + ticks;
while (TIME_BEFORE( current_tick, timeout ))
{
if(!queue_empty(&button_queue))
{
queue_wait(&button_queue, &ev);
return ev.id;
}
yield();
}
return BUTTON_NONE;
queue_wait_w_tmo(&button_queue, &ev, ticks);
return (ev.id != SYS_TIMEOUT)? ev.id: BUTTON_NONE;
}
#ifdef HAVE_RECORDER_KEYPAD

View file

@ -19,6 +19,7 @@
#include "lcd.h"
#include "sh7034.h"
#include "kernel.h"
#include "thread.h"
#include "debug.h"
#define PB13 0x2000
@ -108,7 +109,8 @@ void i2c_ack(int bit)
SCL_INPUT; /* Set the clock to input */
while(!SCL) /* and wait for the MAS to release it */
yield();
sleep_thread();
wake_up_thread();
DELAY;
SCL_OUTPUT;
@ -130,7 +132,8 @@ int i2c_getack(void)
SDA_INPUT; /* And set to input */
SCL_INPUT; /* Set the clock to input */
while(!SCL) /* and wait for the MAS to release it */
yield();
sleep_thread();
wake_up_thread();
if (SDA)
/* ack failed */

View file

@ -19,12 +19,17 @@
#ifndef THREAD_H
#define THREAD_H
#include <stdbool.h>
#define MAXTHREADS 16
#define DEFAULT_STACK_SIZE 0x400 /* Bytes */
int create_thread(void* function, void* stack, int stack_size, char *name);
void switch_thread(void);
void sleep_thread(void);
void wake_up_thread(void);
void init_threads(void);
int thread_stack_usage(int threadnum);
void cpu_sleep(bool enabled);
#endif

View file

@ -59,13 +59,15 @@ void sleep(int ticks)
int timeout = current_tick + ticks + 1;
while (TIME_BEFORE( current_tick, timeout )) {
yield();
sleep_thread();
}
wake_up_thread();
}
void yield(void)
{
switch_thread();
wake_up_thread();
}
/****************************************************************************
@ -96,8 +98,9 @@ void queue_wait(struct event_queue *q, struct event *ev)
{
while(q->read == q->write)
{
switch_thread();
sleep_thread();
}
wake_up_thread();
*ev = q->events[(q->read++) & QUEUE_LENGTH_MASK];
}
@ -108,8 +111,9 @@ void queue_wait_w_tmo(struct event_queue *q, struct event *ev, int ticks)
while(q->read == q->write && TIME_BEFORE( current_tick, timeout ))
{
switch_thread();
sleep_thread();
}
wake_up_thread();
if(q->read != q->write)
{
@ -201,6 +205,7 @@ void IMIA0(void)
}
current_tick++;
wake_up_thread();
TSR0 &= ~0x01;
}
@ -257,7 +262,8 @@ void mutex_lock(struct mutex *m)
{
/* Wait until the lock is open... */
while(m->locked)
yield();
sleep_thread();
wake_up_thread();
/* ...and lock it */
m->locked = true;

View file

@ -845,6 +845,7 @@ static void dma_tick(void)
{
saving = true;
queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
wake_up_thread();
}
}
}
@ -948,6 +949,7 @@ void DEI3(void)
}
CHCR3 &= ~0x0002; /* Clear DMA interrupt */
wake_up_thread();
}
#ifdef HAVE_MAS3587F
@ -1791,9 +1793,10 @@ static void mpeg_thread(void)
}
else
{
/* This doesn't look neccessary...
yield();
if(!queue_empty(&mpeg_queue))
{
{*/
queue_wait(&mpeg_queue, &ev);
switch(ev.id)
{
@ -1897,7 +1900,7 @@ static void mpeg_thread(void)
init_playback_done = true;
break;
}
}
/*}*/
}
#endif
}
@ -1974,7 +1977,8 @@ void mpeg_init_recording(void)
queue_post(&mpeg_queue, MPEG_INIT_RECORDING, NULL);
while(!init_recording_done)
yield();
sleep_thread();
wake_up_thread();
}
void mpeg_init_playback(void)
@ -1983,7 +1987,8 @@ void mpeg_init_playback(void)
queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, NULL);
while(!init_playback_done)
yield();
sleep_thread();
wake_up_thread();
}
static void init_recording(void)

View file

@ -75,7 +75,6 @@ runtests() {
try mkfile /cpa.rock 0
check
try chkfile /cpa.rock
try chkfile /apa.rock
try chkfile /bpa.rock
LOOP=50

View file

@ -16,8 +16,11 @@
* KIND, either express or implied.
*
****************************************************************************/
#include <stdbool.h>
#include "thread.h"
#include "panic.h"
#include "kernel.h"
#include "sh7034.h"
struct regs
{
@ -30,6 +33,8 @@ struct regs
};
int num_threads;
bool cpu_sleep_enabled;
static volatile int num_sleepers;
static int current_thread;
static struct regs thread_contexts[MAXTHREADS] __attribute__ ((section(".idata")));
char *thread_name[MAXTHREADS];
@ -95,6 +100,18 @@ void switch_thread(void)
int next;
unsigned int *stackptr;
#ifdef SIMULATOR
/* Do nothing */
#else
while (cpu_sleep_enabled && num_sleepers == num_threads)
{
/* Enter sleep mode, woken up on interrupt */
SBYCR &= 0x7F;
asm volatile ("sleep");
}
#endif
next = current = current_thread;
if (++next >= num_threads)
next = 0;
@ -108,6 +125,22 @@ void switch_thread(void)
panicf("Stkov %s", thread_name[next]);
}
void cpu_sleep(bool enabled)
{
cpu_sleep_enabled = enabled;
}
void sleep_thread(void)
{
++num_sleepers;
switch_thread();
}
void wake_up_thread(void)
{
num_sleepers = 0;
}
/*---------------------------------------------------------------------------
* Create thread.
* Return 0 if context area could be allocated, else -1.
@ -144,6 +177,7 @@ int create_thread(void* function, void* stack, int stack_size, char *name)
regs->sr = 0;
regs->pr = function;
}
wake_up_thread();
return 0;
}
@ -154,6 +188,7 @@ void init_threads(void)
thread_name[0] = main_thread_name;
thread_stack[0] = stackbegin;
thread_stack_size[0] = (int)stackend - (int)stackbegin;
num_sleepers = 0;
}
int thread_stack_usage(int threadnum)

View file

@ -221,3 +221,8 @@ void lcd_fillrect (int x, int y, int nx, int ny)
(void)ny;
}
#endif
void cpu_sleep(bool enabled)
{
(void)enabled;
}