diff --git a/firmware/export/config/sansafuzev2.h b/firmware/export/config/sansafuzev2.h
index a6c2264..75cdcd2 100644
--- a/firmware/export/config/sansafuzev2.h
+++ b/firmware/export/config/sansafuzev2.h
@@ -47,7 +47,7 @@
#define HAVE_TAGCACHE

/* define this if you have LCD enable function */
-//#define HAVE_LCD_ENABLE
+#define HAVE_LCD_ENABLE

/* Define this if your LCD can be put to sleep. HAVE_LCD_ENABLE
should be defined as well.
@@ -148,13 +148,13 @@
#define BATTERY_TYPES_COUNT 1 /* only one type */

/* Charging implemented in a target-specific algorithm */
-#define CONFIG_CHARGING 0
+#define CONFIG_CHARGING CHARGING_TARGET

/* define this if the unit can be powered or charged via USB */
#define HAVE_USB_POWER

-/* Define this if you have an AMS AS3525*/
-#define CONFIG_CPU AS3525
+/* Define this if you have an AMS AS3525v2 */
+#define CONFIG_CPU AS3525v2

/* Define how much SD sectors are reserved for OF */
#define AMS_OF_SIZE 0xF000
diff --git a/firmware/target/arm/as3525/fmradio-i2c-as3525.c b/firmware/target/arm/as3525/fmradio-i2c-as3525.c
index 622f339..64c04a5 100644
--- a/firmware/target/arm/as3525/fmradio-i2c-as3525.c
+++ b/firmware/target/arm/as3525/fmradio-i2c-as3525.c
@@ -49,7 +49,7 @@
#define I2C_SCL_PIN 7
#define I2C_SDA_PIN 6

-#elif defined(SANSA_FUZE) || defined(SANSA_E200V2)
+#elif defined(SANSA_FUZE) || defined(SANSA_E200V2) || defined(SANSA_FUZEV2)
#define I2C_GPIO(x) GPIOA_PIN(x)
#define I2C_GPIO_DIR GPIOA_DIR
#define I2C_SCL_PIN 6
diff --git a/firmware/target/arm/as3525/powermgmt-target.h b/firmware/target/arm/as3525/powermgmt-target.h
index 5460aba..511bcc7 100644
--- a/firmware/target/arm/as3525/powermgmt-target.h
+++ b/firmware/target/arm/as3525/powermgmt-target.h
@@ -50,7 +50,7 @@
#define CHARGER_TOTAL_TIMER (4*3600*2)
#define ADC_BATTERY ADC_BVDD

-#elif defined(SANSA_FUZE)
+#elif defined(SANSA_FUZE) || defined(SANSA_FUZEV2) /* FIXME */

/* Check if topped-off and monitor voltage while plugged. */
#define BATT_FULL_VOLTAGE 4160
diff --git a/firmware/target/arm/as3525/sansa-fuzev2/backlight-fuzev2.c b/firmware/target/arm/as3525/sansa-fuzev2/backlight-fuzev2.c
index 56b375b..ed31e44 100644
--- a/firmware/target/arm/as3525/sansa-fuzev2/backlight-fuzev2.c
+++ b/firmware/target/arm/as3525/sansa-fuzev2/backlight-fuzev2.c
@@ -45,6 +45,8 @@ bool _backlight_init(void)
{
GPIOB_DIR |= 1<<5; /* for buttonlight, stuff below seems to be needed
for buttonlight as well*/
+
+ ascodec_write(0x25, ascodec_read(0x25) | 2); /* lcd power */
ascodec_write(0x1c, 8|1);
ascodec_write(27, 0xff);
return true;
@@ -66,11 +68,14 @@ void _backlight_on(void)
/* not functional */
void _backlight_off(void)
{
+#if 0
ascodec_write(0x1c, 0);
+ ascodec_write(0x25, ascodec_read(0x25) | ~2); /* lcd power */
ascodec_write(27, 0);
#ifdef HAVE_LCD_ENABLE
lcd_enable(false); /* power off visible display */
#endif
+#endif
}

void _buttonlight_on(void)
@@ -84,3 +89,36 @@ void _buttonlight_off(void)
GPIOB_PIN(5) = 0;
buttonlight_is_on = 0;
}
+
+void blink(int n)
+{
+ while(n--)
+ {
+ int i = 8;
+ while(i--)
+ {
+ if(i&1) _buttonlight_on();
+ else _buttonlight_off();
+ int delay = 0x10000;
+ while(delay--);
+ }
+ }
+}
+
+static void show(unsigned char c)
+{
+ blink(1);
+ if(c) blink(1);
+
+ int delay = 0x100000;
+ while(delay--);
+}
+
+void show_hword(unsigned short x)
+{
+ while(x)
+ {
+ show(x & 1);
+ x >>= 1;
+ }
+}
diff --git a/firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c b/firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c
index 4a5948a..b52a8c4 100644
--- a/firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c
+++ b/firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c
@@ -127,8 +127,16 @@ static void as3525_dbop_init(void)

