diff --git a/firmware/SOURCES b/firmware/SOURCES index 4b174d0..064c8fe 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -1235,6 +1235,7 @@ target/arm/as3525/sansa-e200v2/lcd-e200v2.c target/arm/as3525/lcd-as-e200v2-fuze.S target/arm/as3525/button-e200v2-fuze.c target/arm/as3525/backlight-e200v2-fuze.c +target/arm/as3525/dbop-as3525.c #ifndef BOOTLOADER target/arm/powermgmt-ascodec.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/as3525/sansa-c200v2/button-c200v2.c target/arm/as3525/sansa-c200v2/backlight-c200v2.c +target/arm/as3525/dbop-as3525.c #ifndef BOOTLOADER target/arm/as3525/powermgmt-as3525.c #endif /* !BOOTLOADER */ @@ -1269,6 +1271,7 @@ target/arm/as3525/button-e200v2-fuze.c target/arm/as3525/sansa-fuze/lcd-fuze.c target/arm/as3525/lcd-as-e200v2-fuze.S target/arm/as3525/backlight-e200v2-fuze.c +target/arm/as3525/dbop-as3525.c #ifndef BOOTLOADER target/arm/powermgmt-ascodec.c target/arm/as3525/sansa-fuze/powermgmt-fuze.c diff --git a/firmware/export/config/sansac200v2.h b/firmware/export/config/sansac200v2.h index 65aebf2..dbebeab 100644 --- a/firmware/export/config/sansac200v2.h +++ b/firmware/export/config/sansac200v2.h @@ -197,3 +197,5 @@ #define DEFAULT_REC_MIC_GAIN 23 #define DEFAULT_REC_LEFT_GAIN 23 #define DEFAULT_REC_RIGHT_GAIN 23 + +#define DBOP_PRECHARGE 0xF0FF diff --git a/firmware/export/config/sansae200v2.h b/firmware/export/config/sansae200v2.h index 110555a..8472f88 100644 --- a/firmware/export/config/sansae200v2.h +++ b/firmware/export/config/sansae200v2.h @@ -210,3 +210,5 @@ #define DEFAULT_REC_MIC_GAIN 23 #define DEFAULT_REC_LEFT_GAIN 23 #define DEFAULT_REC_RIGHT_GAIN 23 + +#define DBOP_PRECHARGE 0x80FF diff --git a/firmware/export/config/sansafuze.h b/firmware/export/config/sansafuze.h index 4370aef..15a04de 100644 --- a/firmware/export/config/sansafuze.h +++ b/firmware/export/config/sansafuze.h @@ -59,10 +59,10 @@ */ /* define this if you can flip your LCD */ -//#define HAVE_LCD_FLIP +#define HAVE_LCD_FLIP /* define this if you can invert the colours on your LCD */ -//#define HAVE_LCD_INVERT +#define HAVE_LCD_INVERT /* define this if you have a real-time clock */ @@ -204,3 +204,4 @@ #define INCLUDE_TIMEOUT_API +#define DBOP_PRECHARGE 0x80FF diff --git a/firmware/target/arm/as3525/button-e200v2-fuze.c b/firmware/target/arm/as3525/button-e200v2-fuze.c index 157cdd0..98c660d 100644 --- a/firmware/target/arm/as3525/button-e200v2-fuze.c +++ b/firmware/target/arm/as3525/button-e200v2-fuze.c @@ -20,10 +20,12 @@ * ****************************************************************************/ +#include "config.h" #include "system.h" #include "button.h" #include "button-target.h" #include "backlight.h" +#include "dbop-as3525.h" #ifdef SANSA_FUZE @@ -32,7 +34,6 @@ #define WHEEL_COUNTER_DIV 4 #define ACCEL_INCREMENT 2 #define ACCEL_SHIFT 2 -#define BUTTON_DELAY 60 #endif #ifdef SANSA_E200V2 @@ -41,12 +42,6 @@ #define WHEEL_COUNTER_DIV 2 #define ACCEL_INCREMENT 3 #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 /* Buttons */ @@ -54,10 +49,6 @@ static bool hold_button = false; #ifndef BOOTLOADER static bool hold_button_old = false; #endif -static unsigned short _dbop_din = BUTTON_NONE; - -/* in the lcd driver */ -extern bool lcd_button_support(void); void button_init_device(void) { @@ -66,10 +57,9 @@ void button_init_device(void) } #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 */ - unsigned wheel_value = 0; unsigned btn = BUTTON_NONE; /* old wheel values */ static unsigned old_wheel_value = 0; @@ -112,8 +102,6 @@ static void scrollwheel(unsigned short dbop_din) return; } - wheel_value = (dbop_din >> 13) & (1<<1|1<<0); - if (old_wheel_value == wheel_tbl[0][wheel_value]) btn = BUTTON_SCROLL_FWD; 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; } } - if (accel > 0 -#ifdef SANSA_E200V2 - && !read_missed /* decrement only if reading buttons was successful */ -#endif - ) + if (accel > 0) accel--; old_wheel_value = wheel_value; @@ -174,123 +158,14 @@ bool button_hold(void) return hold_button; } -static void button_delay(void) -{ - int i = BUTTON_DELAY; - while(i--) asm volatile ("nop\n"); -} - unsigned short button_read_dbop(void) { -#ifdef SANSA_FUZE - /* 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 - + unsigned dbop_din = dbop_read_input(); #if defined(HAVE_SCROLLWHEEL) && !defined(BOOTLOADER) - /* read wheel on bit 13 & 14, but sent to the button queue seperately */ - scrollwheel(_dbop_din); + /* scroll wheel handling */ + scrollwheel((dbop_din >> 13) & (1<<1|1<<0)); #endif - -#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; + return dbop_din; } /* @@ -298,51 +173,58 @@ static int button_gpio(void) */ int button_read_device(void) { - int btn = BUTTON_NONE; - unsigned short dbop = button_read_dbop(); #ifdef SANSA_FUZE static unsigned power_counter = 0; #endif - /* hold button */ - if(dbop & (1<<12)) + unsigned short dbop_din; + int btn = BUTTON_NONE; + + dbop_din = button_read_dbop(); + + /* hold button handling */ + hold_button = ((dbop_din & (1<<12)) != 0); +#ifndef BOOTLOADER + /* light handling */ + if (hold_button != hold_button_old) { + hold_button_old = hold_button; + backlight_hold_changed(hold_button); + } +#endif /* BOOTLOADER */ + if (hold_button) { #ifdef SANSA_FUZE power_counter = HZ; #endif - hold_button = true; + return 0; } - else - { - hold_button = false; + + /* 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) - * hold (wait 1 sec) */ - if (power_counter) + */ + if (power_counter > 0) { 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(); + btn &= ~BUTTON_POWER; } - -#ifndef BOOTLOADER - /* light handling */ - if (hold_button != hold_button_old) - { - hold_button_old = hold_button; - backlight_hold_changed(hold_button); - } -#endif /* BOOTLOADER */ +#endif return btn; } + diff --git a/firmware/target/arm/as3525/dbop-as3525.c b/firmware/target/arm/as3525/dbop-as3525.c new file mode 100644 index 0000000..caf50d2 --- /dev/null +++ b/firmware/target/arm/as3525/dbop-as3525.c @@ -0,0 +1,71 @@ +/*************************************************************************** + * __________ __ ___. + * 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" + +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 = 5; + 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; +} diff --git a/firmware/target/arm/as3525/dbop-as3525.h b/firmware/target/arm/as3525/dbop-as3525.h new file mode 100644 index 0000000..6315603 --- /dev/null +++ b/firmware/target/arm/as3525/dbop-as3525.h @@ -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); diff --git a/firmware/target/arm/as3525/debug-as3525.c b/firmware/target/arm/as3525/debug-as3525.c index be78bca..6ec065b 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; * 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) #define DEBUG_DBOP -unsigned short button_dbop_data(void); +#include "dbop-as3525.h" #endif static inline unsigned read_cp15 (void) @@ -392,7 +392,7 @@ bool __dbg_ports(void) #ifdef DEBUG_DBOP line++; 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 line++; 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 b7ce733..8a95c2d 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 @@ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * 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 * modify it under the terms of the GNU General Public License @@ -19,29 +19,20 @@ * ****************************************************************************/ +#include "config.h" #include "system.h" #include "button-target.h" #include "button.h" #include "backlight.h" -#include "powermgmt.h" +#include "dbop-as3525.h" - -static unsigned short _dbop_din = 0xFFFF; - -/* in the lcd driver */ -extern unsigned short int lcd_dbop_input(void); +static unsigned short _dbop_din; static bool hold_button = false; #ifndef BOOTLOADER static bool hold_button_old = false; #endif -/* for the debug menu */ -unsigned short button_dbop_data(void) -{ - return _dbop_din; -} - void button_init_device(void) { GPIOA_DIR &= ~(1<<3); @@ -59,7 +50,7 @@ int button_read_device(void) { int btn = BUTTON_NONE; - _dbop_din = lcd_dbop_input(); + _dbop_din = dbop_read_input(); /* hold button handling */ 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 f48861f..2903097 100644 --- a/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c +++ b/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c @@ -22,23 +22,16 @@ #include "cpu.h" #include "lcd.h" -#include "kernel.h" -#include "thread.h" -#include -#include #include "file.h" #include "debug.h" #include "system.h" -#include "font.h" -#include "bidi.h" #include "clock-target.h" +#include "dbop-as3525.h" +/* The controller is unknown, but some registers appear to be the same as the + HD66789R */ static bool display_on = false; /* is the display turned on? */ static bool display_flipped = false; -/* we need to write a red pixel for correct button reads - * (see lcd_button_support()), but that must not happen while the lcd is - * updating so block lcd_button_support the during updates */ -static volatile bool lcd_busy = false; /* register defines */ #define R_START_OSC 0x00 @@ -105,31 +98,29 @@ static inline void lcd_delay(int x) } while (x--); } -/* DBOP initialisation, do what OF does */ -static void ams3525_dbop_init(void) +static void as3525_dbop_init(void) { CGU_DBOP = (1<<3) | AS3525_DBOP_DIV; DBOP_TIMPOL_01 = 0xe167e167; DBOP_TIMPOL_23 = 0xe167006e; - - /* short count, 16bit write, read-timing =8 */ - DBOP_CTRL = (1<<18)|(1<<12)|(8<<0); + + /* short count: 16 | output data width: 16 | readstrobe line */ + DBOP_CTRL = (1<<18|1<<12|1<<3); GPIOB_AFSEL = 0xfc; GPIOC_AFSEL = 0xff; DBOP_TIMPOL_23 = 0x6000e; - - /* short count,write enable, 16bit write, read-timing =8 */ - DBOP_CTRL = (1<<18)|(1<<16)|(1<<12)|(8<<0); + /* short count: 16|enable write|output data width: 16|read strobe line */ + DBOP_CTRL = (1<<18|1<<16|1<<12|1<<3); DBOP_TIMPOL_01 = 0x6e167; DBOP_TIMPOL_23 = 0xa167e06f; /* TODO: The OF calls some other functions here, but maybe not important */ } -static void lcd_write_single_data16(unsigned short value) +static void lcd_write_value16(unsigned short value) { DBOP_CTRL &= ~(1<<14|1<<13); lcd_delay(10); @@ -141,14 +132,12 @@ static void lcd_write_cmd(int cmd) { /* Write register */ DBOP_TIMPOL_23 = 0xa167006e; - lcd_write_single_data16(cmd); + lcd_write_value16(cmd); /* Wait for fifo to empty */ while ((DBOP_STAT & (1<<10)) == 0); - /* Fuze OF has this loop and it seems to help us now also */ - int delay=8; - while(delay--); + lcd_delay(4); DBOP_TIMPOL_23 = 0xa167e06f; } @@ -157,15 +146,16 @@ void lcd_write_data(const fb_data* p_bytes, int count) { const long *data; if ((int)p_bytes & 0x3) - { /* need to do a single 16bit write beforehand if the address is */ - /* not word aligned*/ - lcd_write_single_data16(*p_bytes); + { /* need to do a single 16bit write beforehand if the address is + * not word aligned */ + lcd_write_value16(*p_bytes); count--;p_bytes++; } - /* from here, 32bit transfers are save */ - /* set it to transfer 4*(outputwidth) units at a time, */ - /* if bit 12 is set it only does 2 halfwords though */ + /* from here, 32bit transfers are save + * set it to transfer 4*(outputwidth) units at a time, + * if bit 12 is set it only does 2 halfwords though */ DBOP_CTRL |= (1<<13|1<<14); + lcd_delay(10); data = (long*)p_bytes; while (count > 1) { @@ -181,7 +171,7 @@ void lcd_write_data(const fb_data* p_bytes, int count) /* due to the 32bit alignment requirement or uneven count, * we possibly need to do a 16bit transfer at the end also */ if (count > 0) - lcd_write_single_data16(*(fb_data*)data); + lcd_write_value16(*(fb_data*)data); } static void lcd_write_reg(int reg, int value) @@ -189,7 +179,7 @@ static void lcd_write_reg(int reg, int value) fb_data data = value; lcd_write_cmd(reg); - lcd_write_single_data16(data); + lcd_write_value16(data); } /*** hardware configuration ***/ @@ -230,11 +220,11 @@ static void lcd_window(int xmin, int ymin, int xmax, int ymax) } else { - lcd_write_reg(R_HORIZ_RAM_ADDR_POS, + lcd_write_reg(R_HORIZ_RAM_ADDR_POS, ((LCD_WIDTH-1 - xmin) << 8) | (LCD_WIDTH-1 - xmax)); - lcd_write_reg(R_VERT_RAM_ADDR_POS, + lcd_write_reg(R_VERT_RAM_ADDR_POS, ((LCD_HEIGHT-1 - ymin) << 8) | (LCD_HEIGHT-1 - ymax)); - lcd_write_reg(R_RAM_ADDR_SET, + lcd_write_reg(R_RAM_ADDR_SET, ((LCD_HEIGHT-1 - ymin) << 8) | (LCD_WIDTH-1 - xmin)); } } @@ -343,22 +333,16 @@ static void _display_on(void) lcd_update(); } -/* LCD init */ void lcd_init_device(void) { - ams3525_dbop_init(); - - /* Init GPIOs the same as the OF */ + as3525_dbop_init(); GPIOA_DIR |= (1<<5); GPIOA_PIN(5) = 0; - - GPIOA_PIN(4) = 0; /*c80b0040 := 0;*/ + GPIOA_PIN(4) = 0; lcd_delay(1); - GPIOA_PIN(5) = (1<<5); - lcd_delay(1); _display_on(); @@ -367,18 +351,18 @@ void lcd_init_device(void) #if defined(HAVE_LCD_ENABLE) void lcd_enable(bool on) { - if(display_on!=on) + if (display_on == on) + return; + + if(on) { - if(on) - { - _display_on(); - send_event(LCD_EVENT_ACTIVATION, NULL); - } - else - { - display_on=false; - lcd_write_reg(R_POWER_CONTROL1, 0x0001); - } + _display_on(); + send_event(LCD_EVENT_ACTIVATION, NULL); + } + else + { + display_on=false; + lcd_write_reg(R_POWER_CONTROL1, 0x0001); } } #endif @@ -388,23 +372,12 @@ bool lcd_active(void) { return display_on; } - #endif /*** update functions ***/ static unsigned lcd_yuv_options = 0; -/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ -extern void lcd_write_yuv420_lines(unsigned char const * const src[3], - int width, - int stride); -extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3], - int width, - int stride, - int x_screen, /* To align dither pattern */ - int y_screen); - void lcd_yuv_set_options(unsigned options) { lcd_yuv_options = options; @@ -414,10 +387,10 @@ static void lcd_window_blit(int xmin, int ymin, int xmax, int ymax) { if (!display_flipped) { - lcd_write_reg(R_HORIZ_RAM_ADDR_POS, + lcd_write_reg(R_HORIZ_RAM_ADDR_POS, ((LCD_WIDTH-1 - xmin) << 8) | (LCD_WIDTH-1 - xmax)); lcd_write_reg(R_VERT_RAM_ADDR_POS, (ymax << 8) | ymin); - lcd_write_reg(R_RAM_ADDR_SET, + lcd_write_reg(R_RAM_ADDR_SET, (ymin << 8) | (LCD_WIDTH-1 - xmin)); } else @@ -428,6 +401,16 @@ static void lcd_window_blit(int xmin, int ymin, int xmax, int ymax) } } +/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ +extern void lcd_write_yuv420_lines(unsigned char const * const src[3], + int width, + int stride); +extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3], + int width, + int stride, + int x_screen, /* To align dither pattern */ + int y_screen); + /* Performance function to blit a YUV bitmap directly to the LCD * src_x, src_y, width and height should be even * x, y, width and height have to be within LCD bounds @@ -439,8 +422,6 @@ void lcd_blit_yuv(unsigned char * const src[3], unsigned char const * yuv_src[3]; off_t z; - lcd_busy = true; - /* Sorry, but width and height must be >= 2 or else */ width &= ~1; height >>= 1; @@ -450,14 +431,9 @@ void lcd_blit_yuv(unsigned char * const src[3], yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); yuv_src[2] = src[2] + (yuv_src[1] - src[1]); - if (!display_flipped) - { - lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VIDEO_NORMAL); - } - else - { - lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VIDEO_FLIPPED); - } + lcd_write_reg(R_ENTRY_MODE, + display_flipped ? R_ENTRY_MODE_VIDEO_FLIPPED : R_ENTRY_MODE_VIDEO_NORMAL + ); if (lcd_yuv_options & LCD_YUV_DITHER) { @@ -465,14 +441,13 @@ void lcd_blit_yuv(unsigned char * const src[3], { lcd_window_blit(y, x, y+1, x+width-1); - /* Start write to GRAM */ lcd_write_cmd(R_WRITE_DATA_2_GRAM); lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y); yuv_src[0] += stride << 1; /* Skip down two luma lines */ yuv_src[1] += stride >> 1; /* Skip down one chroma line */ yuv_src[2] += stride >> 1; - y+=2; + y += 2; } while (--height > 0); } @@ -482,19 +457,16 @@ void lcd_blit_yuv(unsigned char * const src[3], { lcd_window_blit(y, x, y+1, x+width-1); - /* Start write to GRAM */ lcd_write_cmd(R_WRITE_DATA_2_GRAM); lcd_write_yuv420_lines(yuv_src, width, stride); yuv_src[0] += stride << 1; /* Skip down two luma lines */ yuv_src[1] += stride >> 1; /* Skip down one chroma line */ yuv_src[2] += stride >> 1; - y+=2; + y += 2; } while (--height > 0); } - - lcd_busy = false; } /* Update the display. @@ -504,8 +476,6 @@ void lcd_update(void) if (!display_on) return; - lcd_busy = true; - lcd_write_reg(R_ENTRY_MODE, r_entry_mode); /* Set start position and window */ @@ -514,17 +484,13 @@ void lcd_update(void) lcd_write_cmd(R_WRITE_DATA_2_GRAM); lcd_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); - - lcd_busy = false; -} /* lcd_update */ - +} /* Update a fraction of the display. */ void lcd_update_rect(int x, int y, int width, int height) { const fb_data *ptr; - int ymax, xmax; - + int xmax, ymax; if (!display_on) return; @@ -547,43 +513,18 @@ void lcd_update_rect(int x, int y, int width, int height) if (y >= ymax) return; /* nothing left to do */ - lcd_busy = true; - lcd_write_reg(R_ENTRY_MODE, r_entry_mode); - + lcd_window(x, y, xmax, ymax); lcd_write_cmd(R_WRITE_DATA_2_GRAM); - ptr = (fb_data*)&lcd_framebuffer[y][x]; + ptr = &lcd_framebuffer[y][x]; - height = ymax - y; /* fix height */ - do { lcd_write_data(ptr, width); ptr += LCD_WIDTH; } while (--height >= 0); - - lcd_busy = false; -} /* lcd_update_rect */ - -/* writes one red pixel outside the visible area, needed for correct - * dbop reads */ -bool lcd_button_support(void) -{ - fb_data data = (0xf<<12); - - 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_single_data16(data); - return true; } diff --git a/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c b/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c index c9dd69d..61bdc7c 100644 --- a/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c +++ b/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c @@ -28,25 +28,72 @@ #include "debug.h" #include "system.h" #include "clock-target.h" +#include "dbop-as3525.h" /* The controller is unknown, but some registers appear to be the same as the HD66789R */ +static bool display_on = false; /* is the display turned on? */ +static bool display_flipped = false; +/* register defines */ +#define R_START_OSC 0x00 +#define R_DRV_OUTPUT_CONTROL 0x01 +#define R_DRV_WAVEFORM_CONTROL 0x02 #define R_ENTRY_MODE 0x03 -#define R_RAM_ADDR_SET 0x21 -#define R_WRITE_DATA_2_GRAM 0x22 - -#define R_ENTRY_MODE_HORZ 0x7030 +#define R_COMPARE_REG1 0x04 +#define R_COMPARE_REG2 0x05 + +#define R_DISP_CONTROL1 0x07 +#define R_DISP_CONTROL2 0x08 +#define R_DISP_CONTROL3 0x09 + +#define R_FRAME_CYCLE_CONTROL 0x0b +#define R_EXT_DISP_IF_CONTROL 0x0c + +#define R_POWER_CONTROL1 0x10 +#define R_POWER_CONTROL2 0x11 +#define R_POWER_CONTROL3 0x12 +#define R_POWER_CONTROL4 0x13 + +#define R_RAM_ADDR_SET 0x21 +#define R_WRITE_DATA_2_GRAM 0x22 + +#define R_GAMMA_FINE_ADJ_POS1 0x30 +#define R_GAMMA_FINE_ADJ_POS2 0x31 +#define R_GAMMA_FINE_ADJ_POS3 0x32 +#define R_GAMMA_GRAD_ADJ_POS 0x33 + +#define R_GAMMA_FINE_ADJ_NEG1 0x34 +#define R_GAMMA_FINE_ADJ_NEG2 0x35 +#define R_GAMMA_FINE_ADJ_NEG3 0x36 +#define R_GAMMA_GRAD_ADJ_NEG 0x37 + +#define R_GAMMA_AMP_ADJ_RES_POS 0x38 +#define R_GAMMA_AMP_AVG_ADJ_RES_NEG 0x39 + +#define R_GATE_SCAN_POS 0x40 +#define R_VERT_SCROLL_CONTROL 0x41 +#define R_1ST_SCR_DRV_POS 0x42 +#define R_2ND_SCR_DRV_POS 0x43 +#define R_HORIZ_RAM_ADDR_POS 0x44 +#define R_VERT_RAM_ADDR_POS 0x45 + +/* Flip Flag */ +#define R_ENTRY_MODE_HORZ_NORMAL 0x7030 +#define R_ENTRY_MODE_HORZ_FLIPPED 0x7000 +static unsigned short r_entry_mode = R_ENTRY_MODE_HORZ_NORMAL; #define R_ENTRY_MODE_VERT 0x7038 +#define R_ENTRY_MODE_SOLID_VERT 0x1038 +#define R_ENTRY_MODE_VIDEO_NORMAL 0x7020 +#define R_ENTRY_MODE_VIDEO_FLIPPED 0x7010 -static unsigned lcd_yuv_options = 0; -static bool display_on = false; /* is the display turned on? */ -static bool display_flipped = false; -static int xoffset = 20; /* needed for flip */ -/* we need to write a red pixel for correct button reads - * (see lcd_button_support()),but that must not happen while the lcd is updating - * so block lcd_button_support the during updates */ -static volatile int lcd_busy = false; + +/* Reverse Flag */ +#define R_DISP_CONTROL_NORMAL 0x0004 +#define R_DISP_CONTROL_REV 0x0000 +static unsigned short r_disp_control_rev = R_DISP_CONTROL_NORMAL; + +static const int xoffset = 20; static inline void lcd_delay(int x) { @@ -54,7 +101,7 @@ static inline void lcd_delay(int x) asm volatile ("nop\n"); } while (x--); } - + static void as3525_dbop_init(void) { CGU_DBOP = (1<<3) | AS3525_DBOP_DIV; @@ -94,7 +141,6 @@ static void lcd_write_cmd(int cmd) /* Wait for fifo to empty */ while ((DBOP_STAT & (1<<10)) == 0); - /* This loop is unique to the Fuze */ lcd_delay(4); DBOP_TIMPOL_23 = 0xa167e06f; @@ -105,12 +151,12 @@ void lcd_write_data(const fb_data* p_bytes, int count) const long *data; if ((int)p_bytes & 0x3) { /* need to do a single 16bit write beforehand if the address is - * not word aligned*/ + * not word aligned */ lcd_write_value16(*p_bytes); count--;p_bytes++; } - /* from here, 32bit transfers are save */ - /* set it to transfer 4*(outputwidth) units at a time, + /* from here, 32bit transfers are save + * set it to transfer 4*(outputwidth) units at a time, * if bit 12 is set it only does 2 halfwords though */ DBOP_CTRL |= (1<<13|1<<14); lcd_delay(10); @@ -129,92 +175,124 @@ void lcd_write_data(const fb_data* p_bytes, int count) /* due to the 32bit alignment requirement or uneven count, * we possibly need to do a 16bit transfer at the end also */ if (count > 0) - lcd_write_value16(*(unsigned short*)data); + lcd_write_value16(*(fb_data*)data); } static void lcd_write_reg(int reg, int value) { - unsigned short data = value; + fb_data data = value; lcd_write_cmd(reg); lcd_write_value16(data); } -/* turn the display upside down (call lcd_update() afterwards) */ +/*** hardware configuration ***/ + +void lcd_set_contrast(int val) +{ + (void)val; +} + +void lcd_set_invert_display(bool yesno) +{ + r_disp_control_rev = yesno ? R_DISP_CONTROL_REV : + R_DISP_CONTROL_NORMAL; + + if (display_on) + { + lcd_write_reg(R_DISP_CONTROL1, 0x0033 | r_disp_control_rev); + } + +} + +/* turn the display upside down */ void lcd_set_flip(bool yesno) { display_flipped = yesno; - xoffset = yesno ? 0 : 20; /* TODO: Implement flipped mode */ - /* TODO */ + r_entry_mode = yesno ? R_ENTRY_MODE_HORZ_FLIPPED : + R_ENTRY_MODE_HORZ_NORMAL; } - static void _display_on(void) { /* Initialise in the same way as the original firmare */ - lcd_write_reg(0x07, 0); - lcd_write_reg(0x13, 0); + lcd_write_reg(R_DISP_CONTROL1, 0); + lcd_write_reg(R_POWER_CONTROL4, 0); - lcd_write_reg(0x11, 0x3704); + lcd_write_reg(R_POWER_CONTROL2, 0x3704); lcd_write_reg(0x14, 0x1a1b); - lcd_write_reg(0x10, 0x3860); - lcd_write_reg(0x13, 0x40); - - lcd_write_reg(0x13, 0x60); - - lcd_write_reg(0x13, 0x70); - lcd_write_reg(0x01, 277); - lcd_write_reg(0x02, (7<<8)); - lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); - lcd_write_reg(0x08, 0x01); - lcd_write_reg(0x0b, (1<<10)); - lcd_write_reg(0x0c, 0); - - lcd_write_reg(0x30, 0x40); - lcd_write_reg(0x31, 0x0687); - lcd_write_reg(0x32, 0x0306); - lcd_write_reg(0x33, 0x104); - lcd_write_reg(0x34, 0x0585); - lcd_write_reg(0x35, 255+66); - lcd_write_reg(0x36, 0x0687+128); - lcd_write_reg(0x37, 259); - lcd_write_reg(0x38, 0); - lcd_write_reg(0x39, 0); - - lcd_write_reg(0x42, (LCD_WIDTH - 1)); - lcd_write_reg(0x43, 0); - lcd_write_reg(0x44, (LCD_WIDTH - 1)); - lcd_write_reg(0x45, 0); + lcd_write_reg(R_POWER_CONTROL1, 0x3860); + lcd_write_reg(R_POWER_CONTROL4, 0x40); + + lcd_write_reg(R_POWER_CONTROL4, 0x60); + + lcd_write_reg(R_POWER_CONTROL4, 0x70); + lcd_write_reg(R_DRV_OUTPUT_CONTROL, 277); + lcd_write_reg(R_DRV_WAVEFORM_CONTROL, (7<<8)); + lcd_write_reg(R_ENTRY_MODE, r_entry_mode); + lcd_write_reg(R_DISP_CONTROL2, 0x01); + lcd_write_reg(R_FRAME_CYCLE_CONTROL, (1<<10)); + lcd_write_reg(R_EXT_DISP_IF_CONTROL, 0); + + lcd_write_reg(R_GAMMA_FINE_ADJ_POS1, 0x40); + lcd_write_reg(R_GAMMA_FINE_ADJ_POS2, 0x0687); + lcd_write_reg(R_GAMMA_FINE_ADJ_POS3, 0x0306); + lcd_write_reg(R_GAMMA_GRAD_ADJ_POS, 0x104); + lcd_write_reg(R_GAMMA_FINE_ADJ_NEG1, 0x0585); + lcd_write_reg(R_GAMMA_FINE_ADJ_NEG2, 255+66); + lcd_write_reg(R_GAMMA_FINE_ADJ_NEG3, 0x0687+128); + lcd_write_reg(R_GAMMA_GRAD_ADJ_NEG, 259); + lcd_write_reg(R_GAMMA_AMP_ADJ_RES_POS, 0); + lcd_write_reg(R_GAMMA_AMP_AVG_ADJ_RES_NEG, 0); + + lcd_write_reg(R_1ST_SCR_DRV_POS, (LCD_WIDTH - 1)); + lcd_write_reg(R_2ND_SCR_DRV_POS, 0); + lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (LCD_WIDTH - 1)); + lcd_write_reg(R_VERT_RAM_ADDR_POS, 0); lcd_write_reg(0x46, (((LCD_WIDTH - 1) + xoffset) << 8) | xoffset); lcd_write_reg(0x47, (LCD_HEIGHT - 1)); lcd_write_reg(0x48, 0x0); - lcd_write_reg(0x07, 0x11); - lcd_write_reg(0x07, 0x17); + lcd_write_reg(R_DISP_CONTROL1, 0x11); + lcd_write_reg(R_DISP_CONTROL1, 0x17); display_on = true; /* must be done before calling lcd_update() */ lcd_update(); } +void lcd_init_device(void) +{ + as3525_dbop_init(); + + GPIOA_DIR |= (1<<5|1<<4|1<<3); + GPIOA_PIN(5) = 0; + GPIOA_PIN(3) = (1<<3); + GPIOA_PIN(4) = 0; + GPIOA_PIN(5) = (1<<5); + + _display_on(); +} + #if defined(HAVE_LCD_ENABLE) void lcd_enable(bool on) { if (display_on == on) - return; /* nothing to do */ + return; + if(on) { - lcd_write_reg(0, 1); - lcd_write_reg(0x10, 0); - lcd_write_reg(0x11, 0x3704); + lcd_write_reg(R_START_OSC, 1); + lcd_write_reg(R_POWER_CONTROL1, 0); + lcd_write_reg(R_POWER_CONTROL2, 0x3704); lcd_write_reg(0x14, 0x1a1b); - lcd_write_reg(0x10, 0x3860); - lcd_write_reg(0x13, 0x40); - lcd_write_reg(0x13, 0x60); - lcd_write_reg(0x13, 112); - lcd_write_reg(0x07, 0x11); - lcd_write_reg(0x07, 0x17); + lcd_write_reg(R_POWER_CONTROL1, 0x3860); + lcd_write_reg(R_POWER_CONTROL4, 0x40); + lcd_write_reg(R_POWER_CONTROL4, 0x60); + lcd_write_reg(R_POWER_CONTROL4, 112); + lcd_write_reg(R_DISP_CONTROL1, 0x11); + lcd_write_reg(R_DISP_CONTROL1, 0x17); display_on = true; lcd_update(); /* Resync display */ send_event(LCD_EVENT_ACTIVATION, NULL); @@ -223,9 +301,9 @@ void lcd_enable(bool on) } else { - lcd_write_reg(0x07, 0x22); - lcd_write_reg(0x07, 0); - lcd_write_reg(0x10, 1); + lcd_write_reg(R_DISP_CONTROL1, 0x22); + lcd_write_reg(R_DISP_CONTROL1, 0); + lcd_write_reg(R_POWER_CONTROL1, 1); display_on = false; } } @@ -257,6 +335,8 @@ static void lcd_window_y(int ymin, int ymax) lcd_write_reg(0x21, ymin); } +static unsigned lcd_yuv_options = 0; + void lcd_yuv_set_options(unsigned options) { lcd_yuv_options = options; @@ -267,11 +347,15 @@ extern void lcd_write_yuv420_lines(unsigned char const * const src[3], int width, int stride); extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3], - int width, - int stride, - int x_screen, /* To align dither */ - int y_screen); /* pattern */ -/* Performance function to blit a YUV bitmap directly to the LCD */ + int width, + int stride, + int x_screen, /* To align dither pattern */ + int y_screen); + +/* Performance function to blit a YUV bitmap directly to the LCD + * src_x, src_y, width and height should be even + * x, y, width and height have to be within LCD bounds + */ void lcd_blit_yuv(unsigned char * const src[3], int src_x, int src_y, int stride, int x, int y, int width, int height) @@ -279,10 +363,6 @@ void lcd_blit_yuv(unsigned char * const src[3], unsigned char const * yuv_src[3]; off_t z; - lcd_busy = true; - - lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VERT); - /* Sorry, but width and height must be >= 2 or else */ width &= ~1; height >>= 1; @@ -292,6 +372,8 @@ void lcd_blit_yuv(unsigned char * const src[3], yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); yuv_src[2] = src[2] + (yuv_src[1] - src[1]); + lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VERT); + lcd_window_x(x, x + width - 1); if (lcd_yuv_options & LCD_YUV_DITHER) @@ -299,7 +381,7 @@ void lcd_blit_yuv(unsigned char * const src[3], do { lcd_window_y(y, y + 1); - /* Start write to GRAM */ + lcd_write_cmd(R_WRITE_DATA_2_GRAM); lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y); @@ -308,14 +390,14 @@ void lcd_blit_yuv(unsigned char * const src[3], yuv_src[2] += stride >> 1; y += 2; } - while (--height > 0); + while (--height > 0); } else { do { lcd_window_y(y, y + 1); - /* Start write to GRAM */ + lcd_write_cmd(R_WRITE_DATA_2_GRAM); lcd_write_yuv420_lines(yuv_src, width, stride); @@ -324,23 +406,8 @@ void lcd_blit_yuv(unsigned char * const src[3], yuv_src[2] += stride >> 1; y += 2; } - while (--height > 0); + while (--height > 0); } - - lcd_busy = false; -} - -void lcd_init_device() -{ - as3525_dbop_init(); - - GPIOA_DIR |= (1<<5|1<<4|1<<3); - GPIOA_PIN(5) = 0; - GPIOA_PIN(3) = (1<<3); - GPIOA_PIN(4) = 0; - GPIOA_PIN(5) = (1<<5); - - _display_on(); } /* Update the display. @@ -350,31 +417,25 @@ void lcd_update(void) if (!display_on) return; - lcd_busy = true; - - lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); + lcd_write_reg(R_ENTRY_MODE, r_entry_mode); lcd_window_x(0, LCD_WIDTH - 1); lcd_window_y(0, LCD_HEIGHT - 1); - /* Start write to GRAM */ lcd_write_cmd(R_WRITE_DATA_2_GRAM); - /* Write data */ - lcd_write_data((unsigned short *)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); - lcd_busy = false; + lcd_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); } /* Update a fraction of the display. */ void lcd_update_rect(int x, int y, int width, int height) { - int xmax, ymax; const fb_data *ptr; + int xmax, ymax; if (!display_on) return; - xmax = x + width; if (xmax >= LCD_WIDTH) xmax = LCD_WIDTH - 1; /* Clip right */ @@ -393,14 +454,11 @@ void lcd_update_rect(int x, int y, int width, int height) if (y >= ymax) return; /* nothing left to do */ - lcd_busy = true; - - lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); + lcd_write_reg(R_ENTRY_MODE, r_entry_mode); lcd_window_x(x, xmax); lcd_window_y(y, ymax); - /* Start write to GRAM */ lcd_write_cmd(R_WRITE_DATA_2_GRAM); ptr = &lcd_framebuffer[y][x]; @@ -412,23 +470,4 @@ void lcd_update_rect(int x, int y, int width, int height) ptr += LCD_WIDTH; } while (--height >= 0); - lcd_busy = false; -} - -/* writes one read pixel outside the visible area, needed for correct dbop reads */ -bool lcd_button_support(void) -{ - fb_data data = 0xf<<12; - if (lcd_busy) - return false; - lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); - /* 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(data); - - return true; } diff --git a/firmware/target/arm/lcd-c200_c200v2.c b/firmware/target/arm/lcd-c200_c200v2.c index 62f1dc2..45a37d9 100644 --- a/firmware/target/arm/lcd-c200_c200v2.c +++ b/firmware/target/arm/lcd-c200_c200v2.c @@ -25,11 +25,8 @@ #include "lcd.h" #include "kernel.h" #include "system.h" - #ifdef SANSA_C200V2 -/* button driver needs to know if a lcd operation is in progress */ -static bool lcd_busy = false; -static unsigned short dbop_input = 0xFFFF; +#include "dbop-as3525.h" #endif /* Display status */ @@ -183,45 +180,6 @@ static inline void as3525_dbop_init(void) 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 /* LCD init */ @@ -292,13 +250,7 @@ int lcd_default_contrast(void) void lcd_set_contrast(int val) { -#ifdef SANSA_C200V2 - lcd_busy = true; -#endif lcd_send_command(R_CONTRAST_CONTROL1, val); -#ifdef SANSA_C200V2 - lcd_busy = false; -#endif } void lcd_set_invert_display(bool yesno) @@ -313,9 +265,6 @@ void lcd_enable(bool yesno) if (yesno == is_lcd_enabled) return; -#ifdef SANSA_C200V2 - lcd_busy = true; -#endif if ((is_lcd_enabled = yesno)) { lcd_send_command(R_STANDBY_OFF, 0); @@ -326,9 +275,6 @@ void lcd_enable(bool yesno) { lcd_send_command(R_STANDBY_ON, 0); } -#ifdef SANSA_C200V2 - lcd_busy = false; -#endif } #endif @@ -343,18 +289,12 @@ bool lcd_active(void) /* turn the display upside down (call lcd_update() afterwards) */ void lcd_set_flip(bool yesno) { -#ifdef SANSA_C200V2 - lcd_busy = true; -#endif lcd_send_command(R_DRIVER_OUTPUT_MODE, yesno ? 0x02 : 0x07); -#ifdef SANSA_C200V2 - lcd_busy = false; -#endif } /*** update functions ***/ -#if MEMORYSIZE > 2 +#if MEMORYSIZE > 2 /* not for C200V2 */ void lcd_yuv_set_options(unsigned 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]; -#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) { /* 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 @@ -476,8 +410,4 @@ void lcd_update_rect(int x, int y, int width, int height) lcd_write_data(addr, width); addr += LCD_WIDTH; } while (--height > 0); - -#ifdef SANSA_C200V2 - lcd_busy = false; -#endif }