summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorBertrik Sikken <bertrik@sikken.nl>2011-10-30 20:15:08 +0000
committerBertrik Sikken <bertrik@sikken.nl>2011-10-30 20:15:08 +0000
commiteb7cf73dcbc7fff1a17aee93656e30c4a9f3f9f3 (patch)
tree79a1ea264fa4dcd2e2facd0bcbef47847ad60dea /firmware
parent539fb71b9d9eda14c0e370519c38ed4d503d3994 (diff)
downloadrockbox-eb7cf73dcbc7fff1a17aee93656e30c4a9f3f9f3.tar.gz
rockbox-eb7cf73dcbc7fff1a17aee93656e30c4a9f3f9f3.zip
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')
-rw-r--r--firmware/target/arm/as3525/sansa-clipzip/button-clipzip.c96
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 @@
27#include "kernel.h" 27#include "kernel.h"
28#include "system-target.h" 28#include "system-target.h"
29 29
30static int keyscan(void)
31{
32 static int buttons = 0;
33 static int row = 1;
34
35 switch (row) {
36
37 case 1:
38 /* read row 1 */
39 buttons &= ~(BUTTON_RIGHT | BUTTON_SELECT | BUTTON_UP);
40 if (GPIOC_PIN(3)) {
41 buttons |= BUTTON_RIGHT;
42 }
43 if (GPIOC_PIN(4)) {
44 buttons |= BUTTON_SELECT;
45 }
46 if (GPIOC_PIN(5)) {
47 buttons |= BUTTON_UP;
48 }
49
50 /* prepare row 2 */
51 GPIOC_PIN(1) = 0;
52 GPIOC_PIN(2) = (1 << 2);
53 row = 2;
54 break;
55
56 case 2:
57 /* read row 2 */
58 buttons &= ~(BUTTON_HOME | BUTTON_DOWN | BUTTON_LEFT);
59 if (GPIOC_PIN(3)) {
60 buttons |= BUTTON_HOME;
61 }
62 if (GPIOC_PIN(4)) {
63 buttons |= BUTTON_DOWN;
64 }
65 if (GPIOC_PIN(5)) {
66 buttons |= BUTTON_LEFT;
67 }
68
69 /* prepare row 1 */
70 GPIOC_PIN(1) = (1 << 1);
71 GPIOC_PIN(2) = 0;
72 row = 1;
73 break;
74
75 default:
76 row = 1;
77 break;
78 }
79
80 return buttons;
81}
82
30void button_init_device(void) 83void button_init_device(void)
31{ 84{
32 /* GPIO A6, A7 and D6 are direct button inputs */ 85 /* GPIO A6, A7 and D6 are direct button inputs */
@@ -39,15 +92,6 @@ void button_init_device(void)
39 GPIOC_DIR &= ~((1 << 3) | (1 << 4) | (1 << 5)); 92 GPIOC_DIR &= ~((1 << 3) | (1 << 4) | (1 << 5));
40} 93}
41 94
42/* TODO:
43 Instead of using udelay to wait for buttons to settle, we could use a
44 simple state machine to alternate between key matrix rows (like we do on
45 the clip) and this way avoid burning cycles in the udelay.
46
47 TODO:
48 Figure out the real mappings from GPIOs to buttons.
49 The current mapping is just an educated guess.
50*/
51int button_read_device(void) 95int button_read_device(void)
52{ 96{
53 int buttons = 0; 97 int buttons = 0;
@@ -64,39 +108,9 @@ int button_read_device(void)
64 if (GPIOA_PIN(7)) { 108 if (GPIOA_PIN(7)) {
65 buttons |= BUTTON_VOL_UP; 109 buttons |= BUTTON_VOL_UP;
66 } 110 }
67
68 /* key matrix buttons, first row */
69 GPIOC_PIN(1) = (1 << 1);
70 GPIOC_PIN(2) = 0;
71 udelay(500);
72
73 if (GPIOC_PIN(3)) {
74 buttons |= BUTTON_RIGHT;
75 }
76 if (GPIOC_PIN(4)) {
77 buttons |= BUTTON_SELECT;
78 }
79 if (GPIOC_PIN(5)) {
80 buttons |= BUTTON_UP;
81 }
82
83 /* key matrix buttons, second row */
84 GPIOC_PIN(1) = 0;
85 GPIOC_PIN(2) = (1 << 2);
86 udelay(500);
87
88 if (GPIOC_PIN(3)) {
89 buttons |= BUTTON_HOME;
90 }
91 if (GPIOC_PIN(4)) {
92 buttons |= BUTTON_DOWN;
93 }
94 if (GPIOC_PIN(5)) {
95 buttons |= BUTTON_LEFT;
96 }
97 111
98 /* deselect scan rows */ 112 /* keyscan buttons */
99 GPIOC_PIN(2) = 0; 113 buttons |= keyscan();
100 114
101 return buttons; 115 return buttons;
102} 116}