diff options
author | Rafaël Carré <rafael.carre@gmail.com> | 2010-01-06 23:41:36 +0000 |
---|---|---|
committer | Rafaël Carré <rafael.carre@gmail.com> | 2010-01-06 23:41:36 +0000 |
commit | 57667c51cf09de052222484ce94fbd6da113a55c (patch) | |
tree | b85872be9b6c204e7d66a9203a64d78c524a38a5 /firmware/target/arm/as3525/button-e200v2-fuze.c | |
parent | 8e8e2627b27b28a855881db09f2c16bfb2193050 (diff) | |
download | rockbox-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.c | 210 |
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) */ | ||
48 | static 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 |
55 | static bool hold_button_old = false; | 50 | static bool hold_button_old = false; |
56 | #endif | 51 | #endif |
57 | static unsigned short _dbop_din = BUTTON_NONE; | ||
58 | |||
59 | /* in the lcd driver */ | ||
60 | extern bool lcd_button_support(void); | ||
61 | 52 | ||
62 | void button_init_device(void) | 53 | void 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) |
69 | static void scrollwheel(unsigned short dbop_din) | 60 | static 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 | ||
177 | static void button_delay(void) | ||
178 | { | ||
179 | int i = BUTTON_DELAY; | ||
180 | while(i--) asm volatile ("nop\n"); | ||
181 | } | ||
182 | |||
183 | unsigned short button_read_dbop(void) | 161 | unsigned 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 */ | ||
246 | unsigned short button_dbop_data(void) | ||
247 | { | ||
248 | return _dbop_din; | ||
249 | } | ||
250 | |||
251 | static 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 | */ |
299 | int button_read_device(void) | 174 | int 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 | |||