Repository navigation
CL-32, mesh, mono theme, SPI API, logos, and more - #724
Conversation
Walkthrough
Priority: Merge Risk:
|
There was a problem hiding this comment.
Actionable comments posted: 7

Review info
-
Run configuration-
- Source mode: Auto
- Repository: Unavailable
- Branch: Unavailable
- File: No configuration file from this repository applied
- Commit: Unavailable
- Layers: Organization UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
83f12d71-d856-4e68-af2b-16bd19c04e23
Files ignored due to path filters: 24-
Data/system/boot/logo_large.pngis excluded by!**/*.pngData/system/boot/logo_medium.pngis excluded by!**/*.pngData/system/boot/logo_small.pngis excluded by!**/*.pngData/system/boot/logo_usb_large.pngis excluded by!**/*.pngData/system/boot/logo_usb_medium.pngis excluded by!**/*.pngData/system/boot/logo_usb_small.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-advance-28/system/boot/logo_large.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-advance-28/system/boot/logo_medium.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-advance-28/system/boot/logo_small.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-advance-35/system/boot/logo_large.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-advance-35/system/boot/logo_medium.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-advance-35/system/boot/logo_small.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-advance-50/system/boot/logo_large.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-advance-50/system/boot/logo_medium.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-advance-50/system/boot/logo_small.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-basic-28/system/boot/logo_large.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-basic-28/system/boot/logo_medium.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-basic-28/system/boot/logo_small.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-basic-35/system/boot/logo_large.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-basic-35/system/boot/logo_medium.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-basic-35/system/boot/logo_small.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-basic-50/system/boot/logo_large.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-basic-50/system/boot/logo_medium.pngis excluded by!**/*.pngDevices/elecrow-crowpanel-basic-50/system/boot/logo_small.pngis excluded by!**/*.png
Files selected for processing: 13-
Devices/cl32-v04/source/cl32_v4_display.cppLICENSE.mdModules/lvgl-module/source/symbols.cModules/lvgl-module/source/themes/lv_theme_material_mono.cModules/lvgl-module/themes/material_mono.lssModules/mesh-module/source/module.cppPlatforms/platform-esp32/source/drivers/esp32_spi.cppTactility/Private/Tactility/app/boot/BootScreen.hTactility/Source/app/boot/BootInit.cppTactility/Source/app/wificonnect/WifiConnect.cppTactilityKernel/include/tactility/drivers/spi_controller.hTactilityKernel/source/drivers/spi_controller.cppTactilityKernel/source/symbols.c
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.
-
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

Major · Keep the device registered until spi_bus_remove_device() succeeds. · esp32_spi.cpp:130-142
Platforms/platform-esp32/source/drivers/esp32_spi.cpp:130-142
🩺 Stability & Availability | 🟠 Major | ⚡ Quick winKeep the device registered until
spi_bus_remove_device()succeeds.When removal overlaps an unfinished transfer, ESP-IDF can return
ESP_ERR_INVALID_STATE. The current code already erases the device and deletes its wrapper before checking that result.stop()can then pass its empty-device guard and callspi_bus_free()while the ESP-IDF device remains attached. The caller also cannot retry removal.Suggested fix
auto* data = GET_DATA(device); - recursive_mutex_lock(&data->mutex); - data->devices.erase(std::remove(data->devices.begin(), data->devices.end(), spi_device), data->devices.end()); - recursive_mutex_unlock(&data->mutex); if (spi_device->bus_acquired) { if (spi_device->cs != nullptr) gpio_descriptor_set_level(spi_device->cs, false); spi_device_release_bus(spi_device->handle); + spi_device->bus_acquired = false; } const esp_err_t result = spi_bus_remove_device(spi_device->handle); + if (result != ESP_OK) return ERROR_RESOURCE; + + recursive_mutex_lock(&data->mutex); + data->devices.erase(std::remove(data->devices.begin(), data->devices.end(), spi_device), data->devices.end()); + recursive_mutex_unlock(&data->mutex); delete spi_device; - return result == ESP_OK ? ERROR_NONE : ERROR_RESOURCE; + return ERROR_NONE;

Minor · Keep mesh retryable when cleanup fails. · module.cpp:86-96
Modules/mesh-module/source/module.cpp:86-96
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winKeep mesh retryable when cleanup fails.
If
mesh_set_enabled(true)racesstop(),service_manager_remove()can returnERROR_INVALID_STATEafter the service starts again.stop()has already setmodule_activetofalseand removed the boot callback. The kernel then keeps the module marked started becausemodule_stop()received an error. A latermodule_start()returns early, leaving mesh without its callback and without a recovery attempt.Restore the active state and retry the service before returning the cleanup error. Remove the callback only after cleanup succeeds.
Suggested fix
static error_t stop() { - system_event_callback_remove(KERNEL_EVENT_BOOT_COMPLETED, on_boot_completed); - // Waits for a callback that is running, and makes one that is still pending do nothing mutex_lock(&lifecycle_mutex.handle); module_active = false; error_t error = service_manager_stop(mesh_service_manifest.id); @@ if (error == ERROR_NONE) { error = app_manager_remove(mesh_command_manifest.id); } + if (error != ERROR_NONE) { + module_active = true; + if (boot_completed) { + start_service_if_enabled(); + } + mutex_unlock(&lifecycle_mutex.handle); + return error; + } mutex_unlock(&lifecycle_mutex.handle); + system_event_callback_remove(KERNEL_EVENT_BOOT_COMPLETED, on_boot_completed); return error; }

Review info
-
Run configuration-
- Source mode: Auto
- Repository: Unavailable
- Branch: Unavailable
- File: No configuration file from this repository applied
- Commit: Unavailable
- Layers: Organization UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
c849cd91-1a43-48e5-9f5b-da8643eda23b
Files selected for processing: 6-
Documentation/ideas.mdModules/lodepng-module/tests/CMakeLists.txtModules/mesh-module/source/module.cppPlatforms/platform-esp32/source/drivers/esp32_spi.cppTactility/Source/app/boot/BootScreen.cppTactilityKernel/source/drivers/gpio_controller.cpp
Files skipped from review as they are similar to previous changes: 2-
- Platforms/platform-esp32/source/drivers/esp32_spi.cpp
- Modules/mesh-module/source/module.cpp
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review.
-
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

Minor · Check the app directory's stored host before refusing a blank host field. · ui.py:2029-2038
Buildscripts/TactilitySDK/Tools/ui.py:2029-2038
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winCheck the app directory's stored host before refusing a blank host field.
The new guard in
DevConsole._runrefuses install, run, uninstall, bir, and brrr whenever the Device host field is blank.app.pycan still resolve a host without--host. It reads.tactility/device_hostrelative to the process working directory. The new UI starts app actions in the app directory, but it fills and checks the field from<repo>/.tactility/device_host. A host stored only in the app directory therefore cannot fill the field, and the guard blocks a run thatapp.pywould complete.Suggested fix
- if action in ("install", "run", "uninstall", "bir", "brrr") and not self.host_var.get().strip(): + if (action in ("install", "run", "uninstall", "bir", "brrr") + and not self.host_var.get().strip() + and not read_host(Path(app.path))): self._warn("Device host", "Enter the device host first.") returnWith this change, the field stays the primary source. The guard still applies when neither location holds a host.
🔇 Additional comments: 1
Modules/mesh-module/source/module.cpp-95-97: 1
95-97:Major · Stability & Availability · Heavy lift
⚠️ Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.Restore the service manifest before restarting the service.
If the command app manifest is absent,
app_manager_remove()returnsERROR_NOT_FOUNDafterservice_manager_remove()has succeeded. This branch setsmodule_activeto true, butservice_manager_start()cannot find the removed service manifest.module_stop()then leaves the module marked started without a running mesh service. Treat an absent app manifest as already removed, or re-register the service manifest before rolling back. (raw.githubusercontent.com)

Review info
-
Run configuration-
- Source mode: Auto
- Repository: Unavailable
- Branch: Unavailable
- File: No configuration file from this repository applied
- Commit: Unavailable
- Layers: Organization UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
7e02864f-0dd3-427a-be13-fb60d1c85421
Files selected for processing: 3-
Buildscripts/TactilitySDK/Tools/ui.pyModules/mesh-module/source/module.cppPlatforms/platform-esp32/source/drivers/esp32_spi.cpp
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review.
-
Summary
Fixes for the CL-32 and mesh, a mono theme focus fix, two small UI improvements, and a platform-neutral SPI API for external apps.
Changes
CL-32 v04: GPIO conflict warnings
cl32_v4_display.cpp: display detection no longer configures the CS pin, which the SPI driver already owns.gpio: conflictwarning.Mesh: radio selection at boot
mesh-module/module.cpp: the service is now registered without auto-start and starts onKERNEL_EVENT_BOOT_COMPLETEDif it was enabled.Mono theme: focus ring on checked icon buttons
material_mono.lss: a focused, checked or pressed icon button gets a paper gap between the ring and the fill (@focus-inverted-gap, 2 dpx, 1 px in compact mode).lv_theme_material_mono.c.Wi-Fi Connect
Boot logo
BootScreen::getLogicalWidth()).SPI controller API
spi_controllerin TactilityKernel getsadd_device,remove_device,transmit,acquire_busandrelease_bus, with an opaqueSpiDeviceand a plain-CSpiDeviceConfig. Bus init and free stay in the driver's start and stop.symbols.cso ELF apps can use SPI without ESP-IDF symbols.esp32_spi.cppimplements it and drives chip select through the GPIO descriptors it owns.cs_descriptorsnow matchescs_gpiosindex for index, with null for unavailable pins.