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
