Skip to content

Smart tab5keyboard#533

Merged
KenVanHoeylandt merged 24 commits into
TactilityProject:mainfrom
Shadowtrance:smart-tab5keyboard
Jun 19, 2026
Merged

Smart tab5keyboard#533
KenVanHoeylandt merged 24 commits into
TactilityProject:mainfrom
Shadowtrance:smart-tab5keyboard

Conversation

@Shadowtrance

@Shadowtrance Shadowtrance commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Tab5 + Tab5 Keyboard are now "smart" 🧠

  • Detects if the keyboard is connected on boot - if yes, auto-rotates display to landscape (live only, doesn't touch your saved display settings).
  • Hot-pluggable (works, but a bit fiddly - polled ~once/sec, so there's up to a 1s delay either way). detects if attached after boot too.
  • On attach: if the display isn't already in landscape, it live-rotates to landscape (without touching your saved display settings).
  • On detach: if it auto-rotated to landscape on attach, it rotates back to whatever orientation you had before plugging in.
  • If you manually set landscape yourself (via Display Settings) while the keyboard is attached, unplugging won't rotate away from it - your manual choice always wins.
  • LEDs and keyboard registers also get re-synced on reattach (they reset to power-on defaults when unplugged).
  • Bonus: fixed a launcher bug where the home screen icon layout (row vs column) wouldn't update immediately after a rotation change while the launcher was visible - now it reflows live.

Misc changes:

  • Tab5 - switched sd card from SPI to SDMMC driver.
  • Tab5 - num_fbs = 1 > 2.
  • Fixed issue where usb mode logo would act strange and use the incorrect logo when the display wasn't in default orientation when rebooting to usb mode.
  • Added function to get direct framebuffers (MIPI DSI only) - currently only used in my doom port.
  • Added reboot to os from usb msc mode.
  • Minor tweaks to the sdmmc driver.
  • Bonus symbols

Summary by CodeRabbit

  • New Features
    • Added keyboard hot-plug detection with automatic display rotation adjustment for M5Stack Tab5
    • Added a frame buffer access API for displays that expose direct buffers
    • Added “Return to OS” action during USB boot
    • Enabled SDMMC-based storage support (with configurable host slot and max frequency)
  • Bug Fixes
    • Updated I2C scanning to skip address 0x00
    • Improved LVGL rotation handling to avoid stale UI references
    • Increased display frame buffering to improve rendering stability
  • Chores
    • Removed deprecated SD card SPI implementation and related support paths

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9416e28f-afa8-4f2d-b1d5-5ce1f7764859

📥 Commits

Reviewing files that changed from the base of the PR and between efe37b3 and 23e30f8.

📒 Files selected for processing (5)
  • Devices/m5stack-cardputer-adv/m5stack,cardputer-adv.dts
  • Devices/m5stack-cardputer/m5stack,cardputer.dts
  • Devices/m5stack-core2/m5stack,core2.dts
  • Devices/m5stack-cores3/m5stack,cores3.dts
  • Devices/m5stack-stackchan/m5stack,stackchan.dts
✅ Files skipped from review due to trivial changes (1)
  • Devices/m5stack-cardputer-adv/m5stack,cardputer-adv.dts

📝 Walkthrough

Walkthrough

This PR makes several hardware and software improvements for the M5Stack Tab5 device. The SD card interface is migrated from SPI to SDMMC with a new 4-bit bus configuration, configurable slot and frequency parameters, and an LDO power-on delay. Keyboard hot-plug detection is added to Tab5Keyboard with LVGL display auto-rotation when the keyboard attaches or detaches, and a module-level FreeRTOS timer handles post-boot keyboard detection via a new lateStart() method. The display driver gains a getFrameBuffers virtual method for direct panel frame buffer access, with both Tab5 display panels updated to use two frame buffers. USB MSC boot mode now tracks a startedFromBootMode flag so the device restarts automatically when the host ejects the volume, and the boot app captures the USB mode at startup to show a "Return to OS" button. The launcher gains orientation-aware button margin computation. Touch and I2C master drivers are updated to use Device* rather than port numbers, the Grove port-A DTS node replaces the former I2C node, and Grove pin properties are renamed across all device trees for semantic consistency. TactilityC ELF symbol exports are extended for ESP32-P4.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.28% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Smart tab5keyboard' refers to a real and significant part of the changeset (Tab5 keyboard smart detection and auto-rotation), but it is overly narrow and does not cover the main breadth of changes including SD card driver migration, frame buffer adjustments, USB boot mode fixes, launcher layout fixes, and other enhancements.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

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

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (1)
Devices/m5stack-tab5/Source/module.cpp (1)

124-134: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Roll back hp_detect_timer when keyboard timer setup fails.

start() can return ERROR_RESOURCE after hp_detect_timer is already running. That leaves a partially started module state and can block correct re-init behavior on the next start() call.

Suggested fix
     kb_detect_timer = xTimerCreate("kb_detect", pdMS_TO_TICKS(KB_DETECT_POLL_MS), pdTRUE, nullptr, keyboardDetectCallback);
     if (!kb_detect_timer) {
         LOG_E(TAG, "Failed to create kb_detect timer");
+        xTimerStop(hp_detect_timer, pdMS_TO_TICKS(100));
+        xTimerDelete(hp_detect_timer, pdMS_TO_TICKS(100));
+        hp_detect_timer = nullptr;
         return ERROR_RESOURCE;
     }
     if (xTimerStart(kb_detect_timer, pdMS_TO_TICKS(100)) != pdPASS) {
         LOG_E(TAG, "Failed to start kb_detect timer");
         xTimerDelete(kb_detect_timer, pdMS_TO_TICKS(100));
         kb_detect_timer = nullptr;
+        xTimerStop(hp_detect_timer, pdMS_TO_TICKS(100));
+        xTimerDelete(hp_detect_timer, pdMS_TO_TICKS(100));
+        hp_detect_timer = nullptr;
         return ERROR_RESOURCE;
     }

Also applies to: 138-148


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b7ce668b-27ed-459f-84c9-14cd0d272d22

📥 Commits

Reviewing files that changed from the base of the PR and between 8dabda2 and 0b9ea44.

📒 Files selected for processing (22)
  • Devices/m5stack-tab5/Source/Configuration.cpp
  • Devices/m5stack-tab5/Source/devices/Ili9881cDisplay.cpp
  • Devices/m5stack-tab5/Source/devices/SdCard.cpp
  • Devices/m5stack-tab5/Source/devices/SdCard.h
  • Devices/m5stack-tab5/Source/devices/St7123Display.cpp
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.cpp
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.h
  • Devices/m5stack-tab5/Source/module.cpp
  • Devices/m5stack-tab5/m5stack,tab5.dts
  • Drivers/EspLcdCompat/Source/EspLcdDisplayDriver.h
  • Platforms/platform-esp32/bindings/espressif,esp32-sdmmc.yaml
  • Platforms/platform-esp32/include/tactility/drivers/esp32_sdmmc.h
  • Platforms/platform-esp32/source/drivers/esp32_sdmmc_fs.cpp
  • Tactility/Include/Tactility/hal/display/DisplayDriver.h
  • Tactility/Source/app/boot/Boot.cpp
  • Tactility/Source/app/launcher/Launcher.cpp
  • Tactility/Source/hal/usb/UsbTusb.cpp
  • TactilityC/CMakeLists.txt
  • TactilityC/Include/tt_hal_display.h
  • TactilityC/Source/symbols/gcc_soft_float_p4.cpp
  • TactilityC/Source/tt_hal_display.cpp
  • TactilityC/Source/tt_init.cpp
💤 Files with no reviewable changes (2)
  • Devices/m5stack-tab5/Source/devices/SdCard.h
  • Devices/m5stack-tab5/Source/devices/SdCard.cpp

Comment thread Devices/m5stack-tab5/Source/devices/Tab5Keyboard.cpp
Comment thread Devices/m5stack-tab5/Source/module.cpp Outdated
Comment thread Platforms/platform-esp32/bindings/espressif,esp32-sdmmc.yaml
Comment thread Tactility/Source/hal/usb/UsbTusb.cpp Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3ab40414-e598-4267-8318-6f55de2aab62

📥 Commits

Reviewing files that changed from the base of the PR and between 0b9ea44 and bb49ac7.

📒 Files selected for processing (9)
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.cpp
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.h
  • Devices/m5stack-tab5/Source/module.cpp
  • Platforms/platform-esp32/bindings/espressif,esp32-sdmmc.yaml
  • Tactility/Include/Tactility/hal/usb/Usb.h
  • Tactility/Private/Tactility/hal/usb/UsbTusb.h
  • Tactility/Source/app/boot/Boot.cpp
  • Tactility/Source/hal/usb/Usb.cpp
  • Tactility/Source/hal/usb/UsbTusb.cpp
🚧 Files skipped from review as they are similar to previous changes (5)
  • Platforms/platform-esp32/bindings/espressif,esp32-sdmmc.yaml
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.h
  • Tactility/Source/app/boot/Boot.cpp
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.cpp
  • Devices/m5stack-tab5/Source/module.cpp

Comment thread Tactility/Source/hal/usb/UsbTusb.cpp

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
Devices/m5stack-tab5/m5stack,tab5.dts (1)

90-90: ⚠️ Potential issue | 🟠 Major

Replace SDMMC_FREQ_HIGHSPEED with an explicit frequency to match the Tab5 board-validated limit.

The binding documentation explicitly states that SDMMC_FREQ_HIGHSPEED expands to 40000 kHz, but the intended limit for this board is 20000 kHz (the binding's default value). Using the high-speed macro would run the SD bus at twice the validated frequency. Change line 90 to max-freq-khz = <20000>; to maintain board stability.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 127e2780-f329-40ef-9fcf-e6be307f427b

📥 Commits

Reviewing files that changed from the base of the PR and between 4782e81 and c2d293e.

📒 Files selected for processing (14)
  • Devices/m5stack-tab5/CMakeLists.txt
  • Devices/m5stack-tab5/Source/Configuration.cpp
  • Devices/m5stack-tab5/Source/devices/Display.cpp
  • Devices/m5stack-tab5/Source/devices/St7123Touch.cpp
  • Devices/m5stack-tab5/Source/devices/St7123Touch.h
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.cpp
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.h
  • Devices/m5stack-tab5/m5stack,tab5.dts
  • Drivers/GT911Ng/CMakeLists.txt
  • Drivers/GT911Ng/README.md
  • Drivers/GT911Ng/Source/Gt911TouchNg.cpp
  • Drivers/GT911Ng/Source/Gt911TouchNg.h
  • Platforms/platform-esp32/include/tactility/drivers/esp32_i2c_master.h
  • Platforms/platform-esp32/source/drivers/esp32_i2c_master.cpp
💤 Files with no reviewable changes (1)
  • Devices/m5stack-tab5/Source/Configuration.cpp
✅ Files skipped from review due to trivial changes (3)
  • Devices/m5stack-tab5/CMakeLists.txt
  • Drivers/GT911Ng/CMakeLists.txt
  • Drivers/GT911Ng/README.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.h
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.cpp

Comment thread Devices/m5stack-tab5/Source/devices/Display.cpp Outdated
Comment thread Platforms/platform-esp32/source/drivers/usb/esp32_usbhost.cpp Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: dbbf7050-2454-4a52-9992-9873f8f99d97

📥 Commits

Reviewing files that changed from the base of the PR and between 4782e81 and efe37b3.

📒 Files selected for processing (15)
  • Buildscripts/TactilitySDK/TactilitySDK.cmake
  • Devices/m5stack-tab5/Source/Configuration.cpp
  • Devices/m5stack-tab5/Source/devices/Display.cpp
  • Devices/m5stack-tab5/Source/devices/St7123Touch.cpp
  • Devices/m5stack-tab5/Source/devices/St7123Touch.h
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.cpp
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.h
  • Devices/m5stack-tab5/m5stack,tab5.dts
  • Platforms/platform-esp32/bindings/espressif,esp32-grove.yaml
  • Platforms/platform-esp32/include/tactility/drivers/esp32_grove.h
  • Platforms/platform-esp32/include/tactility/drivers/esp32_i2c_master.h
  • Platforms/platform-esp32/source/drivers/esp32_grove.cpp
  • Platforms/platform-esp32/source/drivers/esp32_i2c_master.cpp
  • Tactility/Source/app/i2cscanner/I2cScanner.cpp
  • TactilityKernel/source/kernel_symbols.c
💤 Files with no reviewable changes (1)
  • Buildscripts/TactilitySDK/TactilitySDK.cmake
🚧 Files skipped from review as they are similar to previous changes (6)
  • Devices/m5stack-tab5/Source/devices/St7123Touch.h
  • Devices/m5stack-tab5/Source/devices/St7123Touch.cpp
  • Platforms/platform-esp32/include/tactility/drivers/esp32_i2c_master.h
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.h
  • Platforms/platform-esp32/source/drivers/esp32_i2c_master.cpp
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.cpp

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: dbbf7050-2454-4a52-9992-9873f8f99d97

📥 Commits

Reviewing files that changed from the base of the PR and between 4782e81 and efe37b3.

📒 Files selected for processing (15)
  • Buildscripts/TactilitySDK/TactilitySDK.cmake
  • Devices/m5stack-tab5/Source/Configuration.cpp
  • Devices/m5stack-tab5/Source/devices/Display.cpp
  • Devices/m5stack-tab5/Source/devices/St7123Touch.cpp
  • Devices/m5stack-tab5/Source/devices/St7123Touch.h
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.cpp
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.h
  • Devices/m5stack-tab5/m5stack,tab5.dts
  • Platforms/platform-esp32/bindings/espressif,esp32-grove.yaml
  • Platforms/platform-esp32/include/tactility/drivers/esp32_grove.h
  • Platforms/platform-esp32/include/tactility/drivers/esp32_i2c_master.h
  • Platforms/platform-esp32/source/drivers/esp32_grove.cpp
  • Platforms/platform-esp32/source/drivers/esp32_i2c_master.cpp
  • Tactility/Source/app/i2cscanner/I2cScanner.cpp
  • TactilityKernel/source/kernel_symbols.c
💤 Files with no reviewable changes (1)
  • Buildscripts/TactilitySDK/TactilitySDK.cmake
🚧 Files skipped from review as they are similar to previous changes (6)
  • Devices/m5stack-tab5/Source/devices/St7123Touch.h
  • Devices/m5stack-tab5/Source/devices/St7123Touch.cpp
  • Platforms/platform-esp32/include/tactility/drivers/esp32_i2c_master.h
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.h
  • Platforms/platform-esp32/source/drivers/esp32_i2c_master.cpp
  • Devices/m5stack-tab5/Source/devices/Tab5Keyboard.cpp
🛑 Comments failed to post (2)
Platforms/platform-esp32/source/drivers/esp32_grove.cpp (1)

156-160: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

child_config leaks when child startup fails.

On Line 156, if device_construct_add_start(...) fails, stop_child() runs while data->current_mode is still GROVE_MODE_DISABLED, so Line 53-58 won’t delete the allocated Esp32UartConfig/Esp32I2cMasterConfig. This is a real error-path leak.

Proposed fix
-    error_t err = device_construct_add_start(data->child_device, compatible);
+    // Set mode before startup so stop_child() can free mode-specific config on failure.
+    data->current_mode = mode;
+    error_t err = device_construct_add_start(data->child_device, compatible);
     if (err != ERROR_NONE) {
         LOG_E(TAG, "%s: failed to start child device: %d", device->name, err);
         stop_child(device);
         return err;
     }
-
-    data->current_mode = mode;
     return ERROR_NONE;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    // Set mode before startup so stop_child() can free mode-specific config on failure.
    data->current_mode = mode;
    error_t err = device_construct_add_start(data->child_device, compatible);
    if (err != ERROR_NONE) {
        LOG_E(TAG, "%s: failed to start child device: %d", device->name, err);
        stop_child(device);
        return err;
    }
    return ERROR_NONE;
Tactility/Source/app/i2cscanner/I2cScanner.cpp (1)

187-191: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fail getPort when no bus is selected.

getPort reports success even when portDevice == nullptr, then onScanTimer treats that pointer as valid. This leaves a reachable null-pointer path during scan startup when no active bus was selected.

Suggested fix
 bool I2cScannerApp::getPort(struct Device** outPort) {
     if (mutex.lock(100 / portTICK_PERIOD_MS)) {
-        *outPort = this->portDevice;
+        *outPort = this->portDevice;
+        if (*outPort == nullptr) {
+            mutex.unlock();
+            logger.warn("No I2C port selected");
+            return false;
+        }
         mutex.unlock();
         return true;
     } else {
         logger.warn(LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "getPort");
         return false;

Also applies to: 222-233

@KenVanHoeylandt KenVanHoeylandt merged commit 594b8bd into TactilityProject:main Jun 19, 2026
58 checks passed
@KenVanHoeylandt

Copy link
Copy Markdown
Contributor

Thanks a lot!

@Shadowtrance Shadowtrance deleted the smart-tab5keyboard branch June 19, 2026 20:22
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