Skip to content

Tab5 power expander driver and devicetree parsing improvements#507

Merged
KenVanHoeylandt merged 10 commits intomainfrom
develop
Feb 17, 2026
Merged

Tab5 power expander driver and devicetree parsing improvements#507
KenVanHoeylandt merged 10 commits intomainfrom
develop

Conversation

@KenVanHoeylandt
Copy link
Contributor

@KenVanHoeylandt KenVanHoeylandt commented Feb 16, 2026

Summary by CodeRabbit

  • New Features

    • PI4IOE5V6408 I2C I/O expander driver with public GPIO APIs
    • CLI tool to list devicetree dependencies
  • Device Tree Updates

    • M5Stack Tab5 configured with two I2C IO expanders; PI4IOE5V6408 binding added
  • Build / Tooling

    • Devicetree code generation integrated into build; generated artifacts and dynamic dependency resolution exposed
  • Refactor

    • Kernel/run APIs updated to accept a null‑terminated devicetree modules array; many module symbols renamed
  • Documentation

    • Added README and Apache‑2.0 license for new driver module

@coderabbitai
Copy link

coderabbitai bot commented Feb 16, 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

Walkthrough

Adds a CLI script to extract devicetree dependencies and updates the devicetree code generator to emit forward declarations and a null-terminated dts_modules[] array. Adapts call sites and APIs (tt::run, kernel_init and related callers) to accept dts_modules[] and DtsDevice arrays instead of individual platform/device module pointers. Renames many platform/device module symbols to platform- or board-specific names. Introduces a new pi4ioe5v6408 driver module (bindings, headers, sources, symbols, CMake, devicetree entries) and updates CMake build steps to generate and include devicetree artifacts and resolve dependencies.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and specifically describes the main changes: adding a Tab5 power expander driver (pi4ioe5v6408) and improving devicetree parsing infrastructure.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch develop

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@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: 9

Caution

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

⚠️ Outside diff range comments (1)
TactilityKernel/include/tactility/kernel_init.h (1)

11-19: ⚠️ Potential issue | 🟡 Minor

Stale @param platform_module in doc comment — parameter was removed.

The function signature no longer has a platform_module parameter, but Line 13 still documents it. Update the doc block to match the actual signature.

📝 Proposed fix
 /**
- * Initialize the kernel with platform and device modules, and a device tree.
- * `@param` platform_module The platform module to start. This module should not be constructed yet.
+ * Initialize the kernel with device modules and a device tree.
  * `@param` device_module The device module to start. This module should not be constructed yet. This parameter can be NULL.
  * `@param` dts_modules List of modules from devicetree, null-terminated, non-null parameter
  * `@param` dts_devices The list of generated devices from the devicetree. The array must be terminated with DTS_DEVICE_TERMINATOR. This parameter can be NULL.
  * `@return` ERROR_NONE on success, otherwise an error code
  */
🧹 Nitpick comments (4)
Firmware/CMakeLists.txt (1)

24-27: pip install runs unconditionally on every CMake configure.

This slows down every configure invocation. Consider gating it behind a stamp file or a cache variable so it only runs once (or when dependencies change).

Platforms/platform-esp32/source/drivers/esp32_i2c.cpp (1)

248-257: Minor inconsistency: missing struct keyword in extern declaration.

Other ESP32 driver files (esp32_i2s.cpp, esp32_gpio.cpp, esp32_uart.cpp) use extern struct Module platform_esp32_module;, but this file omits the struct keyword. While valid C++, it's inconsistent.

Suggested fix
-extern Module platform_esp32_module;
+extern struct Module platform_esp32_module;
Drivers/pi4ioe5v6408-module/source/pi4ioe5v6408.cpp (2)

14-26: Inconsistent indentation: mixed tabs and spaces.

Lines 15 and 21 use tabs while lines 16–20 use spaces. The rest of the codebase uses spaces consistently.

Suggested fix
 static error_t start(Device* device) {
-	auto* parent = device_get_parent(device);
+    auto* parent = device_get_parent(device);
     if (device_get_type(parent) != &I2C_CONTROLLER_TYPE) {
         LOG_E(TAG, "Parent device is not I2C");
         return ERROR_RESOURCE;
     }
     LOG_I(TAG, "Started PI4IOE5V6408 device %s", device->name);
-	return ERROR_NONE;
+    return ERROR_NONE;
 }
 
 static error_t stop(Device* device) {
-	return ERROR_NONE;
+    return ERROR_NONE;
 }

14-41: start/stop defined outside extern "C" — inconsistent with other drivers.

All other driver files in this codebase (e.g., esp32_i2s.cpp, esp32_gpio.cpp, esp32_uart.cpp) define their static functions inside the extern "C" block. While this works for static functions (internal linkage), it's inconsistent with the established pattern.

Copy link

@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: 2

🧹 Nitpick comments (5)
Firmware/CMakeLists.txt (2)

88-89: Hardcoded driver source file breaks the DTS abstraction.

symbols.c from pi4ioe5v6408-module is added directly as a source file, bypassing the DTS dependency mechanism used in the ESP path (lines 69–72). This won't scale as more DTS-driven modules are added and creates a maintenance burden for the simulator build.

Consider either wiring the non-ESP path through DTS dependencies the same way, or at minimum adding a comment explaining why this workaround is necessary for the simulator build.


24-27: pip install runs on every CMake configure.

This slows down reconfiguration. Consider guarding this with a cache variable or a stamp file so it only runs once (or when versions change).

Drivers/pi4ioe5v6408-module/include/drivers/pi4ioe5v6408.h (1)

12-15: Consider renaming reg to address for clarity.

The field represents an I2C bus address (as your comment notes), but reg conventionally implies a register offset in I2C contexts. This could confuse maintainers who see GET_CONFIG(device)->reg passed as the address argument to i2c_controller_register8_* helpers.

Drivers/pi4ioe5v6408-module/source/pi4ioe5v6408.cpp (2)

13-21: Unused register constants.

PI4_REGISTER_PULL_ENABLE, PI4_REGISTER_PULL_SELECT, PI4_REGISTER_INTERRUPT_MASK, and PI4_REGISTER_INTERRUPT_LEVEL are defined but never used. Fine to keep if you plan to use them soon; otherwise they're dead code.


39-62: Inconsistent use of struct Device* vs Device* across the API functions.

Lines 39, 49, 54 use struct Device* while lines 44, 59 use bare Device*. Both work in C++ extern "C" blocks, but the inconsistency is noticeable. Consider picking one form for uniformity — ideally matching the header declaration style (struct Device*).

Copy link

@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

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (44)
Devices/elecrow-crowpanel-advance-50/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Stale @warning comment contradicts the new symbol name.

The comment on Line 15 asserts that the variable name must be exactly "device_module", but the variable was just renamed to elecrow_crowpanel_advance_50_module. The comment should be updated or removed to avoid misleading future maintainers.

