1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Rafaël Carré 2010-01-06 23:41:36 +00:00
parent 8e8e2627b2
commit 57667c51cf
9 changed files with 162 additions and 320 deletions

View file

@ -1235,6 +1235,7 @@ target/arm/as3525/sansa-e200v2/lcd-e200v2.c
target/arm/as3525/lcd-as-e200v2-fuze.S target/arm/as3525/lcd-as-e200v2-fuze.S
target/arm/as3525/button-e200v2-fuze.c target/arm/as3525/button-e200v2-fuze.c
target/arm/as3525/backlight-e200v2-fuze.c target/arm/as3525/backlight-e200v2-fuze.c
target/arm/as3525/dbop-as3525.c
#ifndef BOOTLOADER #ifndef BOOTLOADER
target/arm/powermgmt-ascodec.c target/arm/powermgmt-ascodec.c
target/arm/as3525/sansa-e200v2/powermgmt-e200v2.c target/arm/as3525/sansa-e200v2/powermgmt-e200v2.c
@ -1247,6 +1248,7 @@ target/arm/as3525/sansa-e200v2/powermgmt-e200v2.c
target/arm/lcd-c200_c200v2.c target/arm/lcd-c200_c200v2.c
target/arm/as3525/sansa-c200v2/button-c200v2.c target/arm/as3525/sansa-c200v2/button-c200v2.c
target/arm/as3525/sansa-c200v2/backlight-c200v2.c target/arm/as3525/sansa-c200v2/backlight-c200v2.c
target/arm/as3525/dbop-as3525.c
#ifndef BOOTLOADER #ifndef BOOTLOADER
target/arm/as3525/powermgmt-as3525.c target/arm/as3525/powermgmt-as3525.c
#endif /* !BOOTLOADER */ #endif /* !BOOTLOADER */
@ -1269,6 +1271,7 @@ target/arm/as3525/button-e200v2-fuze.c
target/arm/as3525/sansa-fuze/lcd-fuze.c target/arm/as3525/sansa-fuze/lcd-fuze.c
target/arm/as3525/lcd-as-e200v2-fuze.S target/arm/as3525/lcd-as-e200v2-fuze.S
target/arm/as3525/backlight-e200v2-fuze.c target/arm/as3525/backlight-e200v2-fuze.c
target/arm/as3525/dbop-as3525.c
#ifndef BOOTLOADER #ifndef BOOTLOADER
target/arm/powermgmt-ascodec.c target/arm/powermgmt-ascodec.c
target/arm/as3525/sansa-fuze/powermgmt-fuze.c target/arm/as3525/sansa-fuze/powermgmt-fuze.c

View file

