summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--firmware/drivers/lcd-player.c30
-rw-r--r--firmware/export/lcd.h1
-rw-r--r--firmware/target/sh/archos/player/lcd-as-player.S160
3 files changed, 112 insertions, 79 deletions
diff --git a/firmware/drivers/lcd-player.c b/firmware/drivers/lcd-player.c
index c863c9f188..dd99246611 100644
--- a/firmware/drivers/lcd-player.c
+++ b/firmware/drivers/lcd-player.c
@@ -106,8 +106,6 @@ unsigned short buffer_lcd_mirror[11][2];
#ifdef SIMULATOR
unsigned char hardware_buffer_lcd[11][2];
-#else
-static unsigned char lcd_data_byte; /* global write buffer */
#endif
#define NO_CHAR -1
@@ -133,8 +131,7 @@ static void lcd_free_pat(int map_ch)
#ifdef SIMULATOR
hardware_buffer_lcd[x][y]=substitute_char;
#else
- lcd_write_command(LCD_CURSOR(x, y));
- lcd_write_data(&substitute_char, 1);
+ lcd_write_command_e(LCD_CURSOR(x, y), substitute_char);
#endif
}
}
@@ -231,8 +228,7 @@ void xlcd_update(void)
#ifdef SIMULATOR
hardware_buffer_lcd[x][y]=hw_ch;
#else
- lcd_write_command(LCD_CURSOR(x,y));
- lcd_write_data(&hw_ch, 1);
+ lcd_write_command_e(LCD_CURSOR(x,y), hw_ch);
#endif
}
}
@@ -265,9 +261,7 @@ bool lcdx_putc(int x, int y, unsigned short ch)
#ifdef SIMULATOR
hardware_buffer_lcd[x][y]=lcd_char;
#else
- lcd_data_byte = (unsigned char) lcd_char;
- lcd_write_command(LCD_CURSOR(x, y));
- lcd_write_data(&lcd_data_byte, 1);
+ lcd_write_command_e(LCD_CURSOR(x, y), lcd_char);
#endif
return false;
}
@@ -450,15 +444,13 @@ void lcd_icon(int icon, bool enable)
pos = icon_pos[icon];
mask = icon_mask[icon];
-
- lcd_write_command(LCD_ICON(pos));
-
+
if(enable)
icon_mirror[pos] |= mask;
else
icon_mirror[pos] &= ~mask;
- lcd_write_data(&icon_mirror[pos], 1);
+ lcd_write_command_e(LCD_ICON(pos), icon_mirror[pos]);
}
int lcd_default_contrast(void)
@@ -468,9 +460,7 @@ int lcd_default_contrast(void)
void lcd_set_contrast(int val)
{
- lcd_data_byte = (unsigned char) (31 - val);
- lcd_write_command(lcd_contrast_set);
- lcd_write_data(&lcd_data_byte, 1);
+ lcd_write_command_e(lcd_contrast_set, 31 - val);
}
#endif /* SIMULATOR */
@@ -500,9 +490,7 @@ void lcd_init (void)
or_b(0x0f, &PBDRL); /* ... and high */
lcd_write_command(NEW_LCD_FUNCTION_SET + 1); /* CGRAM selected */
- lcd_write_command(NEW_LCD_CONTRAST_SET);
- lcd_data_byte = 0x08;
- lcd_write_data(&lcd_data_byte, 1);
+ lcd_write_command_e(NEW_LCD_CONTRAST_SET, 0x08);
lcd_write_command(NEW_LCD_POWER_SAVE_MODE_OSC_CONTROL_SET + 2);
/* oscillator on */
lcd_write_command(NEW_LCD_POWER_CONTROL_REGISTER_SET + 7);
@@ -599,9 +587,7 @@ void lcd_init (void)
for (i=0; i<300000; i++) asm volatile ("nop"); /* wait 150 ms */
lcd_write_command(0x31);
- lcd_write_command(0xa8); /* Set contrast control */
- lcd_data_byte = 0;
- lcd_write_data(&lcd_data_byte, 1); /* 0 */
+ lcd_write_command_e(0xa8, 0); /* Set contrast control */
}
#endif
#endif /* !SIMULATOR */
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index c4edc478de..cb5ab1dad4 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -46,6 +46,7 @@ typedef unsigned long fb_data;
/* common functions */
extern void lcd_write_command(int byte);
+extern void lcd_write_command_e(int cmd, int data);
extern void lcd_write_command_ex(int cmd, int data1, int data2);
extern void lcd_write_data(const fb_data* p_bytes, int count);
extern void lcd_init(void);
diff --git a/firmware/target/sh/archos/player/lcd-as-player.S b/firmware/target/sh/archos/player/lcd-as-player.S
index 7a6324865f..8dc1219e62 100644
--- a/firmware/target/sh/archos/player/lcd-as-player.S
+++ b/firmware/target/sh/archos/player/lcd-as-player.S
@@ -69,30 +69,76 @@
/* Write a command byte to the lcd controller
*
* Arguments:
- * r4 - data byte (int)
+ * r4 - command byte (int)
*
* Register usage:
* r0 - scratch
- * r1 - data byte (copied)
+ * r1 - command byte (copied)
* r2 - precalculated port value (CS, DS and SC low, SD high)
* r3 - lcd port address
* r5 - 1 (byte count for reuse of the loop in _lcd_write_data)
*/
_lcd_write_command:
- mov.l .lcdr,r3 /* put lcd data port address in r3 */
- mov r4,r1 /* copy data byte to r1 */
- mov #1,r5 /* set byte count to 1 (!) */
+ mov.l .lcdr, r3 /* put lcd data port address in r3 */
+ mov r4, r1 /* copy data byte to r1 */
+ mov #1, r5 /* set byte count to 1 (!) */
/* This code will fail if an interrupt changes the contents of PBDRL.
* If so, we must disable the interrupt here. */
- mov.b @r3,r0 /* r0 = PBDRL */
- or #(LCD_SD),r0 /* r0 |= LCD_SD */
+ mov.b @r3, r0 /* r0 = PBDRL */
+ or #(LCD_SD), r0 /* r0 |= LCD_SD */
and #(~(LCD_CS|LCD_DS|LCD_SC)),r0 /* r0 &= ~(LCD_CS|LCD_DS|LCD_SC) */
bra .single_transfer /* jump into the transfer loop */
- mov r0,r2
+ mov r0, r2
+
+
+ .align 2
+ .global _lcd_write_command_e
+ .type _lcd_write_command_e,@function
+
+/* Write a command byte and a data byte to the lcd controller
+ *
+ * Arguments:
+ * r4 - command byte
+ * r5 - data byte
+ *
+ * Register usage:
+ * r0 - scratch
+ * r1 - command/data byte (copied)
+ * r2 - precalculated port value (CS, DS and SC low, SD high)
+ * r3 - lcd port address
+ * r5 - 1 (byte count for reuse of the loop in _lcd_write_data)
+ * r6 - data byte (saved)
+ * r7 - saved pr
+ */
+
+_lcd_write_command_e:
+ mov.l .lcdr, r3 /* put lcd data port address in r3 */
+ mov r4, r1 /* copy data byte to r1 */
+ mov r5, r6
+ mov #1, r5 /* set byte count to 1 (!) */
+
+ /* This code will fail if an interrupt changes the contents of PBDRL.
+ * If so, we must disable the interrupt here. */
+
+ mov.b @r3, r0 /* r0 = PBDRL */
+ or #(LCD_SD), r0 /* r0 |= LCD_SD */
+ and #(~(LCD_CS|LCD_DS|LCD_SC)),r0 /* r0 &= ~(LCD_CS|LCD_DS|LCD_SC) */
+
+ sts pr, r7
+ bsr .single_transfer /* jump into the transfer loop */
+ mov r0, r2
+
+ lds r7, pr
+ mov r6, r1
+ mov #1, r5 /* set byte count to 1 (!) */
+ or #(LCD_DS|LCD_SD), r0 /* r0 |= LCD_DS|LCD_SD */
+ and #(~(LCD_CS|LCD_SC)), r0 /* r0 &= ~(LCD_CS|LCD_SC) */
+ bra .single_transfer /* jump into the transfer loop */
+ mov r0, r2
.align 2
@@ -116,7 +162,7 @@ _lcd_write_command:
*/
_lcd_write_data:
- mov.l .lcdr,r3 /* put lcd data port address in r3 */
+ mov.l .lcdr, r3 /* put lcd data port address in r3 */
nop /* align here */
/* This code will fail if an interrupt changes the contents of PBDRL.
@@ -126,98 +172,98 @@ _lcd_write_data:
* disable/precalculate/transfer/enable for each iteration. However,
* this would significantly decrease performance. */
- mov.b @r3,r0 /* r0 = PBDRL */
- or #(LCD_DS|LCD_SD),r0 /* r0 |= LCD_DS|LCD_SD */
- and #(~(LCD_CS|LCD_SC)),r0 /* r0 &= ~(LCD_CS|LCD_SC) */
- mov r0,r2
+ mov.b @r3, r0 /* r0 = PBDRL */
+ or #(LCD_DS|LCD_SD), r0 /* r0 |= LCD_DS|LCD_SD */
+ and #(~(LCD_CS|LCD_SC)), r0 /* r0 &= ~(LCD_CS|LCD_SC) */
+ mov r0, r2
.align 2
.multi_transfer:
- mov.b @r4+,r1 /* load data byte from memory */
+ mov.b @r4+, r1 /* load data byte from memory */
.single_transfer:
shll16 r1 /* shift data to most significant byte */
shll8 r1
shll r1 /* shift the msb into carry */
- mov r2,r0 /* copy precalculated port value */
+ mov r2, r0 /* copy precalculated port value */
bt 1f /* data bit = 1? */
- and #(~LCD_SD),r0 /* no: r0 &= ~LCD_SD */
+ and #(~LCD_SD), r0 /* no: r0 &= ~LCD_SD */
1:
shll r1 /* next shift here for alignment */
- mov.b r0,@r3 /* set data to port */
- or #(LCD_SC),r0 /* rise SC (independent of SD level) */
- mov.b r0,@r3 /* set to port */
+ mov.b r0, @r3 /* set data to port */
+ or #(LCD_SC), r0 /* rise SC (independent of SD level) */
+ mov.b r0, @r3 /* set to port */
- mov r2,r0
+ mov r2, r0
bt 1f
- and #(~LCD_SD),r0
+ and #(~LCD_SD), r0
1:
- mov.b r0,@r3
- or #(LCD_SC),r0
- mov.b r0,@r3
+ mov.b r0, @r3
+ or #(LCD_SC), r0
+ mov.b r0, @r3
shll r1
- mov r2,r0
+ mov r2, r0
bt 1f
- and #(~LCD_SD),r0
+ and #(~LCD_SD), r0
1:
shll r1
- mov.b r0,@r3
- or #(LCD_SC),r0
- mov.b r0,@r3
+ mov.b r0, @r3
+ or #(LCD_SC), r0
+ mov.b r0, @r3
- mov r2,r0
+ mov r2, r0
bt 1f
- and #(~LCD_SD),r0
+ and #(~LCD_SD), r0
1:
- mov.b r0,@r3
- or #(LCD_SC),r0
- mov.b r0,@r3
+ mov.b r0, @r3
+ or #(LCD_SC), r0
+ mov.b r0, @r3
shll r1
- mov r2,r0
+ mov r2, r0
bt 1f
- and #(~LCD_SD),r0
+ and #(~LCD_SD), r0
1:
shll r1
- mov.b r0,@r3
- or #(LCD_SC),r0
- mov.b r0,@r3
+ mov.b r0, @r3
+ or #(LCD_SC), r0
+ mov.b r0, @r3
- mov r2,r0
+ mov r2, r0
bt 1f
- and #(~LCD_SD),r0
+ and #(~LCD_SD), r0
1:
- mov.b r0,@r3
- or #(LCD_SC),r0
- mov.b r0,@r3
+ mov.b r0, @r3
+ or #(LCD_SC), r0
+ mov.b r0, @r3
shll r1
- mov r2,r0
+ mov r2, r0
bt 1f
- and #(~LCD_SD),r0
+ and #(~LCD_SD), r0
1:
shll r1
- mov.b r0,@r3
- or #(LCD_SC),r0
- mov.b r0,@r3
+ mov.b r0, @r3
+ or #(LCD_SC), r0
+ mov.b r0, @r3
- mov r2,r0
+ mov r2, r0
bt 1f
- and #(~LCD_SD),r0
+ and #(~LCD_SD), r0
1:
- mov.b r0,@r3
- or #(LCD_SC),r0
- mov.b r0,@r3
+ mov.b r0, @r3
+ or #(LCD_SC), r0
+ mov.b r0, @r3
- add #-1,r5 /* decrease byte count */
- tst r5,r5 /* r5 == 0 ? */
+ add #-1, r5 /* decrease byte count */
+ tst r5, r5 /* r5 == 0 ? */
bf .multi_transfer /* no: next iteration */
or #(LCD_CS|LCD_DS|LCD_SD|LCD_SC),r0 /* restore port */
rts
- mov.b r0,@r3
+ mov.b r0, @r3
/* This is the place to reenable the interrupts, if we have disabled
* them. See above. */