Skip to content

Kampi/usb reworks#12

Merged
Kampi merged 7 commits into1.0_Devfrom
kampi/USB-Reworks
Mar 1, 2026
Merged

Kampi/usb reworks#12
Kampi merged 7 commits into1.0_Devfrom
kampi/USB-Reworks

Conversation

@Kampi
Copy link
Contributor

@Kampi Kampi commented Mar 1, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • Added USB CDC (serial/terminal) support alongside MSC and UVC interfaces
    • Introduced soft storage mount/unmount for improved USB mass storage handling
    • Added USB cable connection detection
    • Implemented automatic memory usage monitoring with periodic updates
  • Improvements

    • Renamed flash storage references to memory for UI consistency
    • Enhanced PSRAM-aware memory allocation across modules
    • Improved USB device lifecycle management
    • Updated ESP-IDF to version 5.5.3 with DSP library support

Refactor USB descriptors to include UVC and CDC support with updated endpoint configurations.
- Add Python script for patching

Signed-off-by: Daniel Kampert <DanielKampert@kampis-elektroecke.de>
@Kampi Kampi self-assigned this Mar 1, 2026
Copilot AI review requested due to automatic review settings March 1, 2026 12:17
@Kampi Kampi merged commit 8cc6eb2 into 1.0_Dev Mar 1, 2026
4 of 7 checks passed
@Kampi Kampi deleted the kampi/USB-Reworks branch March 1, 2026 12:17
@coderabbitai
Copy link

coderabbitai bot commented Mar 1, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9a837ac and 874a7d8.

📒 Files selected for processing (56)
  • .github/copilot-instructions.md
  • components/esp_tinyusb/tinyusb_uvc.c
  • docs/MemoryManager.adoc
  • docs/MemoryMap.adoc
  • docs/USBManager.adoc
  • main/Application/Manager/Memory/memoryManager.cpp
  • main/Application/Manager/Memory/memoryManager.h
  • main/Application/Manager/Network/DNS/dnsServer.cpp
  • main/Application/Manager/Network/Provisioning/provisionHandlers.cpp
  • main/Application/Manager/Network/Provisioning/provisioning.cpp
  • main/Application/Manager/Network/SNTP/sntp.cpp
  • main/Application/Manager/Network/Server/HTTP/http_server.cpp
  • main/Application/Manager/Network/Server/ImageEncoder/Bitmap/bitmapEncoder.cpp
  • main/Application/Manager/Network/Server/ImageEncoder/JPEG/jpegEncoder.cpp
  • main/Application/Manager/Network/Server/ImageEncoder/imageEncoder.cpp
  • main/Application/Manager/Network/Server/RemoteControl/remoteControl.cpp
  • main/Application/Manager/Network/Server/VISA/Private/visaCommands.cpp
  • main/Application/Manager/Network/Server/VISA/visaServer.cpp
  • main/Application/Manager/Network/Server/WebSocket/websocket.cpp
  • main/Application/Manager/Network/networkManager.cpp
  • main/Application/Manager/Settings/Private/settingsDefaultLoader.cpp
  • main/Application/Manager/Settings/Private/settingsJSONLoader.cpp
  • main/Application/Manager/Settings/Private/settingsLoader.h
  • main/Application/Manager/Settings/settingsTypes.h
  • main/Application/Manager/USB/CDC/usbCDC.cpp
  • main/Application/Manager/USB/CDC/usbCDC.h
  • main/Application/Manager/USB/CDC/usbCDCTypes.h
  • main/Application/Manager/USB/Descriptors/descriptors.cpp
  • main/Application/Manager/USB/Descriptors/descriptors.h
  • main/Application/Manager/USB/MSC/usbMSC.cpp
  • main/Application/Manager/USB/MSC/usbMSC.h
  • main/Application/Manager/USB/UVC/usbUVC.cpp
  • main/Application/Manager/USB/descriptors.cpp
  • main/Application/Manager/USB/usbManager.cpp
  • main/Application/Manager/USB/usbManager.h
  • main/Application/Manager/USB/usbTypes.h
  • main/Application/Tasks/Camera/cameraTask.cpp
  • main/Application/Tasks/Devices/devicesTask.cpp
  • main/Application/Tasks/GUI/Private/guiHelper.cpp
  • main/Application/Tasks/GUI/Private/guiHelper.h
  • main/Application/Tasks/GUI/Private/guiImageSave.cpp
  • main/Application/Tasks/GUI/UI/ui_messagebox.cpp
  • main/Application/Tasks/GUI/UI/ui_settings.cpp
  • main/Application/Tasks/GUI/UI/ui_settings.h
  • main/Application/Tasks/GUI/UI/ui_settings_events.cpp
  • main/Application/Tasks/GUI/UI/ui_settings_events.h
  • main/Application/Tasks/GUI/guiTask.cpp
  • main/Application/Tasks/Lepton/leptonTask.cpp
  • main/Application/Tasks/Network/networkTask.cpp
  • main/idf_component.yml
  • main/main.cpp
  • patches/0001-feat-esp_lcd-Add-PSRAM-mode-support-in-SPI-LCD-panel.patch
  • platformio.ini
  • scripts/patch.py
  • sdkconfig.debug
  • sdkconfig.release