/* TODO: The OF calls some other functions here, but maybe not important */
#endif
- REG(0xC810000C) |= 0x1000; /* CCU_IO |= 1<<12 */
- CGU_DBOP |= /*(1<<3)*/ 0x18 | AS3525_DBOP_DIV;
+ GPIOB_AFSEL = 0xfc;
+ GPIOC_AFSEL = 0xff;
+
+ GPIOB_DIR |= 1<<4;
+ GPIOB_PIN(4) = 1<<4;
+
+ CCU_IO |= 0x1000; /* CCU_IO |= 1<<12 */
+
+ CGU_DBOP = (1<<4) /* ? */ | (1<<3) | AS3525_DBOP_DIV;
+
DBOP_TIMPOL_01 = 0xE12FE12F;
DBOP_TIMPOL_23 = 0xE12F0036;
DBOP_CTRL = 0x41004;
@@ -136,9 +144,11 @@ static void as3525_dbop_init(void)
DBOP_CTRL = 0x51004;
DBOP_TIMPOL_01 = 0x60036;
DBOP_TIMPOL_23 = 0xA12FE037;
+
/* OF sets up dma and more after here */
}

+#if 0
static inline void dbop_set_mode(int mode)
{
int delay = 10;
@@ -185,8 +195,15 @@ static void dbop_write_data(const int16_t* p_bytes, int count)
if (count > 0)
dbop_write_data((int16_t*)data, 1);
}
+#endif
+
+static void lcd_write_pixel(unsigned short value)
+{
+ DBOP_DOUT = swap16(value);
+ while ((DBOP_STAT & (1<<10)) == 0);
+}

-static void lcd_write_cmd(short cmd)
+static void lcd_write_cmd(unsigned short cmd)
{
#if 0
/* Write register */
@@ -198,20 +215,19 @@ static void lcd_write_cmd(short cmd)
DBOP_TIMPOL_23 = 0xa167e06f;
#elif 1
volatile int i;
- for(i=0;i<20;i++) nop;
+ for(i=0;i<0x20;i++) asm volatile ("nop\n");

int r3 = 0x2000;
- DBOP_CTRL |= r3;
+ DBOP_CTRL |= r3; //2 serial words
r3 >>= 1;
- DBOP_CTRL &= ~r3;
+ DBOP_CTRL &= ~r3; // 8 bit data width
r3 <<= 2;
- DBOP_CTRL &= ~r3;
+ DBOP_CTRL &= ~r3; //2 serial words
DBOP_TIMPOL_23 = 0xA12F0036;
- cmd = swap16(cmd);
- DBOP_DOUT16 = cmd;
+ DBOP_DOUT = swap16(cmd);

while ((DBOP_STAT & (1<<10)) == 0);
- for(i=0;i<20;i++) nop;
+ for(i=0;i<0x20;i++) asm volatile ("nop\n");
DBOP_TIMPOL_23 = 0xA12FE037;
#else
int i;
@@ -225,9 +241,8 @@ static void lcd_write_cmd(short cmd)

static void lcd_write_reg(int reg, int value)
{
- int16_t data = value;
- lcd_write_cmd(reg);
- dbop_write_data(&data, 1);
+ lcd_write_cmd((unsigned short)reg);
+ lcd_write_pixel((unsigned short)value);
}

/*** hardware configuration ***/
@@ -262,21 +277,109 @@ void lcd_set_flip(bool yesno)
}
#endif

+
+static char gpioa4 = 0;
+#if 0
+static void init_gpio(void)
+{
+ GPIOB_DIR |= 1<<4;
+ GPIOB_PIN(4) = 4;
+
+ GPIOA_DIR &= ~(1<<4);
+ gpioa4 = GPIOA_PIN(4);
+
+}
+#endif
+
+static void GPIOA3_toggle_dir_clear_pin(int input)
+{
+ if (input)
+ GPIOA_DIR &= ~(1<<3);
+ else
+ GPIOA_DIR |= (1<<3);
+
+ GPIOA_PIN(3) = 0;
+}
+
+static unsigned char dbop_read(void)
+{
+ DBOP_CTRL &= ~(1<<16); // not write
+ DBOP_TIMPOL_01 = 0xE12F0036;
+ DBOP_TIMPOL_23 = 0xA12FE037;
+ DBOP_CTRL |= 1<<15; // start read
+ while(!(DBOP_STAT & 1<<16)) ; // wait data valid
+ unsigned char ret = (*(volatile unsigned char*)(DBOP_BASE + 0x14));
+ DBOP_CTRL |= 1<<16; // write
+ DBOP_TIMPOL_01 = 0x60036;
+ DBOP_TIMPOL_23 = 0xA12FE037;
+ return ret;
+}
+
+static void ssp_format(bool fmt)
+{
+ (void)SSP_CR0;
+ SSP_CR1 &= ~(1<<0); // normal serial port enabled
+ SSP_CR0 = fmt ? 0x648F : 3; // 16 bits + divider (serial clk) : 4bit
+ SSP_CR1 = 1<<1; //op enable;
+}
+
+#if 1 //defined(HAVE_LCD_ENABLE)
+void lcd_enable(bool on)
+{
+ if (display_on == on)
+ return;
+
+ if(on)
+ {
+ lcd_write_reg(R_START_OSC, 1);
+ sleep(1);
+ lcd_write_reg(R_POWER_CONTROL1, 0);
+ lcd_write_reg(R_POWER_CONTROL2, 0x3704);
+ lcd_write_reg(0x14, 0x1a1b);
+ lcd_write_reg(R_POWER_CONTROL1, 0x3860);
+ lcd_write_reg(R_POWER_CONTROL4, 0x40);
+ sleep(1);
+ lcd_write_reg(R_POWER_CONTROL4, 0x60);
+ sleep(5);
+ lcd_write_reg(R_POWER_CONTROL4, 0x70);
+ sleep(4);
+ lcd_write_reg(R_DISP_CONTROL1, 0x11);
+ sleep(4);
+ lcd_write_reg(R_DISP_CONTROL1, 0x13 | r_disp_control_rev);
+ display_on = true;
+ //lcd_update(); /* Resync display */
+ //send_event(LCD_EVENT_ACTIVATION, NULL);
+ sleep(0);
+
+ }
+ else
+ {
+ lcd_write_reg(R_DISP_CONTROL1, 0x22);
+ lcd_write_reg(R_DISP_CONTROL1, 0);
+ lcd_write_reg(R_POWER_CONTROL1, 1);
+ display_on = false;
+ }
+}
+#endif
static void _display_on(void)
{
/* Initialise in the same way as the original firmare */
-
+#if 1
lcd_write_reg(R_DISP_CONTROL1, 0);
lcd_write_reg(R_POWER_CONTROL4, 0);
+ sleep(1);

lcd_write_reg(R_POWER_CONTROL2, 0x3704);
lcd_write_reg(0x14, 0x1a1b);
lcd_write_reg(R_POWER_CONTROL1, 0x3860);
lcd_write_reg(R_POWER_CONTROL4, 0x40);
+ sleep(1);

lcd_write_reg(R_POWER_CONTROL4, 0x60);
+ sleep(1);

lcd_write_reg(R_POWER_CONTROL4, 0x70);
+ sleep(1);
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);
@@ -304,67 +407,164 @@ static void _display_on(void)
lcd_write_reg(0x48, 0x0);