@ -20,10 +20,12 @@
* *
****************************************************************************/ ****************************************************************************/
#include "config.h"
#include "system.h" #include "system.h"
#include "button.h" #include "button.h"
#include "button-target.h" #include "button-target.h"
#include "backlight.h" #include "backlight.h"
#include "dbop-as3525.h"
#ifdef SANSA_FUZE #ifdef SANSA_FUZE
@ -32,7 +34,6 @@
#define WHEEL_COUNTER_DIV 4 #define WHEEL_COUNTER_DIV 4
#define ACCEL_INCREMENT 2 #define ACCEL_INCREMENT 2
#define ACCEL_SHIFT 2 #define ACCEL_SHIFT 2
#define BUTTON_DELAY 60
#endif #endif
#ifdef SANSA_E200V2 #ifdef SANSA_E200V2
@ -41,12 +42,6 @@
#define WHEEL_COUNTER_DIV 2 #define WHEEL_COUNTER_DIV 2
#define ACCEL_INCREMENT 3 #define ACCEL_INCREMENT 3
#define ACCEL_SHIFT 1 #define ACCEL_SHIFT 1
#define BUTTON_DELAY 20
/* read_missed is true if buttons could not
* be read (see lcd_button_support) */
static bool read_missed = false;
#endif #endif
/* Buttons */ /* Buttons */
@ -54,10 +49,6 @@ static bool hold_button = false;
#ifndef BOOTLOADER #ifndef BOOTLOADER
static bool hold_button_old = false; static bool hold_button_old = false;
#endif #endif
static unsigned short _dbop_din = BUTTON_NONE;
/* in the lcd driver */
extern bool lcd_button_support(void);
void button_init_device(void) void button_init_device(void)
{ {
@ -66,10 +57,9 @@ void button_init_device(void)
} }
#if !defined(BOOTLOADER) && defined(HAVE_SCROLLWHEEL) #if !defined(BOOTLOADER) && defined(HAVE_SCROLLWHEEL)
static void scrollwheel(unsigned short dbop_din) static void scrollwheel(unsigned int wheel_value)
{ {
/* current wheel values, parsed from dbop and the resulting button */ /* current wheel values, parsed from dbop and the resulting button */
unsigned wheel_value = 0;
unsigned btn = BUTTON_NONE; unsigned btn = BUTTON_NONE;
/* old wheel values */ /* old wheel values */
static unsigned old_wheel_value = 0; static unsigned old_wheel_value = 0;
@ -112,8 +102,6 @@ static void scrollwheel(unsigned short dbop_din)
return; return;
} }
wheel_value = (dbop_din >> 13) & (1<<1|1<<0);
if (old_wheel_value == wheel_tbl[0][wheel_value]) if (old_wheel_value == wheel_tbl[0][wheel_value])
btn = BUTTON_SCROLL_FWD; btn = BUTTON_SCROLL_FWD;
else if (old_wheel_value == wheel_tbl[1][wheel_value]) else if (old_wheel_value == wheel_tbl[1][wheel_value])
@ -158,11 +146,7 @@ static void scrollwheel(unsigned short dbop_din)
last_wheel_post = current_tick; last_wheel_post = current_tick;
} }
} }
if (accel > 0 if (accel > 0)
#ifdef SANSA_E200V2
&& !read_missed /* decrement only if reading buttons was successful */
#endif
)
accel--; accel--;
old_wheel_value = wheel_value; old_wheel_value = wheel_value;
@ -174,123 +158,14 @@ bool button_hold(void)
return hold_button; return hold_button;
} }
static void button_delay(void)
{
int i = BUTTON_DELAY;
while(i--) asm volatile ("nop\n");
}
unsigned short button_read_dbop(void) unsigned short button_read_dbop(void)
{ {
#ifdef SANSA_FUZE unsigned dbop_din = dbop_read_input();
/* skip home and power reading if lcd_button_support was blocked,
* since the dbop bit 15 is invalid then, and use the old value instead
* -20 (arbitary value) indicates valid home&power button read
* (fuze only) */
int old_home_power = -20;
#endif
if(!lcd_button_support())
{
#if defined(SANSA_FUZE)
old_home_power = (_dbop_din & (1<<15|1<<8));
#elif defined(SANSA_E200V2)
read_missed = true;
#endif
}
#ifdef SANSA_E200V2
if (!read_missed) /* read buttons only if lcd_button_support was not blocked */
#endif
{
/* Set up dbop for input */
DBOP_CTRL |= (1<<19); /* Tri-state DBOP on read cycle */
DBOP_CTRL &= ~(1<<16); /* disable output (1:write enabled) */
DBOP_TIMPOL_01 = 0xe167e167; /* Set Timing & Polarity regs 0 & 1 */
DBOP_TIMPOL_23 = 0xe167006e; /* Set Timing & Polarity regs 2 & 3 */
button_delay();
DBOP_CTRL |= (1<<15); /* start read */
while (!(DBOP_STAT & (1<<16))); /* wait for valid data */
_dbop_din = DBOP_DIN; /* Read dbop data*/
/* Reset dbop for output */
DBOP_TIMPOL_01 = 0x6e167; /* Set Timing & Polarity regs 0 & 1 */
DBOP_TIMPOL_23 = 0xa167e06f; /* Set Timing & Polarity regs 2 & 3 */
DBOP_CTRL |= (1<<16); /* Enable output (0:write disable) */
DBOP_CTRL &= ~(1<<19); /* Tri-state when no active write */
}
#ifdef SANSA_FUZE
/* write back old values if blocked */
if (old_home_power != -20)
{
_dbop_din |= old_home_power & 1<<15;
_dbop_din &= 0xfeff|(old_home_power & 1<<8);
}
#endif
#if defined(HAVE_SCROLLWHEEL) && !defined(BOOTLOADER) #if defined(HAVE_SCROLLWHEEL) && !defined(BOOTLOADER)
/* read wheel on bit 13 & 14, but sent to the button queue seperately */ /* scroll wheel handling */
scrollwheel(_dbop_din); scrollwheel((dbop_din >> 13) & (1<<1|1<<0));
#endif #endif
return dbop_din;
#ifdef SANSA_E200V2
read_missed = false;
#endif
return _dbop_din;
}
/* for the debug menu */
unsigned short button_dbop_data(void)
{
return _dbop_din;
}
static int button_gpio(void)
{
int btn = BUTTON_NONE;
if(hold_button)
return btn;
/* disable DBOP output while changing GPIO pins that share lines with it */
DBOP_CTRL &= ~(1<<16);
button_delay();
/* set afsel, so that we can read our buttons */
GPIOC_AFSEL &= ~(1<<2|1<<3|1<<4|1<<5|1<<6);
/* set dir so we can read our buttons (but reset the C pins first) */
GPIOB_DIR &= ~(1<<4);
GPIOC_DIR |= (1<<2|1<<3|1<<4|1<<5|1<<6);
GPIOC_PIN(2) = (1<<2);
GPIOC_PIN(3) = (1<<3);
GPIOC_PIN(4) = (1<<4);
GPIOC_PIN(5) = (1<<5);
GPIOC_PIN(6) = (1<<6);
GPIOC_DIR &= ~(1<<2|1<<3|1<<4|1<<5|1<<6);
/* small delay needed to read buttons correctly */
button_delay();
/* direct GPIO connections */
if (!GPIOC_PIN(3))
btn |= BUTTON_LEFT;
if (!GPIOC_PIN(2))
btn |= BUTTON_UP;
if (!GPIOC_PIN(6))
btn |= BUTTON_DOWN;
if (!GPIOC_PIN(5))
btn |= BUTTON_RIGHT;
if (!GPIOC_PIN(4))
btn |= BUTTON_SELECT;
/* return to settings needed for lcd */
GPIOC_DIR |= (1<<2|1<<3|1<<4|1<<5|1<<6);
GPIOC_AFSEL |= (1<<2|1<<3|1<<4|1<<5|1<<6);
DBOP_CTRL |= (1<<16); /* enable output again */
return btn;
} }
/* /*
@ -298,43 +173,16 @@ static int button_gpio(void)
*/ */
int button_read_device(void) int button_read_device(void)
{ {
int btn = BUTTON_NONE;
unsigned short dbop = button_read_dbop();
#ifdef SANSA_FUZE #ifdef SANSA_FUZE
static unsigned power_counter = 0; static unsigned power_counter = 0;
#endif #endif
/* hold button */ unsigned short dbop_din;
if(dbop & (1<<12)) int btn = BUTTON_NONE;
{
#ifdef SANSA_FUZE
power_counter = HZ;
#endif
hold_button = true;
}
else
{
hold_button = false;
#ifdef SANSA_FUZE
/* read power on bit 8, but not if hold button was just released, since
* you basically always hit power due to the slider mechanism after releasing
* (fuze only)
* hold (wait 1 sec) */
if (power_counter)
power_counter--;
#endif
if (dbop & (1<<8)
#ifdef SANSA_FUZE
&& !power_counter
#endif
)
btn |= BUTTON_POWER;
/* read home on bit 15 */
if (!(dbop & (1<<15)))
btn |= DBOP_BIT15_BUTTON;
btn |= button_gpio(); dbop_din = button_read_dbop();
}
/* hold button handling */
hold_button = ((dbop_din & (1<<12)) != 0);
#ifndef BOOTLOADER #ifndef BOOTLOADER
/* light handling */ /* light handling */
if (hold_button != hold_button_old) if (hold_button != hold_button_old)
@ -343,6 +191,40 @@ int button_read_device(void)
backlight_hold_changed(hold_button); backlight_hold_changed(hold_button);
} }
#endif /* BOOTLOADER */ #endif /* BOOTLOADER */
if (hold_button) {
#ifdef SANSA_FUZE
power_counter = HZ;
#endif
return 0;
}
/* push button handling */
if ((dbop_din & (1 << 2)) == 0)
btn |= BUTTON_UP;
if ((dbop_din & (1 << 3)) == 0)
btn |= BUTTON_LEFT;
if ((dbop_din & (1 << 4)) == 0)
btn |= BUTTON_SELECT;
if ((dbop_din & (1 << 5)) == 0)
btn |= BUTTON_RIGHT;
if ((dbop_din & (1 << 6)) == 0)
btn |= BUTTON_DOWN;
if ((dbop_din & (1 << 8)) != 0)
btn |= BUTTON_POWER;
if ((dbop_din & (1 << 15)) == 0)
btn |= DBOP_BIT15_BUTTON;
#ifdef SANSA_FUZE
/* read power on bit 8, but not if hold button was just released, since
* you basically always hit power due to the slider mechanism after releasing
* (fuze only)
*/
if (power_counter > 0) {
power_counter--;
btn &= ~BUTTON_POWER;
}
#endif
return btn; return btn;
} }