📝 Walkthrough

Walkthrough

Comprehensive refactor introducing composite USB device architecture (MSC, UVC, CDC), implementing soft-mount/remount storage APIs, standardizing SPIRAM-aware memory allocation across modules, updating UI terminology from Flash to Memory, expanding USB and network configurations, and adding supporting documentation.

Changes

Cohort / File(s) Summary
USB Architecture Refactor
main/Application/Manager/USB/usbManager.*, main/Application/Manager/USB/CDC/usbCDC.*, main/Application/Manager/USB/Descriptors/descriptors.*, main/Application/Manager/USB/MSC/usbMSC.*, main/Application/Manager/USB/UVC/usbUVC.cpp, main/Application/Manager/USB/usbTypes.h, main/Application/Manager/USB/descriptors.cpp
Replaces single-mode USB manager with composite device supporting MSC, UVC, and CDC simultaneously. Removes USB_Mode_t and USB_Manager_Config_t types; introduces command-queue-based monitoring task and async enable/disable for MSC/UVC. New USBCDC_Init/Deinit/Write APIs for virtual serial communication. Reorganizes descriptors into unified composite configuration. Updates USBManager_Init signature, adds USBManager_EnableMSC/EnableUVC/IsCableConnected public APIs.
Memory Manager API & Handle Refactoring
main/Application/Manager/Memory/memoryManager.*
Adds MemoryManager_SoftUnmountStorage() and MemoryManager_SoftRemountStorage() to preserve storage handles while unmounting FAT VFS for USB MSC block access. Renames internal state member p_SDCard to SDCard. Refactors storage usage calculation to use disk I/O queries instead of fixed paths. Updates format and remount logic with new soft-mount flow.
Settings & USB Configuration
main/Application/Manager/Settings/settingsTypes.h, main/Application/Manager/Settings/Private/settingsDefaultLoader.cpp, main/Application/Manager/Settings/Private/settingsJSONLoader.cpp, main/Application/Manager/Settings/Private/settingsLoader.h
Extends Settings_USB_t with new UVC_Enabled and CDC_Enabled boolean flags, replacing reserved space. Updates JSON parsing to load new USB feature flags with defaults. Adds preprocessor macros for USB enable defaults.
Network Manager Updates
main/Application/Manager/Network/dnsServer.cpp, main/Application/Manager/Network/provisioning.cpp, main/Application/Manager/Network/SNTP/sntp.cpp, main/Application/Manager/Network/networkManager.cpp
Downgrades provisioning and DNS logging from INFO to DEBUG level. Refactors DNS server initialization to set running state inside task rather than before creation. Updates SNTP to use provided SyncInterval parameter. Introduces NetIf variable for AP interface IP retrieval.
Memory Allocation Standardization
main/Application/Manager/Network/Server/HTTP/http_server.cpp, main/Application/Manager/Network/Server/ImageEncoder/Bitmap/bitmapEncoder.cpp, main/Application/Manager/Network/Server/ImageEncoder/JPEG/jpegEncoder.cpp, main/Application/Manager/Network/Server/ImageEncoder/imageEncoder.cpp, main/Application/Manager/Network/Server/VISA/visaCommands.cpp, main/Application/Manager/Network/Server/WebSocket/websocket.cpp, main/Application/Tasks/GUI/guiTask.cpp, main/Application/Tasks/Lepton/leptonTask.cpp
Introduces conditional Caps variable for heap allocation flags based on CONFIG_SPIRAM across multiple modules. Replaces unconditional MALLOC_CAP_SPIRAM with runtime-determined allocation capabilities, enabling graceful degradation when PSRAM unavailable.
GUI & UI Enhancements
main/Application/Tasks/GUI/Private/guiHelper.*, main/Application/Tasks/GUI/UI/ui_settings.*, main/Application/Tasks/GUI/UI/ui_settings_events.*, main/Application/Tasks/GUI/UI/ui_messagebox.cpp
Adds GUI_Helper_Timer_MemoryUpdate for periodic memory monitoring; updates UI terminology from "Flash" to "Memory" throughout settings pages. Introduces PSRAM DMA configuration and reduced trans_queue_depth (3). Adds USB CDC switch callback. Updates logging levels to DEBUG for non-critical events.
Provisioning & Handler Refactoring
main/Application/Manager/Network/Provisioning/provisionHandlers.cpp, main/Application/Manager/Network/Server/RemoteControl/remoteControl.cpp, main/Application/Manager/Network/Server/VISA/visaServer.cpp
Removes embedded logo PNG declarations; refactors provisioning handlers for memory-aware allocation. Renames variables for consistency (e.g., source_addrSource, VISA_ServerTaskTask_VisaServer). Simplifies battery/temperature getters in remote control module.
Task & Core Initialization
main/Application/Tasks/Camera/cameraTask.cpp, main/Application/Tasks/Devices/devicesTask.cpp, main/Application/Tasks/GUI/guiTask.cpp, main/Application/Tasks/Network/networkTask.cpp, main/main.cpp
Refactors task creation patterns: moves running state initialization inside task rather than before creation; renames local ret/Ret variables to Error for consistency. Adds USBManager_Init() call in main initialization sequence. Removes several explanatory comments during refactoring.
Build System & Patching
platformio.ini, scripts/patch.py, sdkconfig.debug, sdkconfig.release, patches/0001-..., main/idf_component.yml
Upgrades PlatformIO platform URL with commit hash; adds pre-build patch script to apply IDF framework patches. Enables TinyUSB CDC class in sdkconfig with CDC buffer configuration. Adds espressif/esp-dsp dependency (v1.7.0). Updates IDF version to 5.5.3 with new IRAM safety flags and SPI RAM optimizations.
Documentation
.github/copilot-instructions.md, docs/MemoryManager.adoc, docs/MemoryMap.adoc, docs/USBManager.adoc
Adds comprehensive Memory Management documentation covering regions, bounce buffers, and allocation rules. Introduces new MemoryMap.adoc detailing ESP32-S3 memory budget and PSRAM usage. Updates USBManager documentation to reflect new soft-mount/remount lifecycle, descriptor changes (160×120 MJPEG at 9 FPS), and configuration prerequisites. Updates copilot instructions with memory management section.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • Issue #6 #7: Updates .github/copilot-instructions.md with comprehensive copilot guidance; this PR extends it with memory management documentation and timestamp updates, indicating alignment on developer-facing documentation standards.

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

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR reworks the firmware’s USB subsystem toward a composite TinyUSB device (MSC + UVC + CDC), adds an automated ESP-IDF patching step to enable SPI LCD PSRAM mode support, and updates memory/storage handling to safely support MSC by soft-unmounting/remounting the VFS.

