XduooX3 LCD tweaks #2

Group commands for a bit more speed

bitdelay was not being inlined
lower bitdelay to 12 cycles

Clean-up magic numbers

Change-Id: Ifeb57a5532807a598f1ec5e1c55f03e4aa1e133f
This commit is contained in:
William Wilgus 2020-09-07 12:52:04 -04:00 committed by William Wilgus
parent 49a2953ade
commit e18c2f3001

View file

@ -8,6 +8,7 @@
* $Id$ * $Id$
* *
* Copyright (C) 2016 by Roman Stolyarov * Copyright (C) 2016 by Roman Stolyarov
* Copyright (C) 2020 by William Wilgus
* *
* 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
@ -44,6 +45,13 @@
#define PIN_LCD_RES (32*2+18) #define PIN_LCD_RES (32*2+18)
#define PIN_LCD_WR (32*2+19) #define PIN_LCD_WR (32*2+19)
/* LCD_PINS_MASK D0-D7 RD DC CS RES WR */
#define LCD_PINS_MASK 0x000C73FC
/* LCD_DATA_MASK D0-D7 */
#define LCD_DATA_MASK 0x000030FC
/* FRAMEBUF_TO_LCD_DATA -- translate data to match LCD data pins */
#define FRAMEBUF_TO_LCD_DATA(b) (((b & 0xC0) << 6) | ((b & 0x3F) << 2))
/* LCD setup codes */ /* LCD setup codes */
#define LCD_SET_LOWER_COLUMN_ADDRESS ((char)0x00) #define LCD_SET_LOWER_COLUMN_ADDRESS ((char)0x00)
#define LCD_SET_HIGHER_COLUMN_ADDRESS ((char)0x10) #define LCD_SET_HIGHER_COLUMN_ADDRESS ((char)0x10)
@ -82,35 +90,37 @@
#define LCD_COL_OFFSET 2 /* column offset */ #define LCD_COL_OFFSET 2 /* column offset */
static inline void bitdelay(void) #define BITDELAY() \
{ do { \
unsigned int i = 15; volatile unsigned int i = 12; \
__asm__ __volatile__ ( __asm__ __volatile__ ( \
".set noreorder \n" ".set noreorder \n" \
"1: \n" "1: \n" \
"bne %0, $0, 1b \n" "bne %0, $0, 1b \n" \
"addi %0, %0, -1 \n" "addi %0, %0, -1 \n" \
".set reorder \n" ".set reorder \n" \
: "=r" (i) : "=r" (i) \
: "0" (i) : "0" (i) \
); ); \
} } while (0)
void lcd_hw_init(void) void lcd_hw_init(void)
{ {
REG_GPIO_PXFUNC(2) = 0x000C73FC; /* D0-D7 RD DC CS RES WR -- GPIO/INTERRUPT */ REG_GPIO_PXFUNC(2) = LCD_PINS_MASK; /* GPIO/INTERRUPT */
REG_GPIO_PXSELC(2) = 0x000C73FC; /* GPIO */ REG_GPIO_PXSELC(2) = LCD_PINS_MASK; /* GPIO */
REG_GPIO_PXPEC(2) = 0x000C73FC; /* ENABLE PULLUP*/ REG_GPIO_PXPEC(2) = LCD_PINS_MASK; /* ENABLE PULLUP*/
REG_GPIO_PXDIRS(2) = LCD_PINS_MASK; /* OUTPUT */
REG_GPIO_PXDIRS(2) = 0x000C73FC; /* OUTPUT */ REG_GPIO_PXDATS(2) = LCD_PINS_MASK; /* SET BIT */
REG_GPIO_PXDATS(2) = 0x000C73FC; /* D0-D7 RD DC CS RES WR -- SET BIT */ REG_GPIO_PXSLS(2) = LCD_PINS_MASK; /* slew -- fast rate */
REG_GPIO_PXSLC(2) = 0x000C73FC; /* slew -- slow rate */ REG_GPIO_PXDS0C(2) = LCD_PINS_MASK; /* Low pin drive strength */
REG_GPIO_PXDS1C(2) = LCD_PINS_MASK;
REG_GPIO_PXDS2C(2) = LCD_PINS_MASK;
REG_GPIO_PXDS0C(2) = 0x000C73FC; /* Low pin drive strength */ __gpio_clear_pin(PIN_LCD_RD); /* UNUSED */
REG_GPIO_PXDS1C(2) = 0x000C73FC; __gpio_as_input(PIN_LCD_RD); /* UNUSED */
REG_GPIO_PXDS2C(2) = 0x000C73FC;
__gpio_clear_pin(PIN_BL_EN); __gpio_clear_pin(PIN_BL_EN);
__gpio_as_output(PIN_BL_EN); __gpio_as_output(PIN_BL_EN);
@ -125,26 +135,64 @@ void lcd_hw_init(void)
void lcd_write_command(int byte) void lcd_write_command(int byte)
{ {
__gpio_clear_pin(PIN_LCD_DC); __gpio_clear_pin(PIN_LCD_DC);
REG_GPIO_PXDATC(2) = 0x000030FC; REG_GPIO_PXDATC(2) = LCD_DATA_MASK;
REG_GPIO_PXDATS(2) = ((byte & 0xC0) << 6) | ((byte & 0x3F) << 2); REG_GPIO_PXDATS(2) = FRAMEBUF_TO_LCD_DATA(byte);
__gpio_clear_pin(PIN_LCD_WR); __gpio_clear_pin(PIN_LCD_WR);
bitdelay(); BITDELAY();
__gpio_set_pin(PIN_LCD_WR); __gpio_set_pin(PIN_LCD_WR);
bitdelay(); BITDELAY();
}
static void lcd_write_cmd_triplet(int cmd1, int cmd2, int cmd3)
{
#if 0
lcd_write_command(cmd1);
lcd_write_command(cmd2);
lcd_write_command(cmd3);
#else
int command = LCD_DATA_MASK;
__gpio_clear_pin(PIN_LCD_DC);
REG_GPIO_PXDATC(2) = command;
command = FRAMEBUF_TO_LCD_DATA(cmd1);
REG_GPIO_PXDATS(2) = command;
__gpio_clear_pin(PIN_LCD_WR);
BITDELAY();
__gpio_set_pin(PIN_LCD_WR);
BITDELAY();
REG_GPIO_PXDATC(2) = command;
command = FRAMEBUF_TO_LCD_DATA(cmd2);
REG_GPIO_PXDATS(2) = command;
__gpio_clear_pin(PIN_LCD_WR);
BITDELAY();
__gpio_set_pin(PIN_LCD_WR);
BITDELAY();
REG_GPIO_PXDATC(2) = command;
command = FRAMEBUF_TO_LCD_DATA(cmd3);
REG_GPIO_PXDATS(2) = command;
__gpio_clear_pin(PIN_LCD_WR);
BITDELAY();
__gpio_set_pin(PIN_LCD_WR);
BITDELAY();
#endif
} }
void lcd_write_data(const fb_data* p_bytes, int count) void lcd_write_data(const fb_data* p_bytes, int count)
{ {
int data = LCD_DATA_MASK;
__gpio_set_pin(PIN_LCD_DC); __gpio_set_pin(PIN_LCD_DC);
while (count--) while (count--)
{ {
REG_GPIO_PXDATC(2) = 0x000030FC; REG_GPIO_PXDATC(2) = data;
REG_GPIO_PXDATS(2) = ((*p_bytes & 0xC0) << 6) | ((*p_bytes & 0x3F) << 2); data = FRAMEBUF_TO_LCD_DATA(*p_bytes);
p_bytes++; p_bytes++;
REG_GPIO_PXDATS(2) = data;
__gpio_clear_pin(PIN_LCD_WR); __gpio_clear_pin(PIN_LCD_WR);
bitdelay(); BITDELAY();
__gpio_set_pin(PIN_LCD_WR); __gpio_set_pin(PIN_LCD_WR);
bitdelay(); BITDELAY();
} }
} }
@ -275,6 +323,7 @@ void lcd_enable(bool enable)
{ {
lcd_write_command(LCD_SET_DISPLAY_OFF); lcd_write_command(LCD_SET_DISPLAY_OFF);
lcd_enable_power(enable); lcd_enable_power(enable);
REG_GPIO_PXDATC(2) = LCD_DATA_MASK;
} }
} }
@ -296,7 +345,7 @@ void lcd_init_device(void)
/* Set display clock and oscillator frequency */ /* Set display clock and oscillator frequency */
lcd_write_command(LCD_SET_DISPLAY_CLOCK_AND_OSC_FREQ); lcd_write_command(LCD_SET_DISPLAY_CLOCK_AND_OSC_FREQ);
lcd_write_command(0x80); lcd_write_command(0x00); /* External clock Bits [0-3] for divider */
/* Set multiplex ratio*/ /* Set multiplex ratio*/
lcd_write_command(LCD_SET_MULTIPLEX_RATIO); lcd_write_command(LCD_SET_MULTIPLEX_RATIO);
@ -386,9 +435,12 @@ void lcd_blit_mono(const unsigned char *data, int x, int by, int width,
/* Copy display bitmap to hardware */ /* Copy display bitmap to hardware */
while (bheight--) while (bheight--)
{ {
lcd_write_command (LCD_CNTL_PAGE | (by++ & 0xf)); lcd_write_cmd_triplet
lcd_write_command (column_high); (
lcd_write_command (column_low); (LCD_CNTL_PAGE | (by++ & 0xf)),
(column_high),
(column_low)
);
lcd_write_data(data, width); lcd_write_data(data, width);
data += stride; data += stride;
@ -405,6 +457,7 @@ void lcd_grey_data(unsigned char *values, unsigned char *phases, int count)
unsigned long *lval = (unsigned long *)values; unsigned long *lval = (unsigned long *)values;
unsigned long *lpha = (unsigned long *)phases; unsigned long *lpha = (unsigned long *)phases;
const unsigned long mask = 0x80808080; const unsigned long mask = 0x80808080;
int data = LCD_DATA_MASK;
__gpio_set_pin(PIN_LCD_DC); __gpio_set_pin(PIN_LCD_DC);
while(count--) while(count--)
@ -421,13 +474,13 @@ void lcd_grey_data(unsigned char *values, unsigned char *phases, int count)
lpha[0] = lval[0] + (lpha[0] & ~mask); lpha[0] = lval[0] + (lpha[0] & ~mask);
lpha[1] = lval[1] + (lpha[1] & ~mask); lpha[1] = lval[1] + (lpha[1] & ~mask);
REG_GPIO_PXDATC(2) = 0x000030FC; REG_GPIO_PXDATC(2) = data;
REG_GPIO_PXDATS(2) = ((ltmp & 0xC0) << 6) | ((ltmp & 0x3F) << 2); data = FRAMEBUF_TO_LCD_DATA(ltmp);
REG_GPIO_PXDATS(2) = data;
__gpio_clear_pin(PIN_LCD_WR); __gpio_clear_pin(PIN_LCD_WR);
bitdelay(); BITDELAY();
__gpio_set_pin(PIN_LCD_WR); __gpio_set_pin(PIN_LCD_WR);
bitdelay(); /*BITDELAY(); //enough instructions above to satisfy data hold time */
lpha+=2; lpha+=2;
lval+=2; lval+=2;
} }
@ -450,9 +503,12 @@ void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
/* Copy display bitmap to hardware */ /* Copy display bitmap to hardware */
while (bheight--) while (bheight--)
{ {
lcd_write_command (LCD_CNTL_PAGE | (by++ & 0xf)); lcd_write_cmd_triplet
lcd_write_command (column_high); (
lcd_write_command (column_low); (LCD_CNTL_PAGE | (by++ & 0xf)),
(column_high),
(column_low)
);
lcd_grey_data(values, phases, width); lcd_grey_data(values, phases, width);
@ -479,9 +535,12 @@ void lcd_update(void)
/* Copy display bitmap to hardware */ /* Copy display bitmap to hardware */
for (y = 0; y < LCD_FBHEIGHT; y++) for (y = 0; y < LCD_FBHEIGHT; y++)
{ {
lcd_write_command (LCD_CNTL_PAGE | (y & 0xf)); lcd_write_cmd_triplet
lcd_write_command (column_high); (
lcd_write_command (column_low); (LCD_CNTL_PAGE | (y & 0xf)),
(column_high),
(column_low)
);
lcd_write_data (FBADDR(0, y), LCD_WIDTH); lcd_write_data (FBADDR(0, y), LCD_WIDTH);
} }
@ -530,9 +589,12 @@ void lcd_update_rect(int x, int y, int width, int height)
/* Copy specified rectange bitmap to hardware */ /* Copy specified rectange bitmap to hardware */
for (; y <= ymax; y++) for (; y <= ymax; y++)
{ {
lcd_write_command (LCD_CNTL_PAGE | (y & 0xf)); lcd_write_cmd_triplet
lcd_write_command (column_high); (
lcd_write_command (column_low); (LCD_CNTL_PAGE | (y & 0xf)),
(column_high),
(column_low)
);
lcd_write_data (FBADDR(x,y), width); lcd_write_data (FBADDR(x,y), width);
} }