summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2009-06-22 22:24:58 +0000
committerThomas Martitz <kugel@rockbox.org>2009-06-22 22:24:58 +0000
commit8fb4aea70257a7dd45f2f9cd4902dc2a80f38c0d (patch)
tree6746b765803ffe567d338c898b67f401ab033e6c
parentf96f623090de1b6ab228376420bb22b232779f56 (diff)
downloadrockbox-8fb4aea70257a7dd45f2f9cd4902dc2a80f38c0d.tar.gz
rockbox-8fb4aea70257a7dd45f2f9cd4902dc2a80f38c0d.zip
FS#10284 - "Sansa e200v2 & Fuze: Merge the button driver into 1 file" by Dustin Skoracki
Those two drivers were so similar, merging them is worth a few more #ifdefs. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21474 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/as3525/button-e200v2-fuze.c (renamed from firmware/target/arm/as3525/sansa-fuze/button-fuze.c)121
-rw-r--r--firmware/target/arm/as3525/sansa-e200v2/button-e200v2.c248
2 files changed, 86 insertions, 283 deletions
diff --git a/firmware/target/arm/as3525/sansa-fuze/button-fuze.c b/firmware/target/arm/as3525/button-e200v2-fuze.c
index 266ca79deb..6a9f02959c 100644
--- a/firmware/target/arm/as3525/sansa-fuze/button-fuze.c
+++ b/firmware/target/arm/as3525/button-e200v2-fuze.c
@@ -20,19 +20,34 @@
20 * 20 *
21 ****************************************************************************/ 21 ****************************************************************************/
22 22
23
24/* Basic button driver for the Fuze
25 *
26 * TODO: - Get the wheel working with interrupts (seems to be impossible
27 * so far)
28 */
29
30#include "system.h" 23#include "system.h"
31#include "button.h" 24#include "button.h"
32#include "button-target.h" 25#include "button-target.h"
33#include "backlight.h" 26#include "backlight.h"
34 27
28
29#ifdef SANSA_FUZE
30#define DBOP_BIT15_BUTTON BUTTON_HOME
31#define WHEEL_REPEAT_INTERVAL (HZ/5)
32#define WHEEL_COUNTER_DIV 4
33#define ACCEL_INCREMENT 2
34#define ACCEL_SHIFT 2
35#define BUTTON_DELAY 45
36#endif
37
38#ifdef SANSA_E200V2
39#define DBOP_BIT15_BUTTON BUTTON_REC
35#define WHEEL_REPEAT_INTERVAL (HZ/5) 40#define WHEEL_REPEAT_INTERVAL (HZ/5)
41#define WHEEL_COUNTER_DIV 2
42#define ACCEL_INCREMENT 3
43#define ACCEL_SHIFT 1
44#define BUTTON_DELAY 10
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
36 51
37/* Buttons */ 52/* Buttons */
38static bool hold_button = false; 53static bool hold_button = false;
@@ -118,15 +133,15 @@ static void scrollwheel(unsigned short dbop_din)
118 if (TIME_BEFORE(current_tick, last_wheel_post + WHEEL_REPEAT_INTERVAL)) 133 if (TIME_BEFORE(current_tick, last_wheel_post + WHEEL_REPEAT_INTERVAL))
119 { 134 {
120 btn |= BUTTON_REPEAT; 135 btn |= BUTTON_REPEAT;
121 wheel_delta = accel>>2; 136 wheel_delta = accel>>ACCEL_SHIFT;
122 } 137 }
123 138
124 accel += 2; 139 accel += ACCEL_INCREMENT;
125 140
126 /* the wheel is more reliable if we don't send every change, 141 /* the wheel is more reliable if we don't send every change,
127 * every 4th is basically one "physical click" which should 142 * every WHEEL_COUNTER_DIVth is basically one "physical click"
128 * make up 1 item in lists */ 143 * which should make up 1 item in lists */
129 if (++counter >= 4 && queue_empty(&button_queue)) 144 if (++counter >= WHEEL_COUNTER_DIV && queue_empty(&button_queue))
130 { 145 {
131 buttonlight_on(); 146 buttonlight_on();
132 backlight_on(); 147 backlight_on();
@@ -136,7 +151,11 @@ static void scrollwheel(unsigned short dbop_din)
136 last_wheel_post = current_tick; 151 last_wheel_post = current_tick;
137 } 152 }
138 } 153 }
139 if (accel > 0) 154 if (accel > 0
155#ifdef SANSA_E200V2
156 && !read_missed /* decrement only if reading buttons was successful */
157#endif
158 )
140 accel--; 159 accel--;
141 160
142 old_wheel_value = wheel_value; 161 old_wheel_value = wheel_value;
@@ -150,49 +169,69 @@ bool button_hold(void)
150 169
151static void button_delay(void) 170static void button_delay(void)
152{ 171{
153 int i = 50; 172 int i = BUTTON_DELAY;
154 while(i--) asm volatile ("nop\n"); 173 while(i--) asm volatile ("nop\n");
155} 174}
156 175
157unsigned short button_read_dbop(void) 176unsigned short button_read_dbop(void)
158{ 177{
178#ifdef SANSA_FUZE
159 /* skip home and power reading if lcd_button_support was blocked, 179 /* skip home and power reading if lcd_button_support was blocked,
160 * since the dbop bit 15 is invalid then, and use the old value instead */ 180 * since the dbop bit 15 is invalid then, and use the old value instead
161 /* -20 (arbitary value) indicates valid home&power button read */ 181 * -20 (arbitary value) indicates valid home&power button read
182 * (fuze only) */
162 int old_home_power = -20; 183 int old_home_power = -20;
184#endif
163 if(!lcd_button_support()) 185 if(!lcd_button_support())
164 { 186 {
187#if defined(SANSA_FUZE)
165 old_home_power = (_dbop_din & (1<<15|1<<8)); 188 old_home_power = (_dbop_din & (1<<15|1<<8));
189#elif defined(SANSA_E200V2)
190 read_missed = true;
191#endif
166 } 192 }
167 193
168 /* Set up dbop for input */ 194#ifdef SANSA_E200V2
169 DBOP_CTRL |= (1<<19); /* Tri-state DBOP on read cycle */ 195 if (!read_missed) /* read buttons only if lcd_button_support was not blocked */
170 DBOP_CTRL &= ~(1<<16); /* disable output (1:write enabled) */ 196#endif
171 DBOP_TIMPOL_01 = 0xe167e167; /* Set Timing & Polarity regs 0 & 1 */ 197 {
172 DBOP_TIMPOL_23 = 0xe167006e; /* Set Timing & Polarity regs 2 & 3 */ 198 /* Set up dbop for input */
173 199 DBOP_CTRL |= (1<<19); /* Tri-state DBOP on read cycle */
174 button_delay(); 200 DBOP_CTRL &= ~(1<<16); /* disable output (1:write enabled) */
175 DBOP_CTRL |= (1<<15); /* start read */ 201 DBOP_TIMPOL_01 = 0xe167e167; /* Set Timing & Polarity regs 0 & 1 */
176 while (!(DBOP_STAT & (1<<16))); /* wait for valid data */ 202 DBOP_TIMPOL_23 = 0xe167006e; /* Set Timing & Polarity regs 2 & 3 */
177 203
178 _dbop_din = DBOP_DIN; /* Read dbop data*/ 204 button_delay();
179 205 DBOP_CTRL |= (1<<15); /* start read */
180 /* Reset dbop for output */ 206 while (!(DBOP_STAT & (1<<16))); /* wait for valid data */
181 DBOP_TIMPOL_01 = 0x6e167; /* Set Timing & Polarity regs 0 & 1 */ 207
182 DBOP_TIMPOL_23 = 0xa167e06f; /* Set Timing & Polarity regs 2 & 3 */ 208 _dbop_din = DBOP_DIN; /* Read dbop data*/
183 DBOP_CTRL |= (1<<16); /* Enable output (0:write disable) */ 209
184 DBOP_CTRL &= ~(1<<19); /* Tri-state when no active write */ 210 /* Reset dbop for output */
211 DBOP_TIMPOL_01 = 0x6e167; /* Set Timing & Polarity regs 0 & 1 */
212 DBOP_TIMPOL_23 = 0xa167e06f; /* Set Timing & Polarity regs 2 & 3 */
213 DBOP_CTRL |= (1<<16); /* Enable output (0:write disable) */
214 DBOP_CTRL &= ~(1<<19); /* Tri-state when no active write */
215 }
185 216
217#ifdef SANSA_FUZE
186 /* write back old values if blocked */ 218 /* write back old values if blocked */
187 if (old_home_power != -20) 219 if (old_home_power != -20)
188 { 220 {
189 _dbop_din |= old_home_power & 1<<15; 221 _dbop_din |= old_home_power & 1<<15;
190 _dbop_din &= 0xfeff|(old_home_power & 1<<8); 222 _dbop_din &= 0xfeff|(old_home_power & 1<<8);
191 } 223 }
224#endif
225
192#if defined(HAVE_SCROLLWHEEL) && !defined(BOOTLOADER) 226#if defined(HAVE_SCROLLWHEEL) && !defined(BOOTLOADER)
193 /* read wheel on bit 13 & 14, but sent to the button queue seperately */ 227 /* read wheel on bit 13 & 14, but sent to the button queue seperately */
194 scrollwheel(_dbop_din); 228 scrollwheel(_dbop_din);
195#endif 229#endif
230
231#ifdef SANSA_E200V2
232 read_missed = false;
233#endif
234
196 return _dbop_din; 235 return _dbop_din;
197} 236}
198 237
@@ -248,26 +287,38 @@ int button_read_device(void)
248{ 287{
249 int btn = BUTTON_NONE; 288 int btn = BUTTON_NONE;
250 unsigned short dbop = button_read_dbop(); 289 unsigned short dbop = button_read_dbop();
290#ifdef SANSA_FUZE
251 static unsigned power_counter = 0; 291 static unsigned power_counter = 0;
292#endif
252 /* hold button */ 293 /* hold button */
253 if(dbop & (1<<12)) 294 if(dbop & (1<<12))
254 { 295 {
296#ifdef SANSA_FUZE
255 power_counter = HZ; 297 power_counter = HZ;
298#endif
256 hold_button = true; 299 hold_button = true;
257 } 300 }
258 else 301 else
259 { 302 {
260 hold_button = false; 303 hold_button = false;
304#ifdef SANSA_FUZE
261 /* read power on bit 8, but not if hold button was just released, since 305 /* read power on bit 8, but not if hold button was just released, since
262 * you basically always hit power due to the slider mechanism after releasing 306 * you basically always hit power due to the slider mechanism after releasing
307 * (fuze only)
263 * hold (wait 1 sec) */ 308 * hold (wait 1 sec) */
264 if (power_counter) 309 if (power_counter)
265 power_counter--; 310 power_counter--;
266 if (!power_counter && dbop & (1<<8)) 311#endif
312 if (dbop & (1<<8)
313#ifdef SANSA_FUZE
314 && !power_counter
315#endif
316 )
267 btn |= BUTTON_POWER; 317 btn |= BUTTON_POWER;
268 /* read home on bit 15 */ 318 /* read home on bit 15 */
269 if (!(dbop & (1<<15))) 319 if (!(dbop & (1<<15)))
270 btn |= BUTTON_HOME; 320 btn |= DBOP_BIT15_BUTTON;
321
271 btn |= button_gpio(); 322 btn |= button_gpio();
272 } 323 }
273 324
diff --git a/firmware/target/arm/as3525/sansa-e200v2/button-e200v2.c b/firmware/target/arm/as3525/sansa-e200v2/button-e200v2.c
deleted file mode 100644
index 8170c1b895..0000000000
--- a/firmware/target/arm/as3525/sansa-e200v2/button-e200v2.c
+++ /dev/null
@@ -1,248 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Barry Wardell
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22/* Taken from button-h10.c by Barry Wardell and reverse engineering by MrH. */
23
24#include "system.h"
25#include "button.h"
26#include "backlight.h"
27#include "powermgmt.h"
28
29
30static bool hold_button = false;
31#ifndef BOOTLOADER
32static bool hold_button_old = false;
33#endif
34static unsigned short _dbop_din = 0;
35/* read_missed is true if buttons could not
36 * be read (see lcd_button_support) */
37static bool read_missed = false;
38
39#define WHEEL_REPEAT_INTERVAL (HZ/4)
40/* in the lcd driver */
41extern bool lcd_button_support(void);
42
43void button_init_device(void)
44{
45
46}
47
48bool button_hold(void)
49{
50 return hold_button;
51}
52
53#if !defined(BOOTLOADER) && defined(HAVE_SCROLLWHEEL)
54static void scrollwheel(unsigned short dbop_din)
55{
56 /* current wheel values, parsed from dbop and the resulting button */
57 unsigned wheel_value = 0;
58 unsigned btn = BUTTON_NONE;
59 /* old wheel values */
60 static unsigned old_wheel_value = 0;
61 static unsigned old_btn = BUTTON_NONE;
62
63 /* getting BUTTON_REPEAT works like this: Remember when the btn value was
64 * posted to the button_queue last, and if it was recent enough, generate
65 * BUTTON_REPEAT
66 */
67 static long last_wheel_post = 0;
68 /* Repeat is used for the scrollwheel acceleration. If high enough then
69 * jump over some items */
70 static unsigned repeat = 0;
71 /* we omit 1 of 2 posts to the button_queue, that works better, so count */
72 static int counter = 0;
73 /* Read wheel
74 * Bits 13 and 14 of DBOP_DIN change as follows:
75 * Clockwise rotation 00 -> 01 -> 11 -> 10 -> 00
76 * Counter-clockwise 00 -> 10 -> 11 -> 01 -> 00
77 */
78 static const unsigned char wheel_tbl[2][4] =
79 {
80 { 2, 0, 3, 1 }, /* Clockwise rotation */
81 { 1, 3, 0, 2 }, /* Counter-clockwise */
82 };
83
84 if(hold_button)
85 {
86 repeat = counter = 0;
87 return;
88 }
89
90 wheel_value = dbop_din & (1<<13|1<<14);
91 wheel_value >>= 13;
92
93 if (old_wheel_value == wheel_tbl[0][wheel_value])
94 btn = BUTTON_SCROLL_FWD;
95 else if (old_wheel_value == wheel_tbl[1][wheel_value])
96 btn = BUTTON_SCROLL_BACK;
97
98 if (btn != BUTTON_NONE)
99 {
100 if (btn != old_btn)
101 {
102 /* direction reversals nullify repeats */
103 old_btn = btn;
104 repeat = counter = 0;
105 }
106 /* wheel_delta will cause lists to jump over items,
107 * we want this for fast scrolling, but we must keep it accurate
108 * for slow scrolling */
109 int wheel_delta = 0;
110 /* generate repeats if quick enough, scroll slightly too */
111 if (TIME_BEFORE(current_tick, last_wheel_post + WHEEL_REPEAT_INTERVAL))
112 {
113 btn |= BUTTON_REPEAT;
114 wheel_delta = repeat>>1;
115 }
116
117 repeat += 3;
118 /* the wheel is more reliable if we don't send ever change,
119 * every 2th is basically one "physical click" is
120 * 1 item in the rockbox menus */
121 if (++counter >= 2 && queue_empty(&button_queue))
122 {
123 buttonlight_on();
124 backlight_on();
125 queue_post(&button_queue, btn, ((wheel_delta+1)<<24));
126 /* message posted - reset count & last post to the queue */
127 counter = 0;
128 last_wheel_post = current_tick;
129 }
130 }
131 if (repeat > 0 && !read_missed)
132 repeat--;
133
134 old_wheel_value = wheel_value;
135}
136#endif /* !defined(BOOTLOADER) && defined(HAVE_SCROLLWHEEL) */
137
138unsigned short button_read_dbop(void)
139{
140 /*write a red pixel */
141 if (!lcd_button_support())
142 {
143 read_missed = true;
144 }
145 if (!read_missed)
146 {
147 /* Set up dbop for input */
148 while (!(DBOP_STAT & (1<<10))); /* Wait for fifo to empty */
149 DBOP_CTRL |= (1<<19); /* Tri-state DBOP on read cycle */
150 DBOP_CTRL &= ~(1<<16); /* disable output (1:write enabled) */
151 DBOP_TIMPOL_01 = 0xe167e167; /* Set Timing & Polarity regs 0 & 1 */
152 DBOP_TIMPOL_23 = 0xe167006e; /* Set Timing & Polarity regs 2 & 3 */
153
154 DBOP_CTRL |= (1<<15); /* start read */
155 while (!(DBOP_STAT & (1<<16))); /* wait for valid data */
156
157 int delay=10;
158 while(delay--); /* short delay before reading */
159
160 _dbop_din = DBOP_DIN; /* Read dbop data*/
161
162 /* Reset dbop for output */
163 DBOP_TIMPOL_01 = 0x6e167; /* Set Timing & Polarity regs 0 & 1 */
164 DBOP_TIMPOL_23 = 0xa167e06f; /* Set Timing & Polarity regs 2 & 3 */
165 DBOP_CTRL |= (1<<16); /* Enable output (0:write disable) */
166 DBOP_CTRL &= ~(1<<19); /* Tri-state when no active write */
167 }
168#if !defined(BOOTLOADER) && defined(HAVE_SCROLLWHEEL)
169 scrollwheel(_dbop_din);
170#endif
171 read_missed = false;
172 return _dbop_din;
173}
174
175unsigned short button_dbop_data(void)
176{
177 return _dbop_din;
178}
179
180/*
181 * Get button pressed from hardware
182 */
183int button_read_device(void)
184{
185 int btn = BUTTON_NONE;
186 /* read buttons from dbop */
187 unsigned short dbop = button_read_dbop();
188
189 /* hold button */
190 if(dbop & (1<<12))
191 {
192 hold_button = true;
193 return btn;
194 }
195 else
196 {
197 hold_button = false;
198 }
199
200 if (dbop & (1<<8))
201 btn |= BUTTON_POWER;
202
203 if (!(dbop & (1<<15)))
204 btn |= BUTTON_REC;
205
206 /* Set afsel, so that we can read our buttons */
207 GPIOC_AFSEL &= ~(1<<2|1<<3|1<<4|1<<5|1<<6);
208 /* set dir so we can read our buttons (but reset the C pins first) */
209 GPIOB_DIR &= ~(1<<4);
210 GPIOC_DIR |= (1<<2|1<<3|1<<4|1<<5|1<<6);
211 GPIOC_PIN(2) = (1<<2);
212 GPIOC_PIN(3) = (1<<3);
213 GPIOC_PIN(4) = (1<<4);
214 GPIOC_PIN(5) = (1<<5);
215 GPIOC_PIN(6) = (1<<6);
216
217 GPIOC_DIR &= ~(1<<2|1<<3|1<<4|1<<5|1<<6);
218
219 int delay = 8; /* small delay needed to read buttons correctly */
220 while(delay--);
221
222 /* direct GPIO connections */
223 if (!GPIOC_PIN(2))
224 btn |= BUTTON_UP;
225 if (!GPIOC_PIN(3))
226 btn |= BUTTON_LEFT;
227 if (!GPIOC_PIN(4))
228 btn |= BUTTON_SELECT;
229 if (!GPIOC_PIN(5))
230 btn |= BUTTON_RIGHT;
231 if (!GPIOC_PIN(6))
232 btn |= BUTTON_DOWN;
233
234 /* return to settings needed for lcd */
235 GPIOC_DIR |= (1<<2|1<<3|1<<4|1<<5|1<<6);
236 GPIOC_AFSEL |= (1<<2|1<<3|1<<4|1<<5|1<<6);
237
238#ifndef BOOTLOADER
239 /* light handling */
240 if (hold_button != hold_button_old)
241 {
242 hold_button_old = hold_button;
243 backlight_hold_changed(hold_button);
244 }
245#endif /* BOOTLOADER */
246 /* The int_btn variable is set in the button interrupt handler */
247 return btn;
248}