summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/drivers/ata.c6
-rw-r--r--firmware/drivers/button.c15
-rw-r--r--firmware/drivers/i2c.c7
-rw-r--r--firmware/export/thread.h5
-rw-r--r--firmware/kernel.c14
-rw-r--r--firmware/mpeg.c13
-rw-r--r--firmware/test/fat/test.sh1
-rw-r--r--firmware/thread.c35
8 files changed, 70 insertions, 26 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 79193d9800..e65200eea2 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -111,7 +111,8 @@ static int wait_for_bsy(void)
111{ 111{
112 int timeout = current_tick + HZ*10; 112 int timeout = current_tick + HZ*10;
113 while (TIME_BEFORE(current_tick, timeout) && (ATA_ALT_STATUS & STATUS_BSY)) 113 while (TIME_BEFORE(current_tick, timeout) && (ATA_ALT_STATUS & STATUS_BSY))
114 yield(); 114 sleep_thread();
115 wake_up_thread();
115 116
116 if (TIME_BEFORE(current_tick, timeout)) 117 if (TIME_BEFORE(current_tick, timeout))
117 return 1; 118 return 1;
@@ -131,7 +132,8 @@ static int wait_for_rdy(void)
131 132
132 while (TIME_BEFORE(current_tick, timeout) && 133 while (TIME_BEFORE(current_tick, timeout) &&
133 !(ATA_ALT_STATUS & STATUS_RDY)) 134 !(ATA_ALT_STATUS & STATUS_RDY))
134 yield(); 135 sleep_thread();
136 wake_up_thread();
135 137
136 if (TIME_BEFORE(current_tick, timeout)) 138 if (TIME_BEFORE(current_tick, timeout))
137 return STATUS_RDY; 139 return STATUS_RDY;
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c
index 2c33440fef..69d041f65e 100644
--- a/firmware/drivers/button.c
+++ b/firmware/drivers/button.c
@@ -163,19 +163,8 @@ int button_get(bool block)
163int button_get_w_tmo(int ticks) 163int button_get_w_tmo(int ticks)
164{ 164{
165 struct event ev; 165 struct event ev;
166 unsigned int timeout = current_tick + ticks; 166 queue_wait_w_tmo(&button_queue, &ev, ticks);
167 167 return (ev.id != SYS_TIMEOUT)? ev.id: BUTTON_NONE;
168 while (TIME_BEFORE( current_tick, timeout ))
169 {
170 if(!queue_empty(&button_queue))
171 {
172 queue_wait(&button_queue, &ev);
173 return ev.id;
174 }
175 yield();
176 }
177
178 return BUTTON_NONE;
179} 168}
180 169
181#ifdef HAVE_RECORDER_KEYPAD 170#ifdef HAVE_RECORDER_KEYPAD
diff --git a/firmware/drivers/i2c.c b/firmware/drivers/i2c.c
index 97d7a511e1..f0b5907be8 100644
--- a/firmware/drivers/i2c.c
+++ b/firmware/drivers/i2c.c
@@ -19,6 +19,7 @@
19#include "lcd.h" 19#include "lcd.h"
20#include "sh7034.h" 20#include "sh7034.h"
21#include "kernel.h" 21#include "kernel.h"
22#include "thread.h"
22#include "debug.h" 23#include "debug.h"
23 24
24#define PB13 0x2000 25#define PB13 0x2000
@@ -108,7 +109,8 @@ void i2c_ack(int bit)
108 109
109 SCL_INPUT; /* Set the clock to input */ 110 SCL_INPUT; /* Set the clock to input */
110 while(!SCL) /* and wait for the MAS to release it */ 111 while(!SCL) /* and wait for the MAS to release it */
111 yield(); 112 sleep_thread();
113 wake_up_thread();
112 114
113 DELAY; 115 DELAY;
114 SCL_OUTPUT; 116 SCL_OUTPUT;
@@ -130,7 +132,8 @@ int i2c_getack(void)
130 SDA_INPUT; /* And set to input */ 132 SDA_INPUT; /* And set to input */
131 SCL_INPUT; /* Set the clock to input */ 133 SCL_INPUT; /* Set the clock to input */
132 while(!SCL) /* and wait for the MAS to release it */ 134 while(!SCL) /* and wait for the MAS to release it */
133 yield(); 135 sleep_thread();
136 wake_up_thread();
134 137
135 if (SDA) 138 if (SDA)
136 /* ack failed */ 139 /* ack failed */
diff --git a/firmware/export/thread.h b/firmware/export/thread.h
index 7940ddfcf6..7be58d0931 100644
--- a/firmware/export/thread.h
+++ b/firmware/export/thread.h
@@ -19,12 +19,17 @@
19#ifndef THREAD_H 19#ifndef THREAD_H
20#define THREAD_H 20#define THREAD_H
21 21
22#include <stdbool.h>
23
22#define MAXTHREADS 16 24#define MAXTHREADS 16
23#define DEFAULT_STACK_SIZE 0x400 /* Bytes */ 25#define DEFAULT_STACK_SIZE 0x400 /* Bytes */
24 26
25int create_thread(void* function, void* stack, int stack_size, char *name); 27int create_thread(void* function, void* stack, int stack_size, char *name);
26void switch_thread(void); 28void switch_thread(void);
29void sleep_thread(void);
30void wake_up_thread(void);
27void init_threads(void); 31void init_threads(void);
28int thread_stack_usage(int threadnum); 32int thread_stack_usage(int threadnum);
33void cpu_sleep(bool enabled);
29 34
30#endif 35#endif
diff --git a/firmware/kernel.c b/firmware/kernel.c
index 4d2f519171..3255ba0b20 100644
--- a/firmware/kernel.c
+++ b/firmware/kernel.c
@@ -59,13 +59,15 @@ void sleep(int ticks)
59 int timeout = current_tick + ticks + 1; 59 int timeout = current_tick + ticks + 1;
60 60
61 while (TIME_BEFORE( current_tick, timeout )) { 61 while (TIME_BEFORE( current_tick, timeout )) {
62 yield(); 62 sleep_thread();
63 } 63 }
64 wake_up_thread();
64} 65}
65 66
66void yield(void) 67void yield(void)
67{ 68{
68 switch_thread(); 69 switch_thread();
70 wake_up_thread();
69} 71}
70 72
71/**************************************************************************** 73/****************************************************************************
@@ -96,8 +98,9 @@ void queue_wait(struct event_queue *q, struct event *ev)
96{ 98{
97 while(q->read == q->write) 99 while(q->read == q->write)
98 { 100 {
99 switch_thread(); 101 sleep_thread();
100 } 102 }
103 wake_up_thread();
101 104
102 *ev = q->events[(q->read++) & QUEUE_LENGTH_MASK]; 105 *ev = q->events[(q->read++) & QUEUE_LENGTH_MASK];
103} 106}
@@ -108,8 +111,9 @@ void queue_wait_w_tmo(struct event_queue *q, struct event *ev, int ticks)
108 111
109 while(q->read == q->write && TIME_BEFORE( current_tick, timeout )) 112 while(q->read == q->write && TIME_BEFORE( current_tick, timeout ))
110 { 113 {
111 switch_thread(); 114 sleep_thread();
112 } 115 }
116 wake_up_thread();
113 117
114 if(q->read != q->write) 118 if(q->read != q->write)
115 { 119 {
@@ -201,6 +205,7 @@ void IMIA0(void)
201 } 205 }
202 206
203 current_tick++; 207 current_tick++;
208 wake_up_thread();
204 209
205 TSR0 &= ~0x01; 210 TSR0 &= ~0x01;
206} 211}
@@ -257,7 +262,8 @@ void mutex_lock(struct mutex *m)
257{ 262{
258 /* Wait until the lock is open... */ 263 /* Wait until the lock is open... */
259 while(m->locked) 264 while(m->locked)
260 yield(); 265 sleep_thread();
266 wake_up_thread();
261 267
262 /* ...and lock it */ 268 /* ...and lock it */
263 m->locked = true; 269 m->locked = true;
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index 0518dd24e0..6fe60c99c9 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -845,6 +845,7 @@ static void dma_tick(void)
845 { 845 {
846 saving = true; 846 saving = true;
847 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0); 847 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
848 wake_up_thread();
848 } 849 }
849 } 850 }
850 } 851 }
@@ -948,6 +949,7 @@ void DEI3(void)
948 } 949 }
949 950
950 CHCR3 &= ~0x0002; /* Clear DMA interrupt */ 951 CHCR3 &= ~0x0002; /* Clear DMA interrupt */
952 wake_up_thread();
951} 953}
952 954
953#ifdef HAVE_MAS3587F 955#ifdef HAVE_MAS3587F
@@ -1791,9 +1793,10 @@ static void mpeg_thread(void)
1791 } 1793 }
1792 else 1794 else
1793 { 1795 {
1796 /* This doesn't look neccessary...
1794 yield(); 1797 yield();
1795 if(!queue_empty(&mpeg_queue)) 1798 if(!queue_empty(&mpeg_queue))
1796 { 1799 {*/
1797 queue_wait(&mpeg_queue, &ev); 1800 queue_wait(&mpeg_queue, &ev);
1798 switch(ev.id) 1801 switch(ev.id)
1799 { 1802 {
@@ -1897,7 +1900,7 @@ static void mpeg_thread(void)
1897 init_playback_done = true; 1900 init_playback_done = true;
1898 break; 1901 break;
1899 } 1902 }
1900 } 1903 /*}*/
1901 } 1904 }
1902#endif 1905#endif
1903 } 1906 }
@@ -1974,7 +1977,8 @@ void mpeg_init_recording(void)
1974 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, NULL); 1977 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, NULL);
1975 1978
1976 while(!init_recording_done) 1979 while(!init_recording_done)
1977 yield(); 1980 sleep_thread();
1981 wake_up_thread();
1978} 1982}
1979 1983
1980void mpeg_init_playback(void) 1984void mpeg_init_playback(void)
@@ -1983,7 +1987,8 @@ void mpeg_init_playback(void)
1983 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, NULL); 1987 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, NULL);
1984 1988
1985 while(!init_playback_done) 1989 while(!init_playback_done)
1986 yield(); 1990 sleep_thread();
1991 wake_up_thread();
1987} 1992}
1988 1993
1989static void init_recording(void) 1994static void init_recording(void)
diff --git a/firmware/test/fat/test.sh b/firmware/test/fat/test.sh
index 6a26e7ff59..44ff6bb849 100644
--- a/firmware/test/fat/test.sh
+++ b/firmware/test/fat/test.sh
@@ -75,7 +75,6 @@ runtests() {
75 try mkfile /cpa.rock 0 75 try mkfile /cpa.rock 0
76 check 76 check
77 try chkfile /cpa.rock 77 try chkfile /cpa.rock
78 try chkfile /apa.rock
79 try chkfile /bpa.rock 78 try chkfile /bpa.rock
80 79
81 LOOP=50 80 LOOP=50
diff --git a/firmware/thread.c b/firmware/thread.c
index 2651a4f2d7..ea518ca4ee 100644
--- a/firmware/thread.c
+++ b/firmware/thread.c
@@ -16,8 +16,11 @@
16 * KIND, either express or implied. 16 * KIND, either express or implied.
17 * 17 *
18 ****************************************************************************/ 18 ****************************************************************************/
19#include <stdbool.h>
19#include "thread.h" 20#include "thread.h"
20#include "panic.h" 21#include "panic.h"
22#include "kernel.h"
23#include "sh7034.h"
21 24
22struct regs 25struct regs
23{ 26{
@@ -30,6 +33,8 @@ struct regs
30}; 33};
31 34
32int num_threads; 35int num_threads;
36bool cpu_sleep_enabled;
37static volatile int num_sleepers;
33static int current_thread; 38static int current_thread;
34static struct regs thread_contexts[MAXTHREADS] __attribute__ ((section(".idata"))); 39static struct regs thread_contexts[MAXTHREADS] __attribute__ ((section(".idata")));
35char *thread_name[MAXTHREADS]; 40char *thread_name[MAXTHREADS];
@@ -95,6 +100,18 @@ void switch_thread(void)
95 int next; 100 int next;
96 unsigned int *stackptr; 101 unsigned int *stackptr;
97 102
103#ifdef SIMULATOR
104 /* Do nothing */
105#else
106
107 while (cpu_sleep_enabled && num_sleepers == num_threads)
108 {
109 /* Enter sleep mode, woken up on interrupt */
110 SBYCR &= 0x7F;
111 asm volatile ("sleep");
112 }
113
114#endif
98 next = current = current_thread; 115 next = current = current_thread;
99 if (++next >= num_threads) 116 if (++next >= num_threads)
100 next = 0; 117 next = 0;
@@ -108,6 +125,22 @@ void switch_thread(void)
108 panicf("Stkov %s", thread_name[next]); 125 panicf("Stkov %s", thread_name[next]);
109} 126}
110 127
128void cpu_sleep(bool enabled)
129{
130 cpu_sleep_enabled = enabled;
131}
132
133void sleep_thread(void)
134{
135 ++num_sleepers;
136 switch_thread();
137}
138
139void wake_up_thread(void)
140{
141 num_sleepers = 0;
142}
143
111/*--------------------------------------------------------------------------- 144/*---------------------------------------------------------------------------
112 * Create thread. 145 * Create thread.
113 * Return 0 if context area could be allocated, else -1. 146 * 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)
144 regs->sr = 0; 177 regs->sr = 0;
145 regs->pr = function; 178 regs->pr = function;
146 } 179 }
180 wake_up_thread();
147 return 0; 181 return 0;
148} 182}
149 183
@@ -154,6 +188,7 @@ void init_threads(void)
154 thread_name[0] = main_thread_name; 188 thread_name[0] = main_thread_name;
155 thread_stack[0] = stackbegin; 189 thread_stack[0] = stackbegin;
156 thread_stack_size[0] = (int)stackend - (int)stackbegin; 190 thread_stack_size[0] = (int)stackend - (int)stackbegin;
191 num_sleepers = 0;
157} 192}
158 193
159int thread_stack_usage(int threadnum) 194int thread_stack_usage(int threadnum)