summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2004-12-01 00:33:18 +0000
committerJens Arnold <amiconn@rockbox.org>2004-12-01 00:33:18 +0000
commit303b4abfc5b6e7f1fd85876a2c644a4661d9dd02 (patch)
treede3df45eca3b504a5975526fb3a09ff187566a8f
parentbbc593128066d258002bb0a17a09c8dd33c07c46 (diff)
downloadrockbox-303b4abfc5b6e7f1fd85876a2c644a4661d9dd02.tar.gz
rockbox-303b4abfc5b6e7f1fd85876a2c644a4661d9dd02.zip
Button driver overhaul: (1) Unified the button driver functions as much as possible (2) Proper #defines for FM recorder button ADC channels (3) Got rid of old port B #defines only valid for recorder (4) button filtering for all models (5) RoLo with ON after panic should now work for FM/V2
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5472 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/debug_menu.c4
-rw-r--r--firmware/drivers/button.c449
-rw-r--r--firmware/export/adc.h4
-rw-r--r--firmware/export/sh7034.h15
-rw-r--r--firmware/system.c10
5 files changed, 177 insertions, 305 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index 77ebe019f8..880f545d52 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -903,9 +903,12 @@ bool view_battery(void)
903 y = (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) / 10000; 903 y = (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) / 10000;
904 snprintf(buf, 30, "Battery: %d.%02d V", y / 100, y % 100); 904 snprintf(buf, 30, "Battery: %d.%02d V", y / 100, y % 100);
905 lcd_puts(0, 1, buf); 905 lcd_puts(0, 1, buf);
906#ifdef ADC_EXT_POWER
906 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 10000; 907 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 10000;
907 snprintf(buf, 30, "External: %d.%02d V", y / 100, y % 100); 908 snprintf(buf, 30, "External: %d.%02d V", y / 100, y % 100);
908 lcd_puts(0, 2, buf); 909 lcd_puts(0, 2, buf);
910#endif
911#ifdef HAVE_CHARGING
909 snprintf(buf, 30, "Charger: %s", 912 snprintf(buf, 30, "Charger: %s",
910 charger_inserted() ? "present" : "absent"); 913 charger_inserted() ? "present" : "absent");
911 lcd_puts(0, 3, buf); 914 lcd_puts(0, 3, buf);
@@ -914,6 +917,7 @@ bool view_battery(void)
914 charger_enabled ? "yes" : "no"); 917 charger_enabled ? "yes" : "no");
915 lcd_puts(0, 4, buf); 918 lcd_puts(0, 4, buf);
916#endif 919#endif
920#endif
917 y = ( power_history[POWER_HISTORY_LEN-1] * 100 921 y = ( power_history[POWER_HISTORY_LEN-1] * 100
918 + power_history[POWER_HISTORY_LEN-2] * 100 922 + power_history[POWER_HISTORY_LEN-2] * 100
919 - power_history[POWER_HISTORY_LEN-1-CHARGE_END_NEGD+1] * 100 923 - power_history[POWER_HISTORY_LEN-1-CHARGE_END_NEGD+1] * 100
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c
index 7e7eb97cf9..a368976d6e 100644
--- a/firmware/drivers/button.c
+++ b/firmware/drivers/button.c
@@ -16,8 +16,9 @@
16 * KIND, either express or implied. 16 * KIND, either express or implied.
17 * 17 *
18 ****************************************************************************/ 18 ****************************************************************************/
19
19/* 20/*
20 * Archos Jukebox Recorder button functions 21 * Rockbox button functions
21 */ 22 */
22 23
23#include <stdlib.h> 24#include <stdlib.h>
@@ -36,9 +37,9 @@
36struct event_queue button_queue; 37struct event_queue button_queue;
37 38
38static int lastbtn; /* Last valid button status */ 39static int lastbtn; /* Last valid button status */
39#if (CONFIG_KEYPAD == RECORDER_PAD) || (CONFIG_KEYPAD == ONDIO_PAD) || (CONFIG_KEYPAD == IRIVER_H100_PAD)
40static int last_read; /* Last button status, for debouncing/filtering */ 40static int last_read; /* Last button status, for debouncing/filtering */
41static bool flipped; /* bottons can be flipped to match the LCD flip */ 41#ifdef HAVE_LCD_BITMAP
42static bool flipped; /* buttons can be flipped to match the LCD flip */
42#endif 43#endif
43 44
44/* how often we check to see if a button is pressed */ 45/* how often we check to see if a button is pressed */
@@ -74,9 +75,9 @@ static void button_tick(void)
74 if(btn) 75 if(btn)
75 { 76 {
76 queue_post(&button_queue, btn, NULL); 77 queue_post(&button_queue, btn, NULL);
77 } 78 }
78#endif 79#endif
79 80
80 /* only poll every X ticks */ 81 /* only poll every X ticks */
81 if ( ++tick >= POLL_FREQUENCY ) 82 if ( ++tick >= POLL_FREQUENCY )
82 { 83 {
@@ -120,8 +121,8 @@ static void button_tick(void)
120 which doesn't shut down easily with the OFF 121 which doesn't shut down easily with the OFF
121 key */ 122 key */
122#ifdef HAVE_SW_POWEROFF 123#ifdef HAVE_SW_POWEROFF
123 if(btn == BUTTON_OFF && !charger_inserted() && 124 if (btn == BUTTON_OFF && !charger_inserted() &&
124 repeat_count > POWEROFF_COUNT) 125 repeat_count > POWEROFF_COUNT)
125 queue_post(&button_queue, SYS_POWEROFF, NULL); 126 queue_post(&button_queue, SYS_POWEROFF, NULL);
126#endif 127#endif
127 } 128 }
@@ -140,7 +141,7 @@ static void button_tick(void)
140 } 141 }
141 if ( post ) 142 if ( post )
142 { 143 {
143 if(repeat) 144 if (repeat)
144 queue_post(&button_queue, BUTTON_REPEAT | btn, NULL); 145 queue_post(&button_queue, BUTTON_REPEAT | btn, NULL);
145 else 146 else
146 queue_post(&button_queue, btn, NULL); 147 queue_post(&button_queue, btn, NULL);
@@ -166,7 +167,8 @@ int button_get(bool block)
166{ 167{
167 struct event ev; 168 struct event ev;
168 169
169 if ( block || !queue_empty(&button_queue) ) { 170 if ( block || !queue_empty(&button_queue) )
171 {
170 queue_wait(&button_queue, &ev); 172 queue_wait(&button_queue, &ev);
171 return ev.id; 173 return ev.id;
172 } 174 }
@@ -180,23 +182,40 @@ int button_get_w_tmo(int ticks)
180 return (ev.id != SYS_TIMEOUT)? ev.id: BUTTON_NONE; 182 return (ev.id != SYS_TIMEOUT)? ev.id: BUTTON_NONE;
181} 183}
182 184
183#if CONFIG_KEYPAD == IRIVER_H100_PAD 185void button_init(void)
184void button_init()
185{ 186{
186#ifndef SIMULATOR 187 /* hardware inits */
188#if CONFIG_KEYPAD == IRIVER_H100_PAD
187 /* Set GPIO37 as general purpose input */ 189 /* Set GPIO37 as general purpose input */
188 GPIO1_FUNCTION |= 0x00000020; 190 GPIO1_FUNCTION |= 0x00000020;
189 GPIO1_ENABLE &= ~0x00000020; 191 GPIO1_ENABLE &= ~0x00000020;
190#endif 192#elif CONFIG_KEYPAD == RECORDER_PAD
193 /* Set PB4 and PB8 as input pins */
194 PBCR1 &= 0xfffc; /* PB8MD = 00 */
195 PBCR2 &= 0xfcff; /* PB4MD = 00 */
196 PBIOR &= ~0x0110; /* Inputs */
197#elif CONFIG_KEYPAD == PLAYER_PAD
198 /* set PA5 and PA11 as input pins */
199 PACR1 &= 0xff3f; /* PA11MD = 00 */
200 PACR2 &= 0xfbff; /* PA5MD = 0 */
201 PAIOR &= ~0x0820; /* Inputs */
202#elif CONFIG_KEYPAD == ONDIO_PAD
203 /* nothing to initialize here */
204#endif /* CONFIG_KEYPAD */
205
191 queue_init(&button_queue); 206 queue_init(&button_queue);
192 lastbtn = 0; 207 lastbtn = 0;
193 tick_add_task(button_tick); 208 tick_add_task(button_tick);
194 reset_poweroff_timer(); 209 reset_poweroff_timer();
210
211#ifdef HAVE_LCD_BITMAP
195 flipped = false; 212 flipped = false;
213#endif
196} 214}
197 215
216#ifdef HAVE_LCD_BITMAP /* only bitmap displays can be flipped */
198/* 217/*
199 * helper function to swap UP/DOWN, LEFT/RIGHT 218 * helper function to swap UP/DOWN, LEFT/RIGHT (and F1/F3 for Recorder)
200 */ 219 */
201static int button_flip(int button) 220static int button_flip(int button)
202{ 221{
@@ -204,7 +223,11 @@ static int button_flip(int button)
204 223
205 newbutton = button & 224 newbutton = button &
206 ~(BUTTON_UP | BUTTON_DOWN 225 ~(BUTTON_UP | BUTTON_DOWN
207 | BUTTON_LEFT | BUTTON_RIGHT); 226 | BUTTON_LEFT | BUTTON_RIGHT
227#if CONFIG_KEYPAD == RECORDER_PAD
228 | BUTTON_F1 | BUTTON_F3
229#endif
230 );
208 231
209 if (button & BUTTON_UP) 232 if (button & BUTTON_UP)
210 newbutton |= BUTTON_DOWN; 233 newbutton |= BUTTON_DOWN;
@@ -214,6 +237,12 @@ static int button_flip(int button)
214 newbutton |= BUTTON_RIGHT; 237 newbutton |= BUTTON_RIGHT;
215 if (button & BUTTON_RIGHT) 238 if (button & BUTTON_RIGHT)
216 newbutton |= BUTTON_LEFT; 239 newbutton |= BUTTON_LEFT;
240#if CONFIG_KEYPAD == RECORDER_PAD
241 if (button & BUTTON_F1)
242 newbutton |= BUTTON_F3;
243 if (button & BUTTON_F3)
244 newbutton |= BUTTON_F1;
245#endif
217 246
218 return newbutton; 247 return newbutton;
219} 248}
@@ -233,6 +262,75 @@ void button_set_flip(bool flip)
233 set_irq_level(oldlevel); 262 set_irq_level(oldlevel);
234 } 263 }
235} 264}
265#endif /* HAVE_LCD_BITMAP */
266
267/*
268 Archos hardware button hookup
269 =============================
270
271 Recorder / Recorder FM/V2
272 -------------------------
273 F1, F2, F3, UP: connected to AN4 through a resistor network
274 DOWN, PLAY, LEFT, RIGHT: likewise connected to AN5
275
276 The voltage on AN4/ AN5 depends on which keys (or key combo) is pressed
277 FM/V2 has PLAY and RIGHT switched compared to plain recorder
278
279 ON: PB8, low active (plain recorder) / AN3, low active (fm/v2)
280 OFF: PB4, low active (plain recorder) / AN2, high active (fm/v2)
281
282 Player
283 ------
284 LEFT: AN0
285 MENU: AN1
286 RIGHT: AN2
287 PLAY: AN3
288
289 STOP: PA11
290 ON: PA5
291
292 All buttons are low active
293
294 Ondio
295 -----
296 LEFT, RIGHT, UP, DOWN: connected to AN4 through a resistor network
297
298 The voltage on AN4 depends on which keys (or key combo) is pressed
299
300 OPTION: AN2, high active (assigned as MENU)
301 ON/OFF: AN3, low active (assigned as OFF)
302
303*/
304
305#if CONFIG_KEYPAD == RECORDER_PAD
306
307#ifdef HAVE_FMADC
308/* FM Recorder super-special levels */
309#define LEVEL1 150
310#define LEVEL2 385
311#define LEVEL3 545
312#define LEVEL4 700
313#define ROW2_BUTTON1 BUTTON_PLAY
314#define ROW2_BUTTON3 BUTTON_RIGHT
315
316#else
317/* plain bog standard Recorder levels */
318#define LEVEL1 250
319#define LEVEL2 500
320#define LEVEL3 700
321#define LEVEL4 900
322#define ROW2_BUTTON1 BUTTON_RIGHT
323#define ROW2_BUTTON3 BUTTON_PLAY
324#endif /* HAVE_FMADC */
325
326#elif CONFIG_KEYPAD == ONDIO_PAD
327/* Ondio levels */
328#define LEVEL1 165
329#define LEVEL2 415
330#define LEVEL3 585
331#define LEVEL4 755
332
333#endif /* CONFIG_KEYPAD */
236 334
237/* 335/*
238 * Get button pressed from hardware 336 * Get button pressed from hardware
@@ -244,175 +342,57 @@ static int button_read(void)
244 342
245 int data; 343 int data;
246 344
345#if CONFIG_KEYPAD == IRIVER_H100_PAD
346
247 data = adc_scan(0); 347 data = adc_scan(0);
248 348
249 if(data < 0x80) 349 if (data < 0x80)
250 if(data < 0x30) 350 if (data < 0x30)
251 if(data < 0x18) 351 if (data < 0x18)
252 btn = BUTTON_SELECT; 352 btn = BUTTON_SELECT;
253 else 353 else
254 btn = BUTTON_UP; 354 btn = BUTTON_UP;
255 else 355 else
256 if(data < 0x50) 356 if (data < 0x50)
257 btn = BUTTON_LEFT; 357 btn = BUTTON_LEFT;
258 else 358 else
259 btn = BUTTON_DOWN; 359 btn = BUTTON_DOWN;
260 else 360 else
261 if(data < 0xb0) 361 if (data < 0xb0)
262 if(data < 0xa0) 362 if (data < 0xa0)
263 btn = BUTTON_RIGHT; 363 btn = BUTTON_RIGHT;
264 else 364 else
265 btn = BUTTON_OFF; 365 btn = BUTTON_OFF;
266 else 366 else
267 if(data < 0xd0) 367 if (data < 0xd0)
268 btn = BUTTON_MODE; 368 btn = BUTTON_MODE;
269 else 369 else
270 if(data < 0xf0) 370 if (data < 0xf0)
271 btn = BUTTON_REC; 371 btn = BUTTON_REC;
272 372
273 data = GPIO1_READ; 373 data = GPIO1_READ;
274 if ((data & 0x20) == 0) 374 if ((data & 0x20) == 0)
275 btn |= BUTTON_ON; 375 btn |= BUTTON_ON;
276 376
277
278 if (btn && flipped)
279 btn = button_flip(btn); /* swap upside down */
280
281 /* Filter the button status. It is only accepted if we get the same
282 status twice in a row. */
283 if(btn != last_read)
284 retval = lastbtn;
285 else
286 retval = btn;
287 last_read = btn;
288
289 return retval;
290}
291
292bool button_hold(void)
293{
294 return (GPIO1_READ & 0x00000002)?true:false;
295}
296
297#elif CONFIG_KEYPAD == RECORDER_PAD 377#elif CONFIG_KEYPAD == RECORDER_PAD
298 378
299/* AJBR buttons are connected to the CPU as follows:
300 *
301 * ON and OFF are connected to separate port B input pins.
302 *
303 * F1, F2, F3, and UP are connected to the AN4 analog input, each through
304 * a separate voltage divider. The voltage on AN4 depends on which button
305 * (or none, or a combination) is pressed.
306 *
307 * DOWN, PLAY, LEFT, and RIGHT are likewise connected to AN5. */
308
309/* Button analog voltage levels */
310#ifdef HAVE_FMADC 379#ifdef HAVE_FMADC
311/* FM Recorder super-special levels */ 380 if ( adc_read(ADC_BUTTON_ON) < 512 )
312#define LEVEL1 150
313#define LEVEL2 385
314#define LEVEL3 545
315#define LEVEL4 700
316#else
317/* plain bog standard Recorder levels */
318#define LEVEL1 250
319#define LEVEL2 500
320#define LEVEL3 700
321#define LEVEL4 900
322#endif
323
324/*
325 *Initialize buttons
326 */
327void button_init()
328{
329#ifndef SIMULATOR
330 /* Set PB4 and PB8 as input pins */
331 PBCR1 &= 0xfffc; /* PB8MD = 00 */
332 PBCR2 &= 0xfcff; /* PB4MD = 00 */
333 PBIOR &= ~(PBDR_BTN_ON|PBDR_BTN_OFF); /* Inputs */
334#endif
335 queue_init(&button_queue);
336 lastbtn = 0;
337 tick_add_task(button_tick);
338 reset_poweroff_timer();
339 flipped = false;
340}
341
342
343/*
344 * helper function to swap UP/DOWN, LEFT/RIGHT, F1/F3
345 */
346static int button_flip(int button)
347{
348 int newbutton;
349
350 newbutton = button &
351 ~(BUTTON_UP | BUTTON_DOWN
352 | BUTTON_LEFT | BUTTON_RIGHT
353 | BUTTON_F1 | BUTTON_F3);
354
355 if (button & BUTTON_UP)
356 newbutton |= BUTTON_DOWN;
357 if (button & BUTTON_DOWN)
358 newbutton |= BUTTON_UP;
359 if (button & BUTTON_LEFT)
360 newbutton |= BUTTON_RIGHT;
361 if (button & BUTTON_RIGHT)
362 newbutton |= BUTTON_LEFT;
363 if (button & BUTTON_F1)
364 newbutton |= BUTTON_F3;
365 if (button & BUTTON_F3)
366 newbutton |= BUTTON_F1;
367
368 return newbutton;
369}
370
371
372/*
373 * set the flip attribute
374 * better only call this when the queue is empty
375 */
376void button_set_flip(bool flip)
377{
378 if (flip != flipped) /* not the current setting */
379 {
380 /* avoid race condition with the button_tick() */
381 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
382 lastbtn = button_flip(lastbtn);
383 flipped = flip;
384 set_irq_level(oldlevel);
385 }
386}
387
388/*
389 * Get button pressed from hardware
390 */
391static int button_read(void)
392{
393 int btn = BUTTON_NONE;
394 int retval;
395
396 int data;
397
398#ifdef HAVE_FMADC
399 /* TODO: use proper defines here, and not the numerics in the
400 function argument */
401 if ( adc_read(3) < 512 )
402 btn |= BUTTON_ON; 381 btn |= BUTTON_ON;
403 if ( adc_read(2) > 512 ) 382 if ( adc_read(ADC_BUTTON_OFF) > 512 )
404 btn |= BUTTON_OFF; 383 btn |= BUTTON_OFF;
405#else 384#else
406 /* Check port B pins for ON and OFF */ 385 /* check port B pins for ON and OFF */
407 data = PBDR; 386 data = PBDR;
408 if ((data & PBDR_BTN_ON) == 0) 387 if ((data & 0x0100) == 0)
409 btn |= BUTTON_ON; 388 btn |= BUTTON_ON;
410 else if ((data & PBDR_BTN_OFF) == 0) 389 if ((data & 0x0010) == 0)
411 btn |= BUTTON_OFF; 390 btn |= BUTTON_OFF;
412#endif 391#endif
413 392
414 /* Check F1-3 and UP */ 393 /* check F1..F3 and UP */
415 data = adc_read(ADC_BUTTON_ROW1); 394 data = adc_read(ADC_BUTTON_ROW1);
395
416 if (data >= LEVEL4) 396 if (data >= LEVEL4)
417 btn |= BUTTON_F3; 397 btn |= BUTTON_F3;
418 else if (data >= LEVEL3) 398 else if (data >= LEVEL3)
@@ -427,181 +407,68 @@ static int button_read(void)
427 checks when UP is pressed. */ 407 checks when UP is pressed. */
428 if(!(btn & BUTTON_UP)) 408 if(!(btn & BUTTON_UP))
429 { 409 {
430 /* Check DOWN, PLAY, LEFT, RIGHT */ 410 /* check DOWN, PLAY, LEFT, RIGHT */
431 data = adc_read(ADC_BUTTON_ROW2); 411 data = adc_read(ADC_BUTTON_ROW2);
412
432 if (data >= LEVEL4) 413 if (data >= LEVEL4)
433 btn |= BUTTON_DOWN; 414 btn |= BUTTON_DOWN;
434 else if (data >= LEVEL3) { 415 else if (data >= LEVEL3)
435#ifdef HAVE_FMADC 416 btn |= ROW2_BUTTON3;
436 btn |= BUTTON_RIGHT;
437#else
438 btn |= BUTTON_PLAY;
439#endif
440 }
441 else if (data >= LEVEL2) 417 else if (data >= LEVEL2)
442 btn |= BUTTON_LEFT; 418 btn |= BUTTON_LEFT;
443 else if (data >= LEVEL1) { 419 else if (data >= LEVEL1)
444#ifdef HAVE_FMADC 420 btn |= ROW2_BUTTON1;
445 btn |= BUTTON_PLAY;
446#else
447 btn |= BUTTON_RIGHT;
448#endif
449 }
450 } 421 }
451 422
452 if (btn && flipped)
453 btn = button_flip(btn); /* swap upside down */
454
455 /* Filter the button status. It is only accepted if we get the same
456 status twice in a row. */
457 if(btn != last_read)
458 retval = lastbtn;
459 else
460 retval = btn;
461 last_read = btn;
462
463 return retval;
464}
465
466#elif CONFIG_KEYPAD == PLAYER_PAD 423#elif CONFIG_KEYPAD == PLAYER_PAD
467 424
468/* The player has two buttons on port pins:
469
470 STOP: PA11
471 ON: PA5
472
473 The rest are on analog inputs:
474
475 LEFT: AN0
476 MENU: AN1
477 RIGHT: AN2
478 PLAY: AN3
479*/
480
481void button_init(void)
482{
483#ifndef SIMULATOR
484 /* set PA5 and PA11 as input */
485 PACR1 &= 0xff3f; /* PA11MD = 00 */
486 PACR2 &= 0xfbff; /* PA5MD = 0 */
487 PAIOR &= ~0x820;
488#endif
489 queue_init(&button_queue);
490 lastbtn = 0;
491 tick_add_task(button_tick);
492
493 reset_poweroff_timer();
494}
495
496static int button_read(void)
497{
498 int porta = PADR;
499 int btn = BUTTON_NONE;
500
501 /* buttons are active low */ 425 /* buttons are active low */
502 if(adc_read(0) < 0x180) 426 if (adc_read(0) < 0x180)
503 btn |= BUTTON_LEFT; 427 btn |= BUTTON_LEFT;
504 if(adc_read(1) < 0x180) 428 if (adc_read(1) < 0x180)
505 btn |= BUTTON_MENU; 429 btn |= BUTTON_MENU;
506 if(adc_read(2) < 0x180) 430 if(adc_read(2) < 0x180)
507 btn |= BUTTON_RIGHT; 431 btn |= BUTTON_RIGHT;
508 if(adc_read(3) < 0x180) 432 if(adc_read(3) < 0x180)
509 btn |= BUTTON_PLAY; 433 btn |= BUTTON_PLAY;
510 434
511 if ( !(porta & 0x20) ) 435 /* check port A pins for ON and STOP */
436 data = PADR;
437 if ( !(data & 0x0020) )
512 btn |= BUTTON_ON; 438 btn |= BUTTON_ON;
513 if ( !(porta & 0x800) ) 439 if ( !(data & 0x0800) )
514 btn |= BUTTON_STOP; 440 btn |= BUTTON_STOP;
515 441
516 return btn;
517}
518
519#elif CONFIG_KEYPAD == ONDIO_PAD 442#elif CONFIG_KEYPAD == ONDIO_PAD
520 443
521/*
522 * helper function to swap UP/DOWN, LEFT/RIGHT
523 */
524static int button_flip(int button)
525{
526 int newbutton;
527
528 newbutton = button &
529 ~(BUTTON_UP | BUTTON_DOWN
530 | BUTTON_LEFT | BUTTON_RIGHT);
531
532 if (button & BUTTON_UP)
533 newbutton |= BUTTON_DOWN;
534 if (button & BUTTON_DOWN)
535 newbutton |= BUTTON_UP;
536 if (button & BUTTON_LEFT)
537 newbutton |= BUTTON_RIGHT;
538 if (button & BUTTON_RIGHT)
539 newbutton |= BUTTON_LEFT;
540
541 return newbutton;
542}
543
544
545/*
546 * set the flip attribute
547 * better only call this when the queue is empty
548 */
549void button_set_flip(bool flip)
550{
551 if (flip != flipped) /* not the current setting */
552 {
553 /* avoid race condition with the button_tick() */
554 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
555 lastbtn = button_flip(lastbtn);
556 flipped = flip;
557 set_irq_level(oldlevel);
558 }
559}
560
561
562/* The Ondio its 6 buttons on analog inputs:
563 OPTION: AN2 (used as MENU for now)
564 ON/OFF: AN3
565 LEFT/RIGHT/UP/DOWN: AN4
566 We map them like the player keys for now, although this is far from optimal.
567*/
568void button_init(void)
569{
570 queue_init(&button_queue);
571 lastbtn = 0;
572 tick_add_task(button_tick);
573
574 reset_poweroff_timer();
575}
576
577static int button_read(void)
578{
579 int btn = BUTTON_NONE;
580 int retval;
581
582 int data = adc_read(ADC_BUTTON_ROW1);
583
584 if(adc_read(ADC_BUTTON_OPTION) > 0x200) /* active high */ 444 if(adc_read(ADC_BUTTON_OPTION) > 0x200) /* active high */
585 btn |= BUTTON_MENU; 445 btn |= BUTTON_MENU;
586 if(adc_read(ADC_BUTTON_ONOFF) < 0x120) /* active low */ 446 if(adc_read(ADC_BUTTON_ONOFF) < 0x120) /* active low */
587 btn |= BUTTON_OFF; 447 btn |= BUTTON_OFF;
588 448
589 /* Check the 4 direction keys, hard-coded analog limits for now */ 449 /* Check the 4 direction keys */
590 if (data >= 0x2EF) 450 data = adc_read(ADC_BUTTON_ROW1);
451
452 if (data >= LEVEL4)
591 btn |= BUTTON_LEFT; 453 btn |= BUTTON_LEFT;
592 else if (data >= 0x246) 454 else if (data >= LEVEL3)
593 btn |= BUTTON_RIGHT; 455 btn |= BUTTON_RIGHT;
594 else if (data >= 0x19D) 456 else if (data >= LEVEL2)
595 btn |= BUTTON_UP; 457 btn |= BUTTON_UP;
596 else if (data >= 0x0A1) 458 else if (data >= LEVEL1)
597 btn |= BUTTON_DOWN; 459 btn |= BUTTON_DOWN;
598 460
461#endif /* CONFIG_KEYPAD */
462
463
464#ifdef HAVE_LCD_BITMAP
599 if (btn && flipped) 465 if (btn && flipped)
600 btn = button_flip(btn); /* swap upside down */ 466 btn = button_flip(btn); /* swap upside down */
467#endif
601 468
602 /* Filter the button status. It is only accepted if we get the same 469 /* Filter the button status. It is only accepted if we get the same
603 status twice in a row. */ 470 status twice in a row. */
604 if(btn != last_read) 471 if (btn != last_read)
605 retval = lastbtn; 472 retval = lastbtn;
606 else 473 else
607 retval = btn; 474 retval = btn;
@@ -610,6 +477,11 @@ static int button_read(void)
610 return retval; 477 return retval;
611} 478}
612 479
480#if CONFIG_KEYPAD == IRIVER_H100_PAD
481bool button_hold(void)
482{
483 return (GPIO1_READ & 0x00000002)?true:false;
484}
613#endif 485#endif
614 486
615int button_status(void) 487int button_status(void)
@@ -621,3 +493,4 @@ void button_clear_queue(void)
621{ 493{
622 queue_clear(&button_queue); 494 queue_clear(&button_queue);
623} 495}
496
diff --git a/firmware/export/adc.h b/firmware/export/adc.h
index 044391b536..e2c87fa385 100644
--- a/firmware/export/adc.h
+++ b/firmware/export/adc.h
@@ -41,8 +41,6 @@
41#define ADC_BUTTON_ROW1 4 /* Used for scanning the keys, different 41#define ADC_BUTTON_ROW1 4 /* Used for scanning the keys, different
42 voltages for different keys */ 42 voltages for different keys */
43#define ADC_UNREG_POWER 7 /* Battery voltage */ 43#define ADC_UNREG_POWER 7 /* Battery voltage */
44/* FixMe: this doesn't exist, just to make the compiler happy */
45#define ADC_EXT_POWER 5 /* The external power voltage, V=X*0.0148 */
46 44
47#else 45#else
48/* normal JBR channel assignment */ 46/* normal JBR channel assignment */
@@ -51,6 +49,8 @@
51#ifdef HAVE_FMADC 49#ifdef HAVE_FMADC
52#define ADC_CHARGE_REGULATOR 0 /* Uh, we read the battery voltage? */ 50#define ADC_CHARGE_REGULATOR 0 /* Uh, we read the battery voltage? */
53#define ADC_USB_POWER 1 /* USB, reads 0x000 when USB is inserted */ 51#define ADC_USB_POWER 1 /* USB, reads 0x000 when USB is inserted */
52#define ADC_BUTTON_OFF 2 /* the off button, high value if pressed */
53#define ADC_BUTTON_ON 3 /* the on button, low value if pressed */
54#else 54#else
55#define ADC_CHARGE_REGULATOR 1 /* Regulator reference voltage, should read 55#define ADC_CHARGE_REGULATOR 1 /* Regulator reference voltage, should read
56 about 0x1c0 when charging, else 0x3FF */ 56 about 0x1c0 when charging, else 0x3FF */
diff --git a/firmware/export/sh7034.h b/firmware/export/sh7034.h
index 90cbb5a0a4..c15ee2a88f 100644
--- a/firmware/export/sh7034.h
+++ b/firmware/export/sh7034.h
@@ -140,7 +140,7 @@
140#define RSTCSR_ADDR 0x05FFFFBB 140#define RSTCSR_ADDR 0x05FFFFBB
141 141
142#define SBYCR_ADDR 0x05FFFFBC 142#define SBYCR_ADDR 0x05FFFFBC
143 143
144#define PADR_ADDR 0x05FFFFC0 144#define PADR_ADDR 0x05FFFFC0
145#define PBDR_ADDR 0x05FFFFC2 145#define PBDR_ADDR 0x05FFFFC2
146#define PAIOR_ADDR 0x05FFFFC4 146#define PAIOR_ADDR 0x05FFFFC4
@@ -150,7 +150,7 @@
150#define PBCR1_ADDR 0x05FFFFCC 150#define PBCR1_ADDR 0x05FFFFCC
151#define PBCR2_ADDR 0x05FFFFCE 151#define PBCR2_ADDR 0x05FFFFCE
152#define PCDR_ADDR 0x05FFFFD0 152#define PCDR_ADDR 0x05FFFFD0
153 153
154#define CASCR_ADDR 0x05FFFFEE 154#define CASCR_ADDR 0x05FFFFEE
155 155
156/* byte halves of the ports */ 156/* byte halves of the ports */
@@ -164,15 +164,6 @@
164#define PBIORL_ADDR 0x05FFFFC7 164#define PBIORL_ADDR 0x05FFFFC7
165 165
166 166
167/* Port B data register bits */
168#define PBDR_LCD_SDA 0x0001 /* LCD serial data */
169#define PBDR_LCD_SCK 0x0002 /* LCD serial clock */
170#define PBDR_LCD_DC 0x0004 /* LCD data (1) / command (0) */
171#define PBDR_LCD_CS1 0x0008 /* LCD chip select 1 (active low) */
172#define PBDR_BTN_OFF 0x0010 /* Off button (active low) */
173#define PBDR_LED_RED 0x0040 /* Red LED */
174#define PBDR_BTN_ON 0x0100 /* On button (active low) */
175
176/* A/D control/status register bits */ 167/* A/D control/status register bits */
177#define ADCSR_CH 0x07 /* Channel/group select */ 168#define ADCSR_CH 0x07 /* Channel/group select */
178#define ADCSR_CKS 0x08 /* Clock select */ 169#define ADCSR_CKS 0x08 /* Clock select */
@@ -195,7 +186,7 @@
195#define SMR1 (*((volatile unsigned char*)SMR1_ADDR)) 186#define SMR1 (*((volatile unsigned char*)SMR1_ADDR))
196#define BRR1 (*((volatile unsigned char*)BRR1_ADDR)) 187#define BRR1 (*((volatile unsigned char*)BRR1_ADDR))
197#define SCR1 (*((volatile unsigned char*)SCR1_ADDR)) 188#define SCR1 (*((volatile unsigned char*)SCR1_ADDR))
198#define TDR1 (*((volatile unsigned char*)TDR1_ADDR)) 189#define TDR1 (*((volatile unsigned char*)TDR1_ADDR))
199#define SSR1 (*((volatile unsigned char*)SSR1_ADDR)) 190#define SSR1 (*((volatile unsigned char*)SSR1_ADDR))
200#define RDR1 (*((volatile unsigned char*)RDR1_ADDR)) 191#define RDR1 (*((volatile unsigned char*)RDR1_ADDR))
201 192
diff --git a/firmware/system.c b/firmware/system.c
index 0628eb64cb..726d7fd6cc 100644
--- a/firmware/system.c
+++ b/firmware/system.c
@@ -534,11 +534,15 @@ void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
534 for (i = 0; i < 240000; ++i); 534 for (i = 0; i < 240000; ++i);
535 535
536 /* try to restart firmware if ON is pressed */ 536 /* try to restart firmware if ON is pressed */
537#ifdef HAVE_LCD_CHARCELLS 537#if CONFIG_KEYPAD == PLAYER_PAD
538 if (!(PADR & 0x20)) 538 if (!(PADR & 0x0020))
539 rolo_load("/archos.mod"); 539 rolo_load("/archos.mod");
540#elif CONFIG_KEYPAD == RECORDER_PAD
541#ifdef HAVE_FMADC
542 if (!(PCDR & 0x0008))
540#else 543#else
541 if (!(PBDR & PBDR_BTN_ON)) 544 if (!(PBDR & 0x0100))
545#endif
542 rolo_load("/ajbrec.ajz"); 546 rolo_load("/ajbrec.ajz");
543#endif 547#endif
544 } 548 }