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:
parent
8e8e2627b2
commit
57667c51cf
9 changed files with 162 additions and 320 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
77
firmware/target/arm/as3525/dbop-as3525.c
Normal file
77
firmware/target/arm/as3525/dbop-as3525.c
Normal 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;
|
||||||
|
}
|
23
firmware/target/arm/as3525/dbop-as3525.h
Normal file
23
firmware/target/arm/as3525/dbop-as3525.h
Normal 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);
|
|
@ -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]");
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue