diff options
author | Bertrik Sikken <bertrik@sikken.nl> | 2009-06-11 22:17:47 +0000 |
---|---|---|
committer | Bertrik Sikken <bertrik@sikken.nl> | 2009-06-11 22:17:47 +0000 |
commit | 426cdb128470f9b434b6ba55f19b28aac7afaf79 (patch) | |
tree | fbaddb4ed8070e857be8c3b3e5e95be94b52e4fe /firmware/target/arm | |
parent | 79f348a178dd0e36fdc46fcff1899cc4beb592c7 (diff) | |
download | rockbox-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
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/as3525/sansa-clip/button-clip.c | 101 |
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 | |||
25 | void button_init_device(void) | 37 | void 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 | ||
35 | int button_read_device(void) | 52 | int 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 | ||
92 | bool button_hold(void) | 125 | bool button_hold(void) |