summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-06-01 15:28:32 +1000
committerjacqueline <me@jacqueline.id.au>2023-06-01 15:28:54 +1000
commit6fd588e970470b15936187980829916d0dbe77bb (patch)
tree1b1e73ef52bef2e41499ee5ceadc45efd408050b /src/drivers
parentdb2e29a72d9b934e7b58f1d20ac3768eae484ab5 (diff)
downloadtangara-fw-6fd588e970470b15936187980829916d0dbe77bb.tar.gz
Add touchwheel -> encoder adapter
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/CMakeLists.txt2
-rw-r--r--src/drivers/display.cpp32
-rw-r--r--src/drivers/include/relative_wheel.hpp44
-rw-r--r--src/drivers/relative_wheel.cpp78
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