From 31a1a2900423056c18f5d2afd467fb53688058c1 Mon Sep 17 00:00:00 2001 From: William Wilgus Date: Fri, 28 Aug 2020 01:13:44 -0400 Subject: Xduoo X3 Tweak LCD settings Adds contrast setting which actually sets the drive voltage Change-Id: I173238e2efe9e50c6ef4cda9bf991e7ee5568ff5 --- firmware/export/config/xduoox3.h | 7 ++ .../mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c | 127 +++++++++++++++++++-- 2 files changed, 122 insertions(+), 12 deletions(-) (limited to 'firmware') diff --git a/firmware/export/config/xduoox3.h b/firmware/export/config/xduoox3.h index e5b5ed9a10..fa86caf511 100644 --- a/firmware/export/config/xduoox3.h +++ b/firmware/export/config/xduoox3.h @@ -45,6 +45,13 @@ #define LCD_BL_DARKCOLOR 0x000000 #define LCD_BL_BRIGHTCOLOR 0x0de2e5 +/* Define this if your LCD can set contrast */ +#define HAVE_LCD_CONTRAST + +#define MIN_CONTRAST_SETTING -9 +#define MAX_CONTRAST_SETTING -1 +#define DEFAULT_CONTRAST_SETTING -6 + /* define this if you have LCD enable function */ #define HAVE_LCD_ENABLE diff --git a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c index ea29ce266d..ce8840f9d2 100644 --- a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c +++ b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c @@ -148,11 +148,79 @@ void lcd_enable_power(bool onoff) static bool display_on = false; /* used by lcd_enable */ /*** hardware configuration ***/ +int lcd_default_contrast(void) +{ + return DEFAULT_CONTRAST_SETTING; +} void lcd_set_contrast(int val) { - lcd_write_command(LCD_CNTL_CONTRAST); - lcd_write_command(val); + static int last_val = 0xFFFFFF; + + if (val >= 0) /* brightness menu */ + { + lcd_write_command(LCD_CNTL_CONTRAST); + lcd_write_command(val); + } + else if (val != last_val) + { + /* here we change the voltage level and drive times + * longer precharge = dimmer display + * higher voltage = shorter precharge required + */ + int precharge; + int vcomdsel; + switch (val) + { + case -9: + precharge = 0xFF; + vcomdsel = 0x10; + break; + case -8: + precharge = 0xF9; + vcomdsel = 0x10; + break; + case -7: + precharge = 0xF6; + vcomdsel = 0x20; + break; + default: + case -6: + precharge = 0xF1; + vcomdsel = 0x30; + break; + case -5: + precharge = 0xF1; + vcomdsel = 0x40; + break; + case -4: + precharge = 0x91; + vcomdsel = 0x50; + break; + case -3: + precharge = 0x61; + vcomdsel = 0x60; + break; + case -2: + precharge = 0x31; + vcomdsel = 0x65; + break; + case -1: + precharge = 0x11; + vcomdsel = 0x70; + break; + } + last_val = val; + lcd_enable(false); + /* Set pre-charge period */ + lcd_write_command(LCD_SET_PRECHARGE_PERIOD); + lcd_write_command(precharge); /* VCC Generated by Internal DC/DC Circuit */ + + /* Set VCOM deselect level */ + lcd_write_command(LCD_SET_VCOM_DESELECT_LEVEL); + lcd_write_command(vcomdsel); + lcd_enable(true); + } } void lcd_set_invert_display(bool yesno) @@ -252,7 +320,7 @@ void lcd_init_device(void) /* Set VCOM deselect level */ lcd_write_command(LCD_SET_VCOM_DESELECT_LEVEL); - lcd_write_command(0x40); + lcd_write_command(0x20); /* Set normal display mode (not every pixel ON) */ lcd_write_command(LCD_SET_ENTIRE_DISPLAY_OFF); @@ -275,6 +343,22 @@ void lcd_init_device(void) /*** Update functions ***/ +/* returns LCD_CNTL_HIGHCOL or'd with higher 4 bits of + the 8-bit column address for the display data RAM. +*/ +static inline int get_column_high_byte(const int x) +{ + return (LCD_CNTL_HIGHCOL | (((x+LCD_COL_OFFSET) >> 4) & 0xf)); +} + +/* returns LCD_CNTL_LOWCOL or'd with lower 4 bits of + the 8-bit column address for the display data RAM. +*/ +static inline int get_column_low_byte(const int x) +{ + return (LCD_CNTL_LOWCOL | ((x+LCD_COL_OFFSET) & 0xf)); +} + /* Performance function that works with an external buffer note that by and bheight are in 8-pixel units! */ void lcd_blit_mono(const unsigned char *data, int x, int by, int width, @@ -283,12 +367,15 @@ void lcd_blit_mono(const unsigned char *data, int x, int by, int width, if(!display_on) return; + const int column_high = get_column_high_byte(x); + const int column_low = get_column_low_byte(x); + /* Copy display bitmap to hardware */ while (bheight--) { lcd_write_command (LCD_CNTL_PAGE | (by++ & 0xf)); - lcd_write_command (LCD_CNTL_HIGHCOL | (((x+LCD_COL_OFFSET)>>4) & 0xf)); - lcd_write_command (LCD_CNTL_LOWCOL | ((x+LCD_COL_OFFSET) & 0xf)); + lcd_write_command (column_high); + lcd_write_command (column_low); lcd_write_data(data, width); data += stride; @@ -306,6 +393,7 @@ void lcd_grey_data(unsigned char *values, unsigned char *phases, int count) unsigned long *lpha = (unsigned long *)phases; const unsigned long mask = 0x80808080; + __gpio_set_pin(PIN_LCD_DC); while(count--) { /* calculate disp data from phase we only use the last byte (8bits) */ @@ -320,7 +408,12 @@ void lcd_grey_data(unsigned char *values, unsigned char *phases, int count) lpha[0] = lval[0] + (lpha[0] & ~mask); lpha[1] = lval[1] + (lpha[1] & ~mask); - lcd_write_data((const fb_data*) <mp, 1); + REG_GPIO_PXDATC(2) = 0x000030FC; + REG_GPIO_PXDATS(2) = ((ltmp & 0xC0) << 6) | ((ltmp & 0x3F) << 2); + __gpio_clear_pin(PIN_LCD_WR); + bitdelay(); + __gpio_set_pin(PIN_LCD_WR); + bitdelay(); lpha+=2; lval+=2; @@ -335,13 +428,16 @@ void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases, if(!display_on) return; + const int column_high = get_column_high_byte(x); + const int column_low = get_column_low_byte(x); + stride <<= 3; /* 8 pixels per block */ /* Copy display bitmap to hardware */ while (bheight--) { lcd_write_command (LCD_CNTL_PAGE | (by++ & 0xf)); - lcd_write_command (LCD_CNTL_HIGHCOL | (((x+LCD_COL_OFFSET)>>4) & 0xf)); - lcd_write_command (LCD_CNTL_LOWCOL | ((x+LCD_COL_OFFSET) & 0xf)); + lcd_write_command (column_high); + lcd_write_command (column_low); lcd_grey_data(values, phases, width); @@ -361,12 +457,16 @@ void lcd_update(void) if(!display_on) return; + + const int column_high = get_column_high_byte(0); + const int column_low = get_column_low_byte(0); + /* Copy display bitmap to hardware */ for (y = 0; y < LCD_FBHEIGHT; y++) { lcd_write_command (LCD_CNTL_PAGE | (y & 0xf)); - lcd_write_command (LCD_CNTL_HIGHCOL | ((LCD_COL_OFFSET >> 4) & 0xf)); - lcd_write_command (LCD_CNTL_LOWCOL | (LCD_COL_OFFSET & 0xf)); + lcd_write_command (column_high); + lcd_write_command (column_low); lcd_write_data (FBADDR(0, y), LCD_WIDTH); } @@ -381,6 +481,9 @@ void lcd_update_rect(int x, int y, int width, int height) if(!display_on) return; + const int column_high = get_column_high_byte(x); + const int column_low = get_column_low_byte(x); + /* The Y coordinates have to work on even 8 pixel rows */ if (x < 0) { @@ -413,8 +516,8 @@ void lcd_update_rect(int x, int y, int width, int height) for (; y <= ymax; y++) { lcd_write_command (LCD_CNTL_PAGE | (y & 0xf)); - lcd_write_command (LCD_CNTL_HIGHCOL | (((x+LCD_COL_OFFSET) >> 4) & 0xf)); - lcd_write_command (LCD_CNTL_LOWCOL | ((x+LCD_COL_OFFSET) & 0xf)); + lcd_write_command (column_high); + lcd_write_command (column_low); lcd_write_data (FBADDR(x,y), width); } -- cgit