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 be347d1edfd81fef7cf10a7d13906a5e4ecbbe97
Author: Jerzy Kasenberg <[email protected]>
AuthorDate: Wed May 24 15:41:28 2023 +0200

    lvgl/trackball: Add support for Blackberry trackball
    
    Signed-off-by: Jerzy Kasenberg <[email protected]>
---
 hw/drivers/display/lvgl/indev/trackball/pkg.yml    |  33 ++++
 .../display/lvgl/indev/trackball/src/trackball.c   | 217 +++++++++++++++++++++
 hw/drivers/display/lvgl/indev/trackball/syscfg.yml |  66 +++++++
 hw/drivers/display/lvgl/pkg.yml                    |   2 +
 hw/drivers/display/lvgl/syscfg.yml                 |   3 +
 5 files changed, 321 insertions(+)

diff --git a/hw/drivers/display/lvgl/indev/trackball/pkg.yml 
b/hw/drivers/display/lvgl/indev/trackball/pkg.yml
new file mode 100644
index 000000000..35995db9c
--- /dev/null
+++ b/hw/drivers/display/lvgl/indev/trackball/pkg.yml
@@ -0,0 +1,33 @@
+# 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/trackball
+pkg.description: LVGL Blackberry trackball driver
+pkg.author: "Apache Mynewt <[email protected]>"
+pkg.homepage: "http://mynewt.apache.org/";
+pkg.keywords:
+    - mouse
+    - lvgl
+
+pkg.deps:
+
+pkg.include_dirs:
+    - "@lvgl/src"
+
+pkg.init:
+    trackball_register_lv_indev: 1100
diff --git a/hw/drivers/display/lvgl/indev/trackball/src/trackball.c 
b/hw/drivers/display/lvgl/indev/trackball/src/trackball.c
new file mode 100644
index 000000000..9fd51e3e8
--- /dev/null
+++ b/hw/drivers/display/lvgl/indev/trackball/src/trackball.c
@@ -0,0 +1,217 @@
+/*
+ * 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 <os/os_time.h>
+#include <bsp/bsp.h>
+#include <hal/hal_gpio.h>
+
+#include <hal/lv_hal_indev.h>
+#include <core/lv_disp.h>
+#include <core/lv_indev.h>
+#include <lvgl.h>
+#include <bsp/bsp.h>
+
+static lv_indev_drv_t trackball_drv;
+static lv_indev_t *trackball_dev;
+
+#define UP_PIN MYNEWT_VAL(TRACKBALL_UP_PIN)
+#define DOWN_PIN MYNEWT_VAL(TRACKBALL_DOWN_PIN)
+#define LEFT_PIN MYNEWT_VAL(TRACKBALL_LEFT_PIN)
+#define RIGHT_PIN MYNEWT_VAL(TRACKBALL_RIGHT_PIN)
+#define BUTTON_PIN MYNEWT_VAL(TRACKBALL_BUTTON_PIN)
+#define BUTTON_PIN_PULL MYNEWT_VAL(TRACKBALL_BUTTON_PIN_PULL)
+#define BUTTON_PIN_VALUE MYNEWT_VAL(TRACKBALL_BUTTON_PIN_VALUE)
+#define DRAG_PIN MYNEWT_VAL(TRACKBALL_DRAG_PIN)
+#define DRAG_PIN_VALUE MYNEWT_VAL(TRACKBALL_DRAG_PIN_VALUE)
+#define HOLD_TIME MYNEWT_VAL(TRACKBALL_HOLD_TO_DRAG_TIME_MS)
+
+struct accel {
+    uint32_t limit;
+    int increment;
+};
+
+static const struct accel accel_steps[] = {
+    { 10, 4 },
+    { 15, 3 },
+    { 30, 2 },
+    { 0, 1 },
+};
+struct trackball_data {
+    uint32_t up_time;
+    uint32_t down_time;
+    uint32_t left_time;
+    uint32_t right_time;
+    uint32_t press_time;
+    enum {
+        RELEASED,
+        PRESSED_WAITING_FOR_HOLD,
+        PRESSED,
+        PRESS_HELD,
+    } state;
+    bool hold;
+    bool reported;
+    /* Current value for X, Y detected */
+    int x;
+    int y;
+};
+
+static struct trackball_data trackball_data;
+
+static void
+movement_detected(void)
+{
+    if (trackball_data.state == PRESSED_WAITING_FOR_HOLD) {
+        trackball_data.state = PRESSED;
+    }
+}
+
+static int
+increment(uint32_t *t)
+{
+    uint32_t now = os_time_ticks_to_ms32(os_time_get());
+    uint32_t diff = now - *t;
+    *t = now;
+    int i;
+
+    for (i = 0; accel_steps[i].limit; ++i) {
+        if (diff < accel_steps[i].limit) {
+            break;
+        }
+    }
+    movement_detected();
+    return accel_steps[i].increment;
+}
+
+static void
+trackball_up(void *arg)
+{
+    (void)arg;
+
+    trackball_data.y -= increment(&trackball_data.up_time);
+}
+
+static void
+trackball_down(void *arg)
+{
+    (void)arg;
+
+    trackball_data.y += increment(&trackball_data.down_time);
+}
+
+static void
+trackball_left(void *arg)
+{
+    (void)arg;
+
+    trackball_data.x -= increment(&trackball_data.left_time);
+}
+
+static void
+trackball_right(void *arg)
+{
+    (void)arg;
+
+    trackball_data.x += increment(&trackball_data.right_time);
+}
+
+static void
+trackball_button(void *arg)
+{
+    (void)arg;
+    bool pressed = hal_gpio_read(BUTTON_PIN) == BUTTON_PIN_VALUE;
+
+    switch (trackball_data.state) {
+    case RELEASED:
+        if (pressed) {
+            trackball_data.state = PRESSED_WAITING_FOR_HOLD;
+            trackball_data.press_time = os_time_ticks_to_ms32(os_time_get());
+        }
+        break;
+    case PRESSED_WAITING_FOR_HOLD:
+    case PRESSED:
+        if (!pressed) {
+            trackball_data.state = RELEASED;
+        }
+        break;
+    case PRESS_HELD:
+        if (pressed) {
+            trackball_data.state = PRESSED_WAITING_FOR_HOLD;
+            trackball_data.press_time = os_time_ticks_to_ms32(os_time_get());
+        }
+        break;
+    }
+}
+
+/**
+ * Get the current position and state of the touchpad
+ * @param data store the read data here
+ */
+static void
+trackball_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
+{
+    uint32_t now = os_time_ticks_to_ms32(os_time_get());
+
+    if (trackball_data.state == PRESSED_WAITING_FOR_HOLD) {
+        if ((now - trackball_data.press_time) > HOLD_TIME) {
+            trackball_data.state = PRESS_HELD;
+        }
+    }
+    if (DRAG_PIN >= 0) {
+        hal_gpio_write(LED_1, trackball_data.state == PRESS_HELD ? 
DRAG_PIN_VALUE : !DRAG_PIN_VALUE);
+    }
+    data->state = trackball_data.state != RELEASED ? LV_INDEV_STATE_PRESSED : 
LV_INDEV_STATE_RELEASED;
+    if (trackball_data.x < 0) {
+        trackball_data.x = 0;
+    } else if (trackball_data.x >= LV_HOR_RES) {
+        trackball_data.x = LV_HOR_RES - 1;
+    }
+    if (trackball_data.y < 0) {
+        trackball_data.y = 0;
+    } else if (trackball_data.y >= LV_VER_RES) {
+        trackball_data.y = LV_VER_RES - 1;
+    }
+    data->point.x = trackball_data.x;
+    data->point.y = trackball_data.y;
+}
+
+/**
+ * Initialize the trackball indev
+ */
+void
+trackball_register_lv_indev(void)
+{
+    hal_gpio_irq_init(UP_PIN, trackball_up, NULL, HAL_GPIO_TRIG_BOTH, 
HAL_GPIO_PULL_NONE);
+    hal_gpio_irq_init(DOWN_PIN, trackball_down, NULL, HAL_GPIO_TRIG_BOTH, 
HAL_GPIO_PULL_NONE);
+    hal_gpio_irq_init(LEFT_PIN, trackball_left, NULL, HAL_GPIO_TRIG_BOTH, 
HAL_GPIO_PULL_NONE);
+    hal_gpio_irq_init(RIGHT_PIN, trackball_right, NULL, HAL_GPIO_TRIG_BOTH, 
HAL_GPIO_PULL_NONE);
+    hal_gpio_irq_init(BUTTON_PIN, trackball_button, NULL, HAL_GPIO_TRIG_BOTH, 
BUTTON_PIN_PULL);
+    if (DRAG_PIN >= 0) {
+        hal_gpio_init_out(DRAG_PIN, !DRAG_PIN_VALUE);
+    }
+    /* Register a keypad input device */
+    lv_indev_drv_init(&trackball_drv);
+    trackball_drv.type = LV_INDEV_TYPE_POINTER;
+    trackball_drv.read_cb = trackball_read;
+    trackball_dev = lv_indev_drv_register(&trackball_drv);
+
+    /*Set cursor. For simplicity set a HOME symbol now.*/
+    lv_obj_t *mouse_cursor = lv_img_create(lv_scr_act());
+    lv_img_set_src(mouse_cursor, LV_SYMBOL_BLUETOOTH);
+    lv_indev_set_cursor(trackball_dev, mouse_cursor);
+}
diff --git a/hw/drivers/display/lvgl/indev/trackball/syscfg.yml 
b/hw/drivers/display/lvgl/indev/trackball/syscfg.yml
new file mode 100644
index 000000000..7ec695f88
--- /dev/null
+++ b/hw/drivers/display/lvgl/indev/trackball/syscfg.yml
@@ -0,0 +1,66 @@
+# 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:
+    TRACKBALL_UP_PIN:
+        description: Trackball pin marked up.
+        restrictions:
+            - $notnull
+        value:
+    TRACKBALL_DOWN_PIN:
+        description: Trackball pin marked down.
+        restrictions:
+            - $notnull
+        value:
+    TRACKBALL_LEFT_PIN:
+        description: Trackball pin marked left.
+        restrictions:
+            - $notnull
+        value:
+    TRACKBALL_RIGHT_PIN:
+        description: Trackball pin marked right.
+        restrictions:
+            - $notnull
+        value:
+    TRACKBALL_BUTTON_PIN:
+        description: Trackball pin marked button.
+        restrictions:
+            - $notnull
+        value:
+    TRACKBALL_BUTTON_PIN_PULL:
+        description: Trackball button pull up configuration.
+        value: HAL_GPIO_PULL_NONE
+    TRACKBALL_BUTTON_PIN_VALUE:
+        description: >
+            Trackball button active value.
+            0 - GPIO reads 0 button pressed 
+            1 - GPIO reads 1 button pressed
+        value: 0
+    TRACKBALL_DRAG_PIN:
+        description: >
+            Pin for LED indicating that button is held.
+        value: -1
+    TRACKBALL_DRAG_PIN_VALUE:
+        description: >
+            Value to write to TRACKBALL_DRAG_PIN when drag is activated.
+        value: 1
+    TRACKBALL_HOLD_TO_DRAG_TIME_MS:
+        description: >
+            When this time is specified, holding button for this amount of time
+            start sticky button functionality.
+        value: 800
diff --git a/hw/drivers/display/lvgl/pkg.yml b/hw/drivers/display/lvgl/pkg.yml
index b40e34aa6..10bc372b8 100644
--- a/hw/drivers/display/lvgl/pkg.yml
+++ b/hw/drivers/display/lvgl/pkg.yml
@@ -75,6 +75,8 @@ pkg.deps.LVGL_STMPE610:
     - "@apache-mynewt-core/hw/drivers/display/lvgl/indev/stmpe610"
 pkg.deps.LVGL_ADC_TOUCH:
     - "@apache-mynewt-core/hw/drivers/display/lvgl/indev/adc_touch"
+pkg.deps.LVGL_TRACKBALL:
+    - "@apache-mynewt-core/hw/drivers/display/lvgl/indev/trackball"
 
 pkg.cflags:
     - -DLV_CONF_INCLUDE_SIMPLE=1
diff --git a/hw/drivers/display/lvgl/syscfg.yml 
b/hw/drivers/display/lvgl/syscfg.yml
index 7da15004b..55f2fe202 100644
--- a/hw/drivers/display/lvgl/syscfg.yml
+++ b/hw/drivers/display/lvgl/syscfg.yml
@@ -46,6 +46,9 @@ syscfg.defs:
     LVGL_ADC_TOUCH:
         description: Enable ADC touchscreen driver.
         value:
+    LVGL_TRACKBALL:
+        description: Enable Trackball driver.
+        value:
     LVGL_TIMER_PERIOD_MS:
         description: LV timer interval for periodical refresh and touch read
         value: 10

Reply via email to