This is an automated email from the ASF dual-hosted git repository. rymek pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit 8cb3a992d67e16eb70c8823a1a5077ea1cc84da5 Author: Jerzy Kasenberg <[email protected]> AuthorDate: Fri Apr 21 11:24:33 2023 +0200 lvgl/gc9a01: Add initial support for GC9A01 TFT --- hw/drivers/display/lvgl/pkg.yml | 2 + hw/drivers/display/lvgl/syscfg.yml | 3 + hw/drivers/display/lvgl/tft/gc9a01/pkg.yml | 28 +++ hw/drivers/display/lvgl/tft/gc9a01/src/gc9a01.c | 267 ++++++++++++++++++++++++ hw/drivers/display/lvgl/tft/gc9a01/syscfg.yml | 23 ++ 5 files changed, 323 insertions(+) diff --git a/hw/drivers/display/lvgl/pkg.yml b/hw/drivers/display/lvgl/pkg.yml index ad2b72ea9..58c1a228c 100644 --- a/hw/drivers/display/lvgl/pkg.yml +++ b/hw/drivers/display/lvgl/pkg.yml @@ -58,6 +58,8 @@ pkg.deps: - "@apache-mynewt-core/hw/hal" - "@apache-mynewt-core/hw/drivers/display/lcd_itf" +pkg.deps.LVGL_GC9A01: + - "@apache-mynewt-core/hw/drivers/display/lvgl/tft/gc9a01" pkg.deps.LVGL_ILI9341: - "@apache-mynewt-core/hw/drivers/display/lvgl/tft/ili9341" pkg.deps.LVGL_ILI9486: diff --git a/hw/drivers/display/lvgl/syscfg.yml b/hw/drivers/display/lvgl/syscfg.yml index b83a20d05..9c7b3278b 100644 --- a/hw/drivers/display/lvgl/syscfg.yml +++ b/hw/drivers/display/lvgl/syscfg.yml @@ -22,6 +22,9 @@ syscfg.defs: LV_COLOR_16_SWAP changes order of 16 bit RGB value to better match 8 bit SPI protocol. value: 0 + LVGL_GC9A01: + description: Enable GC9A01 display driver. + value: LVGL_ILI9341: description: Enable ILI9341 display driver. value: diff --git a/hw/drivers/display/lvgl/tft/gc9a01/pkg.yml b/hw/drivers/display/lvgl/tft/gc9a01/pkg.yml new file mode 100644 index 000000000..122b03381 --- /dev/null +++ b/hw/drivers/display/lvgl/tft/gc9a01/pkg.yml @@ -0,0 +1,28 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: hw/drivers/display/lvgl/tft/gc9a01 +pkg.description: LVGL display driver for GC9A01 +pkg.author: "Apache Mynewt <[email protected]>" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.cflags: + +pkg.deps: + - "@apache-mynewt-core/hw/drivers/display/lcd_itf" diff --git a/hw/drivers/display/lvgl/tft/gc9a01/src/gc9a01.c b/hw/drivers/display/lvgl/tft/gc9a01/src/gc9a01.c new file mode 100644 index 000000000..87a8c8a5d --- /dev/null +++ b/hw/drivers/display/lvgl/tft/gc9a01/src/gc9a01.c @@ -0,0 +1,267 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <lv_glue.h> +#include <bsp/bsp.h> +#include <hal/lv_hal_disp.h> +#include <hal/hal_gpio.h> +#include <lcd_itf.h> + +#define GC9A01_TFTWIDTH 240 +#define GC9A01_TFTHEIGHT 240 + +#define GC9A01_RDDID 0x04 +#define GC9A01_RDDST 0x09 + +#define GC9A01_SLPIN 0x10 +#define GC9A01_SLPOUT 0x11 +#define GC9A01_PTLON 0x12 +#define GC9A01_NORON 0x13 + +#define GC9A01_INVOFF 0x20 +#define GC9A01_INVON 0x21 + +#define GC9A01_DISPOFF 0x28 +#define GC9A01_DISPON 0x29 +#define GC9A01_CASET 0x2A +#define GC9A01_RASET 0x2B +#define GC9A01_RAMWR 0x2C + +#define GC9A01_PTLAR 0x30 +#define GC9A01_SCRLAR 0x33 +#define GC9A01_TEOFF 0x34 +#define GC9A01_TEON 0x35 +#define GC9A01_MADCTL 0x36 +#define GC9A01_VSCSAD 0x37 +#define GC9A01_IDMOFF 0x38 +#define GC9A01_IDMON 0x39 +#define GC9A01_COLMOD 0x3A +#define GC9A01_WRMRCON 0x3C + +#define GC9A01_SETTSL 0x44 +#define GC9A01_GETSL 0x45 + +#define GC9A01_WRDBRINS 0x51 +#define GC9A01_WRCTRLDSP 0x53 + + +#define GC9A01_PWCTR7 0xA7 + +#define GC9A01_RGBISC 0xB0 +#define GC9A01_BPCTRL 0xB5 +#define GC9A01_DISFUNCTRL 0xB6 +#define GC9A01_TEAREFFCTRL 0xBA + +#define GC9A01_PWCTR1 0xC1 +#define GC9A01_PWCTR2 0xC3 +#define GC9A01_PWCTR3 0xC4 +#define GC9A01_PWCTR4 0xC9 +#define GC9A01_VMCTR1 0xC5 +#define GC9A01_VMOFCTR 0xC7 + +#define GC9A01_RDID1 0xDA +#define GC9A01_RDID2 0xDB +#define GC9A01_RDID3 0xDC + +#define GC9A01_FRAMERATE 0xE8 +#define GC9A01_SPI2DATACTRL 0xE9 + +#define GC9A01_GCV 0xFC + +#define GC9A01_IREN1 0xFE +#define GC9A01_IREN2 0xEF + +#define GC9A01_SETGAMMA1 0xF0 +#define GC9A01_SETGAMMA2 0xF1 +#define GC9A01_SETGAMMA3 0xF2 +#define GC9A01_SETGAMMA4 0xF3 + +#define GC9A01_IFCTRL 0xF6 + +#define GC9A01_MADCTL_MY 0x80 +#define GC9A01_MADCTL_MX 0x40 +#define GC9A01_MADCTL_MV 0x20 +#define GC9A01_MADCTL_ML 0x10 +#define GC9A01_MADCTL_RGB 0x00 +#define GC9A01_MADCTL_BGR 0x08 + +#define GC9A01_HOR_RES GC9A01_TFTWIDTH +#define GC9A01_VER_RES GC9A01_TFTHEIGHT + +static const uint8_t madctl[] = { + GC9A01_MADCTL_MX, + GC9A01_MADCTL_MV | GC9A01_MADCTL_MY | GC9A01_MADCTL_ML, + GC9A01_MADCTL_MY, + GC9A01_MADCTL_MX | GC9A01_MADCTL_MV, +}; + +void +gc9a01_rotate(lv_disp_rot_t rotation) +{ + uint8_t madcmd[2] = { GC9A01_MADCTL, GC9A01_MADCTL_BGR | madctl[rotation] }; + + lcd_ift_write_cmd(madcmd, 2); +} + +LCD_SEQUENCE(init_cmds) + LCD_SEQUENCE_LCD_CS_INACTIVATE(), + LCD_SEQUENCE_LCD_DC_DATA(), + 1, 0, +#if MYNEWT_VAL(LCD_RESET_PIN) < 0 + 1, 1, +#else + LCD_SEQUENCE_LCD_RESET_ACTIVATE(), + LCD_SEQUENCE_DELAY_US(10), + LCD_SEQUENCE_LCD_RESET_INACTIVATE(), +#endif + LCD_SEQUENCE_DELAY(100), + /* command length, command, args */ + 1, 0x01, + 2, 0xEB, 0x14, + 1, GC9A01_IREN1, + 1, GC9A01_IREN2, + 2, 0xEB, 0x14, + 2, 0x84, 0x40, + 2, 0x85, 0xFF, + 2, 0x86, 0xFF, + 2, 0x87, 0xFF, + 2, 0x88, 0x0A, + 2, 0x89, 0x21, + 2, 0x8A, 0x00, + 2, 0x8B, 0x80, + 2, 0x8C, 0x01, + 2, 0x8D, 0x01, + 2, 0x8E, 0xFF, + 2, 0x8F, 0xFF, + 3, GC9A01_DISFUNCTRL, 0x00, 0x00, + 2, GC9A01_COLMOD, 0x55, + 5, 0x90, 0x08, 0x08, 0x08, 0x08, + 2, 0xBD, 0x06, + 2, 0xBC, 0x00, + 4, 0xFF, 0x60, 0x01, 0x04, + 2, GC9A01_PWCTR2, 0x13, + 2, GC9A01_PWCTR3, 0x13, + 2, GC9A01_PWCTR4, 0x22, + 2, 0xBE, 0x11, + 3, 0xE1, 0x10, 0x0E, + 4, 0xDF, 0x21, 0x0C, 0x02, + 7, GC9A01_SETGAMMA1, 0x45, 0x09, 0x08, 0x08, 0x26, 0x2A, + 7, GC9A01_SETGAMMA2, 0x43, 0x70, 0x72, 0x36, 0x37, 0x6F, + 7, GC9A01_SETGAMMA3, 0x45, 0x09, 0x08, 0x08, 0x26, 0x2A, + 7, GC9A01_SETGAMMA4, 0x43, 0x70, 0x72, 0x36, 0x37, 0x6F, + 3, 0xED, 0x1B, 0x0B, + 2, 0xAE, 0x77, + 2, 0xCD, 0x63, + 10, 0x70, 0x07, 0x07, 0x04, 0x0E, 0x0F, 0x09, 0x07, 0x08, 0x03, + 2, GC9A01_FRAMERATE, 0x34, + 13, 0x62, 0x18, 0x0D, 0x71, 0xED, 0x70, 0x70, 0x18, 0x0F, 0x71, 0xEF, 0x70, 0x70, + 13, 0x63, 0x18, 0x11, 0x71, 0xF1, 0x70, 0x70, 0x18, 0x13, 0x71, 0xF3, 0x70, 0x70, + 8, 0x64, 0x28, 0x29, 0xF1, 0x01, 0xF1, 0x00, 0x07, + 11, 0x66, 0x3C, 0x00, 0xCD, 0x67, 0x45, 0x45, 0x10, 0x00, 0x00, 0x00, + 11, 0x67, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0x54, 0x10, 0x32, 0x98, + 8, 0x74, 0x10, 0x85, 0x80, 0x00, 0x00, 0x4E, 0x00, + 3, 0x98, 0x3E, 0x07, + 1, GC9A01_TEON, + 1, GC9A01_INVON, + 1, GC9A01_SLPOUT, + LCD_SEQUENCE_DELAY(100), + 2, GC9A01_MADCTL, 0x48, + 1, GC9A01_DISPON, + LCD_SEQUENCE_DELAY(100), +LCD_SEQUENCE_END + +/** + * Initialize the GC9A01 display controller + */ +void +gc9a01_init(lv_disp_drv_t *driver) +{ + lcd_command_sequence(init_cmds); +} + +static void +gc9a01_drv_update(struct _lv_disp_drv_t *drv) +{ + gc9a01_rotate(drv->rotated); +} + +void +gc9a01_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_p) +{ + int32_t y; + lv_coord_t w; + uint8_t cmd[5]; + + if (area->x2 < 0 || area->y2 < 0 || area->x1 >= GC9A01_HOR_RES || area->y1 >= GC9A01_VER_RES) { + lv_disp_flush_ready(drv); + return; + } + + /* Truncate the area to the screen */ + int32_t act_x1 = area->x1 < 0 ? 0 : area->x1; + int32_t act_y1 = area->y1 < 0 ? 0 : area->y1; + int32_t act_x2 = area->x2 >= GC9A01_HOR_RES ? GC9A01_HOR_RES - 1 : area->x2; + int32_t act_y2 = area->y2 >= GC9A01_VER_RES ? GC9A01_VER_RES - 1 : area->y2; + + w = lv_area_get_width(area); + + /* Column address */ + cmd[0] = GC9A01_CASET; + cmd[1] = (uint8_t)(act_x1 >> 8); + cmd[2] = (uint8_t)act_x1; + cmd[3] = (uint8_t)(act_x2 >> 8); + cmd[4] = (uint8_t)act_x2; + lcd_ift_write_cmd(cmd, 5); + + /* Page address */ + cmd[0] = GC9A01_RASET; + cmd[1] = (uint8_t)(act_y1 >> 8); + cmd[2] = (uint8_t)act_y1; + cmd[3] = (uint8_t)(act_y2 >> 8); + cmd[4] = (uint8_t)act_y2; + lcd_ift_write_cmd(cmd, 5); + + cmd[0] = GC9A01_RAMWR; + lcd_ift_write_cmd(cmd, 1); + + for (y = act_y1; y <= act_y2; y++) { + lcd_itf_write_color_data(color_p, w * sizeof(*color_p)); + color_p += w; + } + + lv_disp_flush_ready(drv); +} + +void +mynewt_lv_drv_init(lv_disp_drv_t *driver) +{ + if (MYNEWT_VAL(LCD_BL_PIN) >= 0) { + hal_gpio_init_out(MYNEWT_VAL(LCD_BL_PIN), 1); + } + if (MYNEWT_VAL(LCD_RESET_PIN) >= 0) { + hal_gpio_init_out(MYNEWT_VAL(LCD_RESET_PIN), 1); + } + lcd_itf_init(); + driver->flush_cb = gc9a01_flush; + driver->drv_update_cb = gc9a01_drv_update; + driver->hor_res = GC9A01_TFTWIDTH; + driver->ver_res = GC9A01_TFTHEIGHT; + + gc9a01_init(driver); +} diff --git a/hw/drivers/display/lvgl/tft/gc9a01/syscfg.yml b/hw/drivers/display/lvgl/tft/gc9a01/syscfg.yml new file mode 100644 index 000000000..b91b1193d --- /dev/null +++ b/hw/drivers/display/lvgl/tft/gc9a01/syscfg.yml @@ -0,0 +1,23 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +syscfg.defs: + +syscfg.vals: + LVGL_DISPLAY_HORIZONTAL_RESOLUTION: 240 + LVGL_DISPLAY_VERTICAL_RESOLUTION: 240
