summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/target/arm/as3525/sansa-c200v2/button-c200v2.c59
-rw-r--r--firmware/target/arm/lcd-c200_c200v2.c50
2 files changed, 62 insertions, 47 deletions
diff --git a/firmware/target/arm/as3525/sansa-c200v2/button-c200v2.c b/firmware/target/arm/as3525/sansa-c200v2/button-c200v2.c
index 965006ce61..b7ce7330c0 100644
--- a/firmware/target/arm/as3525/sansa-c200v2/button-c200v2.c
+++ b/firmware/target/arm/as3525/sansa-c200v2/button-c200v2.c
@@ -26,10 +26,10 @@
26#include "powermgmt.h" 26#include "powermgmt.h"
27 27
28 28
29unsigned short _dbop_din = 0; 29static unsigned short _dbop_din = 0xFFFF;
30 30
31/* in the lcd driver */ 31/* in the lcd driver */
32extern bool lcd_button_support(void); 32extern unsigned short int lcd_dbop_input(void);
33 33
34static bool hold_button = false; 34static bool hold_button = false;
35#ifndef BOOTLOADER 35#ifndef BOOTLOADER
@@ -52,26 +52,6 @@ bool button_hold(void)
52 return hold_button; 52 return hold_button;
53} 53}
54 54
55static void button_read_dbop(void)
56{
57 /* Set up dbop for input */
58 DBOP_CTRL |= (1<<19); /* Tri-state DBOP on read cycle */
59 DBOP_CTRL &= ~(1<<16); /* disable output (1:write enabled) */
60 DBOP_TIMPOL_01 = 0xe167e167; /* Set Timing & Polarity regs 0 & 1 */
61 DBOP_TIMPOL_23 = 0xe167006e; /* Set Timing & Polarity regs 2 & 3 */
62
63 DBOP_CTRL |= (1<<15); /* start read */
64 while (!(DBOP_STAT & (1<<16))); /* wait for valid data */
65
66 _dbop_din = DBOP_DIN; /* Read dbop data*/
67
68 /* Reset dbop for output */
69 DBOP_TIMPOL_01 = 0x6e167; /* Set Timing & Polarity regs 0 & 1 */
70 DBOP_TIMPOL_23 = 0xa167e06f; /* Set Timing & Polarity regs 2 & 3 */
71 DBOP_CTRL |= (1<<16); /* Enable output (0:write disable) */
72 DBOP_CTRL &= ~(1<<19); /* Tri-state when no active write */
73}
74
75/* 55/*
76 * Get button pressed from hardware 56 * Get button pressed from hardware
77 */ 57 */
@@ -79,13 +59,27 @@ int button_read_device(void)
79{ 59{
80 int btn = BUTTON_NONE; 60 int btn = BUTTON_NONE;
81 61
62 _dbop_din = lcd_dbop_input();
63
64 /* hold button handling */
65 hold_button = ((_dbop_din & (1<<12)) == 0);
66#ifndef BOOTLOADER
67 /* light handling */
68 if (hold_button != hold_button_old)
69 {
70 hold_button_old = hold_button;
71 backlight_hold_changed(hold_button);
72 }
73#endif /* BOOTLOADER */
74 if (hold_button) {
75 return 0;
76 }
77
82 /* direct GPIO connections */ 78 /* direct GPIO connections */
83 if (GPIOA_PIN(3)) 79 if (GPIOA_PIN(3))
84 btn |= BUTTON_POWER; 80 btn |= BUTTON_POWER;
85 81
86 if(lcd_button_support()) 82 /* DBOP buttons */
87 button_read_dbop();
88
89 if(!(_dbop_din & (1<<2))) 83 if(!(_dbop_din & (1<<2)))
90 btn |= BUTTON_LEFT; 84 btn |= BUTTON_LEFT;
91 if(!(_dbop_din & (1<<3))) 85 if(!(_dbop_din & (1<<3)))
@@ -96,15 +90,12 @@ int button_read_device(void)
96 btn |= BUTTON_UP; 90 btn |= BUTTON_UP;
97 if(!(_dbop_din & (1<<6))) 91 if(!(_dbop_din & (1<<6)))
98 btn |= BUTTON_RIGHT; 92 btn |= BUTTON_RIGHT;
99 93 if(!(_dbop_din & (1<<13)))
100#ifndef BOOTLOADER 94 btn |= BUTTON_VOL_UP;
101 /* light handling */ 95 if(!(_dbop_din & (1<<14)))
102 if (hold_button != hold_button_old) 96 btn |= BUTTON_VOL_DOWN;
103 { 97 if(!(_dbop_din & (1<<15)))
104 hold_button_old = hold_button; 98 btn |= BUTTON_REC;
105 backlight_hold_changed(hold_button);
106 }
107#endif /* BOOTLOADER */
108 99
109 return btn; 100 return btn;
110} 101}
diff --git a/firmware/target/arm/lcd-c200_c200v2.c b/firmware/target/arm/lcd-c200_c200v2.c
index 06cb475d9d..3ba1bf0f07 100644
--- a/firmware/target/arm/lcd-c200_c200v2.c
+++ b/firmware/target/arm/lcd-c200_c200v2.c
@@ -29,6 +29,7 @@
29#ifdef SANSA_C200V2 29#ifdef SANSA_C200V2
30/* button driver needs to know if a lcd operation is in progress */ 30/* button driver needs to know if a lcd operation is in progress */
31static bool lcd_busy = false; 31static bool lcd_busy = false;
32static unsigned short dbop_input = 0xFFFF;
32#endif 33#endif
33 34
34/* Display status */ 35/* Display status */
@@ -182,24 +183,45 @@ static inline void as3525_dbop_init(void)
182 lcd_delay(20); 183 lcd_delay(20);
183} 184}
184 185
185/* we need to set the DBOP_DOUT pins high, for correct dbop reads */ 186static unsigned short lcd_dbop_read(void)
186bool lcd_button_support(void)
187{ 187{
188 const fb_data data = 0xffff; 188 unsigned int dbop_ctrl_old = DBOP_CTRL;
189 189 unsigned int dbop_timpol23_old = DBOP_TIMPOL_23;
190 if (lcd_busy) /* we can't use dbop for reading if we are in the */ 190 unsigned int value;
191 return false; /* middle of a write operation */ 191
192 /* make sure that the DBOP FIFO is empty */
193 while ((DBOP_STAT & (1<<10)) == 0);
192 194
193 /* use out of screen coordinates */ 195 /* write DBOP_DOUT to pre-charge DBOP data lines with a high level */
194 lcd_send_command(R_X_ADDR_AREA, 0); 196 DBOP_TIMPOL_23 = 0xe167e167; /* no strobe towards lcd */
195 lcd_send_command(1, 0); 197 DBOP_CTRL = (1 << 16) | /* enw=1 (enable write) */
196 lcd_send_command(R_Y_ADDR_AREA, 0); 198 (1 << 12); /* ow=1 (16-bit data width) */
197 lcd_send_command(1, 0); 199 DBOP_DOUT = 0xFFFF; /* all pins high */
200 while ((DBOP_STAT & (1<<10)) == 0);
198 201
199 lcd_write_data(&data, 1); 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}
200 215
201 return true; 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;
202} 223}
224
203#endif 225#endif
204 226
205/* LCD init */ 227/* LCD init */
@@ -430,6 +452,8 @@ void lcd_update_rect(int x, int y, int width, int height)
430 452
431#ifdef SANSA_C200V2 453#ifdef SANSA_C200V2
432 lcd_busy = true; 454 lcd_busy = true;
455 /* perform a dbop read before doing a potentially lengthy lcd update */
456 dbop_input = lcd_dbop_read();
433#endif 457#endif
434 458
435 if (width <= 1) { 459 if (width <= 1) {