Index: firmware/target/arm/lcd-c200_c200v2.c =================================================================== --- firmware/target/arm/lcd-c200_c200v2.c (revision 22622) +++ firmware/target/arm/lcd-c200_c200v2.c (working copy) @@ -29,6 +29,7 @@ #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; #endif /* Display status */ @@ -171,35 +172,61 @@ DBOP_TIMPOL_23 = 0xe167006e; DBOP_CTRL = 0x40008; - GPIOB_AFSEL = 0xc; - GPIOC_AFSEL = 0xff; + GPIOB_AFSEL = 0xc; /* B7, B6 = DBOP */ + GPIOC_AFSEL = 0xff; /* C7..C0 = DBOP */ DBOP_TIMPOL_23 = 0x6006e; - DBOP_CTRL = 0x52008; - DBOP_TIMPOL_01 = 0x6e167; + DBOP_CTRL = 0x52008; /* sdc/enw/osm=2words/ow=8bit/rs_t=8 */ + DBOP_TIMPOL_01 = 0x0006e167; DBOP_TIMPOL_23 = 0xa167e06f; lcd_delay(20); } -/* we need to set the DBOP_DOUT pins high, for correct dbop reads */ -bool lcd_button_support(void) +static unsigned short lcd_dbop_read(void) { - const fb_data data = 0xffff; + 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); - if (lcd_busy) /* we can't use dbop for reading if we are in the */ - return false; /* middle of a write operation */ + /* write DBOP_DOUT to pre-charge DBOP data lines with a high level */ + DBOP_CTRL = (1 << 19) | /* en_data=1 (tri-state enable) */ + (1 << 18) | /* sdc=1 (short data count) */ + (1 << 16) | /* enw=1 (enable write) */ + (0 << 13) | /* osm=0 (single word out) */ + (1 << 12); /* ow=1 (16-bit data width) */ + DBOP_TIMPOL_23 = 0xe167e167; /* no strobe towards lcd */ + DBOP_DOUT32 = 0xFFFF; /* all pins high */ + while ((DBOP_STAT & (1<<10)) == 0); - /* use out of screen coordinates */ - lcd_send_command(R_X_ADDR_AREA, 0); - lcd_send_command(1, 0); - lcd_send_command(R_Y_ADDR_AREA, 0); - lcd_send_command(1, 0); + /* perform a DBOP read */ + DBOP_CTRL = (1 << 19) | /* en_data=1 (tri-state enable) */ + (1 << 18) | /* sdc=1 (short data count) */ + (1 << 15) | /* strd=1 (start read) */ + (1 << 12) | /* ow=1 (16-bit data width) */ + (15 << 0); /* read strobe time, at end of cycle */ + while ((DBOP_STAT & (1<<16)) == 0); + value = DBOP_DIN; + + /* restore previous values */ + DBOP_CTRL = dbop_ctrl_old; + DBOP_TIMPOL_23 = dbop_timpol23_old; + + return value; +} - lcd_write_data(&data, 1); +/* 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; +} - return true; -} #endif /* LCD init */ @@ -431,6 +458,8 @@ #ifdef SANSA_C200V2 lcd_busy = true; #endif + /* perform a dbop read before doing a potentially lengthy lcd update */ + dbop_input = lcd_dbop_read(); if (width <= 1) { /* The X end address must be larger than the X start address, so we Index: firmware/target/arm/as3525/sansa-c200v2/button-c200v2.c =================================================================== --- firmware/target/arm/as3525/sansa-c200v2/button-c200v2.c (revision 22622) +++ firmware/target/arm/as3525/sansa-c200v2/button-c200v2.c (working copy) @@ -26,10 +26,10 @@ #include "powermgmt.h" -unsigned short _dbop_din = 0; +static unsigned short _dbop_din = 0xFFFF; /* in the lcd driver */ -extern bool lcd_button_support(void); +extern unsigned short int lcd_dbop_input(void); static bool hold_button = false; #ifndef BOOTLOADER @@ -49,29 +49,9 @@ bool button_hold(void) { - return hold_button; + return ((_dbop_din & (1<<12)) == 0); } -static void button_read_dbop(void) -{ - /* 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 */ - - 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 */ -} - /* * Get button pressed from hardware */ @@ -79,13 +59,28 @@ { int btn = BUTTON_NONE; + _dbop_din = lcd_dbop_input(); + + hold_button = button_hold(); + +#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) { + return 0; + } + /* direct GPIO connections */ if (GPIOA_PIN(3)) btn |= BUTTON_POWER; - if(lcd_button_support()) - button_read_dbop(); - + /* DBOP buttons */ if(!(_dbop_din & (1<<2))) btn |= BUTTON_LEFT; if(!(_dbop_din & (1<<3))) @@ -96,15 +91,12 @@ btn |= BUTTON_UP; if(!(_dbop_din & (1<<6))) btn |= BUTTON_RIGHT; + if(!(_dbop_din & (1<<13))) + btn |= BUTTON_VOL_UP; + if(!(_dbop_din & (1<<14))) + btn |= BUTTON_VOL_DOWN; + if(!(_dbop_din & (1<<15))) + btn |= BUTTON_REC; -#ifndef BOOTLOADER - /* light handling */ - if (hold_button != hold_button_old) - { - hold_button_old = hold_button; - backlight_hold_changed(hold_button); - } -#endif /* BOOTLOADER */ - return btn; }