summaryrefslogtreecommitdiff
path: root/firmware/target/arm/as3525/button-e200v2-fuze.c
diff options
context:
space:
mode:
authorRafaël Carré <rafael.carre@gmail.com>2010-01-06 23:41:36 +0000
committerRafaël Carré <rafael.carre@gmail.com>2010-01-06 23:41:36 +0000
commit57667c51cf09de052222484ce94fbd6da113a55c (patch)
treeb85872be9b6c204e7d66a9203a64d78c524a38a5 /firmware/target/arm/as3525/button-e200v2-fuze.c
parent8e8e2627b27b28a855881db09f2c16bfb2193050 (diff)
downloadrockbox-57667c51cf09de052222484ce94fbd6da113a55c.tar.gz
rockbox-57667c51cf09de052222484ce94fbd6da113a55c.zip
Sansa AMS: refactor DBOP button reading (e200v2/Fuze/c200v2)
This gets rid of LCD glitches on Sansa Fuze, and now LCD transfers can get interrupted by button reading Flyspray: FS #10603 Author: Bertrik Sikken git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24192 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/as3525/button-e200v2-fuze.c')
-rw-r--r--firmware/target/arm/as3525/button-e200v2-fuze.c210
1 files changed, 46 insertions, 164 deletions
diff --git a/firmware/target/arm/as3525/button-e200v2-fuze.c b/firmware/target/arm/as3525/button-e200v2-fuze.c
index 157cdd02a3..98c660dd45 100644
--- a/firmware/target/arm/as3525/button-e200v2-fuze.c
+++ b/firmware/target/arm/as3525/button-e200v2-fuze.c
@@ -20,10 +20,12 @@
20 * 20 *
21 ****************************************************************************/ 21 ****************************************************************************/
22 22
23#include "config.h"
23#include "system.h" 24#include "system.h"
24#include "button.h" 25#include "button.h"
25#include "button-target.h" 26#include "button-target.h"
26#include "backlight.h" 27#include "backlight.h"
28#include "dbop-as3525.h"
27 29
28 30
29#ifdef SANSA_FUZE 31#ifdef SANSA_FUZE
@@ -32,7 +34,6 @@
32#define WHEEL_COUNTER_DIV 4 34#define WHEEL_COUNTER_DIV 4
33#define ACCEL_INCREMENT 2 35#define ACCEL_INCREMENT 2
34#define ACCEL_SHIFT 2 36#define ACCEL_SHIFT 2
35#define BUTTON_DELAY 60
36#endif 37#endif
37 38
38#ifdef SANSA_E200V2 39#ifdef SANSA_E200V2
@@ -41,12 +42,6 @@
41#define WHEEL_COUNTER_DIV 2 42#define WHEEL_COUNTER_DIV 2
42#define ACCEL_INCREMENT 3 43#define ACCEL_INCREMENT 3
43#define ACCEL_SHIFT 1 44#define ACCEL_SHIFT 1
44#define BUTTON_DELAY 20
45
46/* read_missed is true if buttons could not
47 * be read (see lcd_button_support) */
48static bool read_missed = false;
49
50#endif 45#endif
51 46
52/* Buttons */ 47/* Buttons */
@@ -54,10 +49,6 @@ static bool hold_button = false;
54#ifndef BOOTLOADER 49#ifndef BOOTLOADER
55static bool hold_button_old = false; 50static bool hold_button_old = false;
56#endif 51#endif
57static unsigned short _dbop_din = BUTTON_NONE;
58
59/* in the lcd driver */
60extern bool lcd_button_support(void);
61 52
62void button_init_device(void) 53void button_init_device(void)
63{ 54{
@@ -66,10 +57,9 @@ void button_init_device(void)
66} 57}
67 58
68#if !defined(BOOTLOADER) && defined(HAVE_SCROLLWHEEL) 59#if !defined(BOOTLOADER) && defined(HAVE_SCROLLWHEEL)
69static void scrollwheel(unsigned short dbop_din) 60static void scrollwheel(unsigned int wheel_value)
70{ 61{
71 /* current wheel values, parsed from dbop and the resulting button */ 62 /* current wheel values, parsed from dbop and the resulting button */
72 unsigned wheel_value = 0;
73 unsigned btn = BUTTON_NONE; 63 unsigned btn = BUTTON_NONE;
74 /* old wheel values */ 64 /* old wheel values */
75 static unsigned old_wheel_value = 0; 65 static unsigned old_wheel_value = 0;
@@ -112,8 +102,6 @@ static void scrollwheel(unsigned short dbop_din)
112 return; 102 return;
113 } 103 }
114 104
115 wheel_value = (dbop_din >> 13) & (1<<1|1<<0);
116
117 if (old_wheel_value == wheel_tbl[0][wheel_value]) 105 if (old_wheel_value == wheel_tbl[0][wheel_value])
118 btn = BUTTON_SCROLL_FWD; 106 btn = BUTTON_SCROLL_FWD;
119 else if (old_wheel_value == wheel_tbl[1][wheel_value]) 107 else if (old_wheel_value == wheel_tbl[1][wheel_value])
@@ -158,11 +146,7 @@ static void scrollwheel(unsigned short dbop_din)
158 last_wheel_post = current_tick; 146 last_wheel_post = current_tick;
159 } 147 }
160 } 148 }
161 if (accel > 0 149 if (accel > 0)
162#ifdef SANSA_E200V2
163 && !read_missed /* decrement only if reading buttons was successful */
164#endif
165 )
166 accel--; 150 accel--;
167 151
168 old_wheel_value = wheel_value; 152 old_wheel_value = wheel_value;
@@ -174,123 +158,14 @@ bool button_hold(void)
174 return hold_button; 158 return hold_button;
175} 159}
176 160
177static void button_delay(void)
178{
179 int i = BUTTON_DELAY;
180 while(i--) asm volatile ("nop\n");
181}
182
183unsigned short button_read_dbop(void) 161unsigned short button_read_dbop(void)
184{ 162{
185#ifdef SANSA_FUZE 163 unsigned dbop_din = dbop_read_input();
186 /* skip home and power reading if lcd_button_support was blocked,
187 * since the dbop bit 15 is invalid then, and use the old value instead
188 * -20 (arbitary value) indicates valid home&power button read
189 * (fuze only) */
190 int old_home_power = -20;
191#endif
192 if(!lcd_button_support())
193 {
194#if defined(SANSA_FUZE)
195 old_home_power = (_dbop_din & (1<<15|1<<8));
196#elif defined(SANSA_E200V2)
197 read_missed = true;
198#endif
199 }
200
201#ifdef SANSA_E200V2
202 if (!read_missed) /* read buttons only if lcd_button_support was not blocked */
203#endif
204 {
205 /* Set up dbop for input */
206 DBOP_CTRL |= (1<<19); /* Tri-state DBOP on read cycle */
207 DBOP_CTRL &= ~(1<<16); /* disable output (1:write enabled) */
208 DBOP_TIMPOL_01 = 0xe167e167; /* Set Timing & Polarity regs 0 & 1 */
209 DBOP_TIMPOL_23 = 0xe167006e; /* Set Timing & Polarity regs 2 & 3 */
210
211 button_delay();
212 DBOP_CTRL |= (1<<15); /* start read */
213 while (!(DBOP_STAT & (1<<16))); /* wait for valid data */
214
215 _dbop_din = DBOP_DIN; /* Read dbop data*/
216
217 /* Reset dbop for output */
218 DBOP_TIMPOL_01 = 0x6e167; /* Set Timing & Polarity regs 0 & 1 */
219 DBOP_TIMPOL_23 = 0xa167e06f; /* Set Timing & Polarity regs 2 & 3 */
220 DBOP_CTRL |= (1<<16); /* Enable output (0:write disable) */
221 DBOP_CTRL &= ~(1<<19); /* Tri-state when no active write */
222 }
223
224#ifdef SANSA_FUZE
225 /* write back old values if blocked */
226 if (old_home_power != -20)
227 {
228 _dbop_din |= old_home_power & 1<<15;
229 _dbop_din &= 0xfeff|(old_home_power & 1<<8);
230 }
231#endif
232
233#if defined(HAVE_SCROLLWHEEL) && !defined(BOOTLOADER) 164#if defined(HAVE_SCROLLWHEEL) && !defined(BOOTLOADER)
234 /* read wheel on bit 13 & 14, but sent to the button queue seperately */ 165 /* scroll wheel handling */
235 scrollwheel(_dbop_din); 166 scrollwheel((dbop_din >> 13) & (1<<1|1<<0));
236#endif 167#endif
237 168 return dbop_din;
238#ifdef SANSA_E200V2
239 read_missed = false;
240#endif
241
242 return _dbop_din;
243}
244
245/* for the debug menu */
246unsigned short button_dbop_data(void)
247{
248 return _dbop_din;
249}
250
251static int button_gpio(void)
252{
253 int btn = BUTTON_NONE;
254 if(hold_button)
255 return btn;
256
257 /* disable DBOP output while changing GPIO pins that share lines with it */
258 DBOP_CTRL &= ~(1<<16);
259 button_delay();
260
261 /* set afsel, so that we can read our buttons */
262 GPIOC_AFSEL &= ~(1<<2|1<<3|1<<4|1<<5|1<<6);
263 /* set dir so we can read our buttons (but reset the C pins first) */
264 GPIOB_DIR &= ~(1<<4);
265 GPIOC_DIR |= (1<<2|1<<3|1<<4|1<<5|1<<6);
266 GPIOC_PIN(2) = (1<<2);
267 GPIOC_PIN(3) = (1<<3);
268 GPIOC_PIN(4) = (1<<4);
269 GPIOC_PIN(5) = (1<<5);
270 GPIOC_PIN(6) = (1<<6);
271
272 GPIOC_DIR &= ~(1<<2|1<<3|1<<4|1<<5|1<<6);
273
274 /* small delay needed to read buttons correctly */
275 button_delay();
276
277 /* direct GPIO connections */
278 if (!GPIOC_PIN(3))
279 btn |= BUTTON_LEFT;
280 if (!GPIOC_PIN(2))
281 btn |= BUTTON_UP;
282 if (!GPIOC_PIN(6))
283 btn |= BUTTON_DOWN;
284 if (!GPIOC_PIN(5))
285 btn |= BUTTON_RIGHT;
286 if (!GPIOC_PIN(4))
287 btn |= BUTTON_SELECT;
288 /* return to settings needed for lcd */
289 GPIOC_DIR |= (1<<2|1<<3|1<<4|1<<5|1<<6);
290 GPIOC_AFSEL |= (1<<2|1<<3|1<<4|1<<5|1<<6);
291
292 DBOP_CTRL |= (1<<16); /* enable output again */
293 return btn;
294} 169}
295 170
296/* 171/*
@@ -298,51 +173,58 @@ static int button_gpio(void)
298 */ 173 */
299int button_read_device(void) 174int button_read_device(void)
300{ 175{
301 int btn = BUTTON_NONE;
302 unsigned short dbop = button_read_dbop();
303#ifdef SANSA_FUZE 176#ifdef SANSA_FUZE
304 static unsigned power_counter = 0; 177 static unsigned power_counter = 0;
305#endif 178#endif
306 /* hold button */ 179 unsigned short dbop_din;
307 if(dbop & (1<<12)) 180 int btn = BUTTON_NONE;
181
182 dbop_din = button_read_dbop();
183
184 /* hold button handling */
185 hold_button = ((dbop_din & (1<<12)) != 0);
186#ifndef BOOTLOADER
187 /* light handling */
188 if (hold_button != hold_button_old)
308 { 189 {
190 hold_button_old = hold_button;
191 backlight_hold_changed(hold_button);
192 }
193#endif /* BOOTLOADER */
194 if (hold_button) {
309#ifdef SANSA_FUZE 195#ifdef SANSA_FUZE
310 power_counter = HZ; 196 power_counter = HZ;
311#endif 197#endif
312 hold_button = true; 198 return 0;
313 } 199 }
314 else 200
315 { 201 /* push button handling */
316 hold_button = false; 202 if ((dbop_din & (1 << 2)) == 0)
203 btn |= BUTTON_UP;
204 if ((dbop_din & (1 << 3)) == 0)
205 btn |= BUTTON_LEFT;
206 if ((dbop_din & (1 << 4)) == 0)
207 btn |= BUTTON_SELECT;
208 if ((dbop_din & (1 << 5)) == 0)
209 btn |= BUTTON_RIGHT;
210 if ((dbop_din & (1 << 6)) == 0)
211 btn |= BUTTON_DOWN;
212 if ((dbop_din & (1 << 8)) != 0)
213 btn |= BUTTON_POWER;
214 if ((dbop_din & (1 << 15)) == 0)
215 btn |= DBOP_BIT15_BUTTON;
216
317#ifdef SANSA_FUZE 217#ifdef SANSA_FUZE
318 /* read power on bit 8, but not if hold button was just released, since 218 /* read power on bit 8, but not if hold button was just released, since
319 * you basically always hit power due to the slider mechanism after releasing 219 * you basically always hit power due to the slider mechanism after releasing
320 * (fuze only) 220 * (fuze only)
321 * hold (wait 1 sec) */ 221 */
322 if (power_counter) 222 if (power_counter > 0) {
323 power_counter--; 223 power_counter--;
324#endif 224 btn &= ~BUTTON_POWER;
325 if (dbop & (1<<8)
326#ifdef SANSA_FUZE
327 && !power_counter
328#endif
329 )
330 btn |= BUTTON_POWER;
331 /* read home on bit 15 */
332 if (!(dbop & (1<<15)))
333 btn |= DBOP_BIT15_BUTTON;
334
335 btn |= button_gpio();
336 } 225 }
337 226#endif
338#ifndef BOOTLOADER
339 /* light handling */
340 if (hold_button != hold_button_old)
341 {
342 hold_button_old = hold_button;
343 backlight_hold_changed(hold_button);
344 }
345#endif /* BOOTLOADER */
346 227
347 return btn; 228 return btn;
348} 229}
230