summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBertrik Sikken <bertrik@sikken.nl>2009-06-11 22:17:47 +0000
committerBertrik Sikken <bertrik@sikken.nl>2009-06-11 22:17:47 +0000
commit426cdb128470f9b434b6ba55f19b28aac7afaf79 (patch)
treefbaddb4ed8070e857be8c3b3e5e95be94b52e4fe
parent79f348a178dd0e36fdc46fcff1899cc4beb592c7 (diff)
downloadrockbox-426cdb128470f9b434b6ba55f19b28aac7afaf79.tar.gz
rockbox-426cdb128470f9b434b6ba55f19b28aac7afaf79.zip
Commit FS#10285 - Sansa Clip alternative button driver. This driver alternates one row in the button matrix per kernel tick, avoiding the need for explicit delays between selecting a button row and reading colums.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21253 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/as3525/sansa-clip/button-clip.c101
1 files changed, 67 insertions, 34 deletions
diff --git a/firmware/target/arm/as3525/sansa-clip/button-clip.c b/firmware/target/arm/as3525/sansa-clip/button-clip.c
index 2d2a3a661e..0d4e3a6306 100644
--- a/firmware/target/arm/as3525/sansa-clip/button-clip.c
+++ b/firmware/target/arm/as3525/sansa-clip/button-clip.c
@@ -7,6 +7,7 @@
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2009 Bertrik Sikken
10 * Copyright (C) 2008 François Dinel 11 * Copyright (C) 2008 François Dinel
11 * Copyright (C) 2008 Rafaël Carré 12 * Copyright (C) 2008 Rafaël Carré
12 * 13 *
@@ -22,71 +23,103 @@
22#include "button-target.h" 23#include "button-target.h"
23#include "as3525.h" 24#include "as3525.h"
24 25
26/* The Sansa Clip uses a button matrix that is scanned by selecting one of
27 three rows and reading back the button states from the columns.
28
29 In this driver, the row is changed at each call (i.e. once per tick).
30 In one tick, column data from one row is read back and then the next row
31 is selected for the following tick. This mechanism ensures that there is
32 plenty time between selecting a row and reading the columns, avoiding the
33 need for explicit delays.
34*/
35
36
25void button_init_device(void) 37void button_init_device(void)
26{ 38{
27 GPIOA_DIR &= ~((1<<7) | (1<<3)); 39 GPIOA_DIR &= ~((1<<7) | (1<<3));
28 GPIOB_DIR &= ~((1<<2) | (1<<1) | (1<<0)); 40 GPIOB_DIR &= ~((1<<2) | (1<<1) | (1<<0));
29 GPIOC_PIN(4) = 0x00; 41 GPIOC_PIN(4) = 0;
30 GPIOC_PIN(5) = 0x00; 42 GPIOC_PIN(5) = 0;
31 GPIOC_PIN(6) = 0x00; 43 GPIOC_PIN(6) = 0;
32 GPIOC_DIR |= ((1<<6) | (1<<5) | (1<<4)); 44 GPIOC_DIR |= ((1<<6) | (1<<5) | (1<<4));
45
46 /* get initial readings */
47 button_read_device();
48 button_read_device();
49 button_read_device();
33} 50}
34 51
35int button_read_device(void) 52int button_read_device(void)
36{ 53{
37 int result = 0; 54 static int row = 0;
55 static int buttons = 0;
38 56
39 if(button_hold()) 57 if(button_hold())
40 return result; 58 return 0;
41 59
42 /* direct GPIO connections */ 60 /* direct GPIO connections */
43
44 if (GPIOA_PIN(7)) 61 if (GPIOA_PIN(7))
45 result |= BUTTON_POWER; 62 buttons |= BUTTON_POWER;
63 else
64 buttons &= ~BUTTON_POWER;
46 65
47 /* This is a keypad using C4-C6 as columns and B0-B2 as rows */ 66 /* This is a keypad using C4-C6 as columns and B0-B2 as rows */
48 GPIOC_PIN(4) = (1<<4); 67 switch (row) {
49 asm volatile("nop\nnop\nnop\nnop\nnop\n"); /* small delay */ 68
69 case 0:
70 buttons &= ~(BUTTON_VOL_UP | BUTTON_UP);
71
72 (void)GPIOB_PIN(0); /* C4B0 is unused */
50 73
51 (void)GPIOB_PIN(0); /* C4B0 is unused */ 74 if (GPIOB_PIN(1))
75 buttons |= BUTTON_VOL_UP;
52 76
53 if (GPIOB_PIN(1)) 77 if (GPIOB_PIN(2))
54 result |= BUTTON_VOL_UP; 78 buttons |= BUTTON_UP;
55 79
56 if (GPIOB_PIN(2)) 80 GPIOC_PIN(4) = 0;
57 result |= BUTTON_UP; 81 GPIOC_PIN(5) = (1<<5);
82 row++;
83 break;
58 84
59 GPIOC_PIN(4) = 0x00; 85 case 1:
86 buttons &= ~(BUTTON_LEFT | BUTTON_SELECT | BUTTON_RIGHT);
60 87
61 GPIOC_PIN(5) = (1<<5); 88 if (GPIOB_PIN(0))
62 asm volatile("nop\nnop\nnop\nnop\nnop\n"); /* small delay */ 89 buttons |= BUTTON_LEFT;
63 90
64 if (GPIOB_PIN(0)) 91 if (GPIOB_PIN(1))
65 result |= BUTTON_LEFT; 92 buttons |= BUTTON_SELECT;
66 93
67 if (GPIOB_PIN(1)) 94 if (GPIOB_PIN(2))
68 result |= BUTTON_SELECT; 95 buttons |= BUTTON_RIGHT;
69 96
70 if (GPIOB_PIN(2)) 97 GPIOC_PIN(5) = 0;
71 result |= BUTTON_RIGHT; 98 GPIOC_PIN(6) = (1<<6);
99 row++;
100 break;
72 101
73 GPIOC_PIN(5) = 0x00; 102 case 2:
103 buttons &= ~(BUTTON_DOWN | BUTTON_VOL_DOWN | BUTTON_HOME);
74 104
75 GPIOC_PIN(6) = (1<<6); 105 if (GPIOB_PIN(0))
76 asm volatile("nop\nnop\nnop\nnop\nnop\n"); /* small delay */ 106 buttons |= BUTTON_DOWN;
77 107
78 if (GPIOB_PIN(0)) 108 if (GPIOB_PIN(1))
79 result |= BUTTON_DOWN; 109 buttons |= BUTTON_VOL_DOWN;
80 110
81 if (GPIOB_PIN(1)) 111 if (GPIOB_PIN(2))
82 result |= BUTTON_VOL_DOWN; 112 buttons |= BUTTON_HOME;
83 113
84 if (GPIOB_PIN(2)) 114 GPIOC_PIN(6) = 0;
85 result |= BUTTON_HOME; 115 GPIOC_PIN(4) = (1<<4);
86 116
87 GPIOC_PIN(6) = 0x00; 117 default:
118 row = 0;
119 break;
120 }
88 121
89 return result; 122 return buttons;
90} 123}
91 124
92bool button_hold(void) 125bool button_hold(void)