From a5d7f4ea99ad6e1b6f950a676c265be3b8179f97 Mon Sep 17 00:00:00 2001 From: Serge Vakulenko Date: Tue, 30 Jan 2018 20:22:36 -0800 Subject: [PATCH] Gpanel driver: add support for ILI9481 LCD controller. --- sys/include/gpanel.h | 1 + sys/pic32/gpanel-ili9341.c | 143 +++++++++++++++++++++++++++++++++---- sys/pic32/gpanel-nt35702.c | 18 ++--- sys/pic32/gpanel.c | 5 ++ sys/pic32/ili9341.h | 4 +- sys/pic32/wf32/Config | 26 +++---- sys/pic32/wf32/Makefile | 6 +- 7 files changed, 163 insertions(+), 40 deletions(-) diff --git a/sys/include/gpanel.h b/sys/include/gpanel.h index b848879..6d5b7d0 100644 --- a/sys/include/gpanel.h +++ b/sys/include/gpanel.h @@ -163,6 +163,7 @@ extern int gpanel_height; extern void st7781_init_display(struct gpanel_hw *hw); extern void nt35702_init_display(struct gpanel_hw *hw); extern void ili9341_init_display(struct gpanel_hw *hw); +extern void ili9481_init_display(struct gpanel_hw *hw); extern void s6d04h0_init_display(struct gpanel_hw *hw); #endif /* KERNEL */ diff --git a/sys/pic32/gpanel-ili9341.c b/sys/pic32/gpanel-ili9341.c index 46365c5..a441644 100644 --- a/sys/pic32/gpanel-ili9341.c +++ b/sys/pic32/gpanel-ili9341.c @@ -67,7 +67,7 @@ static void set_window(int x0, int y0, int x1, int y1) /* * Draw a pixel. */ -void ili9341_set_pixel(int x, int y, int color) +void ili_set_pixel(int x, int y, int color) { if (x < 0 || x >= gpanel_width || y < 0 || y >= gpanel_height) return; @@ -139,7 +139,7 @@ static void flood(int color, int npixels) /* * Switch the screen orientation. */ -static void set_rotation(int rotation) +static void ili9341_set_rotation(int rotation) { write_command(ILI9341_Memory_Access_Control); switch (rotation & 3) { @@ -166,15 +166,58 @@ static void set_rotation(int rotation) } } +/* + * Switch the screen orientation. + */ +static void ili9481_set_rotation(int rotation) +{ + write_command(ILI9341_Memory_Access_Control); + switch (rotation & 3) { + case 0: /* Portrait */ + write_data(MADCTL_MX | MADCTL_BGR); + gpanel_width = 320; + gpanel_height = 480; + break; + case 1: /* Landscape */ + write_data(MADCTL_MV | MADCTL_BGR); + gpanel_width = 480; + gpanel_height = 320; + break; + case 2: /* Upside down portrait */ + write_data(MADCTL_MY | MADCTL_BGR); + gpanel_width = 320; + gpanel_height = 480; + break; + case 3: /* Upside down landscape */ + write_data(MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR); + gpanel_width = 480; + gpanel_height = 320; + break; + } +} + static void ili9341_resize(struct gpanel_hw *h, int width, int height) { gpanel_cs_active(); /* Switch screen orientaation. */ if (width > height) - set_rotation(1); /* Landscape */ + ili9341_set_rotation(1); /* Landscape */ else if (width < height) - set_rotation(0); /* Portrait */ + ili9341_set_rotation(0); /* Portrait */ + + gpanel_cs_idle(); +} + +static void ili9481_resize(struct gpanel_hw *h, int width, int height) +{ + gpanel_cs_active(); + + /* Switch screen orientaation. */ + if (width > height) + ili9481_set_rotation(1); /* Landscape */ + else if (width < height) + ili9481_set_rotation(0); /* Portrait */ gpanel_cs_idle(); } @@ -182,7 +225,7 @@ static void ili9341_resize(struct gpanel_hw *h, int width, int height) /* * Fill a rectangle with specified color. */ -void ili9341_fill_rectangle(int x0, int y0, int x1, int y1, int color) +void ili_fill_rectangle(int x0, int y0, int x1, int y1, int color) { if (x0 < 0) x0 = 0; if (y0 < 0) x0 = 0; @@ -212,7 +255,7 @@ void ili9341_fill_rectangle(int x0, int y0, int x1, int y1, int color) /* * Fill a rectangle with user data. */ -void ili9341_draw_image(int x, int y, int width, int height, +void ili_draw_image(int x, int y, int width, int height, const unsigned short *data) { unsigned cnt = width * height; @@ -231,7 +274,7 @@ void ili9341_draw_image(int x, int y, int width, int height, /* * Draw a glyph of one symbol. */ -void ili9341_draw_glyph(const struct gpanel_font_t *font, +void ili_draw_glyph(const struct gpanel_font_t *font, int color, int background, int x, int y, int width, const unsigned short *bits) { @@ -277,7 +320,7 @@ void ili9341_draw_glyph(const struct gpanel_font_t *font, bitmask <<= 1; if (bitmask & 0x8000) - ili9341_set_pixel(x + w, y + h, color); + ili_set_pixel(x + w, y + h, color); } } } @@ -326,7 +369,7 @@ void ili9341_init_display(struct gpanel_hw *h) write_command(ILI9341_Display_ON); - set_rotation(1); /* Landscape */ + ili9341_set_rotation(1); /* Landscape */ gpanel_cs_idle(); /* @@ -334,8 +377,82 @@ void ili9341_init_display(struct gpanel_hw *h) */ h->name = "Ilitek ILI9341"; h->resize = ili9341_resize; - h->set_pixel = ili9341_set_pixel; - h->fill_rectangle = ili9341_fill_rectangle; - h->draw_image = ili9341_draw_image; - h->draw_glyph = ili9341_draw_glyph; + h->set_pixel = ili_set_pixel; + h->fill_rectangle = ili_fill_rectangle; + h->draw_image = ili_draw_image; + h->draw_glyph = ili_draw_glyph; +} + +/* + * Initialize the LCD controller. + * Fill the gpanel_hw descriptor. + */ +void ili9481_init_display(struct gpanel_hw *h) +{ + /* Use a few NOPs to synchronize after the hard Reset. */ + gpanel_cs_active(); + write_command(ILI9341_No_Operation); + write_command(ILI9341_No_Operation); + write_command(ILI9341_No_Operation); + write_command(ILI9341_No_Operation); + + write_command(ILI9341_Sleep_OUT); + udelay(150000); + + write_command(ILI9341_NV_Memory_Write); + write_data(0x07); + write_data(0x42); + write_data(0x18); + + write_command(ILI9341_NV_Memory_Protection_Key); + write_data(0x00); + write_data(0x07); + write_data(0x10); + + write_command(ILI9341_NV_Memory_Status_Read); + write_data(0x01); + write_data(0x02); + + write_command(ILI9341_Power_Control_1); + write_data(0x10); + write_data(0x3B); + write_data(0x00); + write_data(0x02); + write_data(0x11); + + write_command(ILI9341_VCOM_Control_1); + write_data(0x03); + + write_command(ILI9341_Memory_Access_Control); + write_data(0x0A); + + write_command(ILI9341_Pixel_Format_Set); + write_data(0x55); + + write_command(ILI9341_Column_Address_Set); + write_data(0x00); + write_data(0x00); + write_data(0x01); + write_data(0x3F); + + write_command(ILI9341_Page_Address_Set); + write_data(0x00); + write_data(0x00); + write_data(0x01); + write_data(0xE0); + + write_command(ILI9341_Display_ON); + + ili9481_set_rotation(1); /* Landscape */ + gpanel_cs_idle(); + + /* + * Fill the gpanel_hw descriptor. + */ + h->name = "Ilitek ILI9341"; + h->resize = ili9481_resize; + h->set_pixel = ili_set_pixel; + h->fill_rectangle = ili_fill_rectangle; + h->draw_image = ili_draw_image; + h->draw_glyph = ili_draw_glyph; } diff --git a/sys/pic32/gpanel-nt35702.c b/sys/pic32/gpanel-nt35702.c index 92663e3..f2b6e08 100644 --- a/sys/pic32/gpanel-nt35702.c +++ b/sys/pic32/gpanel-nt35702.c @@ -1,7 +1,7 @@ /* * Display driver for NT35702 LCD controller. * This controller is partially compatible with ILI9341 chip, - * so we can reuse most of ili9341_xxx() routines. + * so we can reuse most of ili_xxx() routines. * * Copyright (C) 2015 Serge Vakulenko * @@ -120,11 +120,11 @@ /* * Reuse ILI9341 routines. */ -extern void ili9341_set_pixel(int x, int y, int color); -extern void ili9341_fill_rectangle(int x0, int y0, int x1, int y1, int color); -extern void ili9341_draw_image(int x, int y, int width, int height, +extern void ili_set_pixel(int x, int y, int color); +extern void ili_fill_rectangle(int x0, int y0, int x1, int y1, int color); +extern void ili_draw_image(int x, int y, int width, int height, const unsigned short *data); -extern void ili9341_draw_glyph(const struct gpanel_font_t *font, +extern void ili_draw_glyph(const struct gpanel_font_t *font, int color, int background, int x, int y, int width, const unsigned short *bits); @@ -291,8 +291,8 @@ void nt35702_init_display(struct gpanel_hw *h) */ h->name = "Novatek NT35702"; h->resize = nt35702_resize; - h->set_pixel = ili9341_set_pixel; - h->fill_rectangle = ili9341_fill_rectangle; - h->draw_image = ili9341_draw_image; - h->draw_glyph = ili9341_draw_glyph; + h->set_pixel = ili_set_pixel; + h->fill_rectangle = ili_fill_rectangle; + h->draw_image = ili_draw_image; + h->draw_glyph = ili_draw_glyph; } diff --git a/sys/pic32/gpanel.c b/sys/pic32/gpanel.c index f181b34..14be2af 100644 --- a/sys/pic32/gpanel.c +++ b/sys/pic32/gpanel.c @@ -675,6 +675,11 @@ static int probe(config) ili9341_init_display(&hw); break; + case 0x012200: + /* Ilitek ILI9481. */ + ili9481_init_display(&hw); + break; + case 0x388000: /* Novatek NT35702. */ nt35702_init_display(&hw); diff --git a/sys/pic32/ili9341.h b/sys/pic32/ili9341.h index bdaa781..c4b3c9f 100644 --- a/sys/pic32/ili9341.h +++ b/sys/pic32/ili9341.h @@ -69,8 +69,8 @@ #define ILI9341_VCOM_Control_1 0xC5 #define ILI9341_VCOM_Control_2 0xC7 #define ILI9341_NV_Memory_Write 0xD0 -#define ILI9341_NV_Memory_Protection Key 0xD1 -#define ILI9341_NV_Memory_Status Read 0xD2 +#define ILI9341_NV_Memory_Protection_Key 0xD1 +#define ILI9341_NV_Memory_Status_Read 0xD2 #define ILI9341_Read_ID4 0xD3 #define ILI9341_Positive_Gamma_Correction 0xE0 #define ILI9341_Negative_Gamma_Correction 0xE1 diff --git a/sys/pic32/wf32/Config b/sys/pic32/wf32/Config index e40aab5..9c3ce00 100644 --- a/sys/pic32/wf32/Config +++ b/sys/pic32/wf32/Config @@ -68,16 +68,16 @@ device pwm # TFT display driver with 8-bit parallel interface. # Supported controllers: ST7781, ILI9341, NT35702 device gpanel -signal "LCD_RST" pin RB10 -signal "LCD_CS" pin RB0 -signal "LCD_RD" pin RB2 -signal "LCD_RS" pin RB8 -signal "LCD_WR" pin RB4 -signal "LCD_D0" pin RA14 -signal "LCD_D1" pin RD3 -signal "LCD_D2" pin RE8 -signal "LCD_D3" pin RD0 -signal "LCD_D4" pin RF1 -signal "LCD_D5" pin RD1 -signal "LCD_D6" pin RD2 -signal "LCD_D7" pin RE9 +signal "LCD_RST" pin RB10 # arduino A4 +signal "LCD_CS" pin RB0 # arduino A3 +signal "LCD_RS" pin RB8 # arduino A2 +signal "LCD_WR" pin RB4 # arduino A1 +signal "LCD_RD" pin RB2 # arduino A0 +signal "LCD_D2" pin RE8 # arduino D2 +signal "LCD_D3" pin RD0 # arduino D3 +signal "LCD_D4" pin RF1 # arduino D4 +signal "LCD_D5" pin RD1 # arduino D5 +signal "LCD_D6" pin RD2 # arduino D6 +signal "LCD_D7" pin RE9 # arduino D7 +signal "LCD_D0" pin RA14 # arduino D8 +signal "LCD_D1" pin RD3 # arduino D9 diff --git a/sys/pic32/wf32/Makefile b/sys/pic32/wf32/Makefile index fdb15ba..10d6819 100644 --- a/sys/pic32/wf32/Makefile +++ b/sys/pic32/wf32/Makefile @@ -13,17 +13,17 @@ PARAM += -DGPIO6_ENABLED PARAM += -DADC_ENABLED PARAM += -DPWM_ENABLED PARAM += -DGPANEL_ENABLED +PARAM += -DLCD_D1_PORT=TRISD -DLCD_D1_PIN=3 +PARAM += -DLCD_D0_PORT=TRISA -DLCD_D0_PIN=14 PARAM += -DLCD_D7_PORT=TRISE -DLCD_D7_PIN=9 PARAM += -DLCD_D6_PORT=TRISD -DLCD_D6_PIN=2 PARAM += -DLCD_D5_PORT=TRISD -DLCD_D5_PIN=1 PARAM += -DLCD_D4_PORT=TRISF -DLCD_D4_PIN=1 PARAM += -DLCD_D3_PORT=TRISD -DLCD_D3_PIN=0 PARAM += -DLCD_D2_PORT=TRISE -DLCD_D2_PIN=8 -PARAM += -DLCD_D1_PORT=TRISD -DLCD_D1_PIN=3 -PARAM += -DLCD_D0_PORT=TRISA -DLCD_D0_PIN=14 +PARAM += -DLCD_RD_PORT=TRISB -DLCD_RD_PIN=2 PARAM += -DLCD_WR_PORT=TRISB -DLCD_WR_PIN=4 PARAM += -DLCD_RS_PORT=TRISB -DLCD_RS_PIN=8 -PARAM += -DLCD_RD_PORT=TRISB -DLCD_RD_PIN=2 PARAM += -DLCD_CS_PORT=TRISB -DLCD_CS_PIN=0 PARAM += -DLCD_RST_PORT=TRISB -DLCD_RST_PIN=10 PARAM += -DLED_DISK_PORT=TRISA -DLED_DISK_PIN=1