From 293c6cf5d869503f72593542d9a87bffe0652642 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Mon, 5 Jan 2026 23:58:30 +0100 Subject: [PATCH] Fixes --- .../Source/devices/St7701Display.cpp | 2 +- .../Source/devices/TpagerEncoder.cpp | 60 ++++++++++++++++++- .../Source/devices/TpagerEncoder.h | 3 +- Drivers/DRV2605/Source/Drv2605.cpp | 2 + TactilityCore/Include/Tactility/Check.h | 1 + 5 files changed, 63 insertions(+), 5 deletions(-) diff --git a/Devices/cyd-4848s040c/Source/devices/St7701Display.cpp b/Devices/cyd-4848s040c/Source/devices/St7701Display.cpp index c0b9a7a8..bc337e4e 100644 --- a/Devices/cyd-4848s040c/Source/devices/St7701Display.cpp +++ b/Devices/cyd-4848s040c/Source/devices/St7701Display.cpp @@ -11,7 +11,7 @@ #include #include -static const auto LOGGER = Logger("St7701Display"); +static const auto LOGGER = tt::Logger("St7701Display"); static const st7701_lcd_init_cmd_t st7701_lcd_init_cmds[] = { // {cmd, { data }, data_size, delay_ms} diff --git a/Devices/lilygo-tlora-pager/Source/devices/TpagerEncoder.cpp b/Devices/lilygo-tlora-pager/Source/devices/TpagerEncoder.cpp index 7a07a4dc..1e1c5020 100644 --- a/Devices/lilygo-tlora-pager/Source/devices/TpagerEncoder.cpp +++ b/Devices/lilygo-tlora-pager/Source/devices/TpagerEncoder.cpp @@ -40,7 +40,9 @@ void TpagerEncoder::readCallback(lv_indev_t* indev, lv_indev_data_t* data) { } } -void TpagerEncoder::initEncoder() { +bool TpagerEncoder::initEncoder() { + assert(encPcntUnit == nullptr); + constexpr int LOW_LIMIT = -127; constexpr int HIGH_LIMIT = 126; @@ -49,11 +51,15 @@ void TpagerEncoder::initEncoder() { pcnt_unit_config_t unit_config = { .low_limit = LOW_LIMIT, .high_limit = HIGH_LIMIT, - .flags = {.accum_count = 1}, + .intr_priority = 0, + .flags = { + .accum_count = 1 + }, }; if (pcnt_new_unit(&unit_config, &encPcntUnit) != ESP_OK) { LOGGER.error("Pulsecounter initialization failed"); + return false; } pcnt_glitch_filter_config_t filter_config = { @@ -62,16 +68,31 @@ void TpagerEncoder::initEncoder() { if (pcnt_unit_set_glitch_filter(encPcntUnit, &filter_config) != ESP_OK) { LOGGER.error("Pulsecounter glitch filter config failed"); + return false; } pcnt_chan_config_t chan_1_config = { .edge_gpio_num = ENCODER_B, .level_gpio_num = ENCODER_A, + .flags { + .invert_edge_input = 0, + .invert_level_input = 0, + .virt_edge_io_level = 0, + .virt_level_io_level = 0, + .io_loop_back = 0 + } }; pcnt_chan_config_t chan_2_config = { .edge_gpio_num = ENCODER_A, .level_gpio_num = ENCODER_B, + .flags { + .invert_edge_input = 0, + .invert_level_input = 0, + .virt_edge_io_level = 0, + .virt_level_io_level = 0, + .io_loop_back = 0 + } }; pcnt_channel_handle_t pcnt_chan_1 = nullptr; @@ -80,36 +101,45 @@ void TpagerEncoder::initEncoder() { if ((pcnt_new_channel(encPcntUnit, &chan_1_config, &pcnt_chan_1) != ESP_OK) || (pcnt_new_channel(encPcntUnit, &chan_2_config, &pcnt_chan_2) != ESP_OK)) { LOGGER.error("Pulsecounter channel config failed"); + return false; } // Second argument is rising edge, third argument is falling edge if ((pcnt_channel_set_edge_action(pcnt_chan_1, PCNT_CHANNEL_EDGE_ACTION_DECREASE, PCNT_CHANNEL_EDGE_ACTION_INCREASE) != ESP_OK) || (pcnt_channel_set_edge_action(pcnt_chan_2, PCNT_CHANNEL_EDGE_ACTION_INCREASE, PCNT_CHANNEL_EDGE_ACTION_DECREASE) != ESP_OK)) { LOGGER.error("Pulsecounter edge action config failed"); + return false; } // Second argument is low level, third argument is high level if ((pcnt_channel_set_level_action(pcnt_chan_1, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_INVERSE) != ESP_OK) || (pcnt_channel_set_level_action(pcnt_chan_2, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_INVERSE) != ESP_OK)) { LOGGER.error("Pulsecounter level action config failed"); + return false; } if ((pcnt_unit_add_watch_point(encPcntUnit, LOW_LIMIT) != ESP_OK) || (pcnt_unit_add_watch_point(encPcntUnit, HIGH_LIMIT) != ESP_OK)) { LOGGER.error("Pulsecounter watch point config failed"); + return false; } if (pcnt_unit_enable(encPcntUnit) != ESP_OK) { LOGGER.error("Pulsecounter could not be enabled"); + return false; } if (pcnt_unit_clear_count(encPcntUnit) != ESP_OK) { LOGGER.error("Pulsecounter could not be cleared"); + return false; } if (pcnt_unit_start(encPcntUnit) != ESP_OK) { LOGGER.error("Pulsecounter could not be started"); + return false; } + + return true; } int TpagerEncoder::getEncoderPulses() const { @@ -118,9 +148,28 @@ int TpagerEncoder::getEncoderPulses() const { return pulses; } +bool TpagerEncoder::deinitEncoder() { + assert(encPcntUnit != nullptr); + + if (pcnt_unit_stop(encPcntUnit) != ESP_OK) { + LOGGER.warn("Failed to stop encoder"); + } + + if (pcnt_del_unit(encPcntUnit) != ESP_OK) { + LOGGER.warn("Failed to delete encoder"); + return false; + } + + LOGGER.info("Deinitialized"); + + return true; +} + bool TpagerEncoder::startLvgl(lv_display_t* display) { - initEncoder(); + if (encPcntUnit == nullptr && !initEncoder()) { + return false; + } gpio_input_enable(ENCODER_ENTER); @@ -138,5 +187,10 @@ bool TpagerEncoder::stopLvgl() { lv_indev_delete(encHandle); encHandle = nullptr; + if (encPcntUnit != nullptr && !deinitEncoder()) { + // We're not returning false as LVGL as effectively deinitialized + LOGGER.warn("Deinitialization failed"); + } + return true; } diff --git a/Devices/lilygo-tlora-pager/Source/devices/TpagerEncoder.h b/Devices/lilygo-tlora-pager/Source/devices/TpagerEncoder.h index 3081af03..026d1cb9 100644 --- a/Devices/lilygo-tlora-pager/Source/devices/TpagerEncoder.h +++ b/Devices/lilygo-tlora-pager/Source/devices/TpagerEncoder.h @@ -8,7 +8,8 @@ class TpagerEncoder final : public tt::hal::encoder::EncoderDevice { lv_indev_t* _Nullable encHandle = nullptr; pcnt_unit_handle_t encPcntUnit = nullptr; - void initEncoder(); + bool initEncoder(); + bool deinitEncoder(); static void readCallback(lv_indev_t* indev, lv_indev_data_t* data); diff --git a/Drivers/DRV2605/Source/Drv2605.cpp b/Drivers/DRV2605/Source/Drv2605.cpp index 3957fe30..b5bb4358 100644 --- a/Drivers/DRV2605/Source/Drv2605.cpp +++ b/Drivers/DRV2605/Source/Drv2605.cpp @@ -1,5 +1,6 @@ #include "Drv2605.h" +#include #include static const auto LOGGER = tt::Logger("DRV2605"); @@ -7,6 +8,7 @@ static const auto LOGGER = tt::Logger("DRV2605"); Drv2605::Drv2605(i2c_port_t port, bool autoPlayStartupBuzz) : I2cDevice(port, ADDRESS), autoPlayStartupBuzz(autoPlayStartupBuzz) { if (!init()) { LOGGER.error("Failed to initialize DRV2605"); + tt_crash(); } if (autoPlayStartupBuzz) { diff --git a/TactilityCore/Include/Tactility/Check.h b/TactilityCore/Include/Tactility/Check.h index 81951662..c0f93c94 100644 --- a/TactilityCore/Include/Tactility/Check.h +++ b/TactilityCore/Include/Tactility/Check.h @@ -28,6 +28,7 @@ namespace tt { TT_NORETURN void _crash(); } +// TODO: Move crash logic to kernel namespace and consider refactoring to C++ /** Crash system with message. */ #define tt_crash(...) TT_ARG_CAT(_tt_crash,TT_ARGCOUNT(__VA_ARGS__))(__VA_ARGS__)