diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/ata.c | 6 | ||||
-rw-r--r-- | firmware/drivers/button.c | 15 | ||||
-rw-r--r-- | firmware/drivers/i2c.c | 7 | ||||
-rw-r--r-- | firmware/export/thread.h | 5 | ||||
-rw-r--r-- | firmware/kernel.c | 14 | ||||
-rw-r--r-- | firmware/mpeg.c | 13 | ||||
-rw-r--r-- | firmware/test/fat/test.sh | 1 | ||||
-rw-r--r-- | firmware/thread.c | 35 |
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) | |||
163 | int button_get_w_tmo(int ticks) | 163 | int 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 | ||
25 | int create_thread(void* function, void* stack, int stack_size, char *name); | 27 | int create_thread(void* function, void* stack, int stack_size, char *name); |
26 | void switch_thread(void); | 28 | void switch_thread(void); |
29 | void sleep_thread(void); | ||
30 | void wake_up_thread(void); | ||
27 | void init_threads(void); | 31 | void init_threads(void); |
28 | int thread_stack_usage(int threadnum); | 32 | int thread_stack_usage(int threadnum); |
33 | void 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 | ||
66 | void yield(void) | 67 | void 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 | ||
1980 | void mpeg_init_playback(void) | 1984 | void 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 | ||
1989 | static void init_recording(void) | 1994 | static 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 | ||
22 | struct regs | 25 | struct regs |
23 | { | 26 | { |
@@ -30,6 +33,8 @@ struct regs | |||
30 | }; | 33 | }; |
31 | 34 | ||
32 | int num_threads; | 35 | int num_threads; |
36 | bool cpu_sleep_enabled; | ||
37 | static volatile int num_sleepers; | ||
33 | static int current_thread; | 38 | static int current_thread; |
34 | static struct regs thread_contexts[MAXTHREADS] __attribute__ ((section(".idata"))); | 39 | static struct regs thread_contexts[MAXTHREADS] __attribute__ ((section(".idata"))); |
35 | char *thread_name[MAXTHREADS]; | 40 | char *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 | ||
128 | void cpu_sleep(bool enabled) | ||
129 | { | ||
130 | cpu_sleep_enabled = enabled; | ||
131 | } | ||
132 | |||
133 | void sleep_thread(void) | ||
134 | { | ||
135 | ++num_sleepers; | ||
136 | switch_thread(); | ||
137 | } | ||
138 | |||
139 | void 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 | ||
159 | int thread_stack_usage(int threadnum) | 194 | int thread_stack_usage(int threadnum) |