1
0
Fork 0
forked from len0rd/rockbox

Do extra filtering in H300 (and H100) main unit button reading to suppress wrong readings during voltage transitions. * Optimised multi-button ADC reads to use a balanced binary tree with an initial check for 'any button' to determine the pressed button. * The iriver button driver wouldn't have detected main unit (ADC-connected) buttons as long as remote buttons (ADC-connected) were pressed (btn = value; vs. btn |= value), * Do extra filtering in the recorder v1 OFF button read, to suppress spurious OFF events. * Some more tweaks.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9530 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2006-04-06 07:27:11 +00:00
parent 857db456af
commit cef83c782f

View file

@ -222,7 +222,7 @@ void ipod_4g_button_int(void)
CPU_HI_INT_EN = I2C_MASK; CPU_HI_INT_EN = I2C_MASK;
} }
#endif #endif
#if (CONFIG_KEYPAD == IPOD_3G_PAD) || defined(IPOD_MINI) #if (CONFIG_KEYPAD == IPOD_3G_PAD) || defined(IPOD_MINI)
/* iPod 3G and mini 1G, mini 2G uses iPod 4G code */ /* iPod 3G and mini 1G, mini 2G uses iPod 4G code */
void handle_scroll_wheel(int new_scroll, int was_hold, int reverse) void handle_scroll_wheel(int new_scroll, int was_hold, int reverse)
{ {
@ -393,8 +393,8 @@ static int ipod_3g_button_read(void)
return btn; return btn;
} }
#endif
#endif
static void button_tick(void) static void button_tick(void)
{ {
static int tick = 0; static int tick = 0;
@ -482,10 +482,9 @@ static void button_tick(void)
#ifdef HAVE_SW_POWEROFF #ifdef HAVE_SW_POWEROFF
if ((btn == POWEROFF_BUTTON if ((btn == POWEROFF_BUTTON
#ifdef BUTTON_RC_STOP #ifdef BUTTON_RC_STOP
|| btn == BUTTON_RC_STOP) && || btn == BUTTON_RC_STOP
#else
) &&
#endif #endif
) &&
#if defined(HAVE_CHARGING) && !defined(HAVE_POWEROFF_WHILE_CHARGING) #if defined(HAVE_CHARGING) && !defined(HAVE_POWEROFF_WHILE_CHARGING)
!charger_inserted() && !charger_inserted() &&
#endif #endif
@ -836,14 +835,12 @@ static int button_read(void)
{ {
int btn = BUTTON_NONE; int btn = BUTTON_NONE;
int retval; int retval;
int data; int data;
#if (CONFIG_KEYPAD == IRIVER_H100_PAD)\ #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
|| (CONFIG_KEYPAD == IRIVER_H300_PAD)
static bool hold_button = false; static bool hold_button = false;
static bool remote_hold_button = false; static bool remote_hold_button = false;
static int last_button_val= 0xff;
/* light handling */ /* light handling */
if (hold_button && !button_hold()) if (hold_button && !button_hold())
@ -862,136 +859,146 @@ static int button_read(void)
if (!hold_button) if (!hold_button)
{ {
data = adc_scan(ADC_BUTTONS); data = adc_scan(ADC_BUTTONS);
#if CONFIG_KEYPAD == IRIVER_H100_PAD #if CONFIG_KEYPAD == IRIVER_H100_PAD
if (data < 0x80) if ((data < 0xf0) && ((unsigned)(data - last_button_val + 1) <= 2))
if (data < 0x30) {
if (data < 0x18) if (data < 0x80)
btn = BUTTON_SELECT; if (data < 0x30)
if (data < 0x18)
btn = BUTTON_SELECT;
else
btn = BUTTON_UP;
else else
btn = BUTTON_UP; if (data < 0x50)
btn = BUTTON_LEFT;
else
btn = BUTTON_DOWN;
else else
if (data < 0x50) if (data < 0xb0)
btn = BUTTON_LEFT; if (data < 0xa0)
btn = BUTTON_RIGHT;
else
btn = BUTTON_OFF;
else else
btn = BUTTON_DOWN; if (data < 0xd0)
else btn = BUTTON_MODE;
if (data < 0xb0) else
if (data < 0xa0)
btn = BUTTON_RIGHT;
else
btn = BUTTON_OFF;
else
if (data < 0xd0)
btn = BUTTON_MODE;
else
if (data < 0xf0)
btn = BUTTON_REC; btn = BUTTON_REC;
}
#else /* H300 */ #else /* H300 */
if (data < 0x54) if ((data < 0xba) && ((unsigned)(data - last_button_val + 1) <= 2))
if (data < 0x30) {
if (data < 0x10) if (data < 0x54)
btn = BUTTON_SELECT; if (data < 0x30)
if (data < 0x10)
btn = BUTTON_SELECT;
else
btn = BUTTON_UP;
else else
btn = BUTTON_UP; btn = BUTTON_LEFT;
else else
btn = BUTTON_LEFT; if (data < 0x98)
else if (data < 0x76)
if (data < 0x98) btn = BUTTON_DOWN;
if (data < 0x76) else
btn = BUTTON_DOWN; btn = BUTTON_RIGHT;
else else
btn = BUTTON_RIGHT;
else
if(data < 0xba)
btn = BUTTON_OFF; btn = BUTTON_OFF;
}
#endif #endif
last_button_val = data;
} }
/* remote buttons */ /* remote buttons */
if (!remote_hold_button) if (!remote_hold_button)
{ {
data = adc_scan(ADC_REMOTE); data = adc_scan(ADC_REMOTE);
switch(remote_type()) switch (remote_type())
{ {
case REMOTETYPE_H100_LCD: case REMOTETYPE_H100_LCD:
if (data < 0x73) if (data < 0xf5)
if (data < 0x3f) {
if (data < 0x25) if (data < 0x73)
if(data < 0x0c) if (data < 0x3f)
btn = BUTTON_RC_STOP; if (data < 0x25)
if(data < 0x0c)
btn |= BUTTON_RC_STOP;
else
btn |= BUTTON_RC_VOL_DOWN;
else else
btn = BUTTON_RC_VOL_DOWN; btn |= BUTTON_RC_MODE;
else else
btn = BUTTON_RC_MODE; if (data < 0x5a)
else btn |= BUTTON_RC_VOL_UP;
if (data < 0x5a)
btn = BUTTON_RC_VOL_UP;
else
btn = BUTTON_RC_BITRATE;
else
if (data < 0xa8)
if (data < 0x8c)
btn = BUTTON_RC_REC;
else
btn = BUTTON_RC_SOURCE;
else
if (data < 0xdf)
if(data < 0xc5)
btn = BUTTON_RC_FF;
else else
btn = BUTTON_RC_MENU; btn |= BUTTON_RC_BITRATE;
else
if (data < 0xa8)
if (data < 0x8c)
btn |= BUTTON_RC_REC;
else
btn |= BUTTON_RC_SOURCE;
else else
if (data < 0xf5) if (data < 0xdf)
btn = BUTTON_RC_REW; if(data < 0xc5)
btn |= BUTTON_RC_FF;
else
btn |= BUTTON_RC_MENU;
else
btn |= BUTTON_RC_REW;
}
break; break;
case REMOTETYPE_H300_LCD: case REMOTETYPE_H300_LCD:
if (data < 0x73) if (data < 0xf5)
if (data < 0x42) {
if (data < 0x27) if (data < 0x73)
if(data < 0x0c) if (data < 0x42)
btn = BUTTON_RC_VOL_DOWN; if (data < 0x27)
if(data < 0x0c)
btn |= BUTTON_RC_VOL_DOWN;
else
btn |= BUTTON_RC_FF;
else else
btn = BUTTON_RC_FF; btn |= BUTTON_RC_STOP;
else else
btn = BUTTON_RC_STOP; if (data < 0x5b)
else btn |= BUTTON_RC_MODE;
if (data < 0x5b)
btn = BUTTON_RC_MODE;
else
btn = BUTTON_RC_REC;
else
if (data < 0xab)
if (data < 0x8e)
btn = BUTTON_RC_ON;
else
btn = BUTTON_RC_BITRATE;
else
if (data < 0xde)
if(data < 0xc5)
btn = BUTTON_RC_SOURCE;
else else
btn = BUTTON_RC_VOL_UP; btn |= BUTTON_RC_REC;
else
if (data < 0xab)
if (data < 0x8e)
btn |= BUTTON_RC_ON;
else
btn |= BUTTON_RC_BITRATE;
else else
if (data < 0xf5) if (data < 0xde)
btn = BUTTON_RC_REW; if(data < 0xc5)
btn |= BUTTON_RC_SOURCE;
else
btn |= BUTTON_RC_VOL_UP;
else
btn |= BUTTON_RC_REW;
}
break; break;
case REMOTETYPE_H300_NONLCD: case REMOTETYPE_H300_NONLCD:
if(data<0x7d) if (data < 0xf1)
if(data<0x25) {
btn = BUTTON_RC_FF; if (data < 0x7d)
if (data < 0x25)
btn |= BUTTON_RC_FF;
else
btn |= BUTTON_RC_REW;
else else
btn = BUTTON_RC_REW; if (data < 0xd5)
else btn |= BUTTON_RC_VOL_DOWN;
if(data<0xd5) else
btn = BUTTON_RC_VOL_DOWN; btn |= BUTTON_RC_VOL_UP;
else }
if(data<0xf1) /* 0xff no button pressed */
btn = BUTTON_RC_VOL_UP;
break; break;
} }
} }
/* special buttons */ /* special buttons */
#if CONFIG_KEYPAD == IRIVER_H300_PAD #if CONFIG_KEYPAD == IRIVER_H300_PAD
if (!hold_button) if (!hold_button)
@ -1020,7 +1027,6 @@ static int button_read(void)
} }
#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
static bool hold_button = false; static bool hold_button = false;
/* light handling */ /* light handling */
@ -1032,67 +1038,56 @@ static int button_read(void)
/* normal buttons */ /* normal buttons */
if (!button_hold()) if (!button_hold())
{ {
data = adc_read(ADC_BUTTONS); data = adc_read(ADC_BUTTONS);
if (data < 0x35c)
if (data < 0x151) {
if (data < 0xc7) if (data < 0x151)
if (data < 0x41) if (data < 0xc7)
btn = BUTTON_LEFT; if (data < 0x41)
btn = BUTTON_LEFT;
else
btn = BUTTON_RIGHT;
else else
btn = BUTTON_RIGHT; btn = BUTTON_SELECT;
else else
btn = BUTTON_SELECT; if (data < 0x268)
else if (data < 0x1d7)
if (data < 0x268) btn = BUTTON_UP;
if (data < 0x1d7) else
btn = BUTTON_UP; btn = BUTTON_DOWN;
else else
btn = BUTTON_DOWN; if (data < 0x2f9)
else btn = BUTTON_EQ;
if (data < 0x2f9) else
btn = BUTTON_EQ;
else
if (data < 0x35c)
btn = BUTTON_MODE; btn = BUTTON_MODE;
}
if (adc_read(ADC_BUTTON_PLAY) < 0x64)
btn |= BUTTON_PLAY;
} }
if (!button_hold() && (adc_read(ADC_BUTTON_PLAY) < 0x64))
btn |= BUTTON_PLAY;
#elif CONFIG_KEYPAD == RECORDER_PAD #elif CONFIG_KEYPAD == RECORDER_PAD
#ifndef HAVE_FMADC
#ifdef HAVE_FMADC static int off_button_count = 0;
if ( adc_read(ADC_BUTTON_ON) < 512 )
btn |= BUTTON_ON;
if ( adc_read(ADC_BUTTON_OFF) > 512 )
btn |= BUTTON_OFF;
#else
/* check port B pins for ON and OFF */
data = PBDR;
if ((data & 0x0100) == 0)
btn |= BUTTON_ON;
if ((data & 0x0010) == 0)
btn |= BUTTON_OFF;
#endif #endif
/* check F1..F3 and UP */ /* check F1..F3 and UP */
data = adc_read(ADC_BUTTON_ROW1); data = adc_read(ADC_BUTTON_ROW1);
if (data >= LEVEL1) if (data >= LEVEL1)
{ {
if (data >= LEVEL3) if (data >= LEVEL3)
if (data >= LEVEL4) if (data >= LEVEL4)
btn |= BUTTON_F3; btn = BUTTON_F3;
else else
btn |= BUTTON_UP; btn = BUTTON_UP;
else else
if (data >= LEVEL2) if (data >= LEVEL2)
btn |= BUTTON_F2; btn = BUTTON_F2;
else else
btn |= BUTTON_F1; btn = BUTTON_F1;
} }
/* Some units have mushy keypads, so pressing UP also activates /* Some units have mushy keypads, so pressing UP also activates
the Left/Right buttons. Let's combat that by skipping the AN5 the Left/Right buttons. Let's combat that by skipping the AN5
checks when UP is pressed. */ checks when UP is pressed. */
@ -1100,7 +1095,6 @@ static int button_read(void)
{ {
/* check DOWN, PLAY, LEFT, RIGHT */ /* check DOWN, PLAY, LEFT, RIGHT */
data = adc_read(ADC_BUTTON_ROW2); data = adc_read(ADC_BUTTON_ROW2);
if (data >= LEVEL1) if (data >= LEVEL1)
{ {
if (data >= LEVEL3) if (data >= LEVEL3)
@ -1116,11 +1110,33 @@ static int button_read(void)
} }
} }
#elif CONFIG_KEYPAD == PLAYER_PAD #ifdef HAVE_FMADC
if ( adc_read(ADC_BUTTON_ON) < 512 )
btn |= BUTTON_ON;
if ( adc_read(ADC_BUTTON_OFF) > 512 )
btn |= BUTTON_OFF;
#else
/* check port B pins for ON and OFF */
data = PBDR;
if ((data & 0x0100) == 0)
btn |= BUTTON_ON;
if ((data & 0x0010) == 0)
{
/* When the batteries are low, the low-battery shutdown logic causes
* spurious OFF events due to voltage fluctuation on some units.
* Only accept OFF when read several times in sequence. */
if (++off_button_count > 3)
btn |= BUTTON_OFF;
}
else
off_button_count = 0;
#endif
#elif CONFIG_KEYPAD == PLAYER_PAD
/* buttons are active low */ /* buttons are active low */
if (adc_read(0) < 0x180) if (adc_read(0) < 0x180)
btn |= BUTTON_LEFT; btn = BUTTON_LEFT;
if (adc_read(1) < 0x180) if (adc_read(1) < 0x180)
btn |= BUTTON_MENU; btn |= BUTTON_MENU;
if(adc_read(2) < 0x180) if(adc_read(2) < 0x180)
@ -1136,46 +1152,54 @@ static int button_read(void)
btn |= BUTTON_STOP; btn |= BUTTON_STOP;
#elif CONFIG_KEYPAD == ONDIO_PAD #elif CONFIG_KEYPAD == ONDIO_PAD
/* Check the 4 direction keys */
data = adc_read(ADC_BUTTON_ROW1);
if (data >= LEVEL1)
{
if (data >= LEVEL3)
if (data >= LEVEL4)
btn = BUTTON_LEFT;
else
btn = BUTTON_RIGHT;
else
if (data >= LEVEL2)
btn = BUTTON_UP;
else
btn = BUTTON_DOWN;
}
if(adc_read(ADC_BUTTON_OPTION) > 0x200) /* active high */ if(adc_read(ADC_BUTTON_OPTION) > 0x200) /* active high */
btn |= BUTTON_MENU; btn |= BUTTON_MENU;
if(adc_read(ADC_BUTTON_ONOFF) < 0x120) /* active low */ if(adc_read(ADC_BUTTON_ONOFF) < 0x120) /* active low */
btn |= BUTTON_OFF; btn |= BUTTON_OFF;
/* Check the 4 direction keys */
data = adc_read(ADC_BUTTON_ROW1);
if (data >= LEVEL1)
{
if (data >= LEVEL3)
if (data >= LEVEL4)
btn |= BUTTON_LEFT;
else
btn |= BUTTON_RIGHT;
else
if (data >= LEVEL2)
btn |= BUTTON_UP;
else
btn |= BUTTON_DOWN;
}
#elif CONFIG_KEYPAD == GMINI100_PAD #elif CONFIG_KEYPAD == GMINI100_PAD
data = adc_read(7);
if (data < 0x38a)
{
if (data < 0x1c5)
if (data < 0xe3)
btn = BUTTON_LEFT;
else
btn = BUTTON_DOWN;
else
if (data < 0x2a2)
btn = BUTTON_RIGHT;
else
btn = BUTTON_UP;
}
if (adc_read(7) < 0xE3) data = adc_read(6);
btn |= BUTTON_LEFT; if (data < 0x355)
else if (adc_read(7) < 0x1c5) {
btn |= BUTTON_DOWN; if (data < 0x288)
else if (adc_read(7) < 0x2a2) if (data < 0x233)
btn |= BUTTON_RIGHT; btn |= BUTTON_OFF;
else if (adc_read(7) < 0x38a) else
btn |= BUTTON_UP; btn |= BUTTON_PLAY;
else
if (adc_read(6) < 0x233) btn |= BUTTON_MENU;
btn |= BUTTON_OFF; }
else if (adc_read(6) < 0x288)
btn |= BUTTON_PLAY;
else if (adc_read(6) < 0x355)
btn |= BUTTON_MENU;
data = P7; data = P7;
if (data & 0x01) if (data & 0x01)
@ -1185,6 +1209,7 @@ static int button_read(void)
(void)data; (void)data;
/* The int_btn variable is set in the button interrupt handler */ /* The int_btn variable is set in the button interrupt handler */
btn = int_btn; btn = int_btn;
#elif (CONFIG_KEYPAD == IPOD_3G_PAD) #elif (CONFIG_KEYPAD == IPOD_3G_PAD)
(void)data; (void)data;
btn = ipod_3g_button_read(); btn = ipod_3g_button_read();
@ -1200,27 +1225,29 @@ static int button_read(void)
if (!hold_button) if (!hold_button)
{ {
data = adc_scan(ADC_BUTTONS); data = adc_scan(ADC_BUTTONS);
if(data < 0x7c) if (data < 0xf0)
if(data < 0x42) {
btn = BUTTON_LEFT; if(data < 0x7c)
if(data < 0x42)
btn = BUTTON_LEFT;
else
if(data < 0x62)
btn = BUTTON_RIGHT;
else
btn = BUTTON_SELECT;
else else
if(data < 0x62) if(data < 0xb6)
btn = BUTTON_RIGHT; if(data < 0x98)
btn = BUTTON_REC;
else
btn = BUTTON_PLAY;
else else
btn = BUTTON_SELECT; if(data < 0xd3)
else btn = BUTTON_DOWN;
if(data < 0xb6) else
if(data < 0x98)
btn = BUTTON_REC;
else
btn = BUTTON_PLAY;
else
if(data < 0xd3)
btn = BUTTON_DOWN;
else
if(data < 0xf0)
btn = BUTTON_UP; btn = BUTTON_UP;
} }
}
/* remote buttons */ /* remote buttons */
data = adc_scan(ADC_REMOTE); data = adc_scan(ADC_REMOTE);
@ -1229,28 +1256,30 @@ static int button_read(void)
if(!remote_hold_button) if(!remote_hold_button)
{ {
if(data < 0x7a) if (data < 0xee)
if(data < 0x41) {
btn = BUTTON_RC_REW; if(data < 0x7a)
if(data < 0x41)
btn |= BUTTON_RC_REW;
else
if(data < 0x61)
btn |= BUTTON_RC_FF;
else
btn |= BUTTON_RC_MODE;
else else
if(data < 0x61) if(data < 0xb4)
btn = BUTTON_RC_FF; if(data < 0x96)
btn |= BUTTON_RC_REC;
else
btn |= BUTTON_RC_MENU;
else else
btn = BUTTON_RC_MODE; if(data < 0xd1)
else btn |= BUTTON_RC_VOL_UP;
if(data < 0xb4) else
if(data < 0x96) btn |= BUTTON_RC_VOL_DOWN;
btn = BUTTON_RC_REC; }
else
btn = BUTTON_RC_MENU;
else
if(data < 0xd1)
btn = BUTTON_RC_VOL_UP;
else
if(data < 0xee)
btn = BUTTON_RC_VOL_DOWN;
} }
data = GPIO_READ; data = GPIO_READ;
if (!(data & 0x04000000)) if (!(data & 0x04000000))
btn |= BUTTON_POWER; btn |= BUTTON_POWER;
@ -1260,7 +1289,6 @@ static int button_read(void)
#endif /* CONFIG_KEYPAD */ #endif /* CONFIG_KEYPAD */
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
if (btn && flipped) if (btn && flipped)
btn = button_flip(btn); /* swap upside down */ btn = button_flip(btn); /* swap upside down */