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 220e8ebca1573eebab276cc179996da13fa479fb
Author: Jerzy Kasenberg <[email protected]>
AuthorDate: Thu Mar 2 14:10:36 2023 +0100

    lvgl/xpt2046: Add initial support for XPT2046 touch screen
    
    Signed-off-by: Jerzy Kasenberg <[email protected]>
---
 hw/drivers/display/lvgl/indev/xpt2046/pkg.yml      |  35 ++++
 .../display/lvgl/indev/xpt2046/src/xpt2046.c       | 192 +++++++++++++++++++++
 hw/drivers/display/lvgl/indev/xpt2046/syscfg.yml   |  54 ++++++
 hw/drivers/display/lvgl/pkg.yml                    |   3 +
 hw/drivers/display/lvgl/syscfg.yml                 |   3 +
 5 files changed, 287 insertions(+)

diff --git a/hw/drivers/display/lvgl/indev/xpt2046/pkg.yml 
b/hw/drivers/display/lvgl/indev/xpt2046/pkg.yml
new file mode 100644
index 000000000..b0ef9e5b6
--- /dev/null
+++ b/hw/drivers/display/lvgl/indev/xpt2046/pkg.yml
@@ -0,0 +1,35 @@
+# 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/indev/xpt2046
+pkg.description: LVGL touch screen driver for XPT2046
+pkg.author: "Apache Mynewt <[email protected]>"
+pkg.homepage: "http://mynewt.apache.org/";
+pkg.keywords:
+    - touchscreen
+    - lvgl
+
+pkg.deps:
+    - "@apache-mynewt-core/hw/bus/drivers/spi_common"
+
+pkg.include_dirs:
+    - "@lvgl/src"
+
+pkg.init:
+    xpt2046_os_dev_create: 400
+    xpt2046_register_lv_indev: 1100
diff --git a/hw/drivers/display/lvgl/indev/xpt2046/src/xpt2046.c 
b/hw/drivers/display/lvgl/indev/xpt2046/src/xpt2046.c
new file mode 100644
index 000000000..9ec052066
--- /dev/null
+++ b/hw/drivers/display/lvgl/indev/xpt2046/src/xpt2046.c
@@ -0,0 +1,192 @@
+/*
+ * 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 <stddef.h>
+#include <stdio.h>
+#include <os/os_time.h>
+#include <hal/hal_gpio.h>
+#include <bus/drivers/spi_common.h>
+#include <bsp/bsp.h>
+
+#include <hal/lv_hal_indev.h>
+#include <core/lv_disp.h>
+
+#define CMD_X_READ              0x90
+#define CMD_Y_READ              0xD0
+#define XPT2046_XY_SWAP         MYNEWT_VAL(XPT2046_XY_SWAP)
+#define XPT2046_X_INV           MYNEWT_VAL(XPT2046_X_INV)
+#define XPT2046_Y_INV           MYNEWT_VAL(XPT2046_Y_INV)
+#define XPT2046_MIN_X           MYNEWT_VAL(XPT2046_MIN_X)
+#define XPT2046_MIN_Y           MYNEWT_VAL(XPT2046_MIN_Y)
+#define XPT2046_MAX_X           MYNEWT_VAL(XPT2046_MAX_X)
+#define XPT2046_MAX_Y           MYNEWT_VAL(XPT2046_MAX_Y)
+#define XPT2046_X_RANGE         ((XPT2046_MAX_X) - (XPT2046_MIN_X))
+#define XPT2046_Y_RANGE         ((XPT2046_MAX_Y) - (XPT2046_MIN_Y))
+#define XPT2046_HOR_RES         MYNEWT_VAL(XPT2046_HOR_RES)
+#define XPT2046_VER_RES         MYNEWT_VAL(XPT2046_VER_RES)
+
+struct bus_spi_node touch;
+struct bus_spi_node_cfg touch_spi_cfg = {
+    .node_cfg.bus_name = MYNEWT_VAL(XPT2046_SPI_DEV_NAME),
+    .pin_cs = MYNEWT_VAL(XPT2046_SPI_CS_PIN),
+    .mode = BUS_SPI_MODE_0,
+    .data_order = HAL_SPI_MSB_FIRST,
+    .freq = MYNEWT_VAL(XPT2046_SPI_FREQ),
+};
+
+static struct os_dev *touch_dev;
+static lv_indev_drv_t xpt2046_drv;
+static lv_indev_t *xpt2046_dev;
+
+struct touch_screen_data {
+    /* ADC value for left edge */
+    uint16_t left;
+    /* ADC value for right edge */
+    uint16_t right;
+    /* ADC value for top edge */
+    uint16_t top;
+    /* ADC value for bottom edge */
+    uint16_t bottom;
+    /* Current value for X, Y detected */
+    int x;
+    int y;
+    /* Values that were last reported */
+    int last_x;
+    int last_y;
+};
+
+static struct touch_screen_data touch_screen_data = {
+    .left = MYNEWT_VAL(XPT2046_MIN_X),
+    .right = MYNEWT_VAL(XPT2046_MAX_X),
+    .top = MYNEWT_VAL(XPT2046_MIN_Y),
+    .bottom = MYNEWT_VAL(XPT2046_MAX_Y),
+};
+
+static void
+xpt2046_corr(int16_t *xp, int16_t *yp)
+{
+    int x;
+    int y;
+#if XPT2046_XY_SWAP
+    x = *yp;
+    y = *xp;
+#else
+    x = *xp;
+    y = *yp;
+#endif
+
+    if (x < MYNEWT_VAL(XPT2046_MIN_X)) {
+        x = MYNEWT_VAL(XPT2046_MIN_X);
+    }
+    if (y < MYNEWT_VAL(XPT2046_MIN_Y)) {
+        y = MYNEWT_VAL(XPT2046_MIN_Y);
+    }
+
+    x = (x - XPT2046_MIN_X) * LV_HOR_RES / XPT2046_X_RANGE;
+    y = (y - XPT2046_MIN_Y) * LV_VER_RES / XPT2046_Y_RANGE;
+
+#if XPT2046_X_INV
+    x = LV_HOR_RES - x;
+#endif
+
+#if XPT2046_Y_INV
+    y = LV_VER_RES - y;
+#endif
+    *xp = x;
+    *yp = y;
+}
+
+/**
+ * Get the current position and state of the touchpad
+ * @param data store the read data here
+ * @return false: because no ore data to be read
+ */
+void
+xpt2046_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
+{
+    uint8_t cmd[5] = {0};
+    uint8_t buf[5] = {0};
+    int16_t x;
+    int16_t y;
+    (void)indev_drv;
+
+    if (hal_gpio_read(MYNEWT_VAL(XPT2046_INT_PIN)) == 0) {
+        cmd[0] = CMD_X_READ;
+        cmd[1] = 0;
+        cmd[2] = CMD_Y_READ;
+        cmd[3] = 0;
+        cmd[4] = 0;
+        bus_node_duplex_write_read(touch_dev, cmd, buf, 5, 1000, 0);
+
+        /* Normalize */
+        x = (((uint16_t)buf[1] << 8) | buf[2]) >> 3;
+        y = (((uint16_t)buf[3] << 8) | buf[4]) >> 3;
+
+        /* Convert to screen coordinates */
+        xpt2046_corr(&x, &y);
+
+        touch_screen_data.last_x = x;
+        touch_screen_data.last_y = y;
+
+        data->state = LV_INDEV_STATE_PRESSED;
+    } else {
+        x = touch_screen_data.last_x;
+        y = touch_screen_data.last_y;
+        data->state = LV_INDEV_STATE_RELEASED;
+    }
+
+    data->point.x = x;
+    data->point.y = y;
+}
+
+/**
+ * Initialize the XPT2046
+ */
+void
+xpt2046_register_lv_indev(void)
+{
+    hal_gpio_init_in(MYNEWT_VAL(XPT2046_INT_PIN), HAL_GPIO_PULL_NONE);
+    /* Register a keypad input device */
+    lv_indev_drv_init(&xpt2046_drv);
+    xpt2046_drv.type = LV_INDEV_TYPE_POINTER;
+    xpt2046_drv.read_cb = xpt2046_read;
+    xpt2046_dev = lv_indev_drv_register(&xpt2046_drv);
+}
+
+void
+lv_touch_handler(void)
+{
+
+}
+
+void
+xpt2046_os_dev_create(void)
+{
+    hal_gpio_init_out(MYNEWT_VAL(XPT2046_SPI_CS_PIN), 1);
+
+    struct bus_node_callbacks cbs = { 0 };
+    int rc;
+
+    bus_node_set_callbacks((struct os_dev *)&touch, &cbs);
+
+    rc = bus_spi_node_create("touch", &touch, &touch_spi_cfg, NULL);
+    assert(rc == 0);
+    touch_dev = os_dev_open("touch", 0, NULL);
+}
diff --git a/hw/drivers/display/lvgl/indev/xpt2046/syscfg.yml 
b/hw/drivers/display/lvgl/indev/xpt2046/syscfg.yml
new file mode 100644
index 000000000..37bd86e89
--- /dev/null
+++ b/hw/drivers/display/lvgl/indev/xpt2046/syscfg.yml
@@ -0,0 +1,54 @@
+# 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:
+    XPT2046_SPI_DEV_NAME:
+        description: SPI device name that LCD is connected to.
+        value: '"spi0"'
+    XPT2046_SPI_CS_PIN:
+        description: STMPE610 chip select pin for SPI.
+        value:
+        restrictions: $notnull
+    XPT2046_SPI_FREQ:
+        description: SPI device frequency for LCD
+        value: 1000
+    XPT2046_INT_PIN:
+        description: XPT2046 interrupt pin.
+        value:
+        restrictions: $notnull
+    XPT2046_MIN_X:
+        description: XPT2046 left margin value.
+        value: 200
+    XPT2046_MAX_X:
+        description: XPT2046 right margin value.
+        value: 3800
+    XPT2046_MIN_Y:
+        description: XPT2046 top margin value.
+        value: 200
+    XPT2046_MAX_Y:
+        description: XPT2046 bottom margin value.
+        value: 3800
+    XPT2046_XY_SWAP:
+        description: Swap X and Y axis.
+        value: 0
+    XPT2046_X_INV:
+        description: Invert X coordinate.
+        value: 0
+    XPT2046_Y_INV:
+        description: Invert Y coordinate.
+        value: 0
diff --git a/hw/drivers/display/lvgl/pkg.yml b/hw/drivers/display/lvgl/pkg.yml
index 56360660f..d3a665564 100644
--- a/hw/drivers/display/lvgl/pkg.yml
+++ b/hw/drivers/display/lvgl/pkg.yml
@@ -69,6 +69,9 @@ pkg.deps.LVGL_ST7735S:
 pkg.deps.LVGL_ST7789:
     - "@apache-mynewt-core/hw/drivers/display/lvgl/tft/st7789"
 
+pkg.deps.LVGL_XPT2046:
+    - "@apache-mynewt-core/hw/drivers/display/lvgl/indev/xpt2046"
+
 pkg.cflags:
     - -DLV_CONF_INCLUDE_SIMPLE=1
     - -Wno-unused-variable
diff --git a/hw/drivers/display/lvgl/syscfg.yml 
b/hw/drivers/display/lvgl/syscfg.yml
index 67a4a5837..a1ff05106 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_XPT2046:
+        description: Enable XPT2046 touchscreen driver.
+        value:
     LVGL_TIMER_PERIOD_MS:
         description: LV timer interval for periodical refresh and touch read
         value: 10

Reply via email to