Changes:

  • Enable/configure TinyUSB CDC and add a composite USB manager with command-queue based MSC/UVC enable/disable.
  • Add a PlatformIO pre-build patch system (scripts/patch.py) and a framework patch to add psram_mode support to esp_lcd SPI panel IO.
  • Introduce MemoryManager soft-unmount/remount APIs and update GUI/Lepton/network code to allocate buffers conditionally based on PSRAM availability; update related documentation (USB/Mem).

Reviewed changes

Copilot reviewed 55 out of 56 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
sdkconfig.release Enables TinyUSB CDC in release config.
sdkconfig.debug Updates ESP-IDF config (5.5.3) and enables/configures CDC + other options.
platformio.ini Pins platform-espressif32 to a commit and adds pre-build patch script.
scripts/patch.py Applies patches/*.patch idempotently to the framework package at build time.
patches/0001-*.patch Adds psram_mode flag handling to ESP-IDF esp_lcd SPI panel IO.
main/main.cpp Initializes USB manager during boot.
main/idf_component.yml Adds espressif/esp-dsp dependency.
main/Application/Tasks/* Logging level tweaks, task creation refactors, PSRAM-cap-aware allocations, GUI memory page/USB UI updates.
main/Application/Manager/USB/* Composite USB manager, new CDC module, moved/rewritten descriptors, MSC/VFS handling updates.
main/Application/Manager/Memory/* Adds soft-unmount/remount APIs; updates usage calculation and SD card handle naming.
main/Application/Manager/Network/* Small refactors + allocation caps changes; SNTP sync interval fix.
docs/USBManager.adoc Updates USB manager documentation (partially) for new behavior.
docs/MemoryMap.adoc New comprehensive memory map documentation.
docs/MemoryManager.adoc Documents new soft-unmount/remount APIs and revised MSC workflow.
.github/copilot-instructions.md Adds rule to keep MemoryMap.adoc in sync with allocations/stacks.
Comments suppressed due to low confidence (3)

main/Application/Tasks/GUI/UI/ui_settings.cpp:832

  • Style: missing space after if (should be if (...) to match the project’s formatting rules).
    main/Application/Manager/USB/usbManager.cpp:401
  • usbManager.h documents that enabling MSC/UVC is ignored when the USB cable is not connected, but USBManager_EnableMSC()/EnableUVC() currently enqueue the command unconditionally. This can lead to MSC soft-unmounting/locking the filesystem even when no host is present. Add an isCableConnected check (or update the API contract/docs) to prevent enabling classes unless the device is enumerated.
    docs/USBManager.adoc:218
  • This section still documents/examples USB_Manager_Config_t (which was removed from the codebase) and describes runtime descriptor customization, but the implementation now uses fixed composite descriptors and a parameterless USBManager_Init(). Update these examples and the surrounding text so they match the new USB Manager API and descriptor approach.
**Example (MSC Mode):**

[source,cpp]
----
const USB_Manager_Config_t USB_MSC_Config = {
    .Mode = USB_MODE_MSC,
    .MountPoint = MemoryManager_GetStoragePath(),
    .Manufacturer = "Kampi's Elektroecke",
    .Product = "PyroVision",
    .SerialNumber = "PV-12345678",
    .FrameWidth = 0,        // Not used in MSC mode
    .FrameHeight = 0,       // Not used in MSC mode
    .FrameInterval = 0,     // Not used in MSC mode
};
----

**Example (UVC Mode):**

[source,cpp]
----
const USB_Manager_Config_t USB_UVC_Config = {
    .Mode = USB_MODE_UVC,
    .MountPoint = NULL,     // Not used in UVC mode
    .Manufacturer = "Kampi's Elektroecke",
    .Product = "PyroVision Thermal Webcam",
    .SerialNumber = "PV-12345678",
    .FrameWidth = 160,      // Lepton thermal camera resolution
    .FrameHeight = 120,
    .FrameInterval = 1111111, // 9 FPS (10000000 / 9)
};

Comment on lines +73 to +74
_DNS_Server_State.isRunning = true;

Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

DNS_Server_Start() no longer sets _DNS_Server_State.isRunning before creating the task; instead the task sets it at startup. This introduces a race where DNS_Server_Stop() called right after Start() will early-return (isRunning is still false), leaving the socket open and the task running. Set isRunning=true in DNS_Server_Start() before xTaskCreatePinnedToCore (and remove the assignment in the task), so Stop() is always effective immediately after Start().

Suggested change
_DNS_Server_State.isRunning = true;

Copilot uses AI. Check for mistakes.
Comment on lines +306 to +309
if (_USB_Manager_State.MonitoringTask != NULL) {
vTaskDelete(_USB_Manager_State.MonitoringTask);
_USB_Manager_State.MonitoringTask = NULL;
}
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

The USB monitoring task registers itself with the task watchdog via esp_task_wdt_add(NULL), but USBManager_Deinit() deletes the task via vTaskDelete(_USB_Manager_State.MonitoringTask) without first removing it from the watchdog. This can leave a stale WDT subscription and may trigger watchdog faults later. Before deleting the task, call esp_task_wdt_delete(_USB_Manager_State.MonitoringTask) (or implement a clean exit path where the task calls esp_task_wdt_delete(NULL) before self-deleting).

Copilot uses AI. Check for mistakes.
Comment on lines +227 to 242
_USB_Manager_State.StringDescriptors[0] = USB_LangID;
_USB_Manager_State.StringDescriptors[1] = CONFIG_DEVICE_MANUFACTURER;
_USB_Manager_State.StringDescriptors[2] = CONFIG_DEVICE_NAME;
_USB_Manager_State.StringDescriptors[3] = NULL;

ESP_LOGD(TAG, "USB Descriptors: VID:PID = 0x%04X:0x%04X",
get_Desc_Device()->idVendor,
get_Desc_Device()->idProduct);
ESP_LOGD(TAG, " Manufacturer: %s, Product: %s",
_USB_Manager_State.StringDescriptors[1], _USB_Manager_State.StringDescriptors[2]);

USB_Config.descriptor.device = get_Desc_Device();
USB_Config.descriptor.full_speed_config = get_Desc_Config();
USB_Config.descriptor.string = _USB_Manager_State.StringDescriptors;
USB_Config.descriptor.string_count = 3;

Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

The device descriptor uses STRID_SERIAL (see descriptors.cpp), but USBManager_Init() sets StringDescriptors[3] = NULL and sets USB_Config.descriptor.string_count = 3. This means the host may request a serial string index that TinyUSB can't provide, causing enumeration issues. Provide a valid serial string entry and set string_count to include it (or set iSerialNumber=0 in the device descriptor).

Copilot uses AI. Check for mistakes.
Comment on lines +45 to +46
#define SETTINGS_DEFAULT_USB_UVC_ENABLE false
#define SETTINGS_DEFAULT_USB_CDC_ENABLE false
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

SETTINGS_DEFAULT_USB_UVC_ENABLE and SETTINGS_DEFAULT_USB_CDC_ENABLE are defined twice here, which will trigger macro redefinition warnings/errors (depending on compiler flags) and is likely unintended. Remove the duplicate defines so each default is declared only once.

Suggested change
#define SETTINGS_DEFAULT_USB_UVC_ENABLE false
#define SETTINGS_DEFAULT_USB_CDC_ENABLE false

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +2
From c87755f74b4379079ae46dbcd736c5f03d3091f4 Mon Sep 17 00:00:00 2001
From: Daniel Kampert <DanielKampert@kampis-elektroecke.de>
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

This patch file begins with a UTF-8 BOM (the first line starts with an invisible character before "From"). git apply can fail to parse patches with a BOM on the first line. Save the patch without BOM (UTF-8 without signature) so the pre-build patch script can apply it reliably.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +5
#include <class/msc/msc.h>
#include <class/video/video.h>

#include "descriptors.h"

Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

This new source file is missing the project’s required GPL/license header block at the top (every .cpp/.h/.py file should include it). Add the standard header so licensing stays consistent across the codebase.

Copilot uses AI. Check for mistakes.
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