lcd_write_reg(R_DISP_CONTROL1, 0x11);
+ sleep(4);
+#else
+ lcd_write_reg(0x80, 0x8d);
+ lcd_write_reg(0x92, 0x10);
+ lcd_write_reg(0x15, 0x0);
+ lcd_write_reg(0x7, 0x12);
+ sleep(1);
+ lcd_write_reg(0x7, 0);
+ lcd_write_reg(0x11, 0x1b);
+ lcd_write_reg(0x12, 0x101);
+ lcd_write_reg(0x13, 0x66);
+ lcd_write_reg(0x14, 0x4656);
+ lcd_write_reg(0x10, 0x800);
+ sleep(2);
+ lcd_write_reg(0x11, 0x11b);
+ sleep(2);
+ lcd_write_reg(0x11, 0x306+0x15);
+ sleep(2);
+ lcd_write_reg(0x11, 0x687+0x94);
+ sleep(2);
+ lcd_write_reg(0x11, 0xf1b);
+ sleep(4);
+ lcd_write_reg(0x11, 0xf1b+0x20);
+ sleep(6);
+ lcd_write_reg(0x1, 0x116);
+ lcd_write_reg(0x2, 0x100);
+ lcd_write_reg(0x3, 0x1030);
+ lcd_write_reg(0x7, 0x1030-0x1e);
+ lcd_write_reg(0x8, 0x808);
+ lcd_write_reg(0xb, 0x1030+0xd5);
+ lcd_write_reg(0xc, 0x0);
+ lcd_write_reg(0xf, 0x1a1b-0x1a);
+ sleep(2);
+ lcd_write_reg(0x15, 0x70);
+ lcd_write_reg(0x30, 0x0);
+ lcd_write_reg(0x34, 0xaf);
+ lcd_write_reg(0x35, 0x0);
+ lcd_write_reg(0x36, 0xe5);
+ lcd_write_reg(0x37, 0xa);
+ lcd_write_reg(0x38, 0xaf);
+ lcd_write_reg(0x39, 0x0);
+ lcd_write_reg(0x50, 0x101);
+ lcd_write_reg(0x51, 0x500);
+ lcd_write_reg(0x52, 0x500);
+ lcd_write_reg(0x53, 1 << 10); //
+ lcd_write_reg(0x54, 0x808-3);
+ lcd_write_reg(0x55, 0x9);
+ lcd_write_reg(0x56, 0xf00);
+ lcd_write_reg(0x57, 0xb);
+ lcd_write_reg(0x58, 0x0);
+ lcd_write_reg(0x59, 0x2);
+ lcd_write_reg(0x7, 0x12);
+ sleep(1);
+ lcd_write_reg(0x7, 0x13);
+#endif
lcd_write_reg(R_DISP_CONTROL1, 0x13 | r_disp_control_rev);

