mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-08 12:45:26 -05:00
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:
parent
84706a4188
commit
c4d8d970f6
15 changed files with 101 additions and 31 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue