Skip to content

Tab5 features, StackChan, fixes, drivers....#526

Open
Shadowtrance wants to merge 14 commits into
TactilityProject:mainfrom
Shadowtrance:features-fixes-improvements
Open

Tab5 features, StackChan, fixes, drivers....#526
Shadowtrance wants to merge 14 commits into
TactilityProject:mainfrom
Shadowtrance:features-fixes-improvements

Conversation

@Shadowtrance
Copy link
Copy Markdown
Contributor

@Shadowtrance Shadowtrance commented May 23, 2026

Enable bluetooth for all devices

Tab5 performance improvements
Tab5 Power added along with ina226 driver module
Updated esp_lvgl_port to 2.7.2 for said improvements to work

Added StackChan device + py32ioexpander driver module

Reduced T-Deck memory pressure by shifting display buffers to psram

Added microphone support to i2s_controller

StackChan screensaver because why not

Updated CoreS3 / StackChan touch driver / offsets... spoiler, it still kinda sucks. :(

Added StickS3 sdcard for those who want to make a diy module.

Bonus symbols as usual.

Fixed indentation in DisplayIdle

Added some new functions to i2c_controller

Increased 8MB and 16MB app partition size by 1MB

Probably more... I'm sure the rabbit will summarize it all.

Summary by CodeRabbit

  • New Features

    • Bluetooth enabled for many ESP32‑S3 boards; added M5Stack StackChan board support.
    • INA226 power monitor and PY32 I/O‑expander (GPIO + NeoPixel) drivers added.
    • StackChan animated screensaver and quick‑charge UI/control introduced.
  • Improvements

    • Touch driver reworked for tighter LCD integration.
    • Better audio/microphone initialization and broader SD‑card support on multiple boards.
    • Display buffer SPIRAM option added for improved graphics memory handling.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 23, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

<review_stack_artifact>

</review_stack_artifact>

Walkthrough

Adds BLE across many ESP32 device trees and properties. Introduces new INA226 and PY32 IO-expander modules with bindings and APIs. Adds the full M5Stack StackChan board (DTS, properties, module, display, power, SD) and includes it in CI. Refactors the FT6x36 touch driver and updates consumers. Extends I2S with TDM RX support and I2C 16-bit helpers. Enhances UI with quick-charge controls and a StackChan screensaver. Updates ST7789 to support SPIRAM buffering and adjusts several build dependencies and symbols.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment thread Drivers/py32ioexpander-module/source/py32ioexpander.cpp Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (6)
Platforms/platform-esp32/source/drivers/esp32_i2s.cpp (1)

367-368: 💤 Low value

Validate config->mclk_multiple before casting to i2s_mclk_multiple_t (Platforms/platform-esp32/source/drivers/esp32_i2s.cpp:367-368)

I2sTdmRxConfig::mclk_multiple is a raw uint32_t and is directly cast to .clk_cfg.mclk_multiple with no validation in either the kernel forwarding layer or the ESP32 TDM setup. ESP-IDF’s valid i2s_mclk_multiple_t values are {128, 192, 256, 384, 512, 576, 768, 1024, 1152} (and for 24-bit data, ESP-IDF recommends using a multiple-of-3 like 384/576/768). Consider rejecting invalid values to avoid silently programming an unsupported MCLK ratio.

Drivers/ina226-module/bindings/ti,ina226.yaml (1)

8-10: ⚡ Quick win

Add schema typing/range validation for shunt-milliohms.

shunt-milliohms is currently only marked required (no type / numeric bounds), so invalid values can slip through schema validation. Constrain it to a positive integer.

Suggested schema update
 properties:
   shunt-milliohms:
+    type: int
     required: true
+    minimum: 1
     description: Shunt resistor value in milliohms
Devices/m5stack-tab5/m5stack,tab5.dts (1)

89-95: ⚡ Quick win

Document or remap the UART1 pin overlap with i2c1.

uart1 is mapped to GPIO53/54, which are already used by i2c_port_a (Line 66 and Line 67). This is fine while status = "disabled", but enabling UART later will silently conflict. A short DTS comment or alternate pin assignment would prevent accidental misconfiguration.

Devices/m5stack-cores3/Source/devices/Display.cpp (1)

22-23: ⚡ Quick win

Replace hard-coded touch bounds with derived constants.

Using 319/239 with commented-out constants is brittle and obscures intent. Prefer deriving from panel constants (or explicit - 1 if inclusive max is intentional) to prevent drift.

♻️ Proposed cleanup
-        319,//LCD_HORIZONTAL_RESOLUTION,
-        239,//LCD_VERTICAL_RESOLUTION,
+        LCD_HORIZONTAL_RESOLUTION,
+        LCD_VERTICAL_RESOLUTION,

If the controller needs inclusive maxima:

-        319,//LCD_HORIZONTAL_RESOLUTION,
-        239,//LCD_VERTICAL_RESOLUTION,
+        LCD_HORIZONTAL_RESOLUTION - 1,
+        LCD_VERTICAL_RESOLUTION - 1,
Devices/m5stack-stackchan/Source/devices/Display.cpp (1)

21-22: ⚡ Quick win

Derive touch bounds from display constants instead of hardcoded literals.

Using raw 319/239 risks silent drift if panel resolution constants change. Keep the same behavior but tie it to shared constants.

Proposed refactor
-        319,//LCD_HORIZONTAL_RESOLUTION,
-        239,//LCD_VERTICAL_RESOLUTION,
+        LCD_HORIZONTAL_RESOLUTION - 1,
+        LCD_VERTICAL_RESOLUTION - 1,
Devices/m5stack-stackchan/Source/devices/SdCard.h (1)

3-7: ⚡ Quick win

Harden this public header against transitive-include breakage.

Please include <memory> explicitly and avoid the global using alias in a header to prevent namespace leakage into all includers.

Proposed change
+#include <memory>
 `#include` "Tactility/hal/sdcard/SdCardDevice.h"
-
-using tt::hal::sdcard::SdCardDevice;
-
-std::shared_ptr<SdCardDevice> createSdCard();
+std::shared_ptr<tt::hal::sdcard::SdCardDevice> createSdCard();

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 23702d88-de95-45f1-afbb-7303695ec2ff

📥 Commits

Reviewing files that changed from the base of the PR and between 5c78d55 and f94e685.

⛔ Files ignored due to path filters (2)
  • partitions-16mb.csv is excluded by !**/*.csv
  • partitions-8mb.csv is excluded by !**/*.csv
📒 Files selected for processing (137)
  • .github/workflows/build.yml
  • Buildscripts/DevicetreeCompiler/source/generator.py
  • Buildscripts/DevicetreeCompiler/tests/data/expected_devicetree.c
  • Buildscripts/TactilitySDK/CMakeLists.txt
  • Devices/btt-panda-touch/bigtreetech,panda-touch.dts
  • Devices/btt-panda-touch/device.properties
  • Devices/cyd-4848s040c/cyd,4848s040c.dts
  • Devices/cyd-4848s040c/device.properties
  • Devices/cyd-8048s043c/cyd,8048s043c.dts
  • Devices/cyd-8048s043c/device.properties
  • Devices/elecrow-crowpanel-advance-28/device.properties
  • Devices/elecrow-crowpanel-advance-28/elecrow,crowpanel-advance-28.dts
  • Devices/elecrow-crowpanel-advance-35/device.properties
  • Devices/elecrow-crowpanel-advance-35/elecrow,crowpanel-advance-35.dts
  • Devices/elecrow-crowpanel-advance-50/device.properties
  • Devices/elecrow-crowpanel-advance-50/elecrow,crowpanel-advance-50.dts
  • Devices/elecrow-crowpanel-basic-50/device.properties
  • Devices/elecrow-crowpanel-basic-50/elecrow,crowpanel-basic-50.dts
  • Devices/guition-jc1060p470ciwy/device.properties
  • Devices/guition-jc1060p470ciwy/guition,jc1060p470ciwy.dts
  • Devices/guition-jc3248w535c/device.properties
  • Devices/guition-jc3248w535c/guition,jc3248w535c.dts
  • Devices/guition-jc8048w550c/device.properties
  • Devices/guition-jc8048w550c/guition,jc8048w550c.dts
  • Devices/heltec-wifi-lora-32-v3/device.properties
  • Devices/heltec-wifi-lora-32-v3/heltec,wifi-lora-32-v3.dts
  • Devices/lilygo-tdeck/Source/devices/Display.cpp
  • Devices/lilygo-tdeck/lilygo,tdeck.dts
  • Devices/lilygo-tdisplay-s3/device.properties
  • Devices/lilygo-tdisplay-s3/lilygo,tdisplay-s3.dts
  • Devices/lilygo-tdongle-s3/device.properties
  • Devices/lilygo-tdongle-s3/lilygo,tdongle-s3.dts
  • Devices/lilygo-thmi/device.properties
  • Devices/lilygo-thmi/lilygo,thmi.dts
  • Devices/lilygo-tlora-pager/Source/drivers/TloraPager.cpp
  • Devices/lilygo-tlora-pager/device.properties
  • Devices/lilygo-tlora-pager/lilygo,tlora-pager.dts
  • Devices/m5stack-cardputer-adv/device.properties
  • Devices/m5stack-cardputer-adv/m5stack,cardputer-adv.dts
  • Devices/m5stack-cardputer/device.properties
  • Devices/m5stack-cardputer/m5stack,cardputer.dts
  • Devices/m5stack-core2/Source/devices/Display.cpp
  • Devices/m5stack-cores3/CMakeLists.txt
  • Devices/m5stack-cores3/Source/devices/Display.cpp
  • Devices/m5stack-cores3/device.properties
  • Devices/m5stack-cores3/m5stack,cores3.dts
  • Devices/m5stack-papers3/device.properties
  • Devices/m5stack-papers3/m5stack,papers3.dts
  • Devices/m5stack-stackchan/CMakeLists.txt
  • Devices/m5stack-stackchan/Source/Configuration.cpp
  • Devices/m5stack-stackchan/Source/devices/Display.cpp
  • Devices/m5stack-stackchan/Source/devices/Display.h
  • Devices/m5stack-stackchan/Source/devices/Power.cpp
  • Devices/m5stack-stackchan/Source/devices/Power.h
  • Devices/m5stack-stackchan/Source/devices/SdCard.cpp
  • Devices/m5stack-stackchan/Source/devices/SdCard.h
  • Devices/m5stack-stackchan/Source/module.cpp
  • Devices/m5stack-stackchan/device.properties
  • Devices/m5stack-stackchan/devicetree.yaml
  • Devices/m5stack-stackchan/m5stack,stackchan.dts
  • Devices/m5stack-sticks3/CMakeLists.txt
  • Devices/m5stack-sticks3/Source/Configuration.cpp
  • Devices/m5stack-sticks3/Source/devices/SdCard.cpp
  • Devices/m5stack-sticks3/Source/devices/SdCard.h
  • Devices/m5stack-sticks3/device.properties
  • Devices/m5stack-sticks3/m5stack,sticks3.dts
  • Devices/m5stack-tab5/CMakeLists.txt
  • Devices/m5stack-tab5/Source/Configuration.cpp
  • Devices/m5stack-tab5/Source/devices/Power.cpp
  • Devices/m5stack-tab5/Source/devices/Power.h
  • Devices/m5stack-tab5/Source/module.cpp
  • Devices/m5stack-tab5/device.properties
  • Devices/m5stack-tab5/devicetree.yaml
  • Devices/m5stack-tab5/m5stack,tab5.dts
  • Devices/unphone/device.properties
  • Devices/unphone/unphone.dts
  • Devices/waveshare-esp32-s3-geek/device.properties
  • Devices/waveshare-esp32-s3-geek/waveshare,esp32-s3-geek.dts
  • Devices/waveshare-s3-lcd-13/device.properties
  • Devices/waveshare-s3-lcd-13/waveshare,s3-lcd-13.dts
  • Devices/waveshare-s3-touch-lcd-128/device.properties
  • Devices/waveshare-s3-touch-lcd-128/waveshare,s3-touch-lcd-128.dts
  • Devices/waveshare-s3-touch-lcd-147/device.properties
  • Devices/waveshare-s3-touch-lcd-147/waveshare,s3-touch-lcd-147.dts
  • Devices/waveshare-s3-touch-lcd-43/device.properties
  • Devices/waveshare-s3-touch-lcd-43/waveshare,s3-touch-lcd-43.dts
  • Devices/wireless-tag-wt32-sc01-plus/Source/devices/Display.cpp
  • Devices/wireless-tag-wt32-sc01-plus/device.properties
  • Devices/wireless-tag-wt32-sc01-plus/wireless-tag,wt32-sc01-plus.dts
  • Drivers/FT6x36/CMakeLists.txt
  • Drivers/FT6x36/Source/Ft6x36Touch.cpp
  • Drivers/FT6x36/Source/Ft6x36Touch.h
  • Drivers/FT6x36/Source/ft6x36/FT6X36.cpp
  • Drivers/FT6x36/Source/ft6x36/FT6X36.h
  • Drivers/FT6x36/Source/ft6x36/LICENSE
  • Drivers/FT6x36/Source/ft6x36/README.md
  • Drivers/ST7789/Source/St7789Display.cpp
  • Drivers/ST7789/Source/St7789Display.h
  • Drivers/ina226-module/CMakeLists.txt
  • Drivers/ina226-module/README.md
  • Drivers/ina226-module/bindings/ti,ina226.yaml
  • Drivers/ina226-module/devicetree.yaml
  • Drivers/ina226-module/include/bindings/ina226.h
  • Drivers/ina226-module/include/drivers/ina226.h
  • Drivers/ina226-module/include/ina226_module.h
  • Drivers/ina226-module/source/ina226.cpp
  • Drivers/ina226-module/source/module.cpp
  • Drivers/ina226-module/source/symbols.c
  • Drivers/m5pm1-module/include/drivers/m5pm1.h
  • Drivers/m5pm1-module/source/m5pm1.cpp
  • Drivers/py32ioexpander-module/CMakeLists.txt
  • Drivers/py32ioexpander-module/bindings/m5stack,py32ioexpander.yaml
  • Drivers/py32ioexpander-module/devicetree.yaml
  • Drivers/py32ioexpander-module/include/bindings/py32ioexpander.h
  • Drivers/py32ioexpander-module/include/drivers/py32ioexpander.h
  • Drivers/py32ioexpander-module/include/py32ioexpander_module.h
  • Drivers/py32ioexpander-module/source/module.cpp
  • Drivers/py32ioexpander-module/source/py32ioexpander.cpp
  • Firmware/idf_component.yml
  • Modules/lvgl-module/source/symbols.c
  • Platforms/platform-esp32/source/drivers/esp32_i2s.cpp
  • Tactility/Include/Tactility/hal/power/PowerDevice.h
  • Tactility/Include/Tactility/settings/DisplaySettings.h
  • Tactility/Source/app/display/Display.cpp
  • Tactility/Source/app/power/Power.cpp
  • Tactility/Source/service/displayidle/DisplayIdle.cpp
  • Tactility/Source/service/displayidle/StackChanScreensaver.cpp
  • Tactility/Source/service/displayidle/StackChanScreensaver.h
  • Tactility/Source/settings/DisplaySettings.cpp
  • TactilityC/Source/symbols/freertos.cpp
  • TactilityC/Source/symbols/stl.cpp
  • TactilityKernel/include/tactility/drivers/i2c_controller.h
  • TactilityKernel/include/tactility/drivers/i2s_controller.h
  • TactilityKernel/source/drivers/i2c_controller.cpp
  • TactilityKernel/source/drivers/i2s_controller.cpp
  • TactilityKernel/source/kernel_symbols.c
  • device.py
💤 Files with no reviewable changes (4)
  • Drivers/FT6x36/Source/ft6x36/README.md
  • Drivers/FT6x36/Source/ft6x36/FT6X36.cpp
  • Drivers/FT6x36/Source/ft6x36/LICENSE
  • Drivers/FT6x36/Source/ft6x36/FT6X36.h

Comment thread Devices/m5stack-stackchan/Source/Configuration.cpp Outdated
Comment thread Devices/m5stack-sticks3/Source/Configuration.cpp
Comment thread Devices/m5stack-tab5/Source/devices/Power.cpp
Comment thread Devices/m5stack-tab5/Source/module.cpp Outdated
Comment thread Drivers/ina226-module/source/ina226.cpp Outdated
Comment thread Drivers/m5pm1-module/source/m5pm1.cpp
Comment thread Drivers/py32ioexpander-module/source/py32ioexpander.cpp
Comment thread Drivers/py32ioexpander-module/source/py32ioexpander.cpp
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Drivers/py32ioexpander-module/source/py32ioexpander.cpp (1)

112-119: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

count is undefined; should validate index parameter.

Line 113 references count which does not exist in this function scope. This will fail to compile. The bounds check should validate index against the maximum LED count (32).

🐛 Proposed fix
 error_t py32_led_set_color(Device* device, uint8_t index, uint8_t r, uint8_t g, uint8_t b) {
-    if (count > 32U) return ERROR_RESOURCE;
+    if (index >= 32U) return ERROR_RESOURCE;
     Device* i2c = device_get_parent(device);

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 33f18d7f-4b92-4d71-a445-e1a886b5eed9

📥 Commits

Reviewing files that changed from the base of the PR and between f94e685 and 7a44cde.

📒 Files selected for processing (6)
  • Devices/m5stack-stackchan/Source/Configuration.cpp
  • Devices/m5stack-tab5/Source/module.cpp
  • Drivers/ina226-module/bindings/ti,ina226.yaml
  • Drivers/ina226-module/source/ina226.cpp
  • Drivers/m5pm1-module/source/m5pm1.cpp
  • Drivers/py32ioexpander-module/source/py32ioexpander.cpp

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
Drivers/py32ioexpander-module/source/py32ioexpander.cpp (1)

112-118: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reject LED index 32; only 0..31 are valid.

Line 113 still allows index == 32, but the data window only has 32 slots. That makes the write target REG_LED_DATA + 64, which is outside the valid LED payload range.

Proposed fix
 error_t py32_led_set_color(Device* device, uint8_t index, uint8_t r, uint8_t g, uint8_t b) {
-    if (index > 32U) return ERROR_RESOURCE;
+    if (index >= 32U) return ERROR_RESOURCE;
     Device* i2c = device_get_parent(device);
     // RGB565: [15:11]=R5 [10:5]=G6 [4:0]=B5, stored little-endian
     uint16_t rgb565 = static_cast<uint16_t>(((r >> 3U) << 11U) | ((g >> 2U) << 5U) | (b >> 3U));
     uint8_t buf[2] = {static_cast<uint8_t>(rgb565 & 0xFFU), static_cast<uint8_t>(rgb565 >> 8U)};
     return i2c_controller_write_register(i2c, GET_CONFIG(device)->address, static_cast<uint8_t>(REG_LED_DATA + index * 2U), buf, 2, TIMEOUT);
 }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cae01ce6-09ad-4d3a-ab22-a07da670da5d

📥 Commits

Reviewing files that changed from the base of the PR and between 7a44cde and 34845d2.

📒 Files selected for processing (1)
  • Drivers/py32ioexpander-module/source/py32ioexpander.cpp

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
Devices/m5stack-stackchan/Source/Configuration.cpp (1)

234-234: ⚡ Quick win

Hardcoded I2C_NUM_0 matches "i2c_internal" on StackChan.

i2c_internal in the StackChan devicetree sets port = <I2C_NUM_0>, and initBoot() looks up device_find_by_name("i2c_internal"), so Axp2101(I2C_NUM_0) should use the correct bus for the current configuration.

Still, to reduce future drift, derive the port passed to Axp2101 from the i2c_internal device handle (or the same DT constant) instead of hardcoding.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a812d611-6dd2-4527-9a3e-792c962e7606

📥 Commits

Reviewing files that changed from the base of the PR and between 2fd6f07 and 7421516.

📒 Files selected for processing (1)
  • Devices/m5stack-stackchan/Source/Configuration.cpp

#include <Tactility/hal/Configuration.h>
#include <Axp2101Power.h>
#include <AXP2101.h>
#include <Axp2101.h>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All driver h/c/cpp files are CamelCase, so let's not change that.


static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
auto configuration = std::make_unique<Ft6x36Touch::Configuration>(
auto configuration = std::make_unique<FT6x36Touch::Configuration>(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All driver h/c/cpp files are CamelCase, so let's not change that.

shunt-milliohms:
type: int
required: true
minimum: 1
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is "minimum" supported? If not: Perhaps just add a comment that it should be a minimum of 1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants