This is an automated email from the ASF dual-hosted git repository.

jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit ea8db0f5bd11a6409afe970b22b4ff1eef5f5f66
Author: Jerzy Kasenberg <[email protected]>
AuthorDate: Mon May 19 12:00:07 2025 +0200

    lvgl/st7796s: Add initial support for ST7796S TFT
    
    Initial support for ST7798S displays with
    320x480 resolution.
    
    Signed-off-by: Jerzy Kasenberg <[email protected]>
---
 hw/drivers/display/lvgl/pkg.yml                   |   2 +
 hw/drivers/display/lvgl/syscfg.yml                |   3 +
 hw/drivers/display/lvgl/tft/st7796S/pkg.yml       |  23 ++
 hw/drivers/display/lvgl/tft/st7796S/src/st7796s.c | 275 ++++++++++++++++++++++
 hw/drivers/display/lvgl/tft/st7796S/syscfg.yml    |  26 ++
 5 files changed, 329 insertions(+)

diff --git a/hw/drivers/display/lvgl/pkg.yml b/hw/drivers/display/lvgl/pkg.yml
index 9e37327b2..d1ddf73a4 100644
--- a/hw/drivers/display/lvgl/pkg.yml
+++ b/hw/drivers/display/lvgl/pkg.yml
@@ -68,6 +68,8 @@ pkg.deps.LVGL_ST7735S:
     - "@apache-mynewt-core/hw/drivers/display/lvgl/tft/st7735s"
 pkg.deps.LVGL_ST7789:
     - "@apache-mynewt-core/hw/drivers/display/lvgl/tft/st7789"
+pkg.deps.LVGL_ST7796S:
+    - "@apache-mynewt-core/hw/drivers/display/lvgl/tft/st7796S"
 
 pkg.deps.LVGL_CST816S:
     - "@apache-mynewt-core/hw/drivers/display/lvgl/indev/cst816s"
diff --git a/hw/drivers/display/lvgl/syscfg.yml 
b/hw/drivers/display/lvgl/syscfg.yml
index 7acf04ffd..411dc7b1c 100644
--- a/hw/drivers/display/lvgl/syscfg.yml
+++ b/hw/drivers/display/lvgl/syscfg.yml
@@ -37,6 +37,9 @@ syscfg.defs:
     LVGL_ST7789:
         description: Enable ST7789 display driver.
         value:
+    LVGL_ST7796S:
+        description: Enable ST7796S display driver.
+        value:
     LVGL_XPT2046:
         description: Enable XPT2046 touchscreen driver.
         value:
diff --git a/hw/drivers/display/lvgl/tft/st7796S/pkg.yml 
b/hw/drivers/display/lvgl/tft/st7796S/pkg.yml
new file mode 100644
index 000000000..a288c59b4
--- /dev/null
+++ b/hw/drivers/display/lvgl/tft/st7796S/pkg.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.
+#
+
+pkg.name: hw/drivers/display/lvgl/tft/st7796S
+pkg.description: LVGL display driver for ST7796S
+pkg.author: "Apache Mynewt <[email protected]>"
+pkg.homepage: "http://mynewt.apache.org/";
+pkg.keywords:
diff --git a/hw/drivers/display/lvgl/tft/st7796S/src/st7796s.c 
b/hw/drivers/display/lvgl/tft/st7796S/src/st7796s.c
new file mode 100644
index 000000000..4a498deeb
--- /dev/null
+++ b/hw/drivers/display/lvgl/tft/st7796S/src/st7796s.c
@@ -0,0 +1,275 @@
+/*
+ * 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 <bsp/bsp.h>
+#include <lv_glue.h>
+#include <hal/lv_hal_disp.h>
+#include <hal/hal_gpio.h>
+#include <lcd_itf.h>
+
+/* Magic numbers used to lock/unlock command settings */
+#define ST7796S_UNLOCK_1         0xC3
+#define ST7796S_UNLOCK_2         0x96
+
+#define ST7796S_LOCK_1           0x3C
+#define ST7796S_LOCK_2           0x69
+
+#define ST7796S_NOP              0x00
+#define ST7796S_SWRESET          0x01
+#define ST7796S_RDDID            0x04
+#define ST7796S_RDDST            0x09
+#define ST7796S_RDDPM            0x0A
+#define ST7796S_RDDDMADCTL       0x0B
+#define ST7796S_RDDCOLMOD        0x0C
+#define ST7796S_RDDIM            0x0D
+#define ST7796S_RDDSM            0x0E
+#define ST7796S_RDDSDR           0x0F
+
+#define ST7796S_SLPIN            0x10
+#define ST7796S_SLPOUT           0x11
+#define ST7796S_PTLON            0x12
+#define ST7796S_NORON            0x13
+
+#define ST7796S_INVOFF           0x20
+#define ST7796S_INVON            0x21
+#define ST7796S_DISPOFF          0x28
+#define ST7796S_DISPON           0x29
+#define ST7796S_CASET            0x2A
+#define ST7796S_RASET            0x2B
+#define ST7796S_RAMWR            0x2C
+#define ST7796S_RAMRD            0x2E
+
+#define ST7796S_PTLAR            0x30
+#define ST7796S_VSCRDEF          0x33
+#define ST7796S_TEOFF            0x34
+#define ST7796S_TEON             0x35
+#define ST7796S_MADCTL           0x36
+#define ST7796S_VSCRSADD         0x37
+#define ST7796S_IDMOFF           0x38
+#define ST7796S_IDMON            0x39
+#define ST7796S_COLMOD           0x3A
+#define ST7796S_WRMEMC           0x3C
+#define ST7796S_RDMEMC           0x3E
+#define ST7796S_STE              0x44
+#define ST7796S_GSCAN            0x45
+#define ST7796S_WRDISBV          0x51
+#define ST7796S_RDDISBV          0x52
+#define ST7796S_WRCTRLD          0x53
+#define ST7796S_RDCTRLD          0x54
+#define ST7796S_WRCACE           0x55
+#define ST7796S_RDCABC           0x56
+#define ST7796S_WRCABCMB         0x5E
+#define ST7796S_RDCABCMB         0x5F
+#define ST7796S_RDABCSDR         0x68
+
+#define ST7796S_IFMODE           0xB0
+#define ST7796S_FRMCTR1          0xB1
+#define ST7796S_FRMCTR2          0xB2
+#define ST7796S_FRMCTR3          0xB3
+#define ST7796S_DIC              0xB4
+#define ST7796S_BPC              0xB5
+#define ST7796S_DFC              0xB6
+#define ST7796S_EM               0xB7
+
+#define ST7796S_DGMEN            0xBA
+#define ST7796S_VCOMS            0xBB
+#define ST7796S_POWSAVE          0xBC
+#define ST7796S_DLPOFFSAVE       0xBD
+
+#define ST7796S_PWR1             0xC0
+#define ST7796S_PWR2             0xC1
+#define ST7796S_PWR3             0xC2
+
+#define ST7796S_VCMPCTL          0xC5
+
+#define ST7796S_NVMADW           0xD0
+#define ST7796S_NVMBPROG         0xD1
+#define ST7796S_NVM              0xD2
+#define ST7796S_RDID4            0xD3
+
+#define ST7796S_PGC              0xE0
+#define ST7796S_NGC              0xE1
+#define ST7796S_DGC1             0xE2
+#define ST7796S_DGC2             0xE3
+
+#define ST7796S_DOCA             0xE8
+
+#define ST7796S_PROMCTRL         0xEC
+
+#define ST7796S_CSCON            0xF0
+#define ST7796S_PROMEN           0xFA
+
+#define ST7796S_NVMSET           0xFC
+
+#define ST7796S_PROMCAT          0xFE
+
+#define ST7796S_MADCTL_MY        0x80
+#define ST7796S_MADCTL_MX        0x40
+#define ST7796S_MADCTL_MV        0x20
+#define ST7796S_MADCTL_ML        0x10
+#define ST7796S_MADCTL_RGB       0x00
+#define ST7796S_MADCTL_BGR       0x08
+#define ST7796S_MADCTL_0         ST7796S_MADCTL_MX
+#define ST7796S_MADCTL_90        (ST7796S_MADCTL_MV)
+#define ST7796S_MADCTL_180       (ST7796S_MADCTL_MY | ST7796S_MADCTL_ML)
+#define ST7796S_MADCTL_270       (ST7796S_MADCTL_MY | ST7796S_MADCTL_ML | 
ST7796S_MADCTL_MV | ST7796S_MADCTL_MX)
+
+#define ST7796S_HOR_RES          MYNEWT_VAL(LVGL_DISPLAY_HORIZONTAL_RESOLUTION)
+#define ST7796S_VER_RES          MYNEWT_VAL(LVGL_DISPLAY_VERTICAL_RESOLUTION)
+
+void
+st7789_rotate(lv_disp_rot_t rotation)
+{
+    uint8_t madcmd[2] = { ST7796S_MADCTL, ST7796S_MADCTL_BGR };
+
+    switch (rotation) {
+    case LV_DISP_ROT_270:
+        madcmd[1] |= ST7796S_MADCTL_270;
+        break;
+    case LV_DISP_ROT_180:
+        madcmd[1] |= ST7796S_MADCTL_180;
+        break;
+    case LV_DISP_ROT_90:
+        madcmd[1] |= ST7796S_MADCTL_90;
+        break;
+    case LV_DISP_ROT_NONE:
+        madcmd[1] |= ST7796S_MADCTL_0;
+        break;
+    }
+    lcd_ift_write_cmd(madcmd, 2);
+}
+
+LCD_SEQUENCE(init_cmds)
+        LCD_SEQUENCE_LCD_CS_INACTIVATE(),
+        LCD_SEQUENCE_LCD_DC_DATA(),
+        1, ST7796S_NOP,
+#if MYNEWT_VAL(LCD_RESET_PIN) < 0
+        1, ST7796S_SWRESET,
+        LCD_SEQUENCE_DELAY(5),
+#else
+        LCD_SEQUENCE_LCD_RESET_ACTIVATE(),
+        LCD_SEQUENCE_DELAY_US(100),
+        LCD_SEQUENCE_LCD_RESET_INACTIVATE(),
+        LCD_SEQUENCE_DELAY(5),
+#endif
+        2, ST7796S_CSCON, ST7796S_UNLOCK_1,
+        2, ST7796S_CSCON, ST7796S_UNLOCK_2,
+        2, ST7796S_MADCTL, ST7796S_MADCTL_0 | ST7796S_MADCTL_BGR,
+        2, ST7796S_COLMOD, 0x55,
+        4, ST7796S_DFC, 0x8A, 0x07, 0x3B,
+        5, ST7796S_BPC, 2, 3, 0, 4,
+        3, ST7796S_FRMCTR1, 0x80, 0x10,
+        2, ST7796S_DIC, 0,
+        2, ST7796S_EM, 0xc6,
+        2, ST7796S_VCMPCTL, 0x24,
+        9, ST7796S_DOCA, 0x40, 0x8A, 0x00, 0x00, 0x29, 0x19, 0xA5, 0x33,
+        2, ST7796S_PWR3, 0xA7,
+        15, ST7796S_PGC, 0xF0, 0x09, 0x13, 0x12, 0x12, 0x2B, 0x3C, 0x44, 0x4B, 
0x1B, 0x18, 0x17, 0x1D, 0x21,
+        15, ST7796S_NGC, 0xF0, 0x09, 0x13, 0x0C, 0x0D, 0x27, 0x3B, 0x44, 0x4D, 
0x0B, 0x17, 0x17, 0x1D, 0x21,
+        2, ST7796S_CSCON, ST7796S_LOCK_1,
+        2, ST7796S_CSCON, ST7796S_LOCK_2,
+        1, ST7796S_NORON,
+#if MYNEWT_VAL(ST7796S_INVERSION_ON)
+        1, ST7796S_INVON,
+#else
+        1, ST7796S_INVOFF,
+#endif
+        1, ST7796S_SLPOUT,
+        LCD_SEQUENCE_DELAY(15),
+        1, ST7796S_DISPON,
+LCD_SEQUENCE_END
+
+/**
+ *
+ * Initialize the ST7789 display controller
+ */
+void
+st7789_init(lv_disp_drv_t *driver)
+{
+    (void)driver;
+
+    lcd_command_sequence(init_cmds);
+}
+
+static void
+st7789_drv_update(struct _lv_disp_drv_t *drv)
+{
+    st7789_rotate(drv->rotated);
+}
+
+void
+st7789_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_p)
+{
+    uint8_t cmd[5];
+    lv_disp_t *disp = lv_disp_get_default();
+    lv_coord_t hor_res = lv_disp_get_hor_res(disp);
+    lv_coord_t ver_res = lv_disp_get_ver_res(disp);
+
+    if (area->x2 < 0 || area->y2 < 0 || area->x1 >= hor_res || area->y1 >= 
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 >= hor_res ? hor_res - 1 : area->x2;
+    int32_t act_y2 = area->y2 >= ver_res ? ver_res - 1 : area->y2;
+
+    /* Column addresses */
+    cmd[0] = ST7796S_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] = ST7796S_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] = ST7796S_RAMWR;
+    lcd_ift_write_cmd(cmd, 1);
+
+    lcd_itf_write_color_data(act_x1, act_x2, act_y1, act_y2, color_p);
+
+    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), 
MYNEWT_VAL(LCD_BL_PIN_ACTIVE_LEVEL));
+    }
+    if (MYNEWT_VAL(LCD_RESET_PIN) >= 0) {
+        hal_gpio_init_out(MYNEWT_VAL(LCD_RESET_PIN), 1);
+    }
+    lcd_itf_init();
+    driver->flush_cb = st7789_flush;
+    driver->drv_update_cb = st7789_drv_update;
+    driver->hor_res = ST7796S_HOR_RES;
+    driver->ver_res = ST7796S_VER_RES;
+
+    st7789_init(driver);
+}
diff --git a/hw/drivers/display/lvgl/tft/st7796S/syscfg.yml 
b/hw/drivers/display/lvgl/tft/st7796S/syscfg.yml
new file mode 100644
index 000000000..69d93d64e
--- /dev/null
+++ b/hw/drivers/display/lvgl/tft/st7796S/syscfg.yml
@@ -0,0 +1,26 @@
+# 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:
+    ST7796S_INVERSION_ON:
+        description: ST7796S enable display inversion.
+        value: 0
+
+syscfg.vals:
+    LVGL_DISPLAY_HORIZONTAL_RESOLUTION: 320
+    LVGL_DISPLAY_VERTICAL_RESOLUTION: 480

Reply via email to