View file

@ -0,0 +1,77 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2009 by Bertrik Sikken
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "as3525.h"
#include "dbop-as3525.h"
#if defined(SANSA_FUZE)
#define DBOP_PRECHARGE 0x80FF
#elif defined(SANSA_E200V2) || defined(SANSA_C200V2)
#define DBOP_PRECHARGE 0xF0FF
#endif
static short int dbop_input_value = 0;
/* read the DBOP data pins */
unsigned short dbop_read_input(void)
{
unsigned int dbop_ctrl_old = DBOP_CTRL;
unsigned int dbop_timpol23_old = DBOP_TIMPOL_23;
/* make sure that the DBOP FIFO is empty */
while ((DBOP_STAT & (1<<10)) == 0);
/* write DBOP_DOUT to pre-charge DBOP data lines with a defined level */
DBOP_TIMPOL_23 = 0xe007e007; /* no strobe towards lcd */
int delay = 10;
while (delay--) asm volatile ("nop\n");
DBOP_CTRL = (1 << 19) | /* tri-state output */
(1 << 16) | /* enw=1 (enable write) */
(1 << 12); /* ow=1 (16-bit data width) */
DBOP_DOUT = DBOP_PRECHARGE;
while ((DBOP_STAT & (1<<10)) == 0);
#if defined(SANSA_FUZE) || defined(SANSA_E200V2)
delay = 50;
while (delay--) asm volatile ("nop\n");
#endif
/* perform a DBOP read */
DBOP_CTRL = (1 << 19) | /* tri-state output */
(1 << 15) | /* strd=1 (start read) */
(1 << 12) | /* ow=1 (16-bit data width) */
(31 << 0); /* rs_t=31 (read DBOP at end of cycle) */
while ((DBOP_STAT & (1<<16)) == 0);
dbop_input_value = DBOP_DIN;
/* restore previous values */
DBOP_TIMPOL_23 = dbop_timpol23_old;
DBOP_CTRL = dbop_ctrl_old;
return dbop_input_value;
}
/* for the debug menu */
unsigned short dbop_debug(void)
{
return dbop_input_value;
}