📝 Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
-struct Module elecrow_crowpanel_advance_50_module = {
+struct Module elecrow_crowpanel_advance_50_module = {
Devices/waveshare-esp32-s3-geek/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove or update the stale @warning comment.

The comment on Line 15 says the variable name must be exactly "device_module", but the variable has just been renamed to waveshare_esp32_s3_geek_module. This comment is now incorrect and actively misleading.

✏️ Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module waveshare_esp32_s3_geek_module = {
Devices/lilygo-tdeck/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Stale @warning comment contradicts the rename.

The doc comment on Line 15 still says the variable name must be exactly "device_module", but the variable was just renamed to lilygo_tdeck_module. This warning should be updated or removed to avoid misleading future contributors.

✏️ Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module lilygo_tdeck_module = {
Devices/generic-esp32p4/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove the now-contradictory @warning comment.

The warning on Line 15 states the variable must be named exactly "device_module", but the variable has just been renamed to generic_esp32p4_module. The comment is stale and actively misleading — it should be removed (or updated if a new naming contract exists for this symbol).

🧹 Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module generic_esp32p4_module = {
Devices/heltec-wifi-lora-32-v3/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove or update the stale @warning comment.

The comment on Line 15 asserts the variable name must be exactly "device_module", but the variable was just renamed to heltec_wifi_lora_32_v3_module. This contradicts the change and will mislead future readers.

🧹 Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module heltec_wifi_lora_32_v3_module = {
Devices/waveshare-s3-touch-lcd-128/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove or update the stale @warning comment — it now contradicts the renamed symbol.

Line 15 still asserts "The variable name must be exactly "device_module"", but the variable was just renamed to waveshare_s3_touch_lcd_128_module on Line 16. This is actively misleading for anyone touching this file in the future.

🧹 Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module waveshare_s3_touch_lcd_128_module = {
Devices/waveshare-s3-lcd-13/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove the now-contradictory @warning comment.

The comment on Line 15 asserts the variable name must be "device_module", but the variable was just renamed to waveshare_s3_lcd_13_module. Leaving it in place will actively mislead future maintainers.

🗑️ Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module waveshare_s3_lcd_13_module = {
Devices/cyd-e32r28t/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove the now-contradictory @warning comment.

The comment on Line 15 states the variable name must be exactly "device_module", but the variable has been intentionally renamed to cyd_e32r28t_module as part of the PR-wide convention change. The comment is now stale and misleading.

🗑️ Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module cyd_e32r28t_module = {
Devices/guition-jc1060p470ciwy/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove or update the now-contradictory @warning comment.

The comment on Line 15 explicitly states the variable name must be device_module, but the variable was just renamed to guition_jc1060p470ciwy_module. This is actively misleading and should be removed or updated to reflect the new naming convention.

📝 Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module guition_jc1060p470ciwy_module = {
Devices/wireless-tag-wt32-sc01-plus/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove or update the stale @warning comment.

The comment on line 15 still says the variable name must be "device_module", but the symbol was intentionally renamed to wireless_tag_wt32_sc01_plus_module. Leaving it in place directly contradicts the current code and will confuse future readers.

🗑️ Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module wireless_tag_wt32_sc01_plus_module = {
Devices/cyd-2432s032c/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove/update the stale @warning comment.

The warning on Line 15 says the variable name must be exactly "device_module", but the variable has just been renamed to cyd_2432s032c_module. The comment now contradicts the code and will mislead future readers.

🗑️ Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module cyd_2432s032c_module = {
Devices/m5stack-cores3/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove or update the now-stale @warning comment.

The comment on line 15 explicitly mandates that the variable be named "device_module", but the variable was intentionally renamed to m5stack_cores3_module by this PR. Leaving it in will mislead future contributors into thinking the old name is still a hard requirement.

🧹 Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module m5stack_cores3_module = {
Devices/lilygo-tdisplay-s3/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove the now-stale @warning comment — it contradicts the rename.

The comment on line 15 asserts the variable name must be "device_module", but the variable has been intentionally renamed to lilygo_tdisplay_s3_module. Leaving this warning in place will mislead future contributors into thinking the rename is wrong or must be reverted.

🗑️ Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module lilygo_tdisplay_s3_module = {
Devices/guition-jc3248w535c/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove or update the now-stale @warning comment.

The comment on Line 15 still asserts the variable name must be exactly "device_module", directly contradicting the rename on Line 16. This will mislead future readers and any tooling that keys off it.

📝 Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module guition_jc3248w535c_module = {
Devices/elecrow-crowpanel-basic-50/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove or update the stale @warning comment.

The comment on line 15 states the variable name must be "device_module", but the variable has been intentionally renamed to elecrow_crowpanel_basic_50_module as part of the PR-wide migration to per-module named symbols. The comment now directly contradicts the code and would mislead any developer who encounters it.

🗑️ Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module elecrow_crowpanel_basic_50_module = {
Devices/cyd-4848s040c/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove the now-contradictory @warning comment.

The comment on line 15 asserts that the variable name must be "device_module", but the PR intentionally renames it to cyd_4848s040c_module. Leaving the comment in place actively contradicts the code and will mislead future readers.

🗑️ Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module cyd_4848s040c_module = {
Devices/lilygo-tdisplay/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove the now-contradictory @warning comment.

The comment on line 15 asserts the symbol must be "device_module", but line 16 renames it to lilygo_tdisplay_module. The broader PR intent (switching to a named dts_modules[] array) is precisely what removes that fixed-name requirement, so the warning is now both stale and actively misleading. It should be deleted.

🧹 Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module lilygo_tdisplay_module = {
Devices/m5stack-core2/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove or update the now-contradictory @warning comment.

The comment on line 15 says the variable name must be "device_module", but the variable was just renamed to m5stack_core2_module. This is directly misleading to future maintainers. Since the PR's intent is precisely to move away from the generic device_module name, the comment should be dropped (or reworded if there's still a linkage constraint it's trying to document).

🗑️ Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module m5stack_core2_module = {
Devices/generic-esp32c6/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Stale comment contradicts the rename.

Line 15 still says the variable name must be exactly "device_module", but it was renamed to generic_esp32c6_module. Update or remove this @warning to match the new naming convention.

Suggested fix
-/** `@warning` The variable name must be exactly "device_module" */
-struct Module generic_esp32c6_module = {
+struct Module generic_esp32c6_module = {

Or, if the constraint still applies under the new scheme:

-/** `@warning` The variable name must be exactly "device_module" */
+/** `@warning` The variable name must match the symbol expected by the devicetree code generator */
 struct Module generic_esp32c6_module = {
Devices/guition-jc8048w550c/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove or update the now-contradictory @warning comment.

Line 15 still states /** @warning The variable name must be exactly "device_module" */, but the variable on line 16 has been renamed to guition_jc8048w550c_module. The comment is now stale and misleading — it implies the old generic name is required when the entire PR is moving away from it.

🧹 Proposed fix — drop the stale comment
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module guition_jc8048w550c_module = {
Devices/cyd-2432s024c/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Stale @warning comment contradicts the rename.

Line 15 still reads The variable name must be exactly "device_module", but the symbol is now cyd_2432s024c_module. This will mislead future contributors into thinking the name is constrained. Please update or remove the comment to reflect the new naming convention driven by the devicetree generator.

Suggested fix
-/** `@warning` The variable name must be exactly "device_module" */
+/** `@warning` The variable name must match the symbol expected by the devicetree module list */
 struct Module cyd_2432s024c_module = {
Devices/m5stack-cardputer-adv/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Stale @warning comment contradicts the renamed symbol.

The comment on Line 15 still says the variable name must be exactly "device_module", but the variable was just renamed to m5stack_cardputer_adv_module. This comment is now actively misleading and should be updated or removed.

📝 Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module m5stack_cardputer_adv_module = {
Devices/m5stack-cardputer/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Same stale @warning comment as the -adv variant.

The comment on Line 15 still references "device_module" while the actual symbol is now m5stack_cardputer_module. Update or remove it.

📝 Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module m5stack_cardputer_module = {
Devices/elecrow-crowpanel-advance-28/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove the now-contradictory @warning comment.

The comment on line 15 asserts the variable name must be "device_module", but the variable was just renamed to elecrow_crowpanel_advance_28_module. Leaving this comment in place is actively misleading for anyone who reads or modifies this file later.

🧹 Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module elecrow_crowpanel_advance_28_module = {
Devices/generic-esp32/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove the now-stale @warning comment — it contradicts the rename.

The comment on Line 15 asserts the variable name must be "device_module", but the variable was just renamed to generic_esp32_module. Since the PR migrates the kernel init flow from a single device_module/platform_module convention to a dts_modules[] array lookup, this naming constraint no longer applies and the comment is actively misleading.

🗑️ Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module generic_esp32_module = {
Devices/m5stack-stickc-plus/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Same stale @warning comment — remove or update.

Identical to the plus2 file: the comment still reads "must be exactly device_module" while the symbol is now m5stack_stickc_plus_module.

🗑️ Proposed fix: remove the stale warning
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module m5stack_stickc_plus_module = {
Devices/m5stack-stickc-plus2/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Stale @warning comment contradicts the renamed symbol.

The doc comment on line 15 still says the variable name must be exactly "device_module", but the variable has been renamed to m5stack_stickc_plus2_module. Either remove the comment entirely (since the new naming convention makes it obsolete) or update it to reflect the new requirement.

🗑️ Proposed fix: remove the stale warning
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module m5stack_stickc_plus2_module = {
Devices/unphone/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove stale @warning comment — variable naming is no longer constrained.

The @warning on line 15 asserts the name must be "device_module", but this constraint no longer applies. The devicetree compiler (Buildscripts/DevicetreeCompiler/source/generator.py) dynamically generates dts_modules[] by collecting references to whatever symbol is actually defined in each device module—no fixed naming requirement. The unphone_module rename is safe and has no external callers.

The warning contradicts the code and should be removed to prevent future confusion.

Devices/generic-esp32s3/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove the stale @warning comment that contradicts the current variable name.

The variable has been renamed to generic_esp32s3_module, but the @warning on line 15 still claims it must be exactly "device_module". This comment is now contradictory dead documentation and should be removed.

Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module generic_esp32s3_module = {
Devices/elecrow-crowpanel-basic-35/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove the stale @warning comment — it directly contradicts the renamed variable.

Line 15 asserts the symbol must be named device_module, but the variable is now elecrow_crowpanel_basic_35_module. This comment appears to be a template that was not updated when the device symbol was renamed. Verification confirms no references to the old device_module name exist for this device, so the rename is clean. Remove the misleading comment.

🗑️ Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module elecrow_crowpanel_basic_35_module = {
Devices/elecrow-crowpanel-advance-35/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove stale warning comment that contradicts the device-specific variable name.

The @warning comment on line 15 states the variable must be exactly "device_module", but the variable is intentionally named elecrow_crowpanel_advance_35_module to be device-specific. This comment is stale and misleading.

Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module elecrow_crowpanel_advance_35_module = {
Devices/lilygo-tdongle-s3/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove stale @warning comment that contradicts the renamed symbol.

The warning on line 15 mandates "device_module" as the exact variable name, but the symbol is now lilygo_tdongle_s3_module. No external code references the old name, so the warning is outdated and misleading.

Suggested fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module lilygo_tdongle_s3_module = {
Devices/m5stack-papers3/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove the stale @warning comment on line 15.

The comment states the variable name must be "device_module", but the variable has been renamed to m5stack_papers3_module. This is actively misleading and should be deleted. Verification confirms m5stack-papers3 has no orphaned extern references to the old symbol.

Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module m5stack_papers3_module = {
Devices/simulator/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove stale @warning comment — the variable has been renamed to simulator_module.

Line 15's warning states the variable name must be exactly "device_module", but the actual variable on line 16 is named simulator_module. No extern declarations or bindings in the codebase reference a device_module for the simulator device, confirming the rename is complete and the comment is outdated. Delete the warning comment.

Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module simulator_module = {
Devices/waveshare-s3-touch-lcd-147/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove stale warning comment that contradicts the renamed variable.

The @warning comment on Line 15 states the variable name "must be exactly device_module", but the variable is now waveshare_s3_touch_lcd_147_module. This comment is no longer accurate—no code in this device depends on the old name. Remove it.

Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module waveshare_s3_touch_lcd_147_module = {
Devices/cyd-8048s043c/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove stale @warning comment — the constraint no longer applies to this device.

The @warning on line 15 is outdated. The variable has been renamed to cyd_8048s043c_module and there are no hardcoded dependencies on the exact name "device_module" within this device's code. The comment actively misleads maintainers into thinking the name is a hard requirement when it is not.

-/** `@warning` The variable name must be exactly "device_module" */
 struct Module cyd_8048s043c_module = {
Devices/cyd-2432s028rv3/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove the stale @warning comment on Line 15.

The comment asserts the variable name must be exactly "device_module", but the actual variable is named cyd_2432s028rv3_module. This contradictory comment will mislead anyone reading it. Since no external code references this module by a generic symbol name, the comment can be safely removed.

🧹 Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module cyd_2432s028rv3_module = {
Devices/waveshare-s3-touch-lcd-43/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Same stale @warning — remove it.

🗑️ Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module waveshare_s3_touch_lcd_43_module = {
Devices/lilygo-tlora-pager/Source/module.cpp-23-24 (1)

23-24: ⚠️ Potential issue | 🟡 Minor

Same stale @warning as the other renamed modules — remove it.

🗑️ Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module lilygo_tlora_pager_module = {
Devices/btt-panda-touch/Source/module.cpp-15-16 (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove stale @warning — the constraint it describes no longer applies.

The comment says the variable must be exactly "device_module", but the variable has just been renamed to btt_panda_touch_module. The warning is now factually wrong and will mislead future contributors.

🗑️ Proposed fix
-/** `@warning` The variable name must be exactly "device_module" */
 struct Module btt_panda_touch_module = {
Tactility/Include/Tactility/Tactility.h-27-29 (1)

27-29: ⚠️ Potential issue | 🟡 Minor

dtsDevices nullability not reflected in the doc comment.

kernel_init.cpp accepts a null dts_devices pointer (if (dts_devices)), so callers of tt::run may legally pass nullptr. The current @param dtsDevices doc only says it must be terminated with DTS_DEVICE_TERMINATOR, omitting that it can be null.

📝 Proposed fix
- * `@param` dtsDevices Array that is terminated with DTS_DEVICE_TERMINATOR
+ * `@param` dtsDevices Array terminated with DTS_DEVICE_TERMINATOR, or nullptr if there are no devicetree devices
Devices/m5stack-tab5/Source/Configuration.cpp-68-68 (1)

68-68: ⚠️ Potential issue | 🟡 Minor

= nullptr default in initSound creates a dangerous API — the body unconditionally dereferences io_expander0.

If io_expander0 is omitted (or null after the missing expander check is fixed separately), pi4ioe5v6408_get_output_level will immediately dereference a null pointer. Either remove the default or guard the body.

🔧 Option A — remove the default (preferred, since all callers supply the argument)
-static error_t initSound(::Device* i2c_controller, ::Device* io_expander0 = nullptr) {
+static error_t initSound(::Device* i2c_controller, ::Device* io_expander0) {
Drivers/pi4ioe5v6408-module/source/symbols.c-4-15 (1)

4-15: ⚠️ Potential issue | 🟡 Minor

pi4ioe5v6408_get_output_level missing from the symbol export table.

This function is declared in the public header and actively used by Devices/m5stack-tab5/Source/Configuration.cpp (initSound), but it is not exported via pi4ioe5v6408_module_symbols. Any module performing a runtime symbol lookup for it will fail.

🔧 Proposed fix
     DEFINE_MODULE_SYMBOL(pi4ioe5v6408_set_pull_select),
     DEFINE_MODULE_SYMBOL(pi4ioe5v6408_get_input_level),
+    DEFINE_MODULE_SYMBOL(pi4ioe5v6408_get_output_level),
     DEFINE_MODULE_SYMBOL(pi4ioe5v6408_set_interrupt_mask),
Devices/m5stack-tab5/Source/Configuration.cpp-116-125 (1)

116-125: ⚠️ Potential issue | 🟡 Minor

Log messages report stale ERROR_NONE instead of the actual failure code.

error is assigned once from i2c_controller_write_register_array. If that call succeeds, error == ERROR_NONE for the rest of the function. The return values of pi4ioe5v6408_get_output_level and pi4ioe5v6408_set_output_level are checked inline but never captured, so both error messages will always print "ERROR_NONE" regardless of what actually failed.

🐛 Proposed fix
-    if (pi4ioe5v6408_get_output_level(io_expander0, &output_level, pdMS_TO_TICKS(100)) != ERROR_NONE) {
-        LOG_E(TAG, "Failed to read power level: %s", error_to_string(error));
+    error_t expander_error;
+    if ((expander_error = pi4ioe5v6408_get_output_level(io_expander0, &output_level, pdMS_TO_TICKS(100))) != ERROR_NONE) {
+        LOG_E(TAG, "Failed to read power level: %s", error_to_string(expander_error));
         return ERROR_RESOURCE;
     }
 
-    if (pi4ioe5v6408_set_output_level(io_expander0, output_level | 0b00000010, pdMS_TO_TICKS(100)) != ERROR_NONE) {
-        LOG_E(TAG, "Failed to enable amplifier: %s", error_to_string(error));
+    if ((expander_error = pi4ioe5v6408_set_output_level(io_expander0, output_level | 0b00000010, pdMS_TO_TICKS(100))) != ERROR_NONE) {
+        LOG_E(TAG, "Failed to enable amplifier: %s", error_to_string(expander_error));
         return ERROR_RESOURCE;
     }
🧹 Nitpick comments (3)
Devices/simulator/CMakeLists.txt (1)

15-22: Consider consolidating the two target_link_libraries calls.

Lines 15–20 and line 22 are two separate invocations for the same target. They can be merged into one, and it avoids the question of whether SDL2-static (line 19) and ${SDL2_LIBRARIES} (line 22) overlap.

♻️ Proposed consolidation
-    target_link_libraries(simulator
+    target_link_libraries(simulator
         PRIVATE Tactility
         PRIVATE TactilityCore
         PRIVATE lvgl
         PRIVATE SDL2-static
+        PRIVATE ${SDL2_LIBRARIES}
     )
-
-    target_link_libraries(simulator PRIVATE ${SDL2_LIBRARIES})
Drivers/pi4ioe5v6408-module/include/drivers/pi4ioe5v6408.h (1)

14-17: reg field name conflicts with its comment.

The comment "Address on bus" correctly describes the field's purpose (I2C device address), but the name reg conventionally implies a device register offset, not a bus address. Consider renaming to address or i2c_address for clarity, especially since this struct is part of the public API.

Drivers/pi4ioe5v6408-module/source/pi4ioe5v6408.cpp (1)

89-98: Non-standard C++ compound literal for .compatible.

(const char*[]) { ... } is a C99 compound literal — not part of the C++ standard. GCC and Clang accept it as an extension and give it static storage duration at file scope, so it works on ESP-IDF today. A portable alternative avoids the extension entirely:

♻️ Portable alternative
+static const char* pi4ioe5v6408_compatible[] = { "diodes,pi4ioe5v6408", nullptr };
+
 Driver pi4ioe5v6408_driver = {
     .name = "pi4ioe5v6408",
-    .compatible = (const char*[]) { "diodes,pi4ioe5v6408", nullptr},
+    .compatible = pi4ioe5v6408_compatible,
     ...
 };

Copy link

@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 (4)
Devices/waveshare-s3-touch-lcd-147/Source/module.cpp (1)

15-21: ⚠️ Potential issue | 🔴 Critical

Symbol is orphaned and unreachable — declaration and usage are missing.

The new symbol waveshare_s3_touch_lcd_147_module is defined but never declared in a header or referenced anywhere in the codebase. It has C linkage (inside extern "C"), yet lacks an extern declaration. Either this refactoring is incomplete and the symbol needs to be declared in a public header and registered with the module system, or it is dead code that should be removed. Verify the intended integration point and either add the necessary declaration/registration or remove the unused symbol.

Devices/lilygo-tlora-pager/Source/module.cpp (1)

23-29: ⚠️ Potential issue | 🔴 Critical

Update references to the renamed module symbol in TloraPager.cpp.

The rename from device_module to lilygo_tlora_pager_module is incomplete. The file Devices/lilygo-tlora-pager/Source/drivers/TloraPager.cpp still declares and uses the old symbol name:

  • Line 9: extern struct Module device_module;
  • Line 26: .owner = &device_module,

Both must be updated to use lilygo_tlora_pager_module to match the new symbol name in module.cpp. Without this change, the build will fail with an unresolved symbol error at link time. The new .symbols and .internal field additions are correct.

Devices/elecrow-crowpanel-advance-28/Source/module.cpp (1)

15-20: ⚠️ Potential issue | 🟡 Minor

Add .internal = nullptr to the Module initializer.

The struct Module has an .internal field that the header comment explicitly states should be initialized to NULL by module implementers. All sampled sibling module.cpp files in the repository (btt-panda-touch, cyd-2432s024c, generic-esp32, and others) include .internal = nullptr in their initializers. This file omits it, creating an inconsistency:

Other modules for reference
// btt-panda-touch, cyd-2432s024c, generic-esp32, etc.
struct Module xxx_module = {
    .name = "...",
    .start = start,
    .stop = stop,
    .symbols = nullptr,
    .internal = nullptr
};

While C++ zero-initializes unspecified designated initializer fields (so no runtime risk), follow the documented pattern.

Devices/cyd-4848s040c/Source/module.cpp (1)

15-21: ⚠️ Potential issue | 🟠 Major

Module definition is correct but integration is incomplete.

The symbol rename to cyd_4848s040c_module and expanded initializer are correctly implemented. However, the module is not properly integrated into the system:

  • No public header declares extern struct Module cyd_4848s040c_module (unlike hal_device_module which has tactility/hal_device_module.h)
  • The symbol is not referenced from any application or initialization code
  • The device tree file defines only hardware (GPIO/I2C/SPI), not the module itself

Following the pattern of hal_device_module, the device module either needs to be declared in a public header and registered in the initialization code (e.g., dts_modules[] array), or this incomplete integration must be clarified.

🧹 Nitpick comments (5)
Devices/guition-jc1060p470ciwy/Source/module.cpp (1)

19-20: Redundant explicit nullptr initialisers.

.symbols = nullptr and .internal = nullptr are already zero-initialised by C++ aggregate initialisation when omitted. Keeping them is harmless, but they add noise; consider dropping them for consistency with other modules, or retaining them only if the team prefers explicit initialization as a documentation aid.

♻️ Proposed simplification
 struct Module guition_jc1060p470ciwy_module = {
     .name = "guition-jc1060p470ciwy",
     .start = start,
     .stop = stop,
-    .symbols = nullptr,
-    .internal = nullptr
 };
TactilityKernel/source/kernel_init.cpp (1)

32-68: Bail-on-first-error approach — verify this is the desired behavior.

kernel_init returns ERROR_RESOURCE on the first module or device that fails to initialize, leaving the remaining modules/devices uninitialized. If partial initialization is acceptable (or if some devices are optional), you may want a "best-effort" mode that logs failures and continues. If the current fail-fast approach is intentional (i.e., any failure is fatal), this is fine as-is.

Devices/guition-jc8048w550c/Source/module.cpp (1)

15-21: LGTM — rename and new field initialisation look correct.

The rename to guition_jc8048w550c_module is consistent with board-specific naming, and the two new fields are properly zero-initialised.

However, note: this module is not currently exported or referenced in any dts_modules[] arrays. If this device is meant to be integrated into the module system, you'll need to add a public header with extern struct Module guition_jc8048w550c_module; (following the pattern used by other modules like hal_device_module) and include it in the appropriate device tree registration. If the module is only for internal device use, no further action is needed.

Drivers/pi4ioe5v6408-module/source/pi4ioe5v6408.cpp (2)

39-51: Nit: inconsistent struct Device* vs Device* within the extern "C" block.

The first three functions (lines 39, 44, 49) omit the struct keyword while the remaining seven use struct Device*. The public header uses struct Device* uniformly throughout. Both spellings compile identically in C++, but unifying on struct Device* here would match the header declarations and keep the style consistent within the extern "C" block.

🔧 Proposed fix
-error_t pi4ioe5v6408_set_direction(Device* device, uint8_t bits, TickType_t timeout) {
+error_t pi4ioe5v6408_set_direction(struct Device* device, uint8_t bits, TickType_t timeout) {

-error_t pi4ioe5v6408_set_output_level(Device* device, uint8_t bits, TickType_t timeout) {
+error_t pi4ioe5v6408_set_output_level(struct Device* device, uint8_t bits, TickType_t timeout) {

-error_t pi4ioe5v6408_get_output_level(Device* device, uint8_t* bits, TickType_t timeout) {
+error_t pi4ioe5v6408_get_output_level(struct Device* device, uint8_t* bits, TickType_t timeout) {

89-98: Optional: replace the compound literal with a named static array for standard C++.

(const char*[]) { ... } is a C99 compound literal — not valid in standard C++, though GCC and Clang accept it as an extension. The idiomatic, portable C++ alternative is a file-scoped static array:

♻️ Proposed refactor
+static const char* const pi4ioe5v6408_compatible[] = { "diodes,pi4ioe5v6408", nullptr };
+
 Driver pi4ioe5v6408_driver = {
     .name = "pi4ioe5v6408",
-    .compatible = (const char*[]) { "diodes,pi4ioe5v6408", nullptr},
+    .compatible = pi4ioe5v6408_compatible,
     .start_device = start,
     .stop_device = stop,
     .api = nullptr,
     .device_type = nullptr,
     .owner = &pi4ioe5v6408_module,
     .internal = nullptr
 };

@KenVanHoeylandt KenVanHoeylandt merged commit d2048e0 into main Feb 17, 2026
53 checks passed
@KenVanHoeylandt KenVanHoeylandt deleted the develop branch February 17, 2026 21:59
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.

1 participant

Comments