- display_on = true; /* must be done before calling lcd_update() */
+ display_on = false;
+ lcd_enable(true);
lcd_update();
}
-
+void show_hword(unsigned short);
void lcd_init_device(void)
{
as3525_dbop_init();

- GPIOA_DIR |= (0x20|0x1);
- GPIOA_DIR &= ~(1<<3);
- GPIOA_PIN(3) = 0;
- GPIOA_PIN(0) = 1;
- GPIOA_PIN(4) = 0;
+ GPIOA_DIR |= 1<<5;
+ GPIOA_DIR |= 1<<0;
+ GPIOA_PIN(5) = 0;
+
+ GPIOA3_toggle_dir_clear_pin(1);
+
+ if (gpioa4 == 0)
+ GPIOA_DIR |= 1<<4;
+ else
+ GPIOA_DIR |= 1<<0;
+
+ GPIOA3_toggle_dir_clear_pin(1);
+
+ if (gpioa4)
+ GPIOA_PIN(4) = 0;
+ else
+ GPIOA_PIN(0) = 0;
+
+ GPIOA_DIR |= 1<<0;
+ GPIOA_PIN(0) = 0;
+
+ GPIOB_DIR |= 1<<5;
+
+ /* mess with ssp and gpiob */
+ CGU_PERI |= CGU_SSP_CLOCK_ENABLE;
+ SSP_IMSC = 0; /* No interrupts */
+#if 0
+ SSP_CPSR = AS3525_SSP_PRESCALER; /* OF = 0x10 */
+#else
+ SSP_CPSR = 2; /* 32MHz */
+#endif
+ ssp_format(false);
+
+ /* */
+ GPIOB_PIN(6) = 1<<6;
+ GPIOB_DIR |= 1<<6;
+ GPIOB_PIN(6) = 1<<6;
+
+ //bool
+ SSP_DATA = 0;
+ SSP_DATA;

CCU_IO &= ~(0x1000);
- GPIOB_DIR |= 0x2f;
+
+ GPIOB_DIR |= 0xf;
GPIOB_PIN(0) = 1<<0;
GPIOB_PIN(1) = 1<<1;
GPIOB_PIN(2) = 1<<2;
GPIOB_PIN(3) = 1<<3;
- GPIOA_PIN(4) = 1<<4;
- GPIOA_PIN(5) = 1<<5;

- _display_on();
-}
-
-#if defined(HAVE_LCD_ENABLE)
-void lcd_enable(bool on)
-{
- if (display_on == on)
- return;
-
- if(on)
+ if (gpioa4)
{
- 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(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, 0x13 | r_disp_control_rev);
- display_on = true;
- lcd_update(); /* Resync display */
- send_event(LCD_EVENT_ACTIVATION, NULL);
- sleep(0);
-
+ GPIOA_DIR |= 0x10;
+ GPIOA_PIN(4) = 1<<4;
}
else
{
- lcd_write_reg(R_DISP_CONTROL1, 0x22);
- lcd_write_reg(R_DISP_CONTROL1, 0);
- lcd_write_reg(R_POWER_CONTROL1, 1);
- display_on = false;
+ GPIOA_DIR |= 1<<0;
+ GPIOA_PIN(0) = 1;
}
+
+ sleep(1);
+
+ GPIOA_PIN(5) = 1<<5;
+
+ sleep(1);
+
+ //
+ GPIOA_PIN(0) = 1<<0;
+ lcd_write_cmd(0);
+ ssp_format(true);
+ SSP_DATA = 0xffff;
+ SSP_DATA = 0xffff;
+ GPIOA_PIN(0) = 0;
+ volatile int i = 24;
+ while(i--) asm volatile("nop");
+ unsigned short val = (dbop_read() << 8) | dbop_read();
+ val -= 340;
+ if(val == 0)
+ panicf("OTHER LCD");
+ SSP_DATA = 0;
+ SSP_DATA = 0;
+ ssp_format(false);
+ GPIOA_PIN(0) = 1<<0;
+ //show_hword(val);
+ //sleep(HZ);
+
+ CCU_IO |= 0x1000;
+
+ _display_on();
}
-#endif
+

#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
bool lcd_active(void)
@@ -490,13 +690,18 @@ void lcd_update(void)

lcd_write_cmd(R_WRITE_DATA_2_GRAM);

- lcd_update_rect(0,0, LCD_WIDTH, LCD_HEIGHT);
- //dbop_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT);
+ int i,j;
+ for(i = 0; i < LCD_FBHEIGHT; i++)
+ for(j = 0; j < LCD_FBWIDTH; j++)
+ lcd_write_pixel(lcd_framebuffer[i][j]);
}

/* Update a fraction of the display. */
void lcd_update_rect(int x, int y, int width, int height)
{
+ lcd_update();
+ return;
+
const fb_data *ptr;

if (!display_on)
@@ -537,7 +742,7 @@ void lcd_update_rect(int x, int y, int width, int height)

do
{
- dbop_write_data(ptr, width);
+ //dbop_write_data(ptr, width);
ptr += LCD_WIDTH;
}
while (--height > 0);