forked from len0rd/rockbox
Archos player: Introduce lcd_write_command_e (only one data byte) in the lcd driver, for cleaner C code.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12835 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
f1bf798b8a
commit
cb1c9e447e
3 changed files with 112 additions and 79 deletions
|
|
@ -106,8 +106,6 @@ unsigned short buffer_lcd_mirror[11][2];
|
||||||
|
|
||||||
#ifdef SIMULATOR
|
#ifdef SIMULATOR
|
||||||
unsigned char hardware_buffer_lcd[11][2];
|
unsigned char hardware_buffer_lcd[11][2];
|
||||||
#else
|
|
||||||
static unsigned char lcd_data_byte; /* global write buffer */
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NO_CHAR -1
|
#define NO_CHAR -1
|
||||||
|
|
@ -133,8 +131,7 @@ static void lcd_free_pat(int map_ch)
|
||||||
#ifdef SIMULATOR
|
#ifdef SIMULATOR
|
||||||
hardware_buffer_lcd[x][y]=substitute_char;
|
hardware_buffer_lcd[x][y]=substitute_char;
|
||||||
#else
|
#else
|
||||||
lcd_write_command(LCD_CURSOR(x, y));
|
lcd_write_command_e(LCD_CURSOR(x, y), substitute_char);
|
||||||
lcd_write_data(&substitute_char, 1);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -231,8 +228,7 @@ void xlcd_update(void)
|
||||||
#ifdef SIMULATOR
|
#ifdef SIMULATOR
|
||||||
hardware_buffer_lcd[x][y]=hw_ch;
|
hardware_buffer_lcd[x][y]=hw_ch;
|
||||||
#else
|
#else
|
||||||
lcd_write_command(LCD_CURSOR(x,y));
|
lcd_write_command_e(LCD_CURSOR(x,y), hw_ch);
|
||||||
lcd_write_data(&hw_ch, 1);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -265,9 +261,7 @@ bool lcdx_putc(int x, int y, unsigned short ch)
|
||||||
#ifdef SIMULATOR
|
#ifdef SIMULATOR
|
||||||
hardware_buffer_lcd[x][y]=lcd_char;
|
hardware_buffer_lcd[x][y]=lcd_char;
|
||||||
#else
|
#else
|
||||||
lcd_data_byte = (unsigned char) lcd_char;
|
lcd_write_command_e(LCD_CURSOR(x, y), lcd_char);
|
||||||
lcd_write_command(LCD_CURSOR(x, y));
|
|
||||||
lcd_write_data(&lcd_data_byte, 1);
|
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -450,15 +444,13 @@ void lcd_icon(int icon, bool enable)
|
||||||
|
|
||||||
pos = icon_pos[icon];
|
pos = icon_pos[icon];
|
||||||
mask = icon_mask[icon];
|
mask = icon_mask[icon];
|
||||||
|
|
||||||
lcd_write_command(LCD_ICON(pos));
|
|
||||||
|
|
||||||
if(enable)
|
if(enable)
|
||||||
icon_mirror[pos] |= mask;
|
icon_mirror[pos] |= mask;
|
||||||
else
|
else
|
||||||
icon_mirror[pos] &= ~mask;
|
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)
|
int lcd_default_contrast(void)
|
||||||
|
|
@ -468,9 +460,7 @@ int lcd_default_contrast(void)
|
||||||
|
|
||||||
void lcd_set_contrast(int val)
|
void lcd_set_contrast(int val)
|
||||||
{
|
{
|
||||||
lcd_data_byte = (unsigned char) (31 - val);
|
lcd_write_command_e(lcd_contrast_set, 31 - val);
|
||||||
lcd_write_command(lcd_contrast_set);
|
|
||||||
lcd_write_data(&lcd_data_byte, 1);
|
|
||||||
}
|
}
|
||||||
#endif /* SIMULATOR */
|
#endif /* SIMULATOR */
|
||||||
|
|
||||||
|
|
@ -500,9 +490,7 @@ void lcd_init (void)
|
||||||
or_b(0x0f, &PBDRL); /* ... and high */
|
or_b(0x0f, &PBDRL); /* ... and high */
|
||||||
|
|
||||||
lcd_write_command(NEW_LCD_FUNCTION_SET + 1); /* CGRAM selected */
|
lcd_write_command(NEW_LCD_FUNCTION_SET + 1); /* CGRAM selected */
|
||||||
lcd_write_command(NEW_LCD_CONTRAST_SET);
|
lcd_write_command_e(NEW_LCD_CONTRAST_SET, 0x08);
|
||||||
lcd_data_byte = 0x08;
|
|
||||||
lcd_write_data(&lcd_data_byte, 1);
|
|
||||||
lcd_write_command(NEW_LCD_POWER_SAVE_MODE_OSC_CONTROL_SET + 2);
|
lcd_write_command(NEW_LCD_POWER_SAVE_MODE_OSC_CONTROL_SET + 2);
|
||||||
/* oscillator on */
|
/* oscillator on */
|
||||||
lcd_write_command(NEW_LCD_POWER_CONTROL_REGISTER_SET + 7);
|
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 */
|
for (i=0; i<300000; i++) asm volatile ("nop"); /* wait 150 ms */
|
||||||
|
|
||||||
lcd_write_command(0x31);
|
lcd_write_command(0x31);
|
||||||
lcd_write_command(0xa8); /* Set contrast control */
|
lcd_write_command_e(0xa8, 0); /* Set contrast control */
|
||||||
lcd_data_byte = 0;
|
|
||||||
lcd_write_data(&lcd_data_byte, 1); /* 0 */
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* !SIMULATOR */
|
#endif /* !SIMULATOR */
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ typedef unsigned long fb_data;
|
||||||
|
|
||||||
/* common functions */
|
/* common functions */
|
||||||
extern void lcd_write_command(int byte);
|
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_command_ex(int cmd, int data1, int data2);
|
||||||
extern void lcd_write_data(const fb_data* p_bytes, int count);
|
extern void lcd_write_data(const fb_data* p_bytes, int count);
|
||||||
extern void lcd_init(void);
|
extern void lcd_init(void);
|
||||||
|
|
|
||||||
|
|
@ -69,30 +69,76 @@
|
||||||
/* Write a command byte to the lcd controller
|
/* Write a command byte to the lcd controller
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* r4 - data byte (int)
|
* r4 - command byte (int)
|
||||||
*
|
*
|
||||||
* Register usage:
|
* Register usage:
|
||||||
* r0 - scratch
|
* r0 - scratch
|
||||||
* r1 - data byte (copied)
|
* r1 - command byte (copied)
|
||||||
* r2 - precalculated port value (CS, DS and SC low, SD high)
|
* r2 - precalculated port value (CS, DS and SC low, SD high)
|
||||||
* r3 - lcd port address
|
* r3 - lcd port address
|
||||||
* r5 - 1 (byte count for reuse of the loop in _lcd_write_data)
|
* r5 - 1 (byte count for reuse of the loop in _lcd_write_data)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
_lcd_write_command:
|
_lcd_write_command:
|
||||||
mov.l .lcdr,r3 /* put lcd data port address in r3 */
|
mov.l .lcdr, r3 /* put lcd data port address in r3 */
|
||||||
mov r4,r1 /* copy data byte to r1 */
|
mov r4, r1 /* copy data byte to r1 */
|
||||||
mov #1,r5 /* set byte count to 1 (!) */
|
mov #1, r5 /* set byte count to 1 (!) */
|
||||||
|
|
||||||
/* This code will fail if an interrupt changes the contents of PBDRL.
|
/* This code will fail if an interrupt changes the contents of PBDRL.
|
||||||
* If so, we must disable the interrupt here. */
|
* If so, we must disable the interrupt here. */
|
||||||
|
|
||||||
mov.b @r3,r0 /* r0 = PBDRL */
|
mov.b @r3, r0 /* r0 = PBDRL */
|
||||||
or #(LCD_SD),r0 /* r0 |= LCD_SD */
|
or #(LCD_SD), r0 /* r0 |= LCD_SD */
|
||||||
and #(~(LCD_CS|LCD_DS|LCD_SC)),r0 /* r0 &= ~(LCD_CS|LCD_DS|LCD_SC) */
|
and #(~(LCD_CS|LCD_DS|LCD_SC)),r0 /* r0 &= ~(LCD_CS|LCD_DS|LCD_SC) */
|
||||||
|
|
||||||
bra .single_transfer /* jump into the transfer loop */
|
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
|
.align 2
|
||||||
|
|
@ -116,7 +162,7 @@ _lcd_write_command:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
_lcd_write_data:
|
_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 */
|
nop /* align here */
|
||||||
|
|
||||||
/* This code will fail if an interrupt changes the contents of PBDRL.
|
/* 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,
|
* disable/precalculate/transfer/enable for each iteration. However,
|
||||||
* this would significantly decrease performance. */
|
* this would significantly decrease performance. */
|
||||||
|
|
||||||
mov.b @r3,r0 /* r0 = PBDRL */
|
mov.b @r3, r0 /* r0 = PBDRL */
|
||||||
or #(LCD_DS|LCD_SD),r0 /* r0 |= LCD_DS|LCD_SD */
|
or #(LCD_DS|LCD_SD), r0 /* r0 |= LCD_DS|LCD_SD */
|
||||||
and #(~(LCD_CS|LCD_SC)),r0 /* r0 &= ~(LCD_CS|LCD_SC) */
|
and #(~(LCD_CS|LCD_SC)), r0 /* r0 &= ~(LCD_CS|LCD_SC) */
|
||||||
mov r0,r2
|
mov r0, r2
|
||||||
|
|
||||||
.align 2
|
.align 2
|
||||||
.multi_transfer:
|
.multi_transfer:
|
||||||
mov.b @r4+,r1 /* load data byte from memory */
|
mov.b @r4+, r1 /* load data byte from memory */
|
||||||
|
|
||||||
.single_transfer:
|
.single_transfer:
|
||||||
shll16 r1 /* shift data to most significant byte */
|
shll16 r1 /* shift data to most significant byte */
|
||||||
shll8 r1
|
shll8 r1
|
||||||
|
|
||||||
shll r1 /* shift the msb into carry */
|
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? */
|
bt 1f /* data bit = 1? */
|
||||||
and #(~LCD_SD),r0 /* no: r0 &= ~LCD_SD */
|
and #(~LCD_SD), r0 /* no: r0 &= ~LCD_SD */
|
||||||
1:
|
1:
|
||||||
shll r1 /* next shift here for alignment */
|
shll r1 /* next shift here for alignment */
|
||||||
mov.b r0,@r3 /* set data to port */
|
mov.b r0, @r3 /* set data to port */
|
||||||
or #(LCD_SC),r0 /* rise SC (independent of SD level) */
|
or #(LCD_SC), r0 /* rise SC (independent of SD level) */
|
||||||
mov.b r0,@r3 /* set to port */
|
mov.b r0, @r3 /* set to port */
|
||||||
|
|
||||||
mov r2,r0
|
mov r2, r0
|
||||||
bt 1f
|
bt 1f
|
||||||
and #(~LCD_SD),r0
|
and #(~LCD_SD), r0
|
||||||
1:
|
1:
|
||||||
mov.b r0,@r3
|
mov.b r0, @r3
|
||||||
or #(LCD_SC),r0
|
or #(LCD_SC), r0
|
||||||
mov.b r0,@r3
|
mov.b r0, @r3
|
||||||
|
|
||||||
shll r1
|
shll r1
|
||||||
mov r2,r0
|
mov r2, r0
|
||||||
bt 1f
|
bt 1f
|
||||||
and #(~LCD_SD),r0
|
and #(~LCD_SD), r0
|
||||||
1:
|
1:
|
||||||
shll r1
|
shll r1
|
||||||
mov.b r0,@r3
|
mov.b r0, @r3
|
||||||
or #(LCD_SC),r0
|
or #(LCD_SC), r0
|
||||||
mov.b r0,@r3
|
mov.b r0, @r3
|
||||||
|
|
||||||
mov r2,r0
|
mov r2, r0
|
||||||
bt 1f
|
bt 1f
|
||||||
and #(~LCD_SD),r0
|
and #(~LCD_SD), r0
|
||||||
1:
|
1:
|
||||||
mov.b r0,@r3
|
mov.b r0, @r3
|
||||||
or #(LCD_SC),r0
|
or #(LCD_SC), r0
|
||||||
mov.b r0,@r3
|
mov.b r0, @r3
|
||||||
|
|
||||||
shll r1
|
shll r1
|
||||||
mov r2,r0
|
mov r2, r0
|
||||||
bt 1f
|
bt 1f
|
||||||
and #(~LCD_SD),r0
|
and #(~LCD_SD), r0
|
||||||
1:
|
1:
|
||||||
shll r1
|
shll r1
|
||||||
mov.b r0,@r3
|
mov.b r0, @r3
|
||||||
or #(LCD_SC),r0
|
or #(LCD_SC), r0
|
||||||
mov.b r0,@r3
|
mov.b r0, @r3
|
||||||
|
|
||||||
mov r2,r0
|
mov r2, r0
|
||||||
bt 1f
|
bt 1f
|
||||||
and #(~LCD_SD),r0
|
and #(~LCD_SD), r0
|
||||||
1:
|
1:
|
||||||
mov.b r0,@r3
|
mov.b r0, @r3
|
||||||
or #(LCD_SC),r0
|
or #(LCD_SC), r0
|
||||||
mov.b r0,@r3
|
mov.b r0, @r3
|
||||||
|
|
||||||
shll r1
|
shll r1
|
||||||
mov r2,r0
|
mov r2, r0
|
||||||
bt 1f
|
bt 1f
|
||||||
and #(~LCD_SD),r0
|
and #(~LCD_SD), r0
|
||||||
1:
|
1:
|
||||||
shll r1
|
shll r1
|
||||||
mov.b r0,@r3
|
mov.b r0, @r3
|
||||||
or #(LCD_SC),r0
|
or #(LCD_SC), r0
|
||||||
mov.b r0,@r3
|
mov.b r0, @r3
|
||||||
|
|
||||||
mov r2,r0
|
mov r2, r0
|
||||||
bt 1f
|
bt 1f
|
||||||
and #(~LCD_SD),r0
|
and #(~LCD_SD), r0
|
||||||
1:
|
1:
|
||||||
mov.b r0,@r3
|
mov.b r0, @r3
|
||||||
or #(LCD_SC),r0
|
or #(LCD_SC), r0
|
||||||
mov.b r0,@r3
|
mov.b r0, @r3
|
||||||
|
|
||||||
add #-1,r5 /* decrease byte count */
|
add #-1, r5 /* decrease byte count */
|
||||||
tst r5,r5 /* r5 == 0 ? */
|
tst r5, r5 /* r5 == 0 ? */
|
||||||
bf .multi_transfer /* no: next iteration */
|
bf .multi_transfer /* no: next iteration */
|
||||||
|
|
||||||
or #(LCD_CS|LCD_DS|LCD_SD|LCD_SC),r0 /* restore port */
|
or #(LCD_CS|LCD_DS|LCD_SD|LCD_SC),r0 /* restore port */
|
||||||
rts
|
rts
|
||||||
mov.b r0,@r3
|
mov.b r0, @r3
|
||||||
|
|
||||||
/* This is the place to reenable the interrupts, if we have disabled
|
/* This is the place to reenable the interrupts, if we have disabled
|
||||||
* them. See above. */
|
* them. See above. */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue