summaryrefslogtreecommitdiff
path: root/firmware/drivers/button.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/button.c')
-rw-r--r--firmware/drivers/button.c449
1 files changed, 161 insertions, 288 deletions
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