View file

@ -0,0 +1,23 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2009 by Bertrik Sikken
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
unsigned short int dbop_read_input(void);
unsigned short dbop_debug(void);

View file

@ -68,7 +68,7 @@ extern bool sd_enabled;
* if I put the below into a sansa-fuze/debug-target.h, it doesn't work*/ * if I put the below into a sansa-fuze/debug-target.h, it doesn't work*/
#if defined(SANSA_FUZE) || defined(SANSA_E200V2) || defined(SANSA_C200V2) #if defined(SANSA_FUZE) || defined(SANSA_E200V2) || defined(SANSA_C200V2)
#define DEBUG_DBOP #define DEBUG_DBOP
unsigned short button_dbop_data(void); #include "dbop-as3525.h"
#endif #endif
static inline unsigned read_cp15 (void) static inline unsigned read_cp15 (void)
@ -392,7 +392,7 @@ bool __dbg_ports(void)
#ifdef DEBUG_DBOP #ifdef DEBUG_DBOP
line++; line++;
lcd_puts(0, line++, "[DBOP_DIN]"); lcd_puts(0, line++, "[DBOP_DIN]");
lcd_putsf(0, line++, "DBOP_DIN: %4x", button_dbop_data()); lcd_putsf(0, line++, "DBOP_DIN: %4x", dbop_debug());
#endif #endif
line++; line++;
lcd_puts(0, line++, "[CP15]"); lcd_puts(0, line++, "[CP15]");

