diff options
author | Bertrik Sikken <bertrik@sikken.nl> | 2011-10-30 20:15:08 +0000 |
---|---|---|
committer | Bertrik Sikken <bertrik@sikken.nl> | 2011-10-30 20:15:08 +0000 |
commit | eb7cf73dcbc7fff1a17aee93656e30c4a9f3f9f3 (patch) | |
tree | 79a1ea264fa4dcd2e2facd0bcbef47847ad60dea /firmware/target | |
parent | 539fb71b9d9eda14c0e370519c38ed4d503d3994 (diff) |
Sansa clip zip: use a state machine for scanning buttons to avoid busy-waits
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30871 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/as3525/sansa-clipzip/button-clipzip.c | 96 |
1 files changed, 55 insertions, 41 deletions
diff --git a/firmware/target/arm/as3525/sansa-clipzip/button-clipzip.c b/firmware/target/arm/as3525/sansa-clipzip/button-clipzip.c index e960b49b77..40b20cdce3 100644 --- a/firmware/target/arm/as3525/sansa-clipzip/button-clipzip.c +++ b/firmware/target/arm/as3525/sansa-clipzip/button-clipzip.c @@ -27,6 +27,59 @@ #include "kernel.h" #include "system-target.h" +static int keyscan(void) +{ + static int buttons = 0; + static int row = 1; + + switch (row) { + + case 1: + /* read row 1 */ + buttons &= ~(BUTTON_RIGHT | BUTTON_SELECT | BUTTON_UP); + if (GPIOC_PIN(3)) { + buttons |= BUTTON_RIGHT; + } + if (GPIOC_PIN(4)) { + buttons |= BUTTON_SELECT; + } + if (GPIOC_PIN(5)) { + buttons |= BUTTON_UP; + } + + /* prepare row 2 */ + GPIOC_PIN(1) = 0; + GPIOC_PIN(2) = (1 << 2); + row = 2; + break; + + case 2: + /* read row 2 */ + buttons &= ~(BUTTON_HOME | BUTTON_DOWN | BUTTON_LEFT); + if (GPIOC_PIN(3)) { + buttons |= BUTTON_HOME; + } + if (GPIOC_PIN(4)) { + buttons |= BUTTON_DOWN; + } + if (GPIOC_PIN(5)) { + buttons |= BUTTON_LEFT; + } + + /* prepare row 1 */ + GPIOC_PIN(1) = (1 << 1); + GPIOC_PIN(2) = 0; + row = 1; + break; + + default: + row = 1; + break; + } + + return buttons; +} + void button_init_device(void) { /* GPIO A6, A7 and D6 are direct button inputs */ @@ -39,15 +92,6 @@ void button_init_device(void) GPIOC_DIR &= ~((1 << 3) | (1 << 4) | (1 << 5)); } -/* TODO: - Instead of using udelay to wait for buttons to settle, we could use a - simple state machine to alternate between key matrix rows (like we do on - the clip) and this way avoid burning cycles in the udelay. - - TODO: - Figure out the real mappings from GPIOs to buttons. - The current mapping is just an educated guess. -*/ int button_read_device(void) { int buttons = 0; @@ -64,39 +108,9 @@ int button_read_device(void) if (GPIOA_PIN(7)) { buttons |= BUTTON_VOL_UP; } - - /* key matrix buttons, first row */ - GPIOC_PIN(1) = (1 << 1); - GPIOC_PIN(2) = 0; - udelay(500); - - if (GPIOC_PIN(3)) { - buttons |= BUTTON_RIGHT; - } - if (GPIOC_PIN(4)) { - buttons |= BUTTON_SELECT; - } - if (GPIOC_PIN(5)) { - buttons |= BUTTON_UP; - } - - /* key matrix buttons, second row */ - GPIOC_PIN(1) = 0; - GPIOC_PIN(2) = (1 << 2); - udelay(500); - - if (GPIOC_PIN(3)) { - buttons |= BUTTON_HOME; - } - if (GPIOC_PIN(4)) { - buttons |= BUTTON_DOWN; - } - if (GPIOC_PIN(5)) { - buttons |= BUTTON_LEFT; - } - /* deselect scan rows */ - GPIOC_PIN(2) = 0; + /* keyscan buttons */ + buttons |= keyscan(); return buttons; } |