diff options
-rw-r--r-- | firmware/drivers/button.c | 5 | ||||
-rw-r--r-- | firmware/drivers/lcd.c | 22 | ||||
-rw-r--r-- | firmware/export/kernel.h | 1 | ||||
-rw-r--r-- | firmware/export/system.h | 29 | ||||
-rw-r--r-- | firmware/kernel.c | 12 | ||||
-rw-r--r-- | firmware/system.c | 14 |
6 files changed, 39 insertions, 44 deletions
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c index 06c24e0e45..66c7e978fb 100644 --- a/firmware/drivers/button.c +++ b/firmware/drivers/button.c | |||
@@ -258,10 +258,11 @@ void button_set_flip(bool flip) | |||
258 | { | 258 | { |
259 | if (flip != flipped) /* not the curent setting */ | 259 | if (flip != flipped) /* not the curent setting */ |
260 | { | 260 | { |
261 | cli(); /* avoid race condition with the button_tick() */ | 261 | /* avoid race condition with the button_tick() */ |
262 | int oldlevel = set_irq_level(15); | ||
262 | lastbtn = button_flip(lastbtn); | 263 | lastbtn = button_flip(lastbtn); |
263 | flipped = flip; | 264 | flipped = flip; |
264 | sti(); | 265 | set_irq_level(oldlevel); |
265 | } | 266 | } |
266 | } | 267 | } |
267 | 268 | ||
diff --git a/firmware/drivers/lcd.c b/firmware/drivers/lcd.c index 5c2c514f10..950f8b5057 100644 --- a/firmware/drivers/lcd.c +++ b/firmware/drivers/lcd.c | |||
@@ -188,14 +188,16 @@ void lcd_write_data(unsigned char* p_bytes, int count) | |||
188 | { | 188 | { |
189 | do | 189 | do |
190 | { | 190 | { |
191 | unsigned byte; | 191 | unsigned int byte; |
192 | unsigned sda1; /* precalculated SC=low,SD=1 */ | 192 | unsigned int sda1; /* precalculated SC=low,SD=1 */ |
193 | unsigned clk0sda0; /* precalculated SC and SD low */ | 193 | unsigned int clk0sda0; /* precalculated SC and SD low */ |
194 | unsigned int oldlevel; | ||
194 | 195 | ||
195 | byte = *p_bytes++ << 24; /* fetch to MSB position */ | 196 | byte = *p_bytes++ << 24; /* fetch to MSB position */ |
196 | 197 | ||
197 | cli(); /* make port modifications atomic, in case an IRQ uses PBDRL */ | 198 | /* make port modifications atomic, in case an IRQ uses PBDRL */ |
198 | /* (currently not the case, so this could be optimized away) */ | 199 | /* (currently not the case, so this could be optimized away) */ |
200 | oldlevel = set_irq_level(15); | ||
199 | 201 | ||
200 | /* precalculate the values for later bit toggling, init data write */ | 202 | /* precalculate the values for later bit toggling, init data write */ |
201 | asm ( | 203 | asm ( |
@@ -285,7 +287,7 @@ void lcd_write_data(unsigned char* p_bytes, int count) | |||
285 | : "r0" | 287 | : "r0" |
286 | ); | 288 | ); |
287 | 289 | ||
288 | sti(); | 290 | set_irq_level(oldlevel); |
289 | 291 | ||
290 | } while (--count); /* tail loop is faster */ | 292 | } while (--count); /* tail loop is faster */ |
291 | } | 293 | } |
@@ -298,13 +300,15 @@ void lcd_write_data(unsigned char* p_bytes, int count) | |||
298 | { | 300 | { |
299 | unsigned byte; | 301 | unsigned byte; |
300 | unsigned sda1; /* precalculated SC=low,SD=1 */ | 302 | unsigned sda1; /* precalculated SC=low,SD=1 */ |
303 | unsigned int oldlevel; | ||
301 | 304 | ||
302 | /* take inverse data, so I can use the NEGC instruction below, it is | 305 | /* take inverse data, so I can use the NEGC instruction below, it is |
303 | the only carry add/sub which does not destroy a source register */ | 306 | the only carry add/sub which does not destroy a source register */ |
304 | byte = ~(*p_bytes++ << 24); /* fetch to MSB position */ | 307 | byte = ~(*p_bytes++ << 24); /* fetch to MSB position */ |
305 | 308 | ||
306 | cli(); /* make port modifications atomic, in case an IRQ uses PBDRL */ | 309 | /* make port modifications atomic, in case an IRQ uses PBDRL */ |
307 | /* (currently not the case, so this could be optimized away) */ | 310 | /* (currently not the case, so this could be optimized away) */ |
311 | oldlevel = set_irq_level(15); | ||
308 | 312 | ||
309 | /* precalculate the values for later bit toggling, init data write */ | 313 | /* precalculate the values for later bit toggling, init data write */ |
310 | asm ( | 314 | asm ( |
@@ -386,7 +390,7 @@ void lcd_write_data(unsigned char* p_bytes, int count) | |||
386 | "r0" | 390 | "r0" |
387 | ); | 391 | ); |
388 | 392 | ||
389 | sti(); /* end of atomic port modifications */ | 393 | set_irq_level(oldlevel); |
390 | 394 | ||
391 | } while (--count); /* tail loop is faster */ | 395 | } while (--count); /* tail loop is faster */ |
392 | } | 396 | } |
diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h index 0f69f43ec0..6e11baedf6 100644 --- a/firmware/export/kernel.h +++ b/firmware/export/kernel.h | |||
@@ -64,7 +64,6 @@ extern long current_tick; | |||
64 | extern void kernel_init(void); | 64 | extern void kernel_init(void); |
65 | extern void yield(void); | 65 | extern void yield(void); |
66 | extern void sleep(int ticks); | 66 | extern void sleep(int ticks); |
67 | int set_irq_level(int level); | ||
68 | int tick_add_task(void (*f)(void)); | 67 | int tick_add_task(void (*f)(void)); |
69 | int tick_remove_task(void (*f)(void)); | 68 | int tick_remove_task(void (*f)(void)); |
70 | 69 | ||
diff --git a/firmware/export/system.h b/firmware/export/system.h index 01d2f130d3..5886145d7b 100644 --- a/firmware/export/system.h +++ b/firmware/export/system.h | |||
@@ -23,6 +23,10 @@ | |||
23 | #include "sh7034.h" | 23 | #include "sh7034.h" |
24 | #include "config.h" | 24 | #include "config.h" |
25 | 25 | ||
26 | extern void system_reboot (void); | ||
27 | extern void system_init(void); | ||
28 | extern int set_irq_level(int level); | ||
29 | |||
26 | #define FREQ CPU_FREQ | 30 | #define FREQ CPU_FREQ |
27 | #define BAUDRATE 9600 | 31 | #define BAUDRATE 9600 |
28 | 32 | ||
@@ -113,47 +117,34 @@ static inline int tas (volatile int *pointer) | |||
113 | return result; | 117 | return result; |
114 | } | 118 | } |
115 | 119 | ||
116 | static inline void sti (void) | ||
117 | { | ||
118 | asm volatile ("ldc\t%0,sr" : : "r"(0<<4)); | ||
119 | } | ||
120 | |||
121 | static inline void cli (void) | ||
122 | { | ||
123 | asm volatile ("ldc\t%0,sr" : : "r"(15<<4)); | ||
124 | } | ||
125 | |||
126 | /* Compare And Swap */ | 120 | /* Compare And Swap */ |
127 | static inline int cas (volatile int *pointer,int requested_value,int new_value) | 121 | static inline int cas (volatile int *pointer,int requested_value,int new_value) |
128 | { | 122 | { |
129 | cli(); | 123 | unsigned int oldlevel = set_irq_level(15); |
130 | if (*pointer == requested_value) | 124 | if (*pointer == requested_value) |
131 | { | 125 | { |
132 | *pointer = new_value; | 126 | *pointer = new_value; |
133 | sti (); | 127 | set_irq_level(oldlevel); |
134 | return 1; | 128 | return 1; |
135 | } | 129 | } |
136 | sti (); | 130 | set_irq_level(oldlevel); |
137 | return 0; | 131 | return 0; |
138 | } | 132 | } |
139 | 133 | ||
140 | static inline int cas2 (volatile int *pointer1,volatile int *pointer2,int requested_value1,int requested_value2,int new_value1,int new_value2) | 134 | static inline int cas2 (volatile int *pointer1,volatile int *pointer2,int requested_value1,int requested_value2,int new_value1,int new_value2) |
141 | { | 135 | { |
142 | cli(); | 136 | unsigned int oldlevel = set_irq_level(15); |
143 | if (*pointer1 == requested_value1 && *pointer2 == requested_value2) | 137 | if (*pointer1 == requested_value1 && *pointer2 == requested_value2) |
144 | { | 138 | { |
145 | *pointer1 = new_value1; | 139 | *pointer1 = new_value1; |
146 | *pointer2 = new_value2; | 140 | *pointer2 = new_value2; |
147 | sti (); | 141 | set_irq_level(oldlevel); |
148 | return 1; | 142 | return 1; |
149 | } | 143 | } |
150 | sti (); | 144 | set_irq_level(oldlevel); |
151 | return 0; | 145 | return 0; |
152 | } | 146 | } |
153 | 147 | ||
154 | #endif | 148 | #endif |
155 | 149 | ||
156 | extern void system_reboot (void); | ||
157 | extern void system_init(void); | ||
158 | |||
159 | #endif | 150 | #endif |
diff --git a/firmware/kernel.c b/firmware/kernel.c index 3255ba0b20..1c37f004a4 100644 --- a/firmware/kernel.c +++ b/firmware/kernel.c | |||
@@ -71,18 +71,6 @@ void yield(void) | |||
71 | } | 71 | } |
72 | 72 | ||
73 | /**************************************************************************** | 73 | /**************************************************************************** |
74 | * Interrupt level setting | ||
75 | ****************************************************************************/ | ||
76 | int set_irq_level(int level) | ||
77 | { | ||
78 | int i; | ||
79 | /* Read the old level and set the new one */ | ||
80 | asm volatile ("stc sr, %0" : "=r" (i)); | ||
81 | asm volatile ("ldc %0, sr" : : "r" (level << 4)); | ||
82 | return (i >> 4) & 0x0f; | ||
83 | } | ||
84 | |||
85 | /**************************************************************************** | ||
86 | * Queue handling stuff | 74 | * Queue handling stuff |
87 | ****************************************************************************/ | 75 | ****************************************************************************/ |
88 | void queue_init(struct event_queue *q) | 76 | void queue_init(struct event_queue *q) |
diff --git a/firmware/system.c b/firmware/system.c index 87d3b9dc7d..3ec56f7c15 100644 --- a/firmware/system.c +++ b/firmware/system.c | |||
@@ -302,7 +302,7 @@ void (*vbr[]) (void) __attribute__ ((section (".vectors"))) = | |||
302 | 302 | ||
303 | void system_reboot (void) | 303 | void system_reboot (void) |
304 | { | 304 | { |
305 | cli (); | 305 | set_irq_level(15); |
306 | 306 | ||
307 | asm volatile ("ldc\t%0,vbr" : : "r"(0)); | 307 | asm volatile ("ldc\t%0,vbr" : : "r"(0)); |
308 | 308 | ||
@@ -318,6 +318,18 @@ void system_reboot (void) | |||
318 | "r"(*(int*)0),"r"(4)); | 318 | "r"(*(int*)0),"r"(4)); |
319 | } | 319 | } |
320 | 320 | ||
321 | /**************************************************************************** | ||
322 | * Interrupt level setting | ||
323 | ****************************************************************************/ | ||
324 | int set_irq_level(int level) | ||
325 | { | ||
326 | int i; | ||
327 | /* Read the old level and set the new one */ | ||
328 | asm volatile ("stc sr, %0" : "=r" (i)); | ||
329 | asm volatile ("ldc %0, sr" : : "r" (level << 4)); | ||
330 | return (i >> 4) & 0x0f; | ||
331 | } | ||
332 | |||
321 | void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */ | 333 | void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */ |
322 | { | 334 | { |
323 | bool state = true; | 335 | bool state = true; |