View file

@ -5,9 +5,9 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id: button-e200v2.c 19035 2008-11-07 05:31:05Z jdgordon $ * $Id: button-c200v2.c 19035 2008-11-07 05:31:05Z jdgordon $
* *
* Copyright (C) 2006 by Barry Wardell * Copyright (C) 2006 by Barry Wardell, (C) 2009 by Bertrik Sikken
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -19,29 +19,20 @@
* *
****************************************************************************/ ****************************************************************************/
#include "config.h"
#include "system.h" #include "system.h"
#include "button-target.h" #include "button-target.h"
#include "button.h" #include "button.h"
#include "backlight.h" #include "backlight.h"
#include "powermgmt.h" #include "dbop-as3525.h"
static unsigned short _dbop_din;
static unsigned short _dbop_din = 0xFFFF;
/* in the lcd driver */
extern unsigned short int lcd_dbop_input(void);
static bool hold_button = false; static bool hold_button = false;
#ifndef BOOTLOADER #ifndef BOOTLOADER
static bool hold_button_old = false; static bool hold_button_old = false;
#endif #endif
/* for the debug menu */
unsigned short button_dbop_data(void)
{
return _dbop_din;
}
void button_init_device(void) void button_init_device(void)
{ {
GPIOA_DIR &= ~(1<<3); GPIOA_DIR &= ~(1<<3);
@ -59,7 +50,7 @@ int button_read_device(void)
{ {
int btn = BUTTON_NONE; int btn = BUTTON_NONE;
_dbop_din = lcd_dbop_input(); _dbop_din = dbop_read_input();
/* hold button handling */ /* hold button handling */
hold_button = ((_dbop_din & (1<<12)) == 0); hold_button = ((_dbop_din & (1<<12)) == 0);

View file

@ -26,6 +26,7 @@
#include "debug.h" #include "debug.h"
#include "system.h" #include "system.h"
#include "clock-target.h" #include "clock-target.h"
#include "dbop-as3525.h"
/* The controller is unknown, but some registers appear to be the same as the /* The controller is unknown, but some registers appear to be the same as the
HD66789R */ HD66789R */
@ -89,8 +90,6 @@ static unsigned short r_entry_mode = R_ENTRY_MODE_HORZ_NORMAL;
#define R_DISP_CONTROL_REV 0x0000 #define R_DISP_CONTROL_REV 0x0000
static unsigned short r_disp_control_rev = R_DISP_CONTROL_NORMAL; static unsigned short r_disp_control_rev = R_DISP_CONTROL_NORMAL;
static volatile bool lcd_busy = false;
static inline void lcd_delay(int x) static inline void lcd_delay(int x)
{ {
do { do {
@ -435,8 +434,6 @@ void lcd_blit_yuv(unsigned char * const src[3],
yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
yuv_src[2] = src[2] + (yuv_src[1] - src[1]); yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
lcd_busy = true;
lcd_write_reg(R_ENTRY_MODE, lcd_write_reg(R_ENTRY_MODE,
display_flipped ? R_ENTRY_MODE_VIDEO_FLIPPED : R_ENTRY_MODE_VIDEO_NORMAL display_flipped ? R_ENTRY_MODE_VIDEO_FLIPPED : R_ENTRY_MODE_VIDEO_NORMAL
); );
@ -473,8 +470,6 @@ void lcd_blit_yuv(unsigned char * const src[3],
} }
while (--height > 0); while (--height > 0);
} }
lcd_busy = false;
} }
/* Update the display. /* Update the display.
@ -484,8 +479,6 @@ void lcd_update(void)
if (!display_on) if (!display_on)
return; return;
lcd_busy = true;
lcd_write_reg(R_ENTRY_MODE, r_entry_mode); lcd_write_reg(R_ENTRY_MODE, r_entry_mode);
/* Set start position and window */ /* Set start position and window */
@ -494,8 +487,6 @@ void lcd_update(void)
lcd_write_cmd(R_WRITE_DATA_2_GRAM); lcd_write_cmd(R_WRITE_DATA_2_GRAM);
lcd_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); lcd_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT);
lcd_busy = false;
} }
/* Update a fraction of the display. */ /* Update a fraction of the display. */
@ -525,8 +516,6 @@ void lcd_update_rect(int x, int y, int width, int height)
if (y >= ymax) if (y >= ymax)
return; /* nothing left to do */ return; /* nothing left to do */
lcd_busy = true;
lcd_write_reg(R_ENTRY_MODE, r_entry_mode); lcd_write_reg(R_ENTRY_MODE, r_entry_mode);
lcd_window(x, y, xmax, ymax); lcd_window(x, y, xmax, ymax);
@ -541,25 +530,4 @@ void lcd_update_rect(int x, int y, int width, int height)
ptr += LCD_WIDTH; ptr += LCD_WIDTH;
} }
while (--height >= 0); while (--height >= 0);
lcd_busy = false;
}
/* writes one red pixel outside the visible area, needed for correct
* dbop reads */
bool lcd_button_support(void)
{
if (lcd_busy)
return false;
lcd_write_reg(R_ENTRY_MODE, r_entry_mode);
/* Set start position and window */
lcd_window(LCD_WIDTH+1, LCD_HEIGHT+1, LCD_WIDTH+2, LCD_HEIGHT+2);
lcd_write_cmd(R_WRITE_DATA_2_GRAM);
lcd_write_value16(0xf<<12);
return true;
} }

