summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/SOURCES3
-rw-r--r--firmware/target/arm/as3525/button-e200v2-fuze.c210
-rw-r--r--firmware/target/arm/as3525/dbop-as3525.c77
-rw-r--r--firmware/target/arm/as3525/dbop-as3525.h23
-rw-r--r--firmware/target/arm/as3525/debug-as3525.c4
-rw-r--r--firmware/target/arm/as3525/sansa-c200v2/button-c200v2.c21
-rw-r--r--firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c34
-rw-r--r--firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c34
-rw-r--r--firmware/target/arm/lcd-c200_c200v2.c74
9 files changed, 161 insertions, 319 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 4b174d0d62..064c8fe650 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -1235,6 +1235,7 @@ target/arm/as3525/sansa-e200v2/lcd-e200v2.c
1235target/arm/as3525/lcd-as-e200v2-fuze.S 1235target/arm/as3525/lcd-as-e200v2-fuze.S
1236target/arm/as3525/button-e200v2-fuze.c 1236target/arm/as3525/button-e200v2-fuze.c
1237target/arm/as3525/backlight-e200v2-fuze.c 1237target/arm/as3525/backlight-e200v2-fuze.c
1238target/arm/as3525/dbop-as3525.c
1238#ifndef BOOTLOADER 1239#ifndef BOOTLOADER
1239target/arm/powermgmt-ascodec.c 1240target/arm/powermgmt-ascodec.c
1240target/arm/as3525/sansa-e200v2/powermgmt-e200v2.c 1241target/arm/as3525/sansa-e200v2/powermgmt-e200v2.c
@@ -1247,6 +1248,7 @@ target/arm/as3525/sansa-e200v2/powermgmt-e200v2.c
1247target/arm/lcd-c200_c200v2.c 1248target/arm/lcd-c200_c200v2.c
1248target/arm/as3525/sansa-c200v2/button-c200v2.c 1249target/arm/as3525/sansa-c200v2/button-c200v2.c
1249target/arm/as3525/sansa-c200v2/backlight-c200v2.c 1250target/arm/as3525/sansa-c200v2/backlight-c200v2.c
1251target/arm/as3525/dbop-as3525.c
1250#ifndef BOOTLOADER 1252#ifndef BOOTLOADER
1251target/arm/as3525/powermgmt-as3525.c 1253target/arm/as3525/powermgmt-as3525.c
1252#endif /* !BOOTLOADER */ 1254#endif /* !BOOTLOADER */
@@ -1269,6 +1271,7 @@ target/arm/as3525/button-e200v2-fuze.c
1269target/arm/as3525/sansa-fuze/lcd-fuze.c 1271target/arm/as3525/sansa-fuze/lcd-fuze.c
1270target/arm/as3525/lcd-as-e200v2-fuze.S 1272target/arm/as3525/lcd-as-e200v2-fuze.S
1271target/arm/as3525/backlight-e200v2-fuze.c 1273target/arm/as3525/backlight-e200v2-fuze.c
1274target/arm/as3525/dbop-as3525.c
1272#ifndef BOOTLOADER 1275#ifndef BOOTLOADER
1273target/arm/powermgmt-ascodec.c 1276target/arm/powermgmt-ascodec.c
1274target/arm/as3525/sansa-fuze/powermgmt-fuze.c 1277target/arm/as3525/sansa-fuze/powermgmt-fuze.c
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
diff --git a/firmware/target/arm/as3525/dbop-as3525.c b/firmware/target/arm/as3525/dbop-as3525.c
new file mode 100644
index 0000000000..938eee2fb1
--- /dev/null
+++ b/firmware/target/arm/as3525/dbop-as3525.c
@@ -0,0 +1,77 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 by Bertrik Sikken
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#include "config.h"
23#include "as3525.h"
24#include "dbop-as3525.h"
25
26#if defined(SANSA_FUZE)
27#define DBOP_PRECHARGE 0x80FF
28#elif defined(SANSA_E200V2) || defined(SANSA_C200V2)
29#define DBOP_PRECHARGE 0xF0FF
30#endif
31
32static short int dbop_input_value = 0;
33
34/* read the DBOP data pins */
35unsigned short dbop_read_input(void)
36{
37 unsigned int dbop_ctrl_old = DBOP_CTRL;
38 unsigned int dbop_timpol23_old = DBOP_TIMPOL_23;
39
40 /* make sure that the DBOP FIFO is empty */
41 while ((DBOP_STAT & (1<<10)) == 0);
42
43 /* write DBOP_DOUT to pre-charge DBOP data lines with a defined level */
44 DBOP_TIMPOL_23 = 0xe007e007; /* no strobe towards lcd */
45 int delay = 10;
46 while (delay--) asm volatile ("nop\n");
47 DBOP_CTRL = (1 << 19) | /* tri-state output */
48 (1 << 16) | /* enw=1 (enable write) */
49 (1 << 12); /* ow=1 (16-bit data width) */
50 DBOP_DOUT = DBOP_PRECHARGE;
51 while ((DBOP_STAT & (1<<10)) == 0);
52
53#if defined(SANSA_FUZE) || defined(SANSA_E200V2)
54 delay = 50;
55 while (delay--) asm volatile ("nop\n");
56#endif
57
58 /* perform a DBOP read */
59 DBOP_CTRL = (1 << 19) | /* tri-state output */
60 (1 << 15) | /* strd=1 (start read) */
61 (1 << 12) | /* ow=1 (16-bit data width) */
62 (31 << 0); /* rs_t=31 (read DBOP at end of cycle) */
63 while ((DBOP_STAT & (1<<16)) == 0);
64 dbop_input_value = DBOP_DIN;
65
66 /* restore previous values */
67 DBOP_TIMPOL_23 = dbop_timpol23_old;
68 DBOP_CTRL = dbop_ctrl_old;
69
70 return dbop_input_value;
71}
72
73/* for the debug menu */
74unsigned short dbop_debug(void)
75{
76 return dbop_input_value;
77}
diff --git a/firmware/target/arm/as3525/dbop-as3525.h b/firmware/target/arm/as3525/dbop-as3525.h
new file mode 100644
index 0000000000..63156031c4
--- /dev/null
+++ b/firmware/target/arm/as3525/dbop-as3525.h
@@ -0,0 +1,23 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 by Bertrik Sikken
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
22unsigned short int dbop_read_input(void);
23unsigned short dbop_debug(void);
diff --git a/firmware/target/arm/as3525/debug-as3525.c b/firmware/target/arm/as3525/debug-as3525.c
index be78bca0e0..6ec065b03c 100644
--- a/firmware/target/arm/as3525/debug-as3525.c
+++ b/firmware/target/arm/as3525/debug-as3525.c
@@ -68,7 +68,7 @@ extern bool sd_enabled;
68 * if I put the below into a sansa-fuze/debug-target.h, it doesn't work*/ 68 * if I put the below into a sansa-fuze/debug-target.h, it doesn't work*/
69#if defined(SANSA_FUZE) || defined(SANSA_E200V2) || defined(SANSA_C200V2) 69#if defined(SANSA_FUZE) || defined(SANSA_E200V2) || defined(SANSA_C200V2)
70#define DEBUG_DBOP 70#define DEBUG_DBOP
71unsigned short button_dbop_data(void); 71#include "dbop-as3525.h"
72#endif 72#endif
73 73
74static inline unsigned read_cp15 (void) 74static inline unsigned read_cp15 (void)
@@ -392,7 +392,7 @@ bool __dbg_ports(void)
392#ifdef DEBUG_DBOP 392#ifdef DEBUG_DBOP
393 line++; 393 line++;
394 lcd_puts(0, line++, "[DBOP_DIN]"); 394 lcd_puts(0, line++, "[DBOP_DIN]");
395 lcd_putsf(0, line++, "DBOP_DIN: %4x", button_dbop_data()); 395 lcd_putsf(0, line++, "DBOP_DIN: %4x", dbop_debug());
396#endif 396#endif
397 line++; 397 line++;
398 lcd_puts(0, line++, "[CP15]"); 398 lcd_puts(0, line++, "[CP15]");
diff --git a/firmware/target/arm/as3525/sansa-c200v2/button-c200v2.c b/firmware/target/arm/as3525/sansa-c200v2/button-c200v2.c
index b7ce7330c0..8a95c2d661 100644
--- a/firmware/target/arm/as3525/sansa-c200v2/button-c200v2.c
+++ b/firmware/target/arm/as3525/sansa-c200v2/button-c200v2.c
@@ -5,9 +5,9 @@
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id: button-e200v2.c 19035 2008-11-07 05:31:05Z jdgordon $ 8 * $Id: button-c200v2.c 19035 2008-11-07 05:31:05Z jdgordon $
9 * 9 *
10 * Copyright (C) 2006 by Barry Wardell 10 * Copyright (C) 2006 by Barry Wardell, (C) 2009 by Bertrik Sikken
11 * 11 *
12 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 13 * modify it under the terms of the GNU General Public License
@@ -19,29 +19,20 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#include "config.h"
22#include "system.h" 23#include "system.h"
23#include "button-target.h" 24#include "button-target.h"
24#include "button.h" 25#include "button.h"
25#include "backlight.h" 26#include "backlight.h"
26#include "powermgmt.h" 27#include "dbop-as3525.h"
27 28
28 29static unsigned short _dbop_din;
29static unsigned short _dbop_din = 0xFFFF;
30
31/* in the lcd driver */
32extern unsigned short int lcd_dbop_input(void);
33 30
34static bool hold_button = false; 31static bool hold_button = false;
35#ifndef BOOTLOADER 32#ifndef BOOTLOADER
36static bool hold_button_old = false; 33static bool hold_button_old = false;
37#endif 34#endif
38 35
39/* for the debug menu */
40unsigned short button_dbop_data(void)
41{
42 return _dbop_din;
43}
44
45void button_init_device(void) 36void button_init_device(void)
46{ 37{
47 GPIOA_DIR &= ~(1<<3); 38 GPIOA_DIR &= ~(1<<3);
@@ -59,7 +50,7 @@ int button_read_device(void)
59{ 50{
60 int btn = BUTTON_NONE; 51 int btn = BUTTON_NONE;
61 52
62 _dbop_din = lcd_dbop_input(); 53 _dbop_din = dbop_read_input();
63 54
64 /* hold button handling */ 55 /* hold button handling */
65 hold_button = ((_dbop_din & (1<<12)) == 0); 56 hold_button = ((_dbop_din & (1<<12)) == 0);
diff --git a/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c b/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c
index 79914e2e44..0d990dc538 100644
--- a/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c
+++ b/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c
@@ -26,6 +26,7 @@
26#include "debug.h" 26#include "debug.h"
27#include "system.h" 27#include "system.h"
28#include "clock-target.h" 28#include "clock-target.h"
29#include "dbop-as3525.h"
29 30
30/* The controller is unknown, but some registers appear to be the same as the 31/* The controller is unknown, but some registers appear to be the same as the
31 HD66789R */ 32 HD66789R */
@@ -89,8 +90,6 @@ static unsigned short r_entry_mode = R_ENTRY_MODE_HORZ_NORMAL;
89#define R_DISP_CONTROL_REV 0x0000 90#define R_DISP_CONTROL_REV 0x0000
90static unsigned short r_disp_control_rev = R_DISP_CONTROL_NORMAL; 91static unsigned short r_disp_control_rev = R_DISP_CONTROL_NORMAL;
91 92
92static volatile bool lcd_busy = false;
93
94static inline void lcd_delay(int x) 93static inline void lcd_delay(int x)
95{ 94{
96 do { 95 do {
@@ -435,8 +434,6 @@ void lcd_blit_yuv(unsigned char * const src[3],
435 yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); 434 yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
436 yuv_src[2] = src[2] + (yuv_src[1] - src[1]); 435 yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
437 436
438 lcd_busy = true;
439
440 lcd_write_reg(R_ENTRY_MODE, 437 lcd_write_reg(R_ENTRY_MODE,
441 display_flipped ? R_ENTRY_MODE_VIDEO_FLIPPED : R_ENTRY_MODE_VIDEO_NORMAL 438 display_flipped ? R_ENTRY_MODE_VIDEO_FLIPPED : R_ENTRY_MODE_VIDEO_NORMAL
442 ); 439 );
@@ -473,8 +470,6 @@ void lcd_blit_yuv(unsigned char * const src[3],
473 } 470 }
474 while (--height > 0); 471 while (--height > 0);
475 } 472 }
476
477 lcd_busy = false;
478} 473}
479 474
480/* Update the display. 475/* Update the display.
@@ -484,8 +479,6 @@ void lcd_update(void)
484 if (!display_on) 479 if (!display_on)
485 return; 480 return;
486 481
487 lcd_busy = true;
488
489 lcd_write_reg(R_ENTRY_MODE, r_entry_mode); 482 lcd_write_reg(R_ENTRY_MODE, r_entry_mode);
490 483
491 /* Set start position and window */ 484 /* Set start position and window */
@@ -494,8 +487,6 @@ void lcd_update(void)
494 lcd_write_cmd(R_WRITE_DATA_2_GRAM); 487 lcd_write_cmd(R_WRITE_DATA_2_GRAM);
495 488
496 lcd_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); 489 lcd_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT);
497
498 lcd_busy = false;
499} 490}
500 491
501/* Update a fraction of the display. */ 492/* Update a fraction of the display. */
@@ -525,8 +516,6 @@ void lcd_update_rect(int x, int y, int width, int height)
525 if (y >= ymax) 516 if (y >= ymax)
526 return; /* nothing left to do */ 517 return; /* nothing left to do */
527 518
528 lcd_busy = true;
529
530 lcd_write_reg(R_ENTRY_MODE, r_entry_mode); 519 lcd_write_reg(R_ENTRY_MODE, r_entry_mode);
531 520
532 lcd_window(x, y, xmax, ymax); 521 lcd_window(x, y, xmax, ymax);
@@ -541,25 +530,4 @@ void lcd_update_rect(int x, int y, int width, int height)
541 ptr += LCD_WIDTH; 530 ptr += LCD_WIDTH;
542 } 531 }
543 while (--height >= 0); 532 while (--height >= 0);
544
545 lcd_busy = false;
546}
547
548/* writes one red pixel outside the visible area, needed for correct
549 * dbop reads */
550bool lcd_button_support(void)
551{
552 if (lcd_busy)
553 return false;
554
555 lcd_write_reg(R_ENTRY_MODE, r_entry_mode);
556
557 /* Set start position and window */
558 lcd_window(LCD_WIDTH+1, LCD_HEIGHT+1, LCD_WIDTH+2, LCD_HEIGHT+2);
559
560 lcd_write_cmd(R_WRITE_DATA_2_GRAM);
561
562 lcd_write_value16(0xf<<12);
563
564 return true;
565} 533}
diff --git a/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c b/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c
index d10396cfd4..f9d5e5ace1 100644
--- a/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c
+++ b/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c
@@ -28,6 +28,7 @@
28#include "debug.h" 28#include "debug.h"
29#include "system.h" 29#include "system.h"
30#include "clock-target.h" 30#include "clock-target.h"
31#include "dbop-as3525.h"
31 32
32/* The controller is unknown, but some registers appear to be the same as the 33/* The controller is unknown, but some registers appear to be the same as the
33 HD66789R */ 34 HD66789R */
@@ -92,7 +93,6 @@ static unsigned short r_entry_mode = R_ENTRY_MODE_HORZ_NORMAL;
92static unsigned short r_disp_control_rev = R_DISP_CONTROL_NORMAL; 93static unsigned short r_disp_control_rev = R_DISP_CONTROL_NORMAL;
93 94
94static const int xoffset = 20; 95static const int xoffset = 20;
95static volatile bool lcd_busy = false;
96 96
97static inline void lcd_delay(int x) 97static inline void lcd_delay(int x)
98{ 98{
@@ -379,8 +379,6 @@ void lcd_blit_yuv(unsigned char * const src[3],
379 yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); 379 yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
380 yuv_src[2] = src[2] + (yuv_src[1] - src[1]); 380 yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
381 381
382 lcd_busy = true;
383
384#ifdef HAVE_LCD_FLIP 382#ifdef HAVE_LCD_FLIP
385 lcd_write_reg(R_ENTRY_MODE, 383 lcd_write_reg(R_ENTRY_MODE,
386 display_flipped ? R_ENTRY_MODE_VIDEO_FLIPPED : R_ENTRY_MODE_VIDEO_NORMAL 384 display_flipped ? R_ENTRY_MODE_VIDEO_FLIPPED : R_ENTRY_MODE_VIDEO_NORMAL
@@ -423,8 +421,6 @@ void lcd_blit_yuv(unsigned char * const src[3],
423 } 421 }
424 while (--height > 0); 422 while (--height > 0);
425 } 423 }
426
427 lcd_busy = false;
428} 424}
429 425
430/* Update the display. 426/* Update the display.
@@ -434,8 +430,6 @@ void lcd_update(void)
434 if (!display_on) 430 if (!display_on)
435 return; 431 return;
436 432
437 lcd_busy = true;
438
439 lcd_write_reg(R_ENTRY_MODE, r_entry_mode); 433 lcd_write_reg(R_ENTRY_MODE, r_entry_mode);
440 434
441 lcd_window_x(0, LCD_WIDTH - 1); 435 lcd_window_x(0, LCD_WIDTH - 1);
@@ -444,8 +438,6 @@ void lcd_update(void)
444 lcd_write_cmd(R_WRITE_DATA_2_GRAM); 438 lcd_write_cmd(R_WRITE_DATA_2_GRAM);
445 439
446 lcd_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); 440 lcd_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT);
447
448 lcd_busy = false;
449} 441}
450 442
451/* Update a fraction of the display. */ 443/* Update a fraction of the display. */
@@ -475,8 +467,6 @@ void lcd_update_rect(int x, int y, int width, int height)
475 if (y >= ymax) 467 if (y >= ymax)
476 return; /* nothing left to do */ 468 return; /* nothing left to do */
477 469
478 lcd_busy = true;
479
480 lcd_write_reg(R_ENTRY_MODE, r_entry_mode); 470 lcd_write_reg(R_ENTRY_MODE, r_entry_mode);
481 471
482 lcd_window_x(x, xmax); 472 lcd_window_x(x, xmax);
@@ -493,26 +483,4 @@ void lcd_update_rect(int x, int y, int width, int height)
493 ptr += LCD_WIDTH; 483 ptr += LCD_WIDTH;
494 } 484 }
495 while (--height >= 0); 485 while (--height >= 0);
496
497 lcd_busy = false;
498}
499
500/* writes one red pixel outside the visible area, needed for correct
501 * dbop reads */
502bool lcd_button_support(void)
503{
504 if (lcd_busy)
505 return false;
506
507 lcd_write_reg(R_ENTRY_MODE, r_entry_mode);
508
509 /* Set start position and window */
510 lcd_window_x(-1, 0);
511 lcd_window_y(-1, 0);
512
513 lcd_write_cmd(R_WRITE_DATA_2_GRAM);
514
515 lcd_write_value16(0xf<<12);
516
517 return true;
518} 486}
diff --git a/firmware/target/arm/lcd-c200_c200v2.c b/firmware/target/arm/lcd-c200_c200v2.c
index 62f1dc20f6..45a37d9d7b 100644
--- a/firmware/target/arm/lcd-c200_c200v2.c
+++ b/firmware/target/arm/lcd-c200_c200v2.c
@@ -25,11 +25,8 @@
25#include "lcd.h" 25#include "lcd.h"
26#include "kernel.h" 26#include "kernel.h"
27#include "system.h" 27#include "system.h"
28
29#ifdef SANSA_C200V2 28#ifdef SANSA_C200V2
30/* button driver needs to know if a lcd operation is in progress */ 29#include "dbop-as3525.h"
31static bool lcd_busy = false;
32static unsigned short dbop_input = 0xFFFF;
33#endif 30#endif
34 31
35/* Display status */ 32/* Display status */
@@ -183,45 +180,6 @@ static inline void as3525_dbop_init(void)
183 lcd_delay(20); 180 lcd_delay(20);
184} 181}
185 182
186static unsigned short lcd_dbop_read(void)
187{
188 unsigned int dbop_ctrl_old = DBOP_CTRL;
189 unsigned int dbop_timpol23_old = DBOP_TIMPOL_23;
190 unsigned int value;
191
192 /* make sure that the DBOP FIFO is empty */
193 while ((DBOP_STAT & (1<<10)) == 0);
194
195 /* write DBOP_DOUT to pre-charge DBOP data lines with a high level */
196 DBOP_TIMPOL_23 = 0xe167e167; /* no strobe towards lcd */
197 DBOP_CTRL = (1 << 16) | /* enw=1 (enable write) */
198 (1 << 12); /* ow=1 (16-bit data width) */
199 DBOP_DOUT = 0xFFFF; /* all pins high */
200 while ((DBOP_STAT & (1<<10)) == 0);
201
202 /* perform a DBOP read */
203 DBOP_CTRL = (1 << 15) | /* strd=1 (start read) */
204 (1 << 12) | /* ow=1 (16-bit data width) */
205 (31 << 0); /* rs_t=31 (read DBOP at end of cycle) */
206 while ((DBOP_STAT & (1<<16)) == 0);
207 value = DBOP_DIN;
208
209 /* restore previous values */
210 DBOP_TIMPOL_23 = dbop_timpol23_old;
211 DBOP_CTRL = dbop_ctrl_old;
212
213 return value;
214}
215
216/* get the DBOP input value, either directly or cached if DBOP is busy */
217unsigned short int lcd_dbop_input(void)
218{
219 if (!lcd_busy) {
220 dbop_input = lcd_dbop_read();
221 }
222 return dbop_input;
223}
224
225#endif 183#endif
226 184
227/* LCD init */ 185/* LCD init */
@@ -292,13 +250,7 @@ int lcd_default_contrast(void)
292 250
293void lcd_set_contrast(int val) 251void lcd_set_contrast(int val)
294{ 252{
295#ifdef SANSA_C200V2
296 lcd_busy = true;
297#endif
298 lcd_send_command(R_CONTRAST_CONTROL1, val); 253 lcd_send_command(R_CONTRAST_CONTROL1, val);
299#ifdef SANSA_C200V2
300 lcd_busy = false;
301#endif
302} 254}
303 255
304void lcd_set_invert_display(bool yesno) 256void lcd_set_invert_display(bool yesno)
@@ -313,9 +265,6 @@ void lcd_enable(bool yesno)
313 if (yesno == is_lcd_enabled) 265 if (yesno == is_lcd_enabled)
314 return; 266 return;
315 267
316#ifdef SANSA_C200V2
317 lcd_busy = true;
318#endif
319 if ((is_lcd_enabled = yesno)) 268 if ((is_lcd_enabled = yesno))
320 { 269 {
321 lcd_send_command(R_STANDBY_OFF, 0); 270 lcd_send_command(R_STANDBY_OFF, 0);
@@ -326,9 +275,6 @@ void lcd_enable(bool yesno)
326 { 275 {
327 lcd_send_command(R_STANDBY_ON, 0); 276 lcd_send_command(R_STANDBY_ON, 0);
328 } 277 }
329#ifdef SANSA_C200V2
330 lcd_busy = false;
331#endif
332} 278}
333#endif 279#endif
334 280
@@ -343,18 +289,12 @@ bool lcd_active(void)
343/* turn the display upside down (call lcd_update() afterwards) */ 289/* turn the display upside down (call lcd_update() afterwards) */
344void lcd_set_flip(bool yesno) 290void lcd_set_flip(bool yesno)
345{ 291{
346#ifdef SANSA_C200V2
347 lcd_busy = true;
348#endif
349 lcd_send_command(R_DRIVER_OUTPUT_MODE, yesno ? 0x02 : 0x07); 292 lcd_send_command(R_DRIVER_OUTPUT_MODE, yesno ? 0x02 : 0x07);
350#ifdef SANSA_C200V2
351 lcd_busy = false;
352#endif
353} 293}
354 294
355/*** update functions ***/ 295/*** update functions ***/
356 296
357#if MEMORYSIZE > 2 297#if MEMORYSIZE > 2 /* not for C200V2 */
358void lcd_yuv_set_options(unsigned options) 298void lcd_yuv_set_options(unsigned options)
359{ 299{
360 lcd_yuv_options = options; 300 lcd_yuv_options = options;
@@ -450,12 +390,6 @@ void lcd_update_rect(int x, int y, int width, int height)
450 390
451 addr = &lcd_framebuffer[y][x]; 391 addr = &lcd_framebuffer[y][x];
452 392
453#ifdef SANSA_C200V2
454 lcd_busy = true;
455 /* perform a dbop read before doing a potentially lengthy lcd update */
456 dbop_input = lcd_dbop_read();
457#endif
458
459 if (width <= 1) { 393 if (width <= 1) {
460 /* The X end address must be larger than the X start address, so we 394 /* The X end address must be larger than the X start address, so we
461 * switch to vertical mode for single column updates and set the 395 * switch to vertical mode for single column updates and set the
@@ -476,8 +410,4 @@ void lcd_update_rect(int x, int y, int width, int height)
476 lcd_write_data(addr, width); 410 lcd_write_data(addr, width);
477 addr += LCD_WIDTH; 411 addr += LCD_WIDTH;
478 } while (--height > 0); 412 } while (--height > 0);
479
480#ifdef SANSA_C200V2
481 lcd_busy = false;
482#endif
483} 413}