From 0addef4cf51d9f26c86ac553f0fdd2832d19a5e5 Mon Sep 17 00:00:00 2001 From: GOB Date: Sat, 20 Jun 2026 16:29:57 +0900 Subject: [PATCH 1/4] Default Si12T to the original firmware sensitivity (Type_Low/Level_3) --- src/utils/touch_sensor/touch_sensor.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/utils/touch_sensor/touch_sensor.cpp b/src/utils/touch_sensor/touch_sensor.cpp index ba24488..c1c59d4 100644 --- a/src/utils/touch_sensor/touch_sensor.cpp +++ b/src/utils/touch_sensor/touch_sensor.cpp @@ -13,7 +13,9 @@ static const char* TAG = "TouchSensor"; void TouchSensor_Class::begin() { - _touch_sensor = std::make_unique(SI12T_Type_High, SI12T_Sensitivity_Level_4); + // Match the original StackChan firmware (reg 0x33 = Type_Low/Level_3). The previous default + // was the more sensitive Type_High/Level_4 (0xCC). + _touch_sensor = std::make_unique(SI12T_Type_Low, SI12T_Sensitivity_Level_3); _touch_sensor->begin(); _in_gesture = false; From 451f68397ebab6e115ff834d74b50f1528a367fe Mon Sep 17 00:00:00 2001 From: GOB Date: Sat, 20 Jun 2026 16:29:57 +0900 Subject: [PATCH 2/4] Add SI12T_Set_Config and SI12T_Reset_Reference register helpers --- src/drivers/Si12T/Si12T.cpp | 27 +++++++++++++++++++++++++-- src/drivers/Si12T/Si12T.h | 10 ++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/drivers/Si12T/Si12T.cpp b/src/drivers/Si12T/Si12T.cpp index be56480..61462d5 100644 --- a/src/drivers/Si12T/Si12T.cpp +++ b/src/drivers/Si12T/Si12T.cpp @@ -136,10 +136,33 @@ int8_t Si12T::SI12T_Set_Sensitivity(uint8_t sens_type, uint8_t sens_level) void Si12T::set_Ctrl1(void) { - // sends register data, Auto Moe,FTC=01, Interrupt(Middle,High), Response 4 (2+2) + // CFIG = MS | FTC[1:0] | ILC[1:0] | RTC[2:0]. Defaults reproduce the original 0x22 + // (auto mode, FTC = 10 s, interrupt on middle/high, response cycle 4 = RTC 2 + 2). + SI12T_Set_Config(cfg_ms, cfg_ftc, cfg_ilc, cfg_rtc); +} + +int8_t Si12T::SI12T_Set_Config(uint8_t ms, uint8_t ftc, uint8_t ilc, uint8_t rtc) +{ + cfg_ms = ms & 0x01; + cfg_ftc = ftc & 0x03; + cfg_ilc = ilc & 0x03; + cfg_rtc = rtc & 0x07; + uint8_t value = (cfg_ms << 7) | (cfg_ftc << 5) | (cfg_ilc << 3) | cfg_rtc; + SI12T_Writeregister(SI12T_CTRL1_ADDR, value); uint8_t test; - SI12T_Writeregister(SI12T_CTRL1_ADDR, 0x22); SI12T_Readregister(SI12T_CTRL1_ADDR, &test); + log_d("CFIG: 0x%02x", value); + return 0; +} + +void Si12T::SI12T_Reset_Reference(void) +{ + // Setting a channel bit to 1 forces its reference (baseline) value to update + // (datasheet 12.2.4). Pulse all channels high then back to the normal 0 state. + SI12T_Writeregister(SI12T_REF_RST1_ADDR, 0xFF); // channel 1-8 update + SI12T_Writeregister(SI12T_REF_RST2_ADDR, 0x0F); // channel 9-12 update + SI12T_Writeregister(SI12T_REF_RST1_ADDR, 0x00); + SI12T_Writeregister(SI12T_REF_RST2_ADDR, 0x00); } void Si12T::set_Ctrl2(void) diff --git a/src/drivers/Si12T/Si12T.h b/src/drivers/Si12T/Si12T.h index 7e09cb9..38c18e5 100644 --- a/src/drivers/Si12T/Si12T.h +++ b/src/drivers/Si12T/Si12T.h @@ -59,6 +59,11 @@ class Si12T : public m5::I2C_Device { int8_t SI12T_Set_Sensitivity(uint8_t sens_type, uint8_t sens_level); uint8_t set_sens(uint8_t value); void SI12T_Get_Sensitivity(void); + // Compose and write the CFIG register (0x08 = MS | FTC[1:0] | ILC[1:0] | RTC[2:0]). + // rtc raises the response cycle (= rtc + 2), i.e. the debounce against false touches. + int8_t SI12T_Set_Config(uint8_t ms, uint8_t ftc, uint8_t ilc, uint8_t rtc); + // Force a reference-value (baseline) update on all channels (Ref_rst 0x0A/0x0B). + void SI12T_Reset_Reference(void); void set_Ctrl1(void); void set_Ctrl2(void); void sleep_enable(void); @@ -69,6 +74,11 @@ class Si12T : public m5::I2C_Device { uint8_t sens_type = SI12T_Type_Low; uint8_t sens_level = SI12T_Sensitivity_Level_0; + // CFIG (0x08) fields. Defaults reproduce the original 0x22 register value. + uint8_t cfg_ms = 0; // MS: 0 = auto (fast/slow) mode, 1 = fast mode + uint8_t cfg_ftc = 1; // FTC[1:0]: first-touch recalibration time (01 = 10 s) + uint8_t cfg_ilc = 0; // ILC[1:0]: interrupt level control + uint8_t cfg_rtc = 2; // RTC[2:0]: response cycle - 2 (debounce); response cycle = rtc + 2 byte touch_result; uint8_t point_type[3]; }; From d1447ea00ac21af5268c3e21c1ef158b45123861 Mon Sep 17 00:00:00 2001 From: GOB Date: Sat, 20 Jun 2026 16:30:26 +0900 Subject: [PATCH 3/4] Expose setSensitivity/setResponseCycles/setSleep/recalibrate on TouchSensor_Class --- src/utils/touch_sensor/touch_sensor.cpp | 28 +++++++++++++++++++++++ src/utils/touch_sensor/touch_sensor.h | 30 +++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/src/utils/touch_sensor/touch_sensor.cpp b/src/utils/touch_sensor/touch_sensor.cpp index c1c59d4..6792943 100644 --- a/src/utils/touch_sensor/touch_sensor.cpp +++ b/src/utils/touch_sensor/touch_sensor.cpp @@ -119,3 +119,31 @@ bool TouchSensor_Class::wasSwipedBackward() { return _swipe_result == SwipeDir::Backward; } + +void TouchSensor_Class::setSensitivity(SI12T_Type type, SI12T_Sensitivity_Level level) +{ + if (!_touch_sensor) return; + _touch_sensor->SI12T_Set_Sensitivity(static_cast(type), static_cast(level)); +} + +void TouchSensor_Class::setResponseCycles(uint8_t cycles) +{ + if (!_touch_sensor) return; + _touch_sensor->SI12T_Set_Config(_touch_sensor->cfg_ms, _touch_sensor->cfg_ftc, _touch_sensor->cfg_ilc, cycles); +} + +void TouchSensor_Class::setSleep(bool enable) +{ + if (!_touch_sensor) return; + if (enable) { + _touch_sensor->sleep_enable(); + } else { + _touch_sensor->sleep_disable(); + } +} + +void TouchSensor_Class::recalibrate() +{ + if (!_touch_sensor) return; + _touch_sensor->SI12T_Reset_Reference(); +} diff --git a/src/utils/touch_sensor/touch_sensor.h b/src/utils/touch_sensor/touch_sensor.h index 19b33e0..a889514 100644 --- a/src/utils/touch_sensor/touch_sensor.h +++ b/src/utils/touch_sensor/touch_sensor.h @@ -52,6 +52,36 @@ class TouchSensor_Class : public Button_Class { */ bool wasSwipedBackward(); + /** + * @brief Set the Si12T sensitivity type and level. + * + * @param type SI12T_Type_Low (less sensitive) or SI12T_Type_High (more sensitive). + * @param level SI12T_Sensitivity_Level_0 .. _7. + */ + void setSensitivity(SI12T_Type type, SI12T_Sensitivity_Level level); + + /** + * @brief Set the response-time control (RTC, debounce). The actual response cycle is + * (cycles + 2). Larger values reject spurious single-sample touches. + * + * @param cycles RTC[2:0], range 0-7. + */ + void setResponseCycles(uint8_t cycles); + + /** + * @brief Enter or leave the low-power sleep scan mode. Sleep lowers current draw but + * lengthens response time. + * + * @param enable true = sleep mode, false = active mode. + */ + void setSleep(bool enable); + + /** + * @brief Force a reference (baseline) recalibration on all channels. Useful after an + * external disturbance (e.g. power-rail switching) skews the idle baseline. + */ + void recalibrate(); + private: std::unique_ptr _touch_sensor; std::array _intensities; From 59da6b85fca22aa9475df2b8165ef4d4dff5c16b Mon Sep 17 00:00:00 2001 From: GOB Date: Sat, 20 Jun 2026 17:03:53 +0900 Subject: [PATCH 4/4] Read config back from the chip and expose getters on TouchSensor_Class --- src/drivers/Si12T/Si12T.cpp | 23 +++++++++++++++++ src/drivers/Si12T/Si12T.h | 4 +++ src/utils/touch_sensor/touch_sensor.cpp | 34 +++++++++++++++++++++++++ src/utils/touch_sensor/touch_sensor.h | 30 ++++++++++++++++++++++ 4 files changed, 91 insertions(+) diff --git a/src/drivers/Si12T/Si12T.cpp b/src/drivers/Si12T/Si12T.cpp index 61462d5..0ff3a6b 100644 --- a/src/drivers/Si12T/Si12T.cpp +++ b/src/drivers/Si12T/Si12T.cpp @@ -68,6 +68,8 @@ int8_t Si12T::SI12T_Set_Sensitivity(uint8_t sens_type, uint8_t sens_level) if (sens_type < SI12T_Type_Low || sens_type > SI12T_Type_High) { return -1; } + this->sens_type = sens_type; // cache so getters reflect the current setting + this->sens_level = sens_level; uint8_t value = 0x00; if (sens_type == SI12T_Type_High) { switch (sens_level) { @@ -165,6 +167,27 @@ void Si12T::SI12T_Reset_Reference(void) SI12T_Writeregister(SI12T_REF_RST2_ADDR, 0x00); } +int Si12T::SI12T_Read_Sensitivity(void) +{ + uint8_t data = 0; + if (!SI12T_Readregister(SI12T_SENSITIVITY1_ADDR, &data)) return -1; + return data; +} + +int Si12T::SI12T_Read_Config(void) +{ + uint8_t data = 0; + if (!SI12T_Readregister(SI12T_CTRL1_ADDR, &data)) return -1; + return data; +} + +int Si12T::SI12T_Read_Ctrl(void) +{ + uint8_t data = 0; + if (!SI12T_Readregister(SI12T_CTRL2_ADDR, &data)) return -1; + return data; +} + void Si12T::set_Ctrl2(void) { uint8_t test; diff --git a/src/drivers/Si12T/Si12T.h b/src/drivers/Si12T/Si12T.h index 38c18e5..ccc7619 100644 --- a/src/drivers/Si12T/Si12T.h +++ b/src/drivers/Si12T/Si12T.h @@ -64,6 +64,10 @@ class Si12T : public m5::I2C_Device { int8_t SI12T_Set_Config(uint8_t ms, uint8_t ftc, uint8_t ilc, uint8_t rtc); // Force a reference-value (baseline) update on all channels (Ref_rst 0x0A/0x0B). void SI12T_Reset_Reference(void); + // Read-back helpers. Return the raw register byte (0-255), or -1 on I2C read failure. + int SI12T_Read_Sensitivity(void); // SEN1 (0x02) + int SI12T_Read_Config(void); // CFIG (0x08) + int SI12T_Read_Ctrl(void); // CTRL (0x09) void set_Ctrl1(void); void set_Ctrl2(void); void sleep_enable(void); diff --git a/src/utils/touch_sensor/touch_sensor.cpp b/src/utils/touch_sensor/touch_sensor.cpp index 6792943..28c854d 100644 --- a/src/utils/touch_sensor/touch_sensor.cpp +++ b/src/utils/touch_sensor/touch_sensor.cpp @@ -140,6 +140,7 @@ void TouchSensor_Class::setSleep(bool enable) } else { _touch_sensor->sleep_disable(); } + _asleep = enable; } void TouchSensor_Class::recalibrate() @@ -147,3 +148,36 @@ void TouchSensor_Class::recalibrate() if (!_touch_sensor) return; _touch_sensor->SI12T_Reset_Reference(); } + +SI12T_Type TouchSensor_Class::getSensitivityType() +{ + if (!_touch_sensor) return SI12T_Type_Low; + // SEN register low nibble (channel 1): bit3 = HL (type), bits[2:0] = level. + int raw = _touch_sensor->SI12T_Read_Sensitivity(); + if (raw < 0) return static_cast(_touch_sensor->sens_type); // read failed → cached + return (raw & 0x08) ? SI12T_Type_High : SI12T_Type_Low; +} + +SI12T_Sensitivity_Level TouchSensor_Class::getSensitivityLevel() +{ + if (!_touch_sensor) return SI12T_Sensitivity_Level_0; + int raw = _touch_sensor->SI12T_Read_Sensitivity(); + if (raw < 0) return static_cast(_touch_sensor->sens_level); + return static_cast(raw & 0x07); +} + +uint8_t TouchSensor_Class::getResponseCycles() +{ + if (!_touch_sensor) return 0; + int raw = _touch_sensor->SI12T_Read_Config(); // CFIG: ... | RTC[2:0] + if (raw < 0) return _touch_sensor->cfg_rtc; // read failed → cached + return static_cast(raw & 0x07); +} + +bool TouchSensor_Class::getSleep() +{ + if (!_touch_sensor) return _asleep; + int raw = _touch_sensor->SI12T_Read_Ctrl(); // CTRL: bit2 = SLEEP + if (raw < 0) return _asleep; // read failed → cached + return (raw & 0x04) != 0; +} diff --git a/src/utils/touch_sensor/touch_sensor.h b/src/utils/touch_sensor/touch_sensor.h index a889514..a4a2245 100644 --- a/src/utils/touch_sensor/touch_sensor.h +++ b/src/utils/touch_sensor/touch_sensor.h @@ -82,6 +82,35 @@ class TouchSensor_Class : public Button_Class { */ void recalibrate(); + /** + * @brief Get the sensitivity type, read back from the chip. + * + * @return SI12T_Type_Low or SI12T_Type_High (last set value if the read fails). + */ + SI12T_Type getSensitivityType(); + + /** + * @brief Get the sensitivity level, read back from the chip. + * + * @return SI12T_Sensitivity_Level_0 .. _7 (last set value if the read fails). + */ + SI12T_Sensitivity_Level getSensitivityLevel(); + + /** + * @brief Get the response-time control (RTC), read back from the chip. + * Response cycle is (value + 2). + * + * @return RTC[2:0], range 0-7 (last set value if the read fails). + */ + uint8_t getResponseCycles(); + + /** + * @brief Whether the sensor is in low-power sleep scan mode, read back from the chip. + * + * @return true if sleeping (last set state if the read fails). + */ + bool getSleep(); + private: std::unique_ptr _touch_sensor; std::array _intensities; @@ -92,6 +121,7 @@ class TouchSensor_Class : public Button_Class { bool _touched_flag[3]; bool _in_gesture; uint32_t _last_touched_time; + bool _asleep = false; void update_gesture(); };