View file

@ -28,6 +28,7 @@
#include "debug.h" #include "debug.h"
#include "system.h" #include "system.h"
#include "clock-target.h" #include "clock-target.h"
#include "dbop-as3525.h"
/* The controller is unknown, but some registers appear to be the same as the /* The controller is unknown, but some registers appear to be the same as the
HD66789R */ HD66789R */
@ -92,7 +93,6 @@ static unsigned short r_entry_mode = R_ENTRY_MODE_HORZ_NORMAL;
static unsigned short r_disp_control_rev = R_DISP_CONTROL_NORMAL; static unsigned short r_disp_control_rev = R_DISP_CONTROL_NORMAL;
static const int xoffset = 20; static const int xoffset = 20;
static volatile bool lcd_busy = false;
static inline void lcd_delay(int x) static inline void lcd_delay(int x)
{ {
@ -379,8 +379,6 @@ void lcd_blit_yuv(unsigned char * const src[3],
yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
yuv_src[2] = src[2] + (yuv_src[1] - src[1]); yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
lcd_busy = true;
#ifdef HAVE_LCD_FLIP #ifdef HAVE_LCD_FLIP
lcd_write_reg(R_ENTRY_MODE, lcd_write_reg(R_ENTRY_MODE,
display_flipped ? R_ENTRY_MODE_VIDEO_FLIPPED : R_ENTRY_MODE_VIDEO_NORMAL 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],
} }
while (--height > 0); while (--height > 0);
} }
lcd_busy = false;
} }
/* Update the display. /* Update the display.
@ -434,8 +430,6 @@ void lcd_update(void)
if (!display_on) if (!display_on)
return; return;
lcd_busy = true;
lcd_write_reg(R_ENTRY_MODE, r_entry_mode); lcd_write_reg(R_ENTRY_MODE, r_entry_mode);
lcd_window_x(0, LCD_WIDTH - 1); lcd_window_x(0, LCD_WIDTH - 1);
@ -444,8 +438,6 @@ void lcd_update(void)
lcd_write_cmd(R_WRITE_DATA_2_GRAM); lcd_write_cmd(R_WRITE_DATA_2_GRAM);
lcd_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); lcd_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT);
lcd_busy = false;
} }
/* Update a fraction of the display. */ /* Update a fraction of the display. */
@ -475,8 +467,6 @@ void lcd_update_rect(int x, int y, int width, int height)
if (y >= ymax) if (y >= ymax)
return; /* nothing left to do */ return; /* nothing left to do */
lcd_busy = true;
lcd_write_reg(R_ENTRY_MODE, r_entry_mode); lcd_write_reg(R_ENTRY_MODE, r_entry_mode);
lcd_window_x(x, xmax); lcd_window_x(x, xmax);
@ -493,26 +483,4 @@ void lcd_update_rect(int x, int y, int width, int height)
ptr += LCD_WIDTH; ptr += LCD_WIDTH;
} }
while (--height >= 0); while (--height >= 0);
lcd_busy = false;
}
/* writes one red pixel outside the visible area, needed for correct
* dbop reads */
bool lcd_button_support(void)
{
if (lcd_busy)
return false;
lcd_write_reg(R_ENTRY_MODE, r_entry_mode);
/* Set start position and window */
lcd_window_x(-1, 0);
lcd_window_y(-1, 0);
lcd_write_cmd(R_WRITE_DATA_2_GRAM);
lcd_write_value16(0xf<<12);
return true;
} }

