diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-06-01 15:28:32 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-06-01 15:28:54 +1000 |
| commit | 6fd588e970470b15936187980829916d0dbe77bb (patch) | |
| tree | 1b1e73ef52bef2e41499ee5ceadc45efd408050b /src/drivers | |
| parent | db2e29a72d9b934e7b58f1d20ac3768eae484ab5 (diff) | |
| download | tangara-fw-6fd588e970470b15936187980829916d0dbe77bb.tar.gz | |
Add touchwheel -> encoder adapter
Diffstat (limited to 'src/drivers')
| -rw-r--r-- | src/drivers/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/drivers/display.cpp | 32 | ||||
| -rw-r--r-- | src/drivers/include/relative_wheel.hpp | 44 | ||||
| -rw-r--r-- | src/drivers/relative_wheel.cpp | 78 |
4 files changed, 144 insertions, 12 deletions
diff --git a/src/drivers/CMakeLists.txt b/src/drivers/CMakeLists.txt index 43e67786..82acab3d 100644 --- a/src/drivers/CMakeLists.txt +++ b/src/drivers/CMakeLists.txt @@ -4,7 +4,7 @@ idf_component_register( SRCS "touchwheel.cpp" "dac.cpp" "gpio_expander.cpp" "battery.cpp" "storage.cpp" "i2c.cpp" - "spi.cpp" "display.cpp" "display_init.cpp" "samd.cpp" + "spi.cpp" "display.cpp" "display_init.cpp" "samd.cpp" "relative_wheel.cpp" INCLUDE_DIRS "include" REQUIRES "esp_adc" "fatfs" "result" "lvgl" "span" "tasks") target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS}) diff --git a/src/drivers/display.cpp b/src/drivers/display.cpp index a503d0e9..0c9e56b3 100644 --- a/src/drivers/display.cpp +++ b/src/drivers/display.cpp @@ -12,6 +12,7 @@ #include "assert.h" #include "driver/gpio.h" +#include "driver/ledc.h" #include "driver/spi_master.h" #include "esp_attr.h" #include "esp_err.h" @@ -20,6 +21,7 @@ #include "freertos/portmacro.h" #include "freertos/projdefs.h" #include "hal/gpio_types.h" +#include "hal/ledc_types.h" #include "hal/lv_hal_disp.h" #include "hal/spi_types.h" #include "lvgl/lvgl.h" @@ -95,16 +97,24 @@ auto Display::Create(GpioExpander* expander, gpio_config(&dr_config); gpio_set_level(kDisplayDr, 0); - // TODO: use pwm for the backlight. - gpio_config_t led_config{ - .pin_bit_mask = 1ULL << kDisplayLedEn, - .mode = GPIO_MODE_OUTPUT, - .pull_up_en = GPIO_PULLUP_ENABLE, - .pull_down_en = GPIO_PULLDOWN_DISABLE, - .intr_type = GPIO_INTR_DISABLE, + ledc_timer_config_t led_config { + .speed_mode = LEDC_LOW_SPEED_MODE, + .duty_resolution = LEDC_TIMER_13_BIT, + .timer_num = LEDC_TIMER_0, + .freq_hz = 5000, + .clk_cfg = LEDC_AUTO_CLK, + }; + ledc_timer_config(&led_config); + + ledc_channel_config_t led_channel { + .gpio_num = kDisplayLedEn, + .speed_mode = LEDC_LOW_SPEED_MODE, + .channel = LEDC_CHANNEL_0, + .timer_sel = LEDC_TIMER_0, + .duty = 4095, + .hpoint = 0 }; - gpio_config(&led_config); - gpio_set_level(kDisplayLedEn, 1); + ledc_channel_config(&led_channel); // Next, init the SPI device spi_device_interface_config_t spi_cfg = { @@ -250,7 +260,7 @@ void Display::OnLvglFlush(lv_disp_drv_t* disp_drv, // area is stack-allocated, so it isn't safe to reference from the flush // thread. lv_area_t area_copy = *area; - worker_task_->Dispatch<void>([=, this]() { + //worker_task_->Dispatch<void>([=, this]() { // Ideally we want to complete a single flush as quickly as possible, so // grab the bus for this entire transaction sequence. spi_device_acquire_bus(handle_, portMAX_DELAY); @@ -276,7 +286,7 @@ void Display::OnLvglFlush(lv_disp_drv_t* disp_drv, spi_device_release_bus(handle_); lv_disp_flush_ready(&driver_); - }); + //}); } void RenderMain(void* raw_args) { diff --git a/src/drivers/include/relative_wheel.hpp b/src/drivers/include/relative_wheel.hpp new file mode 100644 index 00000000..3ff64b70 --- /dev/null +++ b/src/drivers/include/relative_wheel.hpp @@ -0,0 +1,44 @@ +/* + * Copyright 2023 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include <stdint.h> +#include <cstdint> +#include <functional> + +#include "esp_err.h" +#include "result.hpp" + +#include "gpio_expander.hpp" +#include "touchwheel.hpp" + +namespace drivers { + +class RelativeWheel { + public: + static auto Create(TouchWheel *touch) -> RelativeWheel* { return new RelativeWheel(touch); } + + explicit RelativeWheel(TouchWheel *touch); + + // Not copyable or movable. + RelativeWheel(const RelativeWheel&) = delete; + RelativeWheel& operator=(const RelativeWheel&) = delete; + + auto Update() -> void; + + auto is_pressed() -> bool; + auto ticks() -> std::int_fast16_t; + + private: + TouchWheel *touch_; + bool is_pressed_; + bool is_first_read_; + std::int_fast16_t ticks_; + uint8_t last_angle_; +}; + +} // namespace drivers diff --git a/src/drivers/relative_wheel.cpp b/src/drivers/relative_wheel.cpp new file mode 100644 index 00000000..f64d213d --- /dev/null +++ b/src/drivers/relative_wheel.cpp @@ -0,0 +1,78 @@ +/* + * Copyright 2023 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "relative_wheel.hpp" + +#include <stdint.h> +#include <cstdint> + +#include "esp_log.h" + +namespace drivers { + +RelativeWheel::RelativeWheel(TouchWheel *touch) + :touch_(touch), + is_pressed_(false), + is_first_read_(true), + ticks_(0), + last_angle_(0) {} + +auto RelativeWheel::Update() -> void { + touch_->Update(); + TouchWheelData d = touch_->GetTouchWheelData(); + is_pressed_ = d.is_touched; + + uint8_t new_angle = d.wheel_position; + if (is_first_read_) { + is_first_read_ = false; + last_angle_ = new_angle; + return; + } + + // Work out the magnitude of travel. + uint8_t change_cw = last_angle_ - new_angle; + uint8_t change_ccw = new_angle - last_angle_; + int change = std::min(change_cw, change_ccw); + + last_angle_ = new_angle; + + // Round to eliminate noise. + if (change <= 2) { + ticks_ = 0; + return; + } + + // Quantize into ticks. + change /= 4; + + // Clamp to reliminate more noise. + if (change > 10) { + change = 0; + } + + // Work out the direction of travel. + if (change_cw > change_ccw) { + change *= -1; + } + + ticks_ = change; +} + +auto RelativeWheel::is_pressed() -> bool { + return is_pressed_; +} + +auto RelativeWheel::ticks() -> std::int_fast16_t { + int_fast16_t t = ticks_; + if (t != 0) { + ESP_LOGI("teeks", "ticks %d", t); + } + ticks_ = 0; + return t; +} + + +} // namespace drivers |