View file

@ -25,11 +25,8 @@
#include "lcd.h" #include "lcd.h"
#include "kernel.h" #include "kernel.h"
#include "system.h" #include "system.h"
#ifdef SANSA_C200V2 #ifdef SANSA_C200V2
/* button driver needs to know if a lcd operation is in progress */ #include "dbop-as3525.h"
static bool lcd_busy = false;
static unsigned short dbop_input = 0xFFFF;
#endif #endif
/* Display status */ /* Display status */
@ -183,45 +180,6 @@ static inline void as3525_dbop_init(void)
lcd_delay(20); lcd_delay(20);
} }
static unsigned short lcd_dbop_read(void)
{
unsigned int dbop_ctrl_old = DBOP_CTRL;
unsigned int dbop_timpol23_old = DBOP_TIMPOL_23;
unsigned int value;
/* make sure that the DBOP FIFO is empty */
while ((DBOP_STAT & (1<<10)) == 0);
/* write DBOP_DOUT to pre-charge DBOP data lines with a high level */
DBOP_TIMPOL_23 = 0xe167e167; /* no strobe towards lcd */
DBOP_CTRL = (1 << 16) | /* enw=1 (enable write) */
(1 << 12); /* ow=1 (16-bit data width) */
DBOP_DOUT = 0xFFFF; /* all pins high */
while ((DBOP_STAT & (1<<10)) == 0);
/* perform a DBOP read */
DBOP_CTRL = (1 << 15) | /* strd=1 (start read) */
(1 << 12) | /* ow=1 (16-bit data width) */
(31 << 0); /* rs_t=31 (read DBOP at end of cycle) */
while ((DBOP_STAT & (1<<16)) == 0);
value = DBOP_DIN;
/* restore previous values */
DBOP_TIMPOL_23 = dbop_timpol23_old;
DBOP_CTRL = dbop_ctrl_old;
return value;
}
/* get the DBOP input value, either directly or cached if DBOP is busy */
unsigned short int lcd_dbop_input(void)
{
if (!lcd_busy) {
dbop_input = lcd_dbop_read();
}
return dbop_input;
}
#endif #endif
/* LCD init */ /* LCD init */
@ -292,13 +250,7 @@ int lcd_default_contrast(void)
void lcd_set_contrast(int val) void lcd_set_contrast(int val)
{ {
#ifdef SANSA_C200V2
lcd_busy = true;
#endif
lcd_send_command(R_CONTRAST_CONTROL1, val); lcd_send_command(R_CONTRAST_CONTROL1, val);
#ifdef SANSA_C200V2
lcd_busy = false;
#endif
} }
void lcd_set_invert_display(bool yesno) void lcd_set_invert_display(bool yesno)
@ -313,9 +265,6 @@ void lcd_enable(bool yesno)
if (yesno == is_lcd_enabled) if (yesno == is_lcd_enabled)
return; return;
#ifdef SANSA_C200V2
lcd_busy = true;
#endif
if ((is_lcd_enabled = yesno)) if ((is_lcd_enabled = yesno))
{ {
lcd_send_command(R_STANDBY_OFF, 0); lcd_send_command(R_STANDBY_OFF, 0);
@ -326,9 +275,6 @@ void lcd_enable(bool yesno)
{ {
lcd_send_command(R_STANDBY_ON, 0); lcd_send_command(R_STANDBY_ON, 0);
} }
#ifdef SANSA_C200V2
lcd_busy = false;
#endif
} }
#endif #endif
@ -343,18 +289,12 @@ bool lcd_active(void)
/* turn the display upside down (call lcd_update() afterwards) */ /* turn the display upside down (call lcd_update() afterwards) */
void lcd_set_flip(bool yesno) void lcd_set_flip(bool yesno)
{ {
#ifdef SANSA_C200V2
lcd_busy = true;
#endif
lcd_send_command(R_DRIVER_OUTPUT_MODE, yesno ? 0x02 : 0x07); lcd_send_command(R_DRIVER_OUTPUT_MODE, yesno ? 0x02 : 0x07);
#ifdef SANSA_C200V2
lcd_busy = false;
#endif
} }
/*** update functions ***/ /*** update functions ***/
#if MEMORYSIZE > 2 #if MEMORYSIZE > 2 /* not for C200V2 */
void lcd_yuv_set_options(unsigned options) void lcd_yuv_set_options(unsigned options)
{ {
lcd_yuv_options = options; lcd_yuv_options = options;
@ -450,12 +390,6 @@ void lcd_update_rect(int x, int y, int width, int height)
addr = &lcd_framebuffer[y][x]; addr = &lcd_framebuffer[y][x];
#ifdef SANSA_C200V2
lcd_busy = true;
/* perform a dbop read before doing a potentially lengthy lcd update */
dbop_input = lcd_dbop_read();
#endif
if (width <= 1) { if (width <= 1) {
/* The X end address must be larger than the X start address, so we /* The X end address must be larger than the X start address, so we
* switch to vertical mode for single column updates and set the * 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)
lcd_write_data(addr, width); lcd_write_data(addr, width);
addr += LCD_WIDTH; addr += LCD_WIDTH;
} while (--height > 0); } while (--height > 0);
#ifdef SANSA_C200V2
lcd_busy = false;
#endif
} }