From 18a4b7342885e37163e0c7ff5cd2c3047578338a Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Sat, 16 Aug 2025 18:52:14 +0200 Subject: [PATCH 01/20] USB Descriptor Rework --- .../ProjectConfig/ProjectConfig/Models.hpp | 2 +- .../usb_device_uvc/tusb/usb_descriptors.c | 181 ++++++----------- dependencies.lock | 2 +- sdkconfig | 191 +++++------------- 4 files changed, 110 insertions(+), 266 deletions(-) diff --git a/components/ProjectConfig/ProjectConfig/Models.hpp b/components/ProjectConfig/ProjectConfig/Models.hpp index 85c9b81..2cbf9df 100644 --- a/components/ProjectConfig/ProjectConfig/Models.hpp +++ b/components/ProjectConfig/ProjectConfig/Models.hpp @@ -32,7 +32,7 @@ struct DeviceMode_t : BaseConfigModel { explicit DeviceMode_t( Preferences *pref) : BaseConfigModel(pref), mode(StreamingMode::AUTO){} void load() { - int stored_mode = this->pref->getInt("mode", 0); + int stored_mode = this->pref->getInt("mode", 1); this->mode = static_cast(stored_mode); ESP_LOGI("DeviceMode", "Loaded device mode: %d", stored_mode); } diff --git a/components/usb_device_uvc/tusb/usb_descriptors.c b/components/usb_device_uvc/tusb/usb_descriptors.c index 0b1f0a4..5d121e9 100644 --- a/components/usb_device_uvc/tusb/usb_descriptors.c +++ b/components/usb_device_uvc/tusb/usb_descriptors.c @@ -22,14 +22,26 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * + * --------------------------------------------------------------------------- + * USB Video Class (UVC) Descriptor Definitions for TinyUSB device stack. + * + * This file describes the device, configuration, and string descriptors for + * a single UVC camera. Build-time options (Kconfig) select whether UVC data + * streams use BULK or ISO endpoints, the pixel format (MJPEG / H.264 / + * Uncompressed), and whether multiple frame sizes are exposed. + * + * Goal: keep the same behavior while making the structure easier to read and + * maintain. Comments explain why each block exists and what each macro does. */ #include "tusb.h" #include "usb_descriptors.h" +#include // memcpy, strlen //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ +// Device descriptor: identifies this as a composite device using IAD for UVC tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -63,6 +75,16 @@ uint8_t const *tud_descriptor_device_cb(void) //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ +// String descriptor indices used in interface descriptors +#define STRID_LANGID 0 +#define STRID_MANUFACTURER 1 +#define STRID_PRODUCT 2 +#define STRID_SERIAL 3 +#define STRID_UVC_CAM1 4 + +// Endpoint numbers for UVC video IN endpoints (device -> host) +#define EPNUM_CAM1_VIDEO_IN 0x81 + #if CFG_TUD_CAM1_VIDEO_STREAMING_BULK #if CONFIG_UVC_CAM1_MULTI_FRAMESIZE @@ -101,76 +123,38 @@ uint8_t const *tud_descriptor_device_cb(void) #endif // CFG_TUD_CAM1_VIDEO_STREAMING_BULK -#if CONFIG_UVC_SUPPORT_TWO_CAM -#if CFG_TUD_CAM2_VIDEO_STREAMING_BULK +// Total length of this configuration +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CAM1_VIDEO_CAPTURE_DESC_LEN) -#if CONFIG_UVC_CAM2_MULTI_FRAMESIZE -#if CONFIG_FORMAT_MJPEG_CAM2 -#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MULTI_MJPEG_BULK_LEN(4)) -#elif CONFIG_FORMAT_H264_CAM2 -#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MULTI_FRAME_BASED_BULK_LEN(4)) -#endif -#else -#if CONFIG_FORMAT_MJPEG_CAM2 -#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MJPEG_BULK_LEN) -#elif CONFIG_FORMAT_H264_CAM2 -#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_FRAME_BASED_BULK_LEN) -#else -#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_UNCOMPR_BULK_LEN) -#endif -#endif // CONFIG_UVC_CAM2_MULTI_FRAMESIZE - -#else - -#if CONFIG_UVC_CAM2_MULTI_FRAMESIZE -#if CONFIG_FORMAT_MJPEG_CAM2 -#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MULTI_MJPEG_LEN(4)) -#elif CONFIG_FORMAT_H264_CAM2 -#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MULTI_FRAME_BASED_LEN(4)) -#endif -#else -#if CONFIG_FORMAT_MJPEG_CAM2 -#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN) -#elif CONFIG_FORMAT_H264_CAM2 -#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_FRAME_BASED_LEN) -#else -#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN) -#endif -#endif // CONFIG_UVC_CAM2_MULTI_FRAMESIZE - -#endif // CFG_TUD_CAM2_VIDEO_STREAMING_BULK -#else -#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN 0 -#endif - -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CAM1_VIDEO_CAPTURE_DESC_LEN + TUD_CAM2_VIDEO_CAPTURE_DESC_LEN) -#define EPNUM_CAM1_VIDEO_IN 0x81 -#if CONFIG_UVC_SUPPORT_TWO_CAM -#define EPNUM_CAM2_VIDEO_IN 0x82 -#endif - -uint8_t const desc_fs_configuration[] = { - // Config number, interface count, string index, total length, attribute, power in mA +// Full-speed configuration descriptor +static uint8_t const desc_fs_configuration[] = { + // TUD_CONFIG_DESCRIPTOR(config_number, interface_count, string_index, + // total_length, attributes, power_mA) TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 500), // IAD for Video Control #if CFG_TUD_CAM1_VIDEO_STREAMING_BULK #if CONFIG_UVC_CAM1_MULTI_FRAMESIZE #if CONFIG_FORMAT_MJPEG_CAM1 - TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_MJPEG_BULK(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE), + // Camera 1, multi-size MJPEG over BULK + TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_MJPEG_BULK(STRID_UVC_CAM1, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE), #elif CONFIG_FORMAT_H264_CAM1 - TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_H264_BULK(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE), + // Camera 1, multi-size H.264 over BULK + TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_H264_BULK(STRID_UVC_CAM1, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE), #endif #else #if CONFIG_FORMAT_MJPEG_CAM1 - TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, + // Camera 1, single-size MJPEG over BULK + TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(STRID_UVC_CAM1, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, UVC_CAM1_FRAME_WIDTH, UVC_CAM1_FRAME_HEIGHT, UVC_CAM1_FRAME_RATE, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE), #elif CONFIG_FORMAT_H264_CAM1 - TUD_VIDEO_CAPTURE_DESCRIPTOR_H264_BULK(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, + // Camera 1, single-size H.264 over BULK + TUD_VIDEO_CAPTURE_DESCRIPTOR_H264_BULK(STRID_UVC_CAM1, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, UVC_CAM1_FRAME_WIDTH, UVC_CAM1_FRAME_HEIGHT, UVC_CAM1_FRAME_RATE, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE), #else - TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, + // Camera 1, single-size Uncompressed (YUY2/etc) over BULK + TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(STRID_UVC_CAM1, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, UVC_CAM1_FRAME_WIDTH, UVC_CAM1_FRAME_HEIGHT, UVC_CAM1_FRAME_RATE, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE), #endif @@ -178,75 +162,32 @@ uint8_t const desc_fs_configuration[] = { #else #if CONFIG_UVC_CAM1_MULTI_FRAMESIZE #if CONFIG_FORMAT_MJPEG_CAM1 - TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_MJPEG(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE), + // Camera 1, multi-size MJPEG over ISO + TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_MJPEG(STRID_UVC_CAM1, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE), #elif CONFIG_FORMAT_H264_CAM1 - TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_H264(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE), + // Camera 1, multi-size H.264 over ISO + TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_H264(STRID_UVC_CAM1, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE), #endif #else #if CONFIG_FORMAT_MJPEG_CAM1 - TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, + // Camera 1, single-size MJPEG over ISO + TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(STRID_UVC_CAM1, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, UVC_CAM1_FRAME_WIDTH, UVC_CAM1_FRAME_HEIGHT, UVC_CAM1_FRAME_RATE, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE), #elif CONFIG_FORMAT_H264_CAM1 - TUD_VIDEO_CAPTURE_DESCRIPTOR_H264(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, + // Camera 1, single-size H.264 over ISO + TUD_VIDEO_CAPTURE_DESCRIPTOR_H264(STRID_UVC_CAM1, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, UVC_CAM1_FRAME_WIDTH, UVC_CAM1_FRAME_HEIGHT, UVC_CAM1_FRAME_RATE, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE), #else - TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, + // Camera 1, single-size Uncompressed over ISO + TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(STRID_UVC_CAM1, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, UVC_CAM1_FRAME_WIDTH, UVC_CAM1_FRAME_HEIGHT, UVC_CAM1_FRAME_RATE, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE), #endif #endif // CONFIG_UVC_CAM1_MULTI_FRAMESIZE #endif // CFG_TUD_CAM1_VIDEO_STREAMING_BULK -#if CONFIG_UVC_SUPPORT_TWO_CAM -#if CFG_TUD_CAM2_VIDEO_STREAMING_BULK -#if CONFIG_UVC_CAM2_MULTI_FRAMESIZE -#if CONFIG_FORMAT_MJPEG_CAM2 - TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_MJPEG_BULK(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN, CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE), -#elif CONFIG_FORMAT_H264_CAM2 - TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_H264_BULK(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN, CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE), -#endif -#else -#if CONFIG_FORMAT_MJPEG_CAM2 - TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN, - UVC_CAM2_FRAME_WIDTH, UVC_CAM2_FRAME_HEIGHT, UVC_CAM2_FRAME_RATE, - CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE), -#elif CONFIG_FORMAT_H264_CAM2 - TUD_VIDEO_CAPTURE_DESCRIPTOR_H264_BULK(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN, - UVC_CAM2_FRAME_WIDTH, UVC_CAM2_FRAME_HEIGHT, UVC_CAM2_FRAME_RATE, - CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE), -#else - TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN, - UVC_CAM2_FRAME_WIDTH, UVC_CAM2_FRAME_HEIGHT, UVC_CAM2_FRAME_RATE, - CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE), -#endif -#endif // CONFIG_UVC_CAM2_MULTI_FRAMESIZE -#else -#if CONFIG_UVC_CAM2_MULTI_FRAMESIZE -#if CONFIG_FORMAT_MJPEG_CAM2 - TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_MJPEG(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN, CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE), -#elif CONFIG_FORMAT_H264_CAM2 - TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_H264(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN, CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE), -#endif -#else -#if CONFIG_FORMAT_MJPEG_CAM2 - TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN, - UVC_CAM2_FRAME_WIDTH, UVC_CAM2_FRAME_HEIGHT, UVC_CAM2_FRAME_RATE, - CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE), -#elif CONFIG_FORMAT_H264_CAM2 - TUD_VIDEO_CAPTURE_DESCRIPTOR_H264(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN, - UVC_CAM2_FRAME_WIDTH, UVC_CAM2_FRAME_HEIGHT, UVC_CAM2_FRAME_RATE, - CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE), -#else - TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM2_VIDEO_IN, - UVC_CAM2_FRAME_WIDTH, UVC_CAM2_FRAME_HEIGHT, UVC_CAM2_FRAME_RATE, - CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE), -#endif -#endif // CONFIG_UVC_CAM2_MULTI_FRAMESIZE -#endif // CFG_TUD_CAM2_VIDEO_STREAMING_BULK -#endif - }; // Invoked when received GET CONFIGURATION DESCRIPTOR @@ -263,30 +204,26 @@ uint8_t const *tud_descriptor_configuration_cb(uint8_t index) // String Descriptors //--------------------------------------------------------------------+ -// array of pointer to string descriptors +// Array of pointers to string literals. Indices must match STRID_* above. char const *string_desc_arr[] = { - (const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409) + (const char[]){0x09, 0x04}, // 0: Supported language: English (0x0409) CONFIG_TUSB_MANUFACTURER, // 1: Manufacturer CONFIG_TUSB_PRODUCT, // 2: Product - CONFIG_TUSB_SERIAL_NUM, // 3: Serials, should use chip ID, overridden with get_serial_number() - "UVC CAM1", // 4: UVC Interface, default, because we're overriding it get_uvc_device_name(), but we still have to keep the structure -#if CONFIG_UVC_SUPPORT_TWO_CAM - "UVC CAM2", // 5: UVC Interface -#endif + CONFIG_TUSB_SERIAL_NUM, // 3: Serial (overridden by get_serial_number()) + "UVC CAM1", // 4: UVC Interface name for Cam1 (overridden by get_uvc_device_name()) }; static uint16_t _desc_str[32]; __attribute__((weak)) const char *get_uvc_device_name(void) { - // ETVR Override, by default we're reporting ourselves as this, users can override it + // Default UVC device name, can be overridden by application return "UVC OpenIris Camera"; } __attribute__((weak)) const char *get_serial_number(void) { - // ETVR Override, by default we're reporting ourselves as the predefined serial number - // this should get overwritten with a better implementation + // Default serial number, can be overridden by application (e.g., chip ID) return CONFIG_TUSB_SERIAL_NUM; } @@ -294,7 +231,6 @@ __attribute__((weak)) const char *get_serial_number(void) // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { - printf("am I being asked for this?"); (void)langid; uint8_t chr_count; @@ -309,15 +245,16 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) + if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { return NULL; } const char *str = string_desc_arr[index]; - if (index == 3) + // Allow dynamic overrides for specific indices + if (index == STRID_SERIAL) str = get_serial_number(); - if (index == 4) + if (index == STRID_UVC_CAM1) str = get_uvc_device_name(); if (str == NULL) str = string_desc_arr[index]; @@ -340,4 +277,4 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) _desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; -} +} \ No newline at end of file diff --git a/dependencies.lock b/dependencies.lock index 95f496d..c7e209c 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -53,7 +53,7 @@ dependencies: idf: source: type: idf - version: 5.4.2 + version: 5.3.3 direct_dependencies: - espressif/cmake_utilities - espressif/esp32-camera diff --git a/sdkconfig b/sdkconfig index e183fa7..b9755fb 100644 --- a/sdkconfig +++ b/sdkconfig @@ -1,6 +1,6 @@ # # Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) 5.4.2 Project Configuration +# Espressif IoT Development Framework (ESP-IDF) 5.3.3 Project Configuration # CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 @@ -138,7 +138,6 @@ CONFIG_SOC_I2C_SUPPORT_RTC=y CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y CONFIG_SOC_I2C_SLAVE_SUPPORT_BROADCAST=y CONFIG_SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS=y -CONFIG_SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE=y CONFIG_SOC_I2S_NUM=2 CONFIG_SOC_I2S_HW_VERSION_2=y CONFIG_SOC_I2S_SUPPORTS_XTAL=y @@ -152,7 +151,6 @@ CONFIG_SOC_I2S_PDM_MAX_RX_LINES=4 CONFIG_SOC_I2S_SUPPORTS_TDM=y CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y CONFIG_SOC_LEDC_SUPPORT_XTAL_CLOCK=y -CONFIG_SOC_LEDC_TIMER_NUM=4 CONFIG_SOC_LEDC_CHANNEL_NUM=8 CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=14 CONFIG_SOC_LEDC_SUPPORT_FADE_STOP=y @@ -309,7 +307,6 @@ CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y CONFIG_SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY=y CONFIG_SOC_PM_CPU_RETENTION_BY_RTCCNTL=y CONFIG_SOC_PM_MODEM_RETENTION_BY_BACKUPDMA=y -CONFIG_SOC_PM_MODEM_PD_BY_SW=y CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y @@ -371,11 +368,10 @@ CONFIG_SOC_ULP_HAS_ADC=y CONFIG_SOC_PHY_COMBO_MODULE=y CONFIG_IDF_CMAKE=y CONFIG_IDF_TOOLCHAIN="gcc" -CONFIG_IDF_TOOLCHAIN_GCC=y CONFIG_IDF_TARGET_ARCH_XTENSA=y CONFIG_IDF_TARGET_ARCH="xtensa" CONFIG_IDF_TARGET="esp32s3" -CONFIG_IDF_INIT_VERSION="$IDF_INIT_VERSION" +CONFIG_IDF_INIT_VERSION="5.3.3" CONFIG_IDF_TARGET_ESP32S3=y CONFIG_IDF_FIRMWARE_CHIP_ID=0x0009 @@ -407,10 +403,6 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set - -# -# Log -# # CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set # CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set # CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set @@ -419,14 +411,6 @@ CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y # CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set CONFIG_BOOTLOADER_LOG_LEVEL=3 -# -# Format -# -# CONFIG_BOOTLOADER_LOG_COLORS is not set -CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y -# end of Format -# end of Log - # # Serial Flash Configurations # @@ -497,7 +481,6 @@ CONFIG_ESP_ROM_HAS_CACHE_WRITEBACK_BUG=y CONFIG_ESP_ROM_HAS_SW_FLOAT=y CONFIG_ESP_ROM_HAS_VERSION=y CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y -CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y # # Boot ROM Behavior @@ -514,9 +497,9 @@ CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y # CONFIG_ESPTOOLPY_NO_STUB is not set # CONFIG_ESPTOOLPY_OCT_FLASH is not set CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT=y -CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set -# CONFIG_ESPTOOLPY_FLASHMODE_DIO is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y # CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y CONFIG_ESPTOOLPY_FLASHMODE="dio" @@ -524,16 +507,17 @@ CONFIG_ESPTOOLPY_FLASHMODE="dio" CONFIG_ESPTOOLPY_FLASHFREQ_80M=y # CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set # CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y CONFIG_ESPTOOLPY_FLASHFREQ="80m" # CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y -# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y # CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +CONFIG_ESPTOOLPY_FLASHSIZE="8MB" # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -550,7 +534,6 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 # CONFIG_PARTITION_TABLE_SINGLE_APP is not set # CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set # CONFIG_PARTITION_TABLE_TWO_OTA is not set -# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="min_spiffs.csv" CONFIG_PARTITION_TABLE_FILENAME="min_spiffs.csv" @@ -595,32 +578,32 @@ CONFIG_WIFI_AP_PASSWORD="12345678" # OpenIris: LED Configuration # CONFIG_LED_BLINK_GPIO=8 -CONFIG_LED_EXTERNAL_GPIO=1 +CONFIG_LED_EXTERNAL_GPIO=9 CONFIG_LED_EXTERNAL_CONTROL=y -CONFIG_LED_EXTERNAL_PWM_FREQ=5000 -CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100 +CONFIG_LED_EXTERNAL_PWM_FREQ=20000 +CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=50 # end of OpenIris: LED Configuration # # Camera sensor pinout configuration # -CONFIG_CAMERA_MODULE_NAME="SWROOM_BABBLE_S3" +CONFIG_CAMERA_MODULE_NAME="FaceFocusVR_Face" CONFIG_PWDN_GPIO_NUM=-1 CONFIG_RESET_GPIO_NUM=-1 -CONFIG_XCLK_GPIO_NUM=4 -CONFIG_SIOD_GPIO_NUM=48 -CONFIG_SIOC_GPIO_NUM=47 -CONFIG_Y9_GPIO_NUM=13 -CONFIG_Y8_GPIO_NUM=5 -CONFIG_Y7_GPIO_NUM=6 -CONFIG_Y6_GPIO_NUM=15 -CONFIG_Y5_GPIO_NUM=17 -CONFIG_Y4_GPIO_NUM=8 -CONFIG_Y3_GPIO_NUM=18 -CONFIG_Y2_GPIO_NUM=16 -CONFIG_VSYNC_GPIO_NUM=21 -CONFIG_HREF_GPIO_NUM=14 -CONFIG_PCLK_GPIO_NUM=7 +CONFIG_XCLK_GPIO_NUM=10 +CONFIG_SIOD_GPIO_NUM=40 +CONFIG_SIOC_GPIO_NUM=39 +CONFIG_Y9_GPIO_NUM=48 +CONFIG_Y8_GPIO_NUM=11 +CONFIG_Y7_GPIO_NUM=12 +CONFIG_Y6_GPIO_NUM=14 +CONFIG_Y5_GPIO_NUM=16 +CONFIG_Y4_GPIO_NUM=18 +CONFIG_Y3_GPIO_NUM=17 +CONFIG_Y2_GPIO_NUM=15 +CONFIG_VSYNC_GPIO_NUM=38 +CONFIG_HREF_GPIO_NUM=47 +CONFIG_PCLK_GPIO_NUM=13 # end of Camera sensor pinout configuration # @@ -633,7 +616,6 @@ CONFIG_COMPILER_OPTIMIZATION_PERF=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set -CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 # CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set @@ -644,18 +626,14 @@ CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set # CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set # CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set -# CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set # CONFIG_COMPILER_WARN_WRITE_STRINGS is not set -CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y # CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set # CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set -# CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set # CONFIG_COMPILER_DUMP_RTL_FILES is not set CONFIG_COMPILER_RT_LIB_GCCLIB=y CONFIG_COMPILER_RT_LIB_NAME="gcc" # CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING is not set CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE=y -# CONFIG_COMPILER_STATIC_ANALYZER is not set # end of Compiler options # @@ -745,12 +723,6 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations -# -# Legacy I2C Driver Configurations -# -# CONFIG_I2C_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy I2C Driver Configurations - # # Legacy PCNT Driver Configurations # @@ -838,7 +810,6 @@ CONFIG_GPTIMER_OBJ_CACHE_SAFE=y # # CONFIG_I2C_ISR_IRAM_SAFE is not set # CONFIG_I2C_ENABLE_DEBUG_LOG is not set -# CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set # end of ESP-Driver:I2C Configurations # @@ -963,7 +934,6 @@ CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set # CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set # CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set -CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 # end of ESP HTTP client # @@ -976,7 +946,6 @@ CONFIG_HTTPD_PURGE_BUF_LEN=32 # CONFIG_HTTPD_LOG_PURGE_DATA is not set CONFIG_HTTPD_WS_SUPPORT=y # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set -CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # end of HTTP Server # @@ -984,14 +953,12 @@ CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set # CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set -CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS OTA # # ESP HTTPS server # # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set -CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS server # @@ -1069,10 +1036,8 @@ CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y # GDMA Configurations # CONFIG_GDMA_CTRL_FUNC_IN_IRAM=y -CONFIG_GDMA_ISR_HANDLER_IN_IRAM=y -CONFIG_GDMA_OBJ_DRAM_SAFE=y -# CONFIG_GDMA_ENABLE_DEBUG_LOG is not set # CONFIG_GDMA_ISR_IRAM_SAFE is not set +# CONFIG_GDMA_ENABLE_DEBUG_LOG is not set # end of GDMA Configurations # @@ -1086,28 +1051,29 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # end of Hardware Settings # -# ESP-Driver:LCD Controller Configurations +# LCD and Touch Panel +# + +# +# LCD Touch Drivers are maintained in the IDF Component Registry +# + +# +# LCD Peripheral Configuration # # CONFIG_LCD_ENABLE_DEBUG_LOG is not set # CONFIG_LCD_RGB_ISR_IRAM_SAFE is not set # CONFIG_LCD_RGB_RESTART_IN_VSYNC is not set -# end of ESP-Driver:LCD Controller Configurations - -# -# ESP-MM: Memory Management Configurations -# -# CONFIG_ESP_MM_CACHE_MSYNC_C2M_CHUNKED_OPS is not set -# end of ESP-MM: Memory Management Configurations +# end of LCD Peripheral Configuration +# end of LCD and Touch Panel # # ESP NETIF Adapter # CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 -# CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y -CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y # CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set # CONFIG_ESP_NETIF_L2_TAP is not set # CONFIG_ESP_NETIF_BRIDGE_EN is not set @@ -1155,23 +1121,21 @@ CONFIG_SPIRAM=y # # SPI RAM config # -CONFIG_SPIRAM_MODE_QUAD=y -# CONFIG_SPIRAM_MODE_OCT is not set +# CONFIG_SPIRAM_MODE_QUAD is not set +CONFIG_SPIRAM_MODE_OCT=y CONFIG_SPIRAM_TYPE_AUTO=y -# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set -# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set # CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y CONFIG_SPIRAM_CLK_IO=30 CONFIG_SPIRAM_CS_IO=26 # CONFIG_SPIRAM_XIP_FROM_PSRAM is not set # CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set # CONFIG_SPIRAM_RODATA is not set -# CONFIG_SPIRAM_SPEED_120M is not set CONFIG_SPIRAM_SPEED_80M=y # CONFIG_SPIRAM_SPEED_40M is not set CONFIG_SPIRAM_SPEED=80 +# CONFIG_SPIRAM_ECC_ENABLE is not set CONFIG_SPIRAM_BOOT_INIT=y -CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION=y # CONFIG_SPIRAM_IGNORE_NOTFOUND is not set # CONFIG_SPIRAM_USE_MEMMAP is not set # CONFIG_SPIRAM_USE_CAPS_ALLOC is not set @@ -1191,11 +1155,6 @@ CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set # end of ESP Ringbuf -# -# ESP Security Specific -# -# end of ESP Security Specific - # # ESP System Settings # @@ -1444,21 +1403,10 @@ CONFIG_FATFS_TIMEOUT_MS=10000 CONFIG_FATFS_PER_FILE_CACHE=y CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y # CONFIG_FATFS_USE_FASTSEEK is not set -CONFIG_FATFS_USE_STRFUNC_NONE=y -# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set -# CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 # CONFIG_FATFS_IMMEDIATE_FSYNC is not set # CONFIG_FATFS_USE_LABEL is not set CONFIG_FATFS_LINK_LOCK=y -# CONFIG_FATFS_USE_DYN_BUFFERS is not set - -# -# File system free space calculation behavior -# -CONFIG_FATFS_DONT_TRUST_FREE_CLUSTER_CNT=0 -CONFIG_FATFS_DONT_TRUST_LAST_ALLOC=0 -# end of File system free space calculation behavior # end of FAT Filesystem support # @@ -1480,7 +1428,6 @@ CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 # CONFIG_FREERTOS_USE_TICK_HOOK is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 # CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set -CONFIG_FREERTOS_USE_TIMERS=y CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" # CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set # CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set @@ -1507,7 +1454,6 @@ CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y CONFIG_FREERTOS_ISR_STACKSIZE=1536 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y -# CONFIG_FREERTOS_FPU_IN_ISR is not set CONFIG_FREERTOS_TICK_SUPPORT_SYSTIMER=y CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL1=y # CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL3 is not set @@ -1516,12 +1462,6 @@ CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER=y # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # end of Port -# -# Extra -# -CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM=y -# end of Extra - CONFIG_FREERTOS_PORT=y CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y @@ -1560,11 +1500,7 @@ CONFIG_HEAP_TRACING_OFF=y # end of Heap memory debugging # -# Log -# - -# -# Log Level +# Log output # # CONFIG_LOG_DEFAULT_LEVEL_NONE is not set # CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set @@ -1577,29 +1513,11 @@ CONFIG_LOG_DEFAULT_LEVEL=3 # CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE=y CONFIG_LOG_MAXIMUM_LEVEL=5 - -# -# Level Settings -# # CONFIG_LOG_MASTER_LEVEL is not set -CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y -# CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set -# CONFIG_LOG_TAG_LEVEL_IMPL_LINKED_LIST is not set -CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST=y -# CONFIG_LOG_TAG_LEVEL_CACHE_ARRAY is not set -CONFIG_LOG_TAG_LEVEL_CACHE_BINARY_MIN_HEAP=y -CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 -# end of Level Settings -# end of Log Level - -# -# Format -# CONFIG_LOG_COLORS=y CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set -# end of Format -# end of Log +# end of Log output # # LWIP @@ -1638,8 +1556,6 @@ CONFIG_LWIP_ESP_MLDV6_REPORT=y CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y -# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set -# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set @@ -1654,7 +1570,6 @@ CONFIG_LWIP_DHCPS=y CONFIG_LWIP_DHCPS_LEASE_UNIT=60 CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y -CONFIG_LWIP_DHCPS_ADD_DNS=y # end of DHCP server # CONFIG_LWIP_AUTOIP is not set @@ -1713,12 +1628,12 @@ CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 # CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 # CONFIG_LWIP_SLIP_SUPPORT is not set # @@ -1839,7 +1754,6 @@ CONFIG_MBEDTLS_HAVE_TIME=y # CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y -CONFIG_MBEDTLS_SHA1_C=y CONFIG_MBEDTLS_SHA512_C=y # CONFIG_MBEDTLS_SHA3_C is not set CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y @@ -1895,8 +1809,6 @@ CONFIG_MBEDTLS_X509_CSR_PARSE_C=y # end of Certificates CONFIG_MBEDTLS_ECP_C=y -CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y -CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y # CONFIG_MBEDTLS_DHM_C is not set CONFIG_MBEDTLS_ECDH_C=y CONFIG_MBEDTLS_ECDSA_C=y @@ -1921,7 +1833,6 @@ CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM=y # CONFIG_MBEDTLS_THREADING_C is not set CONFIG_MBEDTLS_ERROR_STRINGS=y CONFIG_MBEDTLS_FS_IO=y -# CONFIG_MBEDTLS_ALLOW_WEAK_CERTIFICATE_VERIFICATION is not set # end of mbedTLS # @@ -1964,7 +1875,6 @@ CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND=y # CONFIG_NVS_ENCRYPTION is not set # CONFIG_NVS_ASSERT_ERROR_CHECK is not set # CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set -# CONFIG_NVS_ALLOCATE_CACHE_IN_SPIRAM is not set # end of NVS # @@ -2033,10 +1943,10 @@ CONFIG_SPI_FLASH_HPM_AUTO=y CONFIG_SPI_FLASH_HPM_ON=y CONFIG_SPI_FLASH_HPM_DC_AUTO=y # CONFIG_SPI_FLASH_HPM_DC_DISABLE is not set +CONFIG_SPI_FLASH_SUSPEND_QVL_SUPPORTED=y # CONFIG_SPI_FLASH_AUTO_SUSPEND is not set CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 # CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set -# CONFIG_SPI_FLASH_FORCE_ENABLE_C6_H2_SUSPEND is not set # end of Optional and Experimental Features (READ DOCS FIRST) # end of Main Flash configuration @@ -2197,8 +2107,6 @@ CONFIG_VFS_MAX_COUNT=8 # CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 # end of Host File System I/O (Semihosting) - -CONFIG_VFS_INITIALIZE_DEV_NULL=y # end of Virtual file system # @@ -2386,9 +2294,9 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y CONFIG_LOG_BOOTLOADER_LEVEL=3 # CONFIG_APP_ROLLBACK_ENABLE is not set # CONFIG_FLASH_ENCRYPTION_ENABLED is not set -CONFIG_FLASHMODE_QIO=y +# CONFIG_FLASHMODE_QIO is not set # CONFIG_FLASHMODE_QOUT is not set -# CONFIG_FLASHMODE_DIO is not set +CONFIG_FLASHMODE_DIO=y # CONFIG_FLASHMODE_DOUT is not set CONFIG_MONITOR_BAUD=115200 # CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set @@ -2521,7 +2429,6 @@ CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=2048 CONFIG_TIMER_QUEUE_LENGTH=10 # CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set -CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y # CONFIG_HAL_ASSERTION_SILIENT is not set # CONFIG_L2_TO_L3_COPY is not set CONFIG_ESP_GRATUITOUS_ARP=y From 21e8dbe264ce5f31c0df986f0b35fb33a6fc6b98 Mon Sep 17 00:00:00 2001 From: Lorow Date: Tue, 19 Aug 2025 00:03:31 +0200 Subject: [PATCH 02/20] Add PoC PWN duty cycle adjustment command for FaceFocus --- .../CommandManager/CommandManager.cpp | 63 ++++++++++------ .../CommandManager/CommandManager.hpp | 1 + .../commands/device_commands.cpp | 35 ++++++++- .../commands/device_commands.hpp | 2 + components/LEDManager/CMakeLists.txt | 2 +- .../LEDManager/LEDManager/LEDManager.cpp | 71 +++++++++++-------- .../LEDManager/LEDManager/LEDManager.hpp | 4 +- .../ProjectConfig/ProjectConfig/Models.hpp | 48 ++++++++----- .../ProjectConfig/ProjectConfig.cpp | 39 ++++++---- .../ProjectConfig/ProjectConfig.hpp | 12 ++-- main/openiris_main.cpp | 10 ++- sdkconfig.board.project_babble | 2 +- tools/openiris_setup.py | 37 +++++++++- 13 files changed, 227 insertions(+), 99 deletions(-) diff --git a/components/CommandManager/CommandManager/CommandManager.cpp b/components/CommandManager/CommandManager/CommandManager.cpp index 7932a1d..c4f897f 100644 --- a/components/CommandManager/CommandManager/CommandManager.cpp +++ b/components/CommandManager/CommandManager/CommandManager.cpp @@ -23,53 +23,76 @@ std::unordered_map commandTypeMap = { {"connect_wifi", CommandType::CONNECT_WIFI}, {"switch_mode", CommandType::SWITCH_MODE}, {"get_device_mode", CommandType::GET_DEVICE_MODE}, + {"set_led_duty_cycle", CommandType::SET_LED_DUTY_CYCLE}, }; -std::function CommandManager::createCommand(const CommandType type, std::string_view json) const { +std::function CommandManager::createCommand(const CommandType type, std::string_view json) const +{ switch (type) { case CommandType::PING: - return { PingCommand }; + return {PingCommand}; case CommandType::PAUSE: - return [json] { return PauseCommand(json); }; + return [json] + { return PauseCommand(json); }; case CommandType::SET_STREAMING_MODE: - return [this, json] {return setDeviceModeCommand(this->registry, json); }; + return [this, json] + { return setDeviceModeCommand(this->registry, json); }; case CommandType::UPDATE_OTA_CREDENTIALS: - return [this, json] { return updateOTACredentialsCommand(this->registry, json); }; + return [this, json] + { return updateOTACredentialsCommand(this->registry, json); }; case CommandType::SET_WIFI: - return [this, json] { return setWiFiCommand(this->registry, json); }; + return [this, json] + { return setWiFiCommand(this->registry, json); }; case CommandType::UPDATE_WIFI: - return [this, json] { return updateWiFiCommand(this->registry, json); }; + return [this, json] + { return updateWiFiCommand(this->registry, json); }; case CommandType::UPDATE_AP_WIFI: - return [this, json] { return updateAPWiFiCommand(this->registry, json); }; + return [this, json] + { return updateAPWiFiCommand(this->registry, json); }; case CommandType::DELETE_NETWORK: - return [this, json] { return deleteWiFiCommand(this->registry, json); }; + return [this, json] + { return deleteWiFiCommand(this->registry, json); }; case CommandType::SET_MDNS: - return [this, json] { return setMDNSCommand(this->registry, json); }; + return [this, json] + { return setMDNSCommand(this->registry, json); }; case CommandType::UPDATE_CAMERA: - return [this, json] { return updateCameraCommand(this->registry, json); }; + return [this, json] + { return updateCameraCommand(this->registry, json); }; case CommandType::RESTART_CAMERA: - return [this, json] { return restartCameraCommand(this->registry, json); }; + return [this, json] + { return restartCameraCommand(this->registry, json); }; case CommandType::GET_CONFIG: - return [this] { return getConfigCommand(this->registry); }; + return [this] + { return getConfigCommand(this->registry); }; case CommandType::SAVE_CONFIG: - return [this] { return saveConfigCommand(this->registry); }; + return [this] + { return saveConfigCommand(this->registry); }; case CommandType::RESET_CONFIG: - return [this, json] { return resetConfigCommand(this->registry, json); }; + return [this, json] + { return resetConfigCommand(this->registry, json); }; case CommandType::RESTART_DEVICE: return restartDeviceCommand; case CommandType::SCAN_NETWORKS: - return [this] { return scanNetworksCommand(this->registry); }; + return [this] + { return scanNetworksCommand(this->registry); }; case CommandType::START_STREAMING: return startStreamingCommand; case CommandType::GET_WIFI_STATUS: - return [this] { return getWiFiStatusCommand(this->registry); }; + return [this] + { return getWiFiStatusCommand(this->registry); }; case CommandType::CONNECT_WIFI: - return [this] { return connectWiFiCommand(this->registry); }; + return [this] + { return connectWiFiCommand(this->registry); }; case CommandType::SWITCH_MODE: - return [this, json] { return switchModeCommand(this->registry, json); }; + return [this, json] + { return switchModeCommand(this->registry, json); }; case CommandType::GET_DEVICE_MODE: - return [this] { return getDeviceModeCommand(this->registry); }; + return [this] + { return getDeviceModeCommand(this->registry); }; + case CommandType::SET_LED_DUTY_CYCLE: + return [this, json] + { return updateLEDDutyCycleCommand(this->registry, json); }; default: return nullptr; } diff --git a/components/CommandManager/CommandManager/CommandManager.hpp b/components/CommandManager/CommandManager/CommandManager.hpp index 02231e3..5db67d0 100644 --- a/components/CommandManager/CommandManager/CommandManager.hpp +++ b/components/CommandManager/CommandManager/CommandManager.hpp @@ -44,6 +44,7 @@ enum class CommandType CONNECT_WIFI, SWITCH_MODE, GET_DEVICE_MODE, + SET_LED_DUTY_CYCLE, }; class CommandManager diff --git a/components/CommandManager/CommandManager/commands/device_commands.cpp b/components/CommandManager/CommandManager/commands/device_commands.cpp index 2ffc4dd..0ccd9ca 100644 --- a/components/CommandManager/CommandManager/commands/device_commands.cpp +++ b/components/CommandManager/CommandManager/commands/device_commands.cpp @@ -25,6 +25,8 @@ CommandResult setDeviceModeCommand(std::shared_ptr registry, const auto projectConfig = registry->resolve(DependencyType::project_config); projectConfig->setDeviceMode(static_cast(mode)); + cJSON_Delete(parsedJson); + return CommandResult::getSuccessResult("Device mode set"); } @@ -64,10 +66,41 @@ CommandResult updateOTACredentialsCommand(std::shared_ptr re } } - projectConfig->setDeviceConfig(OTALogin, OTAPassword, OTAPort); + cJSON_Delete(parsedJson); + + projectConfig->setOTAConfig(OTALogin, OTAPassword, OTAPort); return CommandResult::getSuccessResult("OTA Config set"); } +CommandResult updateLEDDutyCycleCommand(std::shared_ptr registry, std::string_view jsonPayload) +{ + const auto parsedJson = cJSON_Parse(jsonPayload.data()); + if (parsedJson == nullptr) + { + return CommandResult::getErrorResult("Invalid payload"); + } + + const auto dutyCycleObject = cJSON_GetObjectItem(parsedJson, "dutyCycle"); + if (dutyCycleObject == nullptr) + { + return CommandResult::getErrorResult("Invalid payload - missing dutyCycle"); + } + + const auto dutyCycle = dutyCycleObject->valueint; + + if (dutyCycle < 0 || dutyCycle > 100) + { + return CommandResult::getErrorResult("Invalid payload - unsupported dutyCycle"); + } + + const auto projectConfig = registry->resolve(DependencyType::project_config); + projectConfig->setLEDDUtyCycleConfig(dutyCycle); + + cJSON_Delete(parsedJson); + + return CommandResult::getSuccessResult("LED duty cycle set"); +} + CommandResult restartDeviceCommand() { OpenIrisTasks::ScheduleRestart(2000); diff --git a/components/CommandManager/CommandManager/commands/device_commands.hpp b/components/CommandManager/CommandManager/commands/device_commands.hpp index 4eb1b3d..22cde8a 100644 --- a/components/CommandManager/CommandManager/commands/device_commands.hpp +++ b/components/CommandManager/CommandManager/commands/device_commands.hpp @@ -13,6 +13,8 @@ CommandResult setDeviceModeCommand(std::shared_ptr registry, CommandResult updateOTACredentialsCommand(std::shared_ptr registry, std::string_view jsonPayload); +CommandResult updateLEDDutyCycleCommand(std::shared_ptr registry, std::string_view jsonPayload); + CommandResult restartDeviceCommand(); CommandResult startStreamingCommand(); diff --git a/components/LEDManager/CMakeLists.txt b/components/LEDManager/CMakeLists.txt index b377b09..4466f41 100644 --- a/components/LEDManager/CMakeLists.txt +++ b/components/LEDManager/CMakeLists.txt @@ -1,4 +1,4 @@ idf_component_register(SRCS "LEDManager/LEDManager.cpp" INCLUDE_DIRS "LEDManager" - REQUIRES StateManager driver esp_driver_ledc Helpers + REQUIRES StateManager driver esp_driver_ledc Helpers ProjectConfig ) \ No newline at end of file diff --git a/components/LEDManager/LEDManager/LEDManager.cpp b/components/LEDManager/LEDManager/LEDManager.cpp index 97ad6e0..19c7da4 100644 --- a/components/LEDManager/LEDManager/LEDManager.cpp +++ b/components/LEDManager/LEDManager/LEDManager.cpp @@ -48,10 +48,7 @@ ledStateMap_t LEDManager::ledStateMap = { { false, false, - { - {LED_ON, 200}, {LED_OFF, 200}, {LED_ON, 200}, {LED_OFF, 200}, {LED_ON, 200}, {LED_OFF, 200}, - {LED_ON, 200}, {LED_OFF, 200}, {LED_ON, 200}, {LED_OFF, 200} - }, + {{LED_ON, 200}, {LED_OFF, 200}, {LED_ON, 200}, {LED_OFF, 200}, {LED_ON, 200}, {LED_OFF, 200}, {LED_ON, 200}, {LED_OFF, 200}, {LED_ON, 200}, {LED_OFF, 200}}, }, }, { @@ -65,32 +62,38 @@ ledStateMap_t LEDManager::ledStateMap = { }; LEDManager::LEDManager(gpio_num_t pin, gpio_num_t illumninator_led_pin, - QueueHandle_t ledStateQueue) : blink_led_pin(pin), - illumninator_led_pin(illumninator_led_pin), - ledStateQueue(ledStateQueue), - currentState(LEDStates_e::LedStateNone) { + QueueHandle_t ledStateQueue, std::shared_ptr deviceConfig) : blink_led_pin(pin), + illumninator_led_pin(illumninator_led_pin), + ledStateQueue(ledStateQueue), + currentState(LEDStates_e::LedStateNone), + deviceConfig(deviceConfig) +{ } -void LEDManager::setup() { - ESP_LOGD(LED_MANAGER_TAG, "Setting up status led."); +void LEDManager::setup() +{ + ESP_LOGI(LED_MANAGER_TAG, "Setting up status led."); gpio_reset_pin(blink_led_pin); /* Set the GPIO as a push/pull output */ gpio_set_direction(blink_led_pin, GPIO_MODE_OUTPUT); this->toggleLED(LED_OFF); #ifdef CONFIG_LED_EXTERNAL_CONTROL - ESP_LOGD(LED_MANAGER_TAG, "Setting up illuminator led."); + ESP_LOGI(LED_MANAGER_TAG, "Setting up illuminator led."); const int freq = CONFIG_LED_EXTERNAL_PWM_FREQ; const auto resolution = LEDC_TIMER_8_BIT; - const int dutyCycle = (CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE * 255) / 100; + const auto deviceConfig = this->deviceConfig->getDeviceConfig(); + + const uint32_t dutyCycle = (deviceConfig.led_external_pwm_duty_cycle * 255) / 100; + + ESP_LOGI(LED_MANAGER_TAG, "Setting dutyCycle to: %lu ", dutyCycle); ledc_timer_config_t ledc_timer = { .speed_mode = LEDC_LOW_SPEED_MODE, .duty_resolution = resolution, .timer_num = LEDC_TIMER_0, .freq_hz = freq, - .clk_cfg = LEDC_AUTO_CLK - }; + .clk_cfg = LEDC_AUTO_CLK}; ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer)); @@ -101,8 +104,7 @@ void LEDManager::setup() { .intr_type = LEDC_INTR_DISABLE, .timer_sel = LEDC_TIMER_0, .duty = dutyCycle, - .hpoint = 0 - }; + .hpoint = 0}; ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel)); #endif @@ -110,37 +112,46 @@ void LEDManager::setup() { ESP_LOGD(LED_MANAGER_TAG, "Done."); } -void LEDManager::handleLED() { - if (!this->finishedPattern) { +void LEDManager::handleLED() +{ + if (!this->finishedPattern) + { displayCurrentPattern(); return; } - if (xQueueReceive(this->ledStateQueue, &buffer, 10)) { + if (xQueueReceive(this->ledStateQueue, &buffer, 10)) + { this->updateState(buffer); - } else { + } + else + { // we've finished displaying the pattern, so let's check if it's repeatable and if so - reset it - if (ledStateMap[this->currentState].isRepeatable || ledStateMap[this->currentState].isError) { + if (ledStateMap[this->currentState].isRepeatable || ledStateMap[this->currentState].isError) + { this->currentPatternIndex = 0; this->finishedPattern = false; } } } -void LEDManager::displayCurrentPattern() { +void LEDManager::displayCurrentPattern() +{ auto [state, delayTime] = ledStateMap[this->currentState].patterns[this->currentPatternIndex]; this->toggleLED(state); this->timeToDelayFor = delayTime; if (this->currentPatternIndex < ledStateMap[this->currentState].patterns.size() - 1) this->currentPatternIndex++; - else { + else + { this->finishedPattern = true; this->toggleLED(LED_OFF); } } -void LEDManager::updateState(const LEDStates_e newState) { +void LEDManager::updateState(const LEDStates_e newState) +{ // we should change the displayed state // only if we finished displaying the current one - which is handled by the task // if the new state is not the same as the current one @@ -153,21 +164,25 @@ void LEDManager::updateState(const LEDStates_e newState) { if (newState == this->currentState) return; - if (ledStateMap.contains(newState)) { + if (ledStateMap.contains(newState)) + { this->currentState = newState; this->currentPatternIndex = 0; this->finishedPattern = false; } } -void LEDManager::toggleLED(const bool state) const { +void LEDManager::toggleLED(const bool state) const +{ gpio_set_level(blink_led_pin, state); } -void HandleLEDDisplayTask(void *pvParameter) { +void HandleLEDDisplayTask(void *pvParameter) +{ auto *ledManager = static_cast(pvParameter); - while (true) { + while (true) + { ledManager->handleLED(); vTaskDelay(ledManager->getTimeToDelayFor()); } diff --git a/components/LEDManager/LEDManager/LEDManager.hpp b/components/LEDManager/LEDManager/LEDManager.hpp index af92387..1f4fa67 100644 --- a/components/LEDManager/LEDManager/LEDManager.hpp +++ b/components/LEDManager/LEDManager/LEDManager.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include // it kinda looks like different boards have these states swapped @@ -41,7 +42,7 @@ typedef std::unordered_map class LEDManager { public: - LEDManager(gpio_num_t blink_led_pin, gpio_num_t illumninator_led_pin, QueueHandle_t ledStateQueue); + LEDManager(gpio_num_t blink_led_pin, gpio_num_t illumninator_led_pin, QueueHandle_t ledStateQueue, std::shared_ptr deviceConfig); void setup(); void handleLED(); @@ -60,6 +61,7 @@ private: LEDStates_e buffer; LEDStates_e currentState; + std::shared_ptr deviceConfig; size_t currentPatternIndex = 0; size_t timeToDelayFor = 100; diff --git a/components/ProjectConfig/ProjectConfig/Models.hpp b/components/ProjectConfig/ProjectConfig/Models.hpp index 85c9b81..4326344 100644 --- a/components/ProjectConfig/ProjectConfig/Models.hpp +++ b/components/ProjectConfig/ProjectConfig/Models.hpp @@ -21,35 +21,39 @@ struct BaseConfigModel Preferences *pref; }; -enum class StreamingMode { +enum class StreamingMode +{ AUTO, UVC, WIFI, }; -struct DeviceMode_t : BaseConfigModel { +struct DeviceMode_t : BaseConfigModel +{ StreamingMode mode; - explicit DeviceMode_t( Preferences *pref) : BaseConfigModel(pref), mode(StreamingMode::AUTO){} + explicit DeviceMode_t(Preferences *pref) : BaseConfigModel(pref), mode(StreamingMode::AUTO) {} - void load() { + void load() + { int stored_mode = this->pref->getInt("mode", 0); this->mode = static_cast(stored_mode); ESP_LOGI("DeviceMode", "Loaded device mode: %d", stored_mode); } - void save() const { + void save() const + { this->pref->putInt("mode", static_cast(this->mode)); ESP_LOGI("DeviceMode", "Saved device mode: %d", static_cast(this->mode)); } }; - struct DeviceConfig_t : BaseConfigModel { DeviceConfig_t(Preferences *pref) : BaseConfigModel(pref) {} std::string OTALogin; std::string OTAPassword; + int led_external_pwm_duty_cycle; int OTAPort; void load() @@ -57,20 +61,23 @@ struct DeviceConfig_t : BaseConfigModel this->OTALogin = this->pref->getString("OTALogin", "openiris"); this->OTAPassword = this->pref->getString("OTAPassword", "openiris"); this->OTAPort = this->pref->getInt("OTAPort", 3232); + this->led_external_pwm_duty_cycle = this->pref->getInt("led_ext_pwm", CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE); }; - void save() const { + void save() const + { this->pref->putString("OTALogin", this->OTALogin.c_str()); this->pref->putString("OTAPassword", this->OTAPassword.c_str()); this->pref->putInt("OTAPort", this->OTAPort); + this->pref->putInt("led_ext_pwm", this->led_external_pwm_duty_cycle); }; std::string toRepresentation() const { return Helpers::format_string( "\"device_config\": {\"OTALogin\": \"%s\", \"OTAPassword\": \"%s\", " - "\"OTAPort\": %u}", - this->OTALogin.c_str(), this->OTAPassword.c_str(), this->OTAPort); + "\"OTAPort\": %u, \"led_external_pwm_duty_cycle\": %u}", + this->OTALogin.c_str(), this->OTAPassword.c_str(), this->OTAPort, this->led_external_pwm_duty_cycle); }; }; @@ -94,7 +101,8 @@ struct MDNSConfig_t : BaseConfigModel this->hostname = this->pref->getString("hostname", default_hostname); }; - void save() const { + void save() const + { this->pref->putString("hostname", this->hostname.c_str()); }; @@ -125,7 +133,8 @@ struct CameraConfig_t : BaseConfigModel this->brightness = this->pref->getInt("brightness", 2); }; - void save() const { + void save() const + { this->pref->putInt("vflip", this->vflip); this->pref->putInt("href", this->href); this->pref->putInt("framesize", this->framesize); @@ -186,12 +195,13 @@ struct WiFiConfig_t : BaseConfigModel this->password = this->pref->getString(("password" + iter_str).c_str(), ""); this->channel = this->pref->getUInt(("channel" + iter_str).c_str()); this->power = this->pref->getUInt(("power" + iter_str).c_str()); - - ESP_LOGI("WiFiConfig", "Loaded network %d: name=%s, ssid=%s, channel=%d", + + ESP_LOGI("WiFiConfig", "Loaded network %d: name=%s, ssid=%s, channel=%d", index, this->name.c_str(), this->ssid.c_str(), this->channel); }; - void save() const { + void save() const + { char buffer[2]; auto const iter_str = std::string(Helpers::itoa(this->index, buffer, 10)); @@ -200,8 +210,8 @@ struct WiFiConfig_t : BaseConfigModel this->pref->putString(("password" + iter_str).c_str(), this->password.c_str()); this->pref->putUInt(("channel" + iter_str).c_str(), this->channel); this->pref->putUInt(("power" + iter_str).c_str(), this->power); - - ESP_LOGI("WiFiConfig", "Saved network %d: name=%s, ssid=%s, channel=%d", + + ESP_LOGI("WiFiConfig", "Saved network %d: name=%s, ssid=%s, channel=%d", this->index, this->name.c_str(), this->ssid.c_str(), this->channel); }; @@ -228,7 +238,8 @@ struct AP_WiFiConfig_t : BaseConfigModel this->password = this->pref->getString("apPassword", CONFIG_WIFI_AP_PASSWORD); }; - void save() const { + void save() const + { this->pref->putString("apSSID", this->ssid.c_str()); this->pref->putString("apPass", this->password.c_str()); this->pref->putUInt("apChannel", this->channel); @@ -254,7 +265,8 @@ struct WiFiTxPower_t : BaseConfigModel this->power = this->pref->getUInt("txpower", 52); }; - void save() const { + void save() const + { this->pref->putUInt("txpower", this->power); }; diff --git a/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp b/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp index ae7b189..ca38622 100644 --- a/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp +++ b/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp @@ -24,7 +24,8 @@ ProjectConfig::ProjectConfig(Preferences *pref) : pref(pref), ProjectConfig::~ProjectConfig() = default; -void ProjectConfig::save() const { +void ProjectConfig::save() const +{ ESP_LOGD(CONFIGURATION_TAG, "Saving project config"); this->config.device.save(); this->config.device_mode.save(); @@ -92,14 +93,22 @@ bool ProjectConfig::reset() //! DeviceConfig //* //********************************************************************************************************************** -void ProjectConfig::setDeviceConfig(const std::string &OTALogin, - const std::string &OTAPassword, - const int OTAPort) +void ProjectConfig::setOTAConfig(const std::string &OTALogin, + const std::string &OTAPassword, + const int OTAPort) { ESP_LOGD(CONFIGURATION_TAG, "Updating device config"); this->config.device.OTALogin.assign(OTALogin); this->config.device.OTAPassword.assign(OTAPassword); this->config.device.OTAPort = OTAPort; + this->config.device.save(); +} + +void ProjectConfig::setLEDDUtyCycleConfig(int led_external_pwm_duty_cycle) +{ + this->config.device.led_external_pwm_duty_cycle = led_external_pwm_duty_cycle; + ESP_LOGI(CONFIGURATION_TAG, "Setting duty cycle to %d", led_external_pwm_duty_cycle); + this->config.device.save(); } void ProjectConfig::setMDNSConfig(const std::string &hostname) @@ -120,6 +129,7 @@ void ProjectConfig::setCameraConfig(const uint8_t vflip, this->config.camera.framesize = framesize; this->config.camera.quality = quality; this->config.camera.brightness = brightness; + this->config.camera.save(); ESP_LOGD(CONFIGURATION_TAG, "Updating Camera config"); } @@ -133,8 +143,8 @@ void ProjectConfig::setWifiConfig(const std::string &networkName, const auto size = this->config.networks.size(); const auto it = std::ranges::find_if(this->config.networks, - [&](const WiFiConfig_t &network) - { return network.name == networkName; }); + [&](const WiFiConfig_t &network) + { return network.name == networkName; }); if (it != this->config.networks.end()) { @@ -191,8 +201,8 @@ void ProjectConfig::deleteWifiConfig(const std::string &networkName) } const auto it = std::ranges::find_if(this->config.networks, - [&](const WiFiConfig_t &network) - { return network.name == networkName; }); + [&](const WiFiConfig_t &network) + { return network.name == networkName; }); if (it != this->config.networks.end()) { @@ -205,6 +215,7 @@ void ProjectConfig::deleteWifiConfig(const std::string &networkName) void ProjectConfig::setWiFiTxPower(uint8_t power) { this->config.txpower.power = power; + this->config.txpower.save(); ESP_LOGD(CONFIGURATION_TAG, "Updating wifi tx power"); } @@ -215,12 +226,14 @@ void ProjectConfig::setAPWifiConfig(const std::string &ssid, this->config.ap_network.ssid.assign(ssid); this->config.ap_network.password.assign(password); this->config.ap_network.channel = channel; + this->config.ap_network.save(); ESP_LOGD(CONFIGURATION_TAG, "Updating access point config"); } -void ProjectConfig::setDeviceMode(const StreamingMode deviceMode) { +void ProjectConfig::setDeviceMode(const StreamingMode deviceMode) +{ this->config.device_mode.mode = deviceMode; - this->config.device_mode.save(); // Save immediately + this->config.device_mode.save(); // Save immediately } //********************************************************************************************************************** @@ -258,10 +271,12 @@ TrackerConfig_t &ProjectConfig::getTrackerConfig() return this->config; } -DeviceMode_t &ProjectConfig::getDeviceModeConfig() { +DeviceMode_t &ProjectConfig::getDeviceModeConfig() +{ return this->config.device_mode; } -StreamingMode ProjectConfig::getDeviceMode() { +StreamingMode ProjectConfig::getDeviceMode() +{ return this->config.device_mode.mode; } \ No newline at end of file diff --git a/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp b/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp index 045a8a6..07d04da 100644 --- a/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp +++ b/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp @@ -22,11 +22,6 @@ public: void load(); void save() const; - void wifiConfigSave(); - void cameraConfigSave(); - void deviceConfigSave(); - void mdnsConfigSave(); - void wifiTxPowerConfigSave(); bool reset(); DeviceConfig_t &getDeviceConfig(); @@ -38,9 +33,10 @@ public: WiFiTxPower_t &getWiFiTxPowerConfig(); TrackerConfig_t &getTrackerConfig(); - void setDeviceConfig(const std::string &OTALogin, - const std::string &OTAPassword, - int OTAPort); + void setOTAConfig(const std::string &OTALogin, + const std::string &OTAPassword, + int OTAPort); + void setLEDDUtyCycleConfig(int led_external_pwm_duty_cycle); void setMDNSConfig(const std::string &hostname); void setCameraConfig(uint8_t vflip, uint8_t framesize, diff --git a/main/openiris_main.cpp b/main/openiris_main.cpp index 8c908d6..1e66792 100644 --- a/main/openiris_main.cpp +++ b/main/openiris_main.cpp @@ -53,7 +53,7 @@ auto *restAPI = new RestAPI("http://0.0.0.0:81", commandManager); UVCStreamManager uvcStream; #endif -auto *ledManager = new LEDManager(BLINK_GPIO, CONFIG_LED_C_PIN_GPIO, ledStateQueue); +auto *ledManager = new LEDManager(BLINK_GPIO, CONFIG_LED_C_PIN_GPIO, ledStateQueue, deviceConfig); auto *serialManager = new SerialManager(commandManager, &timerHandle, deviceConfig); static void initNVSStorage() @@ -274,10 +274,10 @@ extern "C" void app_main(void) // setup CI and building for other boards // finish todos, overhaul stuff a bit + // esp_log_set_vprintf(&websocket_logger); Logo::printASCII(); initNVSStorage(); - - // esp_log_set_vprintf(&websocket_logger); + deviceConfig->load(); ledManager->setup(); xTaskCreate( @@ -297,7 +297,6 @@ extern "C" void app_main(void) 3, nullptr); - deviceConfig->load(); serialManager->setup(); static TaskHandle_t serialManagerHandle = nullptr; @@ -308,8 +307,7 @@ extern "C" void app_main(void) 1024 * 6, serialManager, 1, // we only rely on the serial manager during provisioning, we can run it slower - &serialManagerHandle - ); + &serialManagerHandle); wifiManager->Begin(); mdnsManager.start(); diff --git a/sdkconfig.board.project_babble b/sdkconfig.board.project_babble index 47b59a9..1ef150a 100644 --- a/sdkconfig.board.project_babble +++ b/sdkconfig.board.project_babble @@ -50,5 +50,5 @@ CONFIG_LED_EXTERNAL_CONTROL=y CONFIG_LED_EXTERNAL_PWM_FREQ=5000 CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100 CONFIG_LED_EXTERNAL_GPIO=1 -CONFIG_CAMERA_USB_XCLK_FREQ=23000000 # NOT TESTED +CONFIG_CAMERA_USB_XCLK_FREQ=23000000 CONFIG_GENERAL_WIRED_MODE=y \ No newline at end of file diff --git a/tools/openiris_setup.py b/tools/openiris_setup.py index d797918..3b8ff30 100644 --- a/tools/openiris_setup.py +++ b/tools/openiris_setup.py @@ -410,6 +410,17 @@ class OpenIrisDevice: print(f"❌ Failed to parse mode response: {e}") return "unknown" + def set_led_duty_cycle(self, duty_cycle): + """Sets the PWN duty cycle of the LED""" + print(f"🌟 Setting LED duty cycle to {duty_cycle}%...") + response = self.send_command("set_led_duty_cycle", {"dutyCycle": duty_cycle}) + if "error" in response: + print(f"❌ Failed to set LED duty cycle: {response['error']}") + return False + + print("✅ LED duty cycle set successfully") + return True + def monitor_logs(self): """Monitor device logs until interrupted""" print("📋 Monitoring device logs (Press Ctrl+C to exit)...") @@ -736,6 +747,24 @@ def switch_device_mode(device: OpenIrisDevice, args = None): print("❌ Invalid mode selection") +def set_led_duty_cycle(device: OpenIrisDevice, args=None): + while True: + input_data = input("Enter LED external PWM duty cycle (0-100) or `back` to exit: \n") + if input_data.lower() == "back": + break + + try: + duty_cycle = int(input_data) + except ValueError: + print("❌ Invalid input. Please enter a number between 0 and 100.") + + if duty_cycle < 0 or duty_cycle > 100: + print("❌ Duty cycle must be between 0 and 100.") + else: + device.set_led_duty_cycle(duty_cycle) + break + + def monitor_logs(device: OpenIrisDevice, args = None): device.monitor_logs() @@ -750,7 +779,8 @@ COMMANDS_MAP = { "7": attempt_wifi_connection, "8": start_streaming, "9": switch_device_mode, - "10": monitor_logs, + "10": set_led_duty_cycle, + "11": monitor_logs, } @@ -848,9 +878,10 @@ def main(): print("7. 🔗 Connect to WiFi") print("8. 🚀 Start streaming mode") print("9. 🔄 Switch device mode (WiFi/UVC/Auto)") - print("10. 📋 Monitor logs") + print("10. 💡 Update PWM Duty Cycle") + print("11. 📋 Monitor logs") print("exit. 🚪 Exit") - choice = input("\nSelect option (1-10): ").strip() + choice = input("\nSelect option (1-11): ").strip() if choice == "exit": break From 5a201d875ee04d9bef2d4fc865ee99e5cece80ef Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Fri, 22 Aug 2025 01:01:49 +0200 Subject: [PATCH 03/20] Added PWM live control and get_led_duty_cycle --- components/CommandManager/CMakeLists.txt | 2 +- .../CommandManager/CommandManager.cpp | 4 +++ .../CommandManager/CommandManager.hpp | 1 + .../CommandManager/DependencyRegistry.hpp | 3 +- .../commands/device_commands.cpp | 17 ++++++++++ .../commands/device_commands.hpp | 1 + .../LEDManager/LEDManager/LEDManager.cpp | 23 +++++++++++++ .../LEDManager/LEDManager/LEDManager.hpp | 4 +++ main/openiris_main.cpp | 1 + tools/openiris_setup.py | 34 ++++++++++++++++--- 10 files changed, 84 insertions(+), 6 deletions(-) diff --git a/components/CommandManager/CMakeLists.txt b/components/CommandManager/CMakeLists.txt index 16e8afc..e4b61ca 100644 --- a/components/CommandManager/CMakeLists.txt +++ b/components/CommandManager/CMakeLists.txt @@ -11,5 +11,5 @@ idf_component_register( INCLUDE_DIRS "CommandManager" "CommandManager/commands" - REQUIRES ProjectConfig cJSON CameraManager OpenIrisTasks wifiManager Helpers + REQUIRES ProjectConfig cJSON CameraManager OpenIrisTasks wifiManager Helpers LEDManager ) \ No newline at end of file diff --git a/components/CommandManager/CommandManager/CommandManager.cpp b/components/CommandManager/CommandManager/CommandManager.cpp index c4f897f..151b08e 100644 --- a/components/CommandManager/CommandManager/CommandManager.cpp +++ b/components/CommandManager/CommandManager/CommandManager.cpp @@ -24,6 +24,7 @@ std::unordered_map commandTypeMap = { {"switch_mode", CommandType::SWITCH_MODE}, {"get_device_mode", CommandType::GET_DEVICE_MODE}, {"set_led_duty_cycle", CommandType::SET_LED_DUTY_CYCLE}, + {"get_led_duty_cycle", CommandType::GET_LED_DUTY_CYCLE}, }; std::function CommandManager::createCommand(const CommandType type, std::string_view json) const @@ -93,6 +94,9 @@ std::function CommandManager::createCommand(const CommandType t case CommandType::SET_LED_DUTY_CYCLE: return [this, json] { return updateLEDDutyCycleCommand(this->registry, json); }; + case CommandType::GET_LED_DUTY_CYCLE: + return [this] + { return getLEDDutyCycleCommand(this->registry); }; default: return nullptr; } diff --git a/components/CommandManager/CommandManager/CommandManager.hpp b/components/CommandManager/CommandManager/CommandManager.hpp index 5db67d0..ab9aa5b 100644 --- a/components/CommandManager/CommandManager/CommandManager.hpp +++ b/components/CommandManager/CommandManager/CommandManager.hpp @@ -45,6 +45,7 @@ enum class CommandType SWITCH_MODE, GET_DEVICE_MODE, SET_LED_DUTY_CYCLE, + GET_LED_DUTY_CYCLE, }; class CommandManager diff --git a/components/CommandManager/CommandManager/DependencyRegistry.hpp b/components/CommandManager/CommandManager/DependencyRegistry.hpp index 48b6ee8..b0758dd 100644 --- a/components/CommandManager/CommandManager/DependencyRegistry.hpp +++ b/components/CommandManager/CommandManager/DependencyRegistry.hpp @@ -8,7 +8,8 @@ enum class DependencyType { project_config, camera_manager, - wifi_manager + wifi_manager, + led_manager }; class DependencyRegistry diff --git a/components/CommandManager/CommandManager/commands/device_commands.cpp b/components/CommandManager/CommandManager/commands/device_commands.cpp index 0ccd9ca..8accbbd 100644 --- a/components/CommandManager/CommandManager/commands/device_commands.cpp +++ b/components/CommandManager/CommandManager/commands/device_commands.cpp @@ -1,4 +1,5 @@ #include "device_commands.hpp" +#include "LEDManager.hpp" // Implementation inspired by SummerSigh work, initial PR opened in openiris repo, adapted to this rewrite CommandResult setDeviceModeCommand(std::shared_ptr registry, std::string_view jsonPayload) @@ -96,6 +97,13 @@ CommandResult updateLEDDutyCycleCommand(std::shared_ptr regi const auto projectConfig = registry->resolve(DependencyType::project_config); projectConfig->setLEDDUtyCycleConfig(dutyCycle); + // Try to apply the change live via LEDManager if available + auto ledMgr = registry->resolve(DependencyType::led_manager); + if (ledMgr) + { + ledMgr->setExternalLEDDutyCycle(static_cast(dutyCycle)); + } + cJSON_Delete(parsedJson); return CommandResult::getSuccessResult("LED duty cycle set"); @@ -107,6 +115,15 @@ CommandResult restartDeviceCommand() return CommandResult::getSuccessResult("Device restarted"); } +CommandResult getLEDDutyCycleCommand(std::shared_ptr registry) +{ + const auto projectConfig = registry->resolve(DependencyType::project_config); + const auto deviceCfg = projectConfig->getDeviceConfig(); + int duty = deviceCfg.led_external_pwm_duty_cycle; + auto result = std::format("{{ \"led_external_pwm_duty_cycle\": {} }}", duty); + return CommandResult::getSuccessResult(result); +} + CommandResult startStreamingCommand() { activateStreaming(false); // Don't disable setup interfaces by default diff --git a/components/CommandManager/CommandManager/commands/device_commands.hpp b/components/CommandManager/CommandManager/commands/device_commands.hpp index 22cde8a..9e89db4 100644 --- a/components/CommandManager/CommandManager/commands/device_commands.hpp +++ b/components/CommandManager/CommandManager/commands/device_commands.hpp @@ -14,6 +14,7 @@ CommandResult setDeviceModeCommand(std::shared_ptr registry, CommandResult updateOTACredentialsCommand(std::shared_ptr registry, std::string_view jsonPayload); CommandResult updateLEDDutyCycleCommand(std::shared_ptr registry, std::string_view jsonPayload); +CommandResult getLEDDutyCycleCommand(std::shared_ptr registry); CommandResult restartDeviceCommand(); diff --git a/components/LEDManager/LEDManager/LEDManager.cpp b/components/LEDManager/LEDManager/LEDManager.cpp index 19c7da4..8ba2460 100644 --- a/components/LEDManager/LEDManager/LEDManager.cpp +++ b/components/LEDManager/LEDManager/LEDManager.cpp @@ -177,6 +177,29 @@ void LEDManager::toggleLED(const bool state) const gpio_set_level(blink_led_pin, state); } +void LEDManager::setExternalLEDDutyCycle(uint8_t dutyPercent) +{ +#ifdef CONFIG_LED_EXTERNAL_CONTROL + dutyPercent = std::min(100, dutyPercent); + const uint32_t dutyCycle = (static_cast(dutyPercent) * 255) / 100; + ESP_LOGI(LED_MANAGER_TAG, "Updating external LED duty to %u%% (raw %lu)", dutyPercent, dutyCycle); + + // Persist into config immediately so it survives reboot + if (this->deviceConfig) + { + this->deviceConfig->setLEDDUtyCycleConfig(dutyPercent); + } + + // Apply to LEDC hardware live + // We configured channel 0 in setup with LEDC_LOW_SPEED_MODE + ESP_ERROR_CHECK_WITHOUT_ABORT(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, dutyCycle)); + ESP_ERROR_CHECK_WITHOUT_ABORT(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0)); +#else + (void)dutyPercent; // unused + ESP_LOGW(LED_MANAGER_TAG, "CONFIG_LED_EXTERNAL_CONTROL not enabled; ignoring duty update"); +#endif +} + void HandleLEDDisplayTask(void *pvParameter) { auto *ledManager = static_cast(pvParameter); diff --git a/components/LEDManager/LEDManager/LEDManager.hpp b/components/LEDManager/LEDManager/LEDManager.hpp index 1f4fa67..8f0838f 100644 --- a/components/LEDManager/LEDManager/LEDManager.hpp +++ b/components/LEDManager/LEDManager/LEDManager.hpp @@ -48,6 +48,10 @@ public: void handleLED(); size_t getTimeToDelayFor() const { return timeToDelayFor; } + // Apply new external LED PWM duty cycle immediately (0-100) + void setExternalLEDDutyCycle(uint8_t dutyPercent); + uint8_t getExternalLEDDutyCycle() const { return deviceConfig ? deviceConfig->getDeviceConfig().led_external_pwm_duty_cycle : 0; } + private: void toggleLED(bool state) const; void displayCurrentPattern(); diff --git a/main/openiris_main.cpp b/main/openiris_main.cpp index 1e66792..33b171d 100644 --- a/main/openiris_main.cpp +++ b/main/openiris_main.cpp @@ -228,6 +228,7 @@ extern "C" void app_main(void) dependencyRegistry->registerService(DependencyType::project_config, deviceConfig); dependencyRegistry->registerService(DependencyType::camera_manager, cameraHandler); dependencyRegistry->registerService(DependencyType::wifi_manager, wifiManager); + dependencyRegistry->registerService(DependencyType::led_manager, std::shared_ptr(ledManager, [](LEDManager*){})); // uvc plan // cleanup the logs - done // prepare the camera to be initialized with UVC - done? diff --git a/tools/openiris_setup.py b/tools/openiris_setup.py index 3b8ff30..8aa97f2 100644 --- a/tools/openiris_setup.py +++ b/tools/openiris_setup.py @@ -421,6 +421,24 @@ class OpenIrisDevice: print("✅ LED duty cycle set successfully") return True + def get_led_duty_cycle(self) -> Optional[int]: + """Get the current LED PWM duty cycle from the device""" + response = self.send_command("get_led_duty_cycle") + if "error" in response: + print(f"❌ Failed to get LED duty cycle: {response['error']}") + return None + try: + results = response.get("results", []) + if results: + result_data = json.loads(results[0]) + payload = result_data["result"] + if isinstance(payload, str): + payload = json.loads(payload) + return int(payload.get("led_external_pwm_duty_cycle")) + except Exception as e: + print(f"❌ Failed to parse LED duty cycle: {e}") + return None + def monitor_logs(self): """Monitor device logs until interrupted""" print("📋 Monitoring device logs (Press Ctrl+C to exit)...") @@ -761,14 +779,20 @@ def set_led_duty_cycle(device: OpenIrisDevice, args=None): if duty_cycle < 0 or duty_cycle > 100: print("❌ Duty cycle must be between 0 and 100.") else: + # Apply immediately; stay in loop for further tweaks device.set_led_duty_cycle(duty_cycle) - break def monitor_logs(device: OpenIrisDevice, args = None): device.monitor_logs() +def get_led_duty_cycle(device: OpenIrisDevice, args=None): + duty = device.get_led_duty_cycle() + if duty is not None: + print(f"💡 Current LED duty cycle: {duty}%") + + COMMANDS_MAP = { "1": scan_networks, "2": display_networks, @@ -780,7 +804,8 @@ COMMANDS_MAP = { "8": start_streaming, "9": switch_device_mode, "10": set_led_duty_cycle, - "11": monitor_logs, + "11": get_led_duty_cycle, + "12": monitor_logs, } @@ -879,9 +904,10 @@ def main(): print("8. 🚀 Start streaming mode") print("9. 🔄 Switch device mode (WiFi/UVC/Auto)") print("10. 💡 Update PWM Duty Cycle") - print("11. 📋 Monitor logs") + print("11. 💡Get PWM Duty Cycle") + print("12. 📖 Monitor logs") print("exit. 🚪 Exit") - choice = input("\nSelect option (1-11): ").strip() + choice = input("\nSelect option (1-12): ").strip() if choice == "exit": break From 8ff2e4ca1a7921a9bf528e51bd28456d39819ae5 Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Fri, 22 Aug 2025 01:06:22 +0200 Subject: [PATCH 04/20] test --- components/CommandManager/CommandManager/CommandManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/CommandManager/CommandManager/CommandManager.cpp b/components/CommandManager/CommandManager/CommandManager.cpp index 151b08e..5eff927 100644 --- a/components/CommandManager/CommandManager/CommandManager.cpp +++ b/components/CommandManager/CommandManager/CommandManager.cpp @@ -25,7 +25,7 @@ std::unordered_map commandTypeMap = { {"get_device_mode", CommandType::GET_DEVICE_MODE}, {"set_led_duty_cycle", CommandType::SET_LED_DUTY_CYCLE}, {"get_led_duty_cycle", CommandType::GET_LED_DUTY_CYCLE}, -}; +};test std::function CommandManager::createCommand(const CommandType type, std::string_view json) const { From 76735a26953e5add726f20dd7faa5337fe9d9e77 Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Fri, 22 Aug 2025 01:06:33 +0200 Subject: [PATCH 05/20] test2 --- components/CommandManager/CommandManager/CommandManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/CommandManager/CommandManager/CommandManager.cpp b/components/CommandManager/CommandManager/CommandManager.cpp index 5eff927..151b08e 100644 --- a/components/CommandManager/CommandManager/CommandManager.cpp +++ b/components/CommandManager/CommandManager/CommandManager.cpp @@ -25,7 +25,7 @@ std::unordered_map commandTypeMap = { {"get_device_mode", CommandType::GET_DEVICE_MODE}, {"set_led_duty_cycle", CommandType::SET_LED_DUTY_CYCLE}, {"get_led_duty_cycle", CommandType::GET_LED_DUTY_CYCLE}, -};test +}; std::function CommandManager::createCommand(const CommandType type, std::string_view json) const { From 19e707cabb364935e9b7169850fd99ac33c96704 Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Fri, 22 Aug 2025 01:33:02 +0200 Subject: [PATCH 06/20] Refactor USB Video Class descriptor comments for clarity and maintainability --- components/usb_device_uvc/tusb/usb_descriptors.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/components/usb_device_uvc/tusb/usb_descriptors.c b/components/usb_device_uvc/tusb/usb_descriptors.c index 5d121e9..baf881f 100644 --- a/components/usb_device_uvc/tusb/usb_descriptors.c +++ b/components/usb_device_uvc/tusb/usb_descriptors.c @@ -21,17 +21,6 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. - * - * --------------------------------------------------------------------------- - * USB Video Class (UVC) Descriptor Definitions for TinyUSB device stack. - * - * This file describes the device, configuration, and string descriptors for - * a single UVC camera. Build-time options (Kconfig) select whether UVC data - * streams use BULK or ISO endpoints, the pixel format (MJPEG / H.264 / - * Uncompressed), and whether multiple frame sizes are exposed. - * - * Goal: keep the same behavior while making the structure easier to read and - * maintain. Comments explain why each block exists and what each macro does. */ #include "tusb.h" From 817101e40d595c95263f08b484d559423b1338be Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Fri, 22 Aug 2025 02:24:02 +0200 Subject: [PATCH 07/20] Add command for retrieving device serial number and MAC address --- .../CommandManager/CommandManager.cpp | 4 +++ .../CommandManager/CommandManager.hpp | 1 + .../commands/device_commands.cpp | 22 ++++++++++++ .../commands/device_commands.hpp | 4 ++- tools/openiris_setup.py | 34 +++++++++++++++++-- 5 files changed, 62 insertions(+), 3 deletions(-) diff --git a/components/CommandManager/CommandManager/CommandManager.cpp b/components/CommandManager/CommandManager/CommandManager.cpp index 151b08e..7255b1d 100644 --- a/components/CommandManager/CommandManager/CommandManager.cpp +++ b/components/CommandManager/CommandManager/CommandManager.cpp @@ -25,6 +25,7 @@ std::unordered_map commandTypeMap = { {"get_device_mode", CommandType::GET_DEVICE_MODE}, {"set_led_duty_cycle", CommandType::SET_LED_DUTY_CYCLE}, {"get_led_duty_cycle", CommandType::GET_LED_DUTY_CYCLE}, + {"get_serial", CommandType::GET_SERIAL}, }; std::function CommandManager::createCommand(const CommandType type, std::string_view json) const @@ -97,6 +98,9 @@ std::function CommandManager::createCommand(const CommandType t case CommandType::GET_LED_DUTY_CYCLE: return [this] { return getLEDDutyCycleCommand(this->registry); }; + case CommandType::GET_SERIAL: + return [this] + { return getSerialNumberCommand(this->registry); }; default: return nullptr; } diff --git a/components/CommandManager/CommandManager/CommandManager.hpp b/components/CommandManager/CommandManager/CommandManager.hpp index ab9aa5b..53eeb7c 100644 --- a/components/CommandManager/CommandManager/CommandManager.hpp +++ b/components/CommandManager/CommandManager/CommandManager.hpp @@ -46,6 +46,7 @@ enum class CommandType GET_DEVICE_MODE, SET_LED_DUTY_CYCLE, GET_LED_DUTY_CYCLE, + GET_SERIAL, }; class CommandManager diff --git a/components/CommandManager/CommandManager/commands/device_commands.cpp b/components/CommandManager/CommandManager/commands/device_commands.cpp index 8accbbd..7579b74 100644 --- a/components/CommandManager/CommandManager/commands/device_commands.cpp +++ b/components/CommandManager/CommandManager/commands/device_commands.cpp @@ -1,5 +1,7 @@ #include "device_commands.hpp" #include "LEDManager.hpp" +#include "esp_mac.h" +#include // Implementation inspired by SummerSigh work, initial PR opened in openiris repo, adapted to this rewrite CommandResult setDeviceModeCommand(std::shared_ptr registry, std::string_view jsonPayload) @@ -197,3 +199,23 @@ CommandResult getDeviceModeCommand(std::shared_ptr registry) auto result = std::format("{{ \"mode\": \"{}\", \"value\": {} }}", modeStr, static_cast(currentMode)); return CommandResult::getSuccessResult(result); } + +CommandResult getSerialNumberCommand(std::shared_ptr /*registry*/) +{ + // Read MAC for STA interface + uint8_t mac[6] = {0}; + esp_read_mac(mac, ESP_MAC_WIFI_STA); + + char serial_no_sep[13]; + // Serial without separators (12 hex chars) + std::snprintf(serial_no_sep, sizeof(serial_no_sep), "%02X%02X%02X%02X%02X%02X", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + char mac_colon[18]; + // MAC with colons + std::snprintf(mac_colon, sizeof(mac_colon), "%02X:%02X:%02X:%02X:%02X:%02X", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + auto result = std::format("{{ \"serial\": \"{}\", \"mac\": \"{}\" }}", serial_no_sep, mac_colon); + return CommandResult::getSuccessResult(result); +} diff --git a/components/CommandManager/CommandManager/commands/device_commands.hpp b/components/CommandManager/CommandManager/commands/device_commands.hpp index 9e89db4..3d3f36f 100644 --- a/components/CommandManager/CommandManager/commands/device_commands.hpp +++ b/components/CommandManager/CommandManager/commands/device_commands.hpp @@ -22,4 +22,6 @@ CommandResult startStreamingCommand(); CommandResult switchModeCommand(std::shared_ptr registry, std::string_view jsonPayload); -CommandResult getDeviceModeCommand(std::shared_ptr registry); \ No newline at end of file +CommandResult getDeviceModeCommand(std::shared_ptr registry); + +CommandResult getSerialNumberCommand(std::shared_ptr registry); \ No newline at end of file diff --git a/tools/openiris_setup.py b/tools/openiris_setup.py index 8aa97f2..62b5c90 100644 --- a/tools/openiris_setup.py +++ b/tools/openiris_setup.py @@ -439,6 +439,26 @@ class OpenIrisDevice: print(f"❌ Failed to parse LED duty cycle: {e}") return None + def get_serial_info(self) -> Optional[Tuple[str, str]]: + """Get device serial number and MAC address""" + response = self.send_command("get_serial") + if "error" in response: + print(f"❌ Failed to get serial/MAC: {response['error']}") + return None + try: + results = response.get("results", []) + if results: + result_data = json.loads(results[0]) + payload = result_data["result"] + if isinstance(payload, str): + payload = json.loads(payload) + serial = payload.get("serial") + mac = payload.get("mac") + return serial, mac + except Exception as e: + print(f"❌ Failed to parse serial/MAC: {e}") + return None + def monitor_logs(self): """Monitor device logs until interrupted""" print("📋 Monitoring device logs (Press Ctrl+C to exit)...") @@ -793,6 +813,14 @@ def get_led_duty_cycle(device: OpenIrisDevice, args=None): print(f"💡 Current LED duty cycle: {duty}%") +def get_serial(device: OpenIrisDevice, args=None): + info = device.get_serial_info() + if info is not None: + serial, mac = info +# print(f"🔑 Serial: {serial}") + print(f"🔗 MAC: {mac}") + + COMMANDS_MAP = { "1": scan_networks, "2": display_networks, @@ -806,6 +834,7 @@ COMMANDS_MAP = { "10": set_led_duty_cycle, "11": get_led_duty_cycle, "12": monitor_logs, + "13": get_serial, } @@ -904,10 +933,11 @@ def main(): print("8. 🚀 Start streaming mode") print("9. 🔄 Switch device mode (WiFi/UVC/Auto)") print("10. 💡 Update PWM Duty Cycle") - print("11. 💡Get PWM Duty Cycle") + print("11. 💡 Get PWM Duty Cycle") print("12. 📖 Monitor logs") + print("13. 🔑 Show Serial/MAC") print("exit. 🚪 Exit") - choice = input("\nSelect option (1-12): ").strip() + choice = input("\nSelect option (1-13): ").strip() if choice == "exit": break From 8c78c7f927cc444704d90e1ae2ad6ec75d715f91 Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Fri, 22 Aug 2025 03:04:34 +0200 Subject: [PATCH 08/20] Satisfying my OCD!!!!!!, Enhance WiFi configuration flow and user prompts in setup tool lol --- tools/openiris_setup.py | 251 ++++++++++++++++++++++++++++++++++------ 1 file changed, 218 insertions(+), 33 deletions(-) diff --git a/tools/openiris_setup.py b/tools/openiris_setup.py index 62b5c90..186fd69 100644 --- a/tools/openiris_setup.py +++ b/tools/openiris_setup.py @@ -680,9 +680,9 @@ def configure_wifi(device: OpenIrisDevice, args = None): if device.set_wifi(selected_network.ssid, password): print("✅ WiFi configured successfully!") print("💡 Next steps:") - print(" 4. Check WiFi status") - print(" 5. Connect to WiFi (if needed)") - print(" 6. Start streaming when connected") + print(" • Open WiFi menu to connect to WiFi (if needed)") + print(" • Open WiFi menu to check WiFi status") + print(" • Start streaming from the main menu when connected") break else: print("❌ Invalid network number") @@ -757,12 +757,127 @@ def check_wifi_status(device: OpenIrisDevice, args = None): def attempt_wifi_connection(device: OpenIrisDevice, args = None): device.connect_wifi() - print("🕰️ Wait a few seconds then check status (option 4)") + print("🕰️ Wait a few seconds then check status in the WiFi menu") def start_streaming(device: OpenIrisDevice, args = None): device.start_streaming() - print("🚀 Streaming started! Use option 8 to monitor logs.") + print("🚀 Streaming started! Use 'Monitor logs' from the main menu.") + + +# ----- WiFi submenu ----- +def wifi_auto_setup(device: OpenIrisDevice, args=None): + print("\n⚙️ Automatic WiFi setup starting...") + scan_timeout = getattr(args, "scan_timeout", 30) if args else 30 + + # 1) Scan + if not device.scan_networks(timeout=scan_timeout): + print("❌ Auto-setup aborted: no networks found or scan failed") + return + + # 2) Show networks (sorted strongest-first already) + display_networks(device) + + # 3) Select a network (default strongest) + choice = input("Select network number [default: 1] or 'back': ").strip() + if choice.lower() == "back": + return + try: + idx = int(choice) - 1 if choice else 0 + except ValueError: + idx = 0 + + sorted_networks = sorted(device.networks, key=lambda x: x.rssi, reverse=True) + if not (0 <= idx < len(sorted_networks)): + print("⚠️ Invalid selection, using strongest network") + idx = 0 + + selected = sorted_networks[idx] + print(f"\n🔐 Selected: {selected.ssid if selected.ssid else ''}") + if selected.auth_mode == 0: + password = "" + print("🔓 Open network - no password required") + else: + password = input("Enter WiFi password: ") + + # 4) Configure WiFi + if not device.set_wifi(selected.ssid, password): + print("❌ Auto-setup aborted: failed to configure WiFi") + return + + # 5) Connect + if not device.connect_wifi(): + print("❌ Auto-setup aborted: failed to start WiFi connection") + return + + # 6) Wait for IP / connected status + print("⏳ Connecting to WiFi, waiting for IP...") + start = time.time() + timeout_s = 30 + ip = None + last_status = None + while time.time() - start < timeout_s: + status = device.get_wifi_status() + last_status = status + ip = (status or {}).get("ip_address") + if ip and ip not in ("0.0.0.0", "", None): + break + time.sleep(0.5) + + if ip and ip not in ("0.0.0.0", "", None): + print(f"✅ Connected! IP Address: {ip}") + else: + print("⚠️ Connection not confirmed within timeout") + if last_status: + print(f" Status: {last_status.get('status', 'unknown')} | IP: {last_status.get('ip_address', '-')}") + + +def wifi_menu(device: OpenIrisDevice, args=None): + while True: + print("\n📶 WiFi Settings:") + print(f"{str(1):>2} ⚙️ Automatic WiFi setup") + print(f"{str(2):>2} � Manual WiFi actions") + print("back 🔙 Back") + + choice = input("\nSelect option (1-2 or 'back'): ").strip() + if choice.lower() == "back": + break + + if choice == "1": + wifi_auto_setup(device, args) + elif choice == "2": + wifi_manual_menu(device, args) + else: + print("❌ Invalid option") + + +def wifi_manual_menu(device: OpenIrisDevice, args=None): + while True: + print("\n📁 WiFi Manual Actions:") + print(f"{str(1):>2} � Scan for WiFi networks") + print(f"{str(2):>2} � Show available networks") + print(f"{str(3):>2} 🔐 Configure WiFi") + print(f"{str(4):>2} � Connect to WiFi") + print(f"{str(5):>2} 🛰️ Check WiFi status") + print("back 🔙 Back") + + choice = input("\nSelect option (1-5 or 'back'): ").strip() + if choice.lower() == "back": + break + + sub_map = { + "1": scan_networks, + "2": display_networks, + "3": configure_wifi, + "4": attempt_wifi_connection, + "5": check_wifi_status, + } + + handler = sub_map.get(choice) + if not handler: + print("❌ Invalid option") + continue + handler(device, args) def switch_device_mode(device: OpenIrisDevice, args = None): @@ -821,20 +936,95 @@ def get_serial(device: OpenIrisDevice, args=None): print(f"🔗 MAC: {mac}") +# ----- Aggregated GET: settings summary ----- +def _probe_serial(device: OpenIrisDevice) -> Dict: + info = device.get_serial_info() + if info is None: + return {"serial": None, "mac": None} + serial, mac = info + return {"serial": serial, "mac": mac} + + +def _probe_led_pwm(device: OpenIrisDevice) -> Dict: + duty = device.get_led_duty_cycle() + return {"led_external_pwm_duty_cycle": duty} + + +def _probe_mode(device: OpenIrisDevice) -> Dict: + mode = device.get_device_mode() + return {"mode": mode} + + +def _probe_wifi_status(device: OpenIrisDevice) -> Dict: + # Returns dict as provided by device; pass through + status = device.get_wifi_status() or {} + return {"wifi_status": status} + + +def get_settings(device: OpenIrisDevice, args=None): + print("\n🧩 Collecting device settings...\n") + + probes = [ + ("Identity", _probe_serial), + ("LED", _probe_led_pwm), + ("Mode", _probe_mode), + ("WiFi", _probe_wifi_status), + ] + + summary: Dict[str, Dict] = {} + + for label, probe in probes: + try: + data = probe(device) + summary[label] = data + except Exception as e: + summary[label] = {"error": str(e)} + + # Pretty print summary + # Identity + ident = summary.get("Identity", {}) + serial = ident.get("serial") + mac = ident.get("mac") + # print(f"🔑 Serial: {serial}") # Serial display intentionally disabled; MAC is sufficient + if mac: + print(f"🔗 MAC: {mac}") + if not serial and not mac: + print("🔑 Serial/MAC: unavailable") + + # LED + led = summary.get("LED", {}) + duty = led.get("led_external_pwm_duty_cycle") + if duty is not None: + print(f"💡 LED PWM Duty: {duty}%") + else: + print("💡 LED PWM Duty: unknown") + + # Mode + mode = summary.get("Mode", {}).get("mode") + print(f"🎚️ Mode: {mode if mode else 'unknown'}") + + # WiFi + wifi = summary.get("WiFi", {}).get("wifi_status", {}) + if wifi: + status = wifi.get("status", "unknown") + ip = wifi.get("ip_address") or "-" + configured = wifi.get("networks_configured", 0) + print(f"📶 WiFi: {status} | IP: {ip} | Networks configured: {configured}") + else: + print("📶 WiFi: status unavailable") + + print("") + + COMMANDS_MAP = { - "1": scan_networks, - "2": display_networks, - "3": configure_wifi, - "4": configure_mdns, - "5": configure_mdns, - "6": check_wifi_status, - "7": attempt_wifi_connection, - "8": start_streaming, - "9": switch_device_mode, - "10": set_led_duty_cycle, - "11": get_led_duty_cycle, - "12": monitor_logs, - "13": get_serial, + "1": wifi_menu, + "2": configure_mdns, + "3": configure_mdns, + "4": start_streaming, + "5": switch_device_mode, + "6": set_led_duty_cycle, + "7": monitor_logs, + "8": get_settings, } @@ -923,21 +1113,16 @@ def main(): # Main interaction loop while True: print("\n🔧 Setup Options:") - print("1. 🔍 Scan for WiFi networks") - print("2. 📡 Show available networks") - print("3. 🔐 Configure WiFi") - print("4. 🌐 Configure MDNS") - print("5. 💻 Configure UVC Name") - print("6. 📶 Check WiFi status") - print("7. 🔗 Connect to WiFi") - print("8. 🚀 Start streaming mode") - print("9. 🔄 Switch device mode (WiFi/UVC/Auto)") - print("10. 💡 Update PWM Duty Cycle") - print("11. 💡 Get PWM Duty Cycle") - print("12. 📖 Monitor logs") - print("13. 🔑 Show Serial/MAC") - print("exit. 🚪 Exit") - choice = input("\nSelect option (1-13): ").strip() + print(f"{str(1):>2} � WiFi settings") + print(f"{str(2):>2} 🌐 Configure MDNS") + print(f"{str(3):>2} 💻 Configure UVC Name") + print(f"{str(4):>2} 🚀 Start streaming mode") + print(f"{str(5):>2} 🔄 Switch device mode (WiFi/UVC/Auto)") + print(f"{str(6):>2} 💡 Update PWM Duty Cycle") + print(f"{str(7):>2} 📖 Monitor logs") + print(f"{str(8):>2} 🧩 Get settings summary") + print("exit 🚪 Exit") + choice = input("\nSelect option (1-8): ").strip() if choice == "exit": break From 40833490d40455a1df4e54e27c9beaa22b503934 Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Fri, 22 Aug 2025 03:11:43 +0200 Subject: [PATCH 09/20] Fixed emojis --- tools/openiris_setup.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/openiris_setup.py b/tools/openiris_setup.py index 186fd69..7c29998 100644 --- a/tools/openiris_setup.py +++ b/tools/openiris_setup.py @@ -836,8 +836,8 @@ def wifi_menu(device: OpenIrisDevice, args=None): while True: print("\n📶 WiFi Settings:") print(f"{str(1):>2} ⚙️ Automatic WiFi setup") - print(f"{str(2):>2} � Manual WiFi actions") - print("back 🔙 Back") + print(f"{str(2):>2} 📁 Manual WiFi actions") + print("back Back") choice = input("\nSelect option (1-2 or 'back'): ").strip() if choice.lower() == "back": @@ -854,12 +854,12 @@ def wifi_menu(device: OpenIrisDevice, args=None): def wifi_manual_menu(device: OpenIrisDevice, args=None): while True: print("\n📁 WiFi Manual Actions:") - print(f"{str(1):>2} � Scan for WiFi networks") - print(f"{str(2):>2} � Show available networks") + print(f"{str(1):>2} 🔍 Scan for WiFi networks") + print(f"{str(2):>2} 📡 Show available networks") print(f"{str(3):>2} 🔐 Configure WiFi") - print(f"{str(4):>2} � Connect to WiFi") + print(f"{str(4):>2} 🔗 Connect to WiFi") print(f"{str(5):>2} 🛰️ Check WiFi status") - print("back 🔙 Back") + print("back Back") choice = input("\nSelect option (1-5 or 'back'): ").strip() if choice.lower() == "back": @@ -1113,7 +1113,7 @@ def main(): # Main interaction loop while True: print("\n🔧 Setup Options:") - print(f"{str(1):>2} � WiFi settings") + print(f"{str(1):>2} 📶 WiFi settings") print(f"{str(2):>2} 🌐 Configure MDNS") print(f"{str(3):>2} 💻 Configure UVC Name") print(f"{str(4):>2} 🚀 Start streaming mode") From 05e122ffdd3db530a681db20a751fb4cb96c2ed0 Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Fri, 22 Aug 2025 12:45:42 +0200 Subject: [PATCH 10/20] README.md --- README.md | 194 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 146 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 8e6e412..ddfdd99 100644 --- a/README.md +++ b/README.md @@ -1,69 +1,167 @@ | Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -# Blink Example +## OpenIris-ESPIDF -(See the README.md file in the upper level 'examples' directory for more information about examples.) +Firmware and tools for OpenIris on ESP32/ESP32‑S3 — Wi‑Fi, UVC streaming, and a handy Python setup CLI. -This example demonstrates how to blink a LED by using the GPIO driver or using the [led_strip](https://components.espressif.com/component/espressif/led_strip) library if the LED is addressable e.g. [WS2812](https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf). The `led_strip` library is installed via [component manager](main/idf_component.yml). +Short, friendly, and practical. -## How to Use Example +--- -Before project configuration and build, be sure to set the correct chip target using `idf.py set-target `. +## What’s inside +- ESP‑IDF firmware (C/C++) with modules for Camera, Wi‑Fi, UVC, REST/Serial commands, and more +- Python tools to make setup easy over USB serial: + - `tools/switchBoardType.py` — choose a board profile (loads the right sdkconfig) + - `tools/openiris_setup.py` — interactive CLI for Wi‑Fi, MDNS/Name, Mode, LED PWM, Logs, and a Settings Summary + - `tools/wifi_scanner.py` — optional Wi‑Fi scanner -### Hardware Required +--- -* A development board with normal LED or addressable LED on-board (e.g., ESP32-S3-DevKitC, ESP32-C6-DevKitC etc.) -* A USB cable for Power supply and programming +## Prerequisites +- ESP‑IDF installed and available in your terminal (`idf.py` works) +- Python 3.10+ with `pip` +- USB cable to your board +- Optional: install Python dependencies for the tools -See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it. +Windows (cmd): +```cmd +python -m pip install -r tools\requirements.txt +``` +macOS/Linux (bash): +```bash +python3 -m pip install -r tools/requirements.txt +``` +Note for Windows: If emojis don’t render nicely, it’s only cosmetic — everything still works. -### Configure the Project +--- -Open the project configuration menu (`idf.py menuconfig`). +## First-time setup on Windows (VS Code + ESP‑IDF extension) +If you’re starting fresh on Windows, this workflow is smooth and reliable: -In the `Example Configuration` menu: +1) Install tooling +- Git: https://git-scm.com/downloads/win +- Visual Studio Code: https://code.visualstudio.com/ -* Select the LED type in the `Blink LED type` option. - * Use `GPIO` for regular LED - * Use `LED strip` for addressable LED -* If the LED type is `LED strip`, select the backend peripheral - * `RMT` is only available for ESP targets with RMT peripheral supported - * `SPI` is available for all ESP targets -* Set the GPIO number used for the signal in the `Blink GPIO number` option. -* Set the blinking period in the `Blink period in ms` option. - -### Build and Flash - -Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. - -(To exit the serial monitor, type ``Ctrl-]``.) - -See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. - -## Example Output - -As you run the example, you will see the LED blinking, according to the previously defined period. For the addressable LED, you can also change the LED color by setting the `led_strip_set_pixel(led_strip, 0, 16, 16, 16);` (LED Strip, Pixel Number, Red, Green, Blue) with values from 0 to 255 in the [source file](main/blink_example_main.c). - -```text -I (315) example: Example configured to blink addressable LED! -I (325) example: Turning the LED OFF! -I (1325) example: Turning the LED ON! -I (2325) example: Turning the LED OFF! -I (3325) example: Turning the LED ON! -I (4325) example: Turning the LED OFF! -I (5325) example: Turning the LED ON! -I (6325) example: Turning the LED OFF! -I (7325) example: Turning the LED ON! -I (8325) example: Turning the LED OFF! +2) Get the source code +- Create a folder where you want the repo (e.g., `D:\OpenIris-ESPIDF\`). In File Explorer, right‑click the folder and choose “Open in Terminal”. +- Clone and open in VS Code: +```cmd +git clone https://github.com/lorow/OpenIris-ESPIDF.git +cd OpenIris-ESPIDF +code . ``` -Note: The color order could be different according to the LED model. +3) Install the ESP‑IDF VS Code extension +- In VS Code, open the Extensions tab and install: https://marketplace.visualstudio.com/items?itemName=espressif.esp-idf-extension -The pixel number indicates the pixel position in the LED strip. For a single LED, use 0. +4) Set the default terminal profile to Command Prompt +- Press Ctrl+Shift+P → search “Terminal: Select Default Profile” → choose “Command Prompt”. +- Restart VS Code from its normal shortcut (not from Git Bash). This avoids running ESP‑IDF in the wrong shell. + +5) Configure ESP‑IDF in the extension +- On first launch, the extension may prompt to install ESP‑IDF and tools — follow the steps. It can take a while. +- If you see the extension’s home page instead, click “Configure extension”, pick “EXPRESS”, choose “GitHub” as the server and version “v5.3.3”. +- Then open the ESP‑IDF Explorer tab and click “Open ESP‑IDF Terminal”. We’ll use that for builds. + +6) Default board profile and switching +- The project ships with multiple board profiles; one default may target internal “Project Babble” boards. +- If you have a Seeed XIAO ESP32S3 (or another board), switch the profile with the helper script: +```cmd +python .\tools\switchBoardType.py --board xiao-esp32s3 --diff +``` +- You can re‑run this anytime to switch boards; `--diff` shows the changes. + +After this, you’re ready for the Quick start below. + +--- + +## Quick start + +### 1) Pick your board (loads the default configuration) +Windows (cmd): +```cmd +python .\tools\switchBoardType.py --board xiao-esp32s3 --diff +``` +macOS/Linux (bash): +```bash +python3 ./tools/switchBoardType.py --board xiao-esp32s3 --diff +``` +- Set `--board` to your target board +- `--diff` shows what changed in the config + +### 2) Build & flash +- Set the target (e.g., ESP32‑S3): +```cmd +idf.py set-target esp32s3 +``` +- Build, flash, and open the serial monitor: +```cmd +idf.py -p COM15 flash monitor +``` +Replace `COM15` with your port (Windows: `COM…`, Linux: `/dev/ttyUSB…`, macOS: `/dev/cu.usbmodem…`). +Exit the monitor with `Ctrl+]`. + +### 3) Use the Python setup CLI (recommended) +Configure the device conveniently over USB serial. + +Windows (cmd): +```cmd +python .\tools\openiris_setup.py --port COM15 +``` +macOS/Linux (bash): +```bash +python3 ./tools/openiris_setup.py --port /dev/ttyUSB0 +``` +What the CLI can do: +- Wi‑Fi menu: automatic (scan → pick → password → connect → wait for IP) or manual (scan, show, configure, connect, status) +- Set MDNS/Device name (also used for the UVC device name) +- Switch mode (Wi‑Fi / UVC / Auto) +- Adjust LED PWM +- Show a Settings Summary (MAC, Wi‑Fi status, mode, PWM, …) +- View logs + +Tip: On start, the CLI keeps the device in a setup state so replies are stable. + +--- + +## Serial number & MAC +- Internally, the serial number is derived from the Wi‑Fi MAC address. +- The CLI displays the MAC by default (clearer); it’s the value used as the serial number. +- The UVC device name is based on the MDNS hostname. + +--- + +## Common workflows +- Fast Wi‑Fi setup: in the CLI, go to “Wi‑Fi settings” → “Automatic setup”, then check “status”. +- Change name/MDNS: set the device name in the CLI, then replug USB — UVC will show the new name. +- Adjust brightness/LED: set LED PWM in the CLI. +- Quick health check: run “Get settings summary” after flashing to verify the device state. + +--- + +## Project layout (short) +- `main/` — entry point +- `components/` — modules (Camera, WiFi, UVC, CommandManager, …) +- `tools/` — Python helper tools (board switch, setup CLI, scanner) + +If you want to dig deeper: commands are mapped via the `CommandManager` under `components/CommandManager/...`. + +--- ## Troubleshooting +- No device/port found? + - Pass `--port` explicitly (e.g., `--port COM15`). + - Right after reset, the device emits heartbeats for a short time; the CLI finds it fastest during that window. +- UVC doesn’t appear on the host? + - Switch mode to UVC and replug USB. On Windows the first driver init can take a moment. +- Wi‑Fi won’t connect? + - Check password/channel. Use the automatic setup in the CLI and then inspect the status. +- ESP‑IDF not detected? + - Ensure the ESP‑IDF environment is active in the terminal (IDF Command Prompt or the extension’s ESP‑IDF Terminal; alternatively source `export.ps1`/`export.sh`). +- Missing Python modules? + - Run `pip install -r tools/requirements.txt`. -* If the LED isn't blinking, check the GPIO or the LED type selection in the `Example Configuration` menu. +--- -For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. +Have fun with OpenIris! Feedback, issues, and PRs are welcome. From 4778ae6c528f36ab12ff80e161dfa1ed0a97903c Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Sat, 23 Aug 2025 15:28:55 +0200 Subject: [PATCH 11/20] Update README and improve LEDManager and StreamServer functionality - Enhanced LEDManager state update logic to allow recovery from error states - Fixed buffer declaration in StreamServer for multipart headers - Updated LEDManager instantiation to use shared_ptr for better memory management --- README.md | 8 ++---- .../LEDManager/LEDManager/LEDManager.cpp | 28 +++++++++---------- .../StreamServer/StreamServer.cpp | 5 ++-- main/openiris_main.cpp | 6 ++-- sdkconfig | 2 +- 5 files changed, 24 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index ddfdd99..9b9d5ee 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,9 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| Supported Targets (IDK lol) | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | ## OpenIris-ESPIDF -Firmware and tools for OpenIris on ESP32/ESP32‑S3 — Wi‑Fi, UVC streaming, and a handy Python setup CLI. - -Short, friendly, and practical. +Firmware and tools for OpenIris — Wi‑Fi, UVC streaming, and a handy Python setup CLI. --- @@ -20,7 +18,7 @@ Short, friendly, and practical. ## Prerequisites - ESP‑IDF installed and available in your terminal (`idf.py` works) -- Python 3.10+ with `pip` +- Python 3.10+ with `pip` (on Windows this is installed automatically when you set up the ESP‑IDF VS Code extension; see “First-time setup on Windows” below) - USB cable to your board - Optional: install Python dependencies for the tools diff --git a/components/LEDManager/LEDManager/LEDManager.cpp b/components/LEDManager/LEDManager/LEDManager.cpp index 8ba2460..159b750 100644 --- a/components/LEDManager/LEDManager/LEDManager.cpp +++ b/components/LEDManager/LEDManager/LEDManager.cpp @@ -152,24 +152,21 @@ void LEDManager::displayCurrentPattern() void LEDManager::updateState(const LEDStates_e newState) { - // we should change the displayed state - // only if we finished displaying the current one - which is handled by the task - // if the new state is not the same as the current one - // and if can actually display the state - - // if we've got an error state - that's it, we'll just keep repeating it indefinitely - if (ledStateMap[this->currentState].isError) + // Only update when new state differs and is known. + if (!ledStateMap.contains(newState)) return; if (newState == this->currentState) return; - if (ledStateMap.contains(newState)) - { - this->currentState = newState; - this->currentPatternIndex = 0; - this->finishedPattern = false; - } + // Allow recovery from error states: if both current and new are error, ignore. + // Otherwise permit transitioning out of error when a non-error state arrives. + if (ledStateMap[this->currentState].isError && ledStateMap[newState].isError) + return; + + this->currentState = newState; + this->currentPatternIndex = 0; + this->finishedPattern = false; } void LEDManager::toggleLED(const bool state) const @@ -203,10 +200,13 @@ void LEDManager::setExternalLEDDutyCycle(uint8_t dutyPercent) void HandleLEDDisplayTask(void *pvParameter) { auto *ledManager = static_cast(pvParameter); + TickType_t lastWakeTime = xTaskGetTickCount(); while (true) { ledManager->handleLED(); - vTaskDelay(ledManager->getTimeToDelayFor()); + const TickType_t delayTicks = pdMS_TO_TICKS(ledManager->getTimeToDelayFor()); + // Ensure at least 1 tick delay to yield CPU + vTaskDelayUntil(&lastWakeTime, delayTicks > 0 ? delayTicks : 1); } } diff --git a/components/StreamServer/StreamServer/StreamServer.cpp b/components/StreamServer/StreamServer/StreamServer.cpp index c40f5cc..5908452 100644 --- a/components/StreamServer/StreamServer/StreamServer.cpp +++ b/components/StreamServer/StreamServer/StreamServer.cpp @@ -20,7 +20,8 @@ esp_err_t StreamHelpers::stream(httpd_req_t *req) size_t _jpg_buf_len = 0; uint8_t *_jpg_buf = nullptr; - char *part_buf[256]; + // Buffer for multipart header; was mistakenly declared as array of pointers + char part_buf[256]; static int64_t last_frame = 0; if (!last_frame) last_frame = esp_timer_get_time(); @@ -55,7 +56,7 @@ esp_err_t StreamHelpers::stream(httpd_req_t *req) response = httpd_resp_send_chunk(req, STREAM_BOUNDARY, strlen(STREAM_BOUNDARY)); if (response == ESP_OK) { - size_t hlen = snprintf((char *)part_buf, 128, STREAM_PART, _jpg_buf_len, _timestamp.tv_sec, _timestamp.tv_usec); + size_t hlen = snprintf((char *)part_buf, sizeof(part_buf), STREAM_PART, _jpg_buf_len, _timestamp.tv_sec, _timestamp.tv_usec); response = httpd_resp_send_chunk(req, (const char *)part_buf, hlen); } if (response == ESP_OK) diff --git a/main/openiris_main.cpp b/main/openiris_main.cpp index 33b171d..69a4139 100644 --- a/main/openiris_main.cpp +++ b/main/openiris_main.cpp @@ -53,7 +53,7 @@ auto *restAPI = new RestAPI("http://0.0.0.0:81", commandManager); UVCStreamManager uvcStream; #endif -auto *ledManager = new LEDManager(BLINK_GPIO, CONFIG_LED_C_PIN_GPIO, ledStateQueue, deviceConfig); +auto ledManager = std::make_shared(BLINK_GPIO, CONFIG_LED_C_PIN_GPIO, ledStateQueue, deviceConfig); auto *serialManager = new SerialManager(commandManager, &timerHandle, deviceConfig); static void initNVSStorage() @@ -228,7 +228,7 @@ extern "C" void app_main(void) dependencyRegistry->registerService(DependencyType::project_config, deviceConfig); dependencyRegistry->registerService(DependencyType::camera_manager, cameraHandler); dependencyRegistry->registerService(DependencyType::wifi_manager, wifiManager); - dependencyRegistry->registerService(DependencyType::led_manager, std::shared_ptr(ledManager, [](LEDManager*){})); + dependencyRegistry->registerService(DependencyType::led_manager, ledManager); // uvc plan // cleanup the logs - done // prepare the camera to be initialized with UVC - done? @@ -294,7 +294,7 @@ extern "C" void app_main(void) HandleLEDDisplayTask, "HandleLEDDisplayTask", 1024 * 2, - ledManager, + ledManager.get(), 3, nullptr); diff --git a/sdkconfig b/sdkconfig index b9755fb..08e7daa 100644 --- a/sdkconfig +++ b/sdkconfig @@ -581,7 +581,7 @@ CONFIG_LED_BLINK_GPIO=8 CONFIG_LED_EXTERNAL_GPIO=9 CONFIG_LED_EXTERNAL_CONTROL=y CONFIG_LED_EXTERNAL_PWM_FREQ=20000 -CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=50 +CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100 # end of OpenIris: LED Configuration # From e1838b4ca4fcf2fb8be6a7b21a68d864427dce91 Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Sat, 23 Aug 2025 15:55:30 +0200 Subject: [PATCH 12/20] Refactor UVCStream buffer management and improve serial number formatting --- components/UVCStream/UVCStream/UVCStream.cpp | 33 ++++++++++++------- components/UVCStream/UVCStream/UVCStream.hpp | 2 ++ .../usb_device_uvc/tusb/usb_descriptors.c | 1 + 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/components/UVCStream/UVCStream/UVCStream.cpp b/components/UVCStream/UVCStream/UVCStream.cpp index 38890e2..f0d8985 100644 --- a/components/UVCStream/UVCStream/UVCStream.cpp +++ b/components/UVCStream/UVCStream/UVCStream.cpp @@ -1,10 +1,10 @@ #include "UVCStream.hpp" -constexpr int UVC_MAX_FRAMESIZE_SIZE(75 * 1024); +#include // for snprintf static const char *UVC_STREAM_TAG = "[UVC DEVICE]"; extern "C" { - static char serial_number_str[18]; + static char serial_number_str[13]; const char *get_uvc_device_name() { @@ -23,9 +23,9 @@ extern "C" { return CONFIG_TUSB_SERIAL_NUM; } - sniprintf(serial_number_str, sizeof(serial_number_str), "%02X:%02X:%02X:%02X:%02X:%02X", - mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5] - ); + // 12 hex chars without separators + snprintf(serial_number_str, sizeof(serial_number_str), "%02X%02X%02X%02X%02X%02X", + mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5]); } return serial_number_str; } @@ -33,7 +33,7 @@ extern "C" { static esp_err_t UVCStreamHelpers::camera_start_cb(uvc_format_t format, int width, int height, int rate, void *cb_ctx) { - (void)cb_ctx; + auto *mgr = static_cast(cb_ctx); ESP_LOGI(UVC_STREAM_TAG, "Camera Start"); ESP_LOGI(UVC_STREAM_TAG, "Format: %d, width: %d, height: %d, rate: %d", format, width, height, rate); framesize_t frame_size = FRAMESIZE_QVGA; @@ -78,7 +78,7 @@ static void UVCStreamHelpers::camera_stop_cb(void *cb_ctx) static uvc_fb_t *UVCStreamHelpers::camera_fb_get_cb(void *cb_ctx) { - (void)cb_ctx; + auto *mgr = static_cast(cb_ctx); s_fb.cam_fb_p = esp_camera_fb_get(); if (!s_fb.cam_fb_p) @@ -93,9 +93,10 @@ static uvc_fb_t *UVCStreamHelpers::camera_fb_get_cb(void *cb_ctx) s_fb.uvc_fb.format = UVC_FORMAT_JPEG; // we gotta make sure we're ALWAYS using JPEG s_fb.uvc_fb.timestamp = s_fb.cam_fb_p->timestamp; - if (s_fb.uvc_fb.len > UVC_MAX_FRAMESIZE_SIZE) + // Ensure frame fits into configured UVC transfer buffer + if (mgr && s_fb.uvc_fb.len > mgr->getUvcBufferSize()) { - ESP_LOGE(UVC_STREAM_TAG, "Frame size %d is larger than max frame size %d", s_fb.uvc_fb.len, UVC_MAX_FRAMESIZE_SIZE); + ESP_LOGE(UVC_STREAM_TAG, "Frame size %d exceeds UVC buffer size %u", (int)s_fb.uvc_fb.len, (unsigned)mgr->getUvcBufferSize()); esp_camera_fb_return(s_fb.cam_fb_p); return nullptr; } @@ -120,7 +121,16 @@ esp_err_t UVCStreamManager::setup() ESP_LOGI(UVC_STREAM_TAG, "Setting up UVC Stream"); - uvc_buffer = static_cast(malloc(UVC_MAX_FRAMESIZE_SIZE)); + // Derive transfer buffer size from configuration/descriptor settings. + // Use a conservative default if not defined elsewhere. + // For now, allocate based on commonly used max frame size or future Kconfig value. + // You can wire this to a Kconfig like CONFIG_UVC_MAX_FRAME_SIZE. + if (uvc_buffer_size == 0) + { + // default to 75 KiB if not set elsewhere + uvc_buffer_size = 75 * 1024; + } + uvc_buffer = static_cast(malloc(uvc_buffer_size)); if (uvc_buffer == nullptr) { ESP_LOGE(UVC_STREAM_TAG, "Allocating buffer for UVC Device failed"); @@ -129,11 +139,12 @@ esp_err_t UVCStreamManager::setup() uvc_device_config_t config = { .uvc_buffer = uvc_buffer, - .uvc_buffer_size = UVC_MAX_FRAMESIZE_SIZE, + .uvc_buffer_size = uvc_buffer_size, .start_cb = UVCStreamHelpers::camera_start_cb, .fb_get_cb = UVCStreamHelpers::camera_fb_get_cb, .fb_return_cb = UVCStreamHelpers::camera_fb_return_cb, .stop_cb = UVCStreamHelpers::camera_stop_cb, + .cb_ctx = this, }; esp_err_t ret = uvc_device_config(0, &config); diff --git a/components/UVCStream/UVCStream/UVCStream.hpp b/components/UVCStream/UVCStream/UVCStream.hpp index 9048569..786e7b8 100644 --- a/components/UVCStream/UVCStream/UVCStream.hpp +++ b/components/UVCStream/UVCStream/UVCStream.hpp @@ -51,10 +51,12 @@ namespace UVCStreamHelpers class UVCStreamManager { uint8_t *uvc_buffer = nullptr; + uint32_t uvc_buffer_size = 0; public: esp_err_t setup(); esp_err_t start(); + uint32_t getUvcBufferSize() const { return uvc_buffer_size; } }; #endif // UVCSTREAM_HPP diff --git a/components/usb_device_uvc/tusb/usb_descriptors.c b/components/usb_device_uvc/tusb/usb_descriptors.c index baf881f..24dc7c1 100644 --- a/components/usb_device_uvc/tusb/usb_descriptors.c +++ b/components/usb_device_uvc/tusb/usb_descriptors.c @@ -119,6 +119,7 @@ uint8_t const *tud_descriptor_device_cb(void) static uint8_t const desc_fs_configuration[] = { // TUD_CONFIG_DESCRIPTOR(config_number, interface_count, string_index, // total_length, attributes, power_mA) + // attributes: 0 = bus-powered (default). Add TUSB_DESC_CONFIG_ATT_SELF_POWERED or _REMOTE_WAKEUP if needed. TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 500), // IAD for Video Control #if CFG_TUD_CAM1_VIDEO_STREAMING_BULK From 3f96e468f0f70563145c13901276a8a62820295e Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Sat, 23 Aug 2025 19:12:53 +0200 Subject: [PATCH 13/20] Refactor global state management for startup commands and USB handover (no Race-Condition); enhance SerialManager shutdown process and buffer handling in UVCStream. --- components/Helpers/Helpers/main_globals.cpp | 19 ++++--- components/Helpers/Helpers/main_globals.hpp | 4 ++ .../SerialManager/SerialManager.cpp | 50 +++++++++++++++++-- .../SerialManager/SerialManager.hpp | 1 + components/UVCStream/CMakeLists.txt | 2 +- components/UVCStream/UVCStream/UVCStream.cpp | 6 ++- main/openiris_main.cpp | 14 ++++++ 7 files changed, 82 insertions(+), 14 deletions(-) diff --git a/components/Helpers/Helpers/main_globals.cpp b/components/Helpers/Helpers/main_globals.cpp index cab36f8..8078234 100644 --- a/components/Helpers/Helpers/main_globals.cpp +++ b/components/Helpers/Helpers/main_globals.cpp @@ -4,15 +4,15 @@ // Forward declarations extern void start_video_streaming(void *arg); -bool startupCommandReceived = false; +static bool s_startupCommandReceived = false; bool getStartupCommandReceived() { - return startupCommandReceived; + return s_startupCommandReceived; } void setStartupCommandReceived(bool startupCommandReceived) { - startupCommandReceived = startupCommandReceived; + s_startupCommandReceived = startupCommandReceived; } static TaskHandle_t *g_serial_manager_handle = nullptr; @@ -27,15 +27,15 @@ void setSerialManagerHandle(TaskHandle_t *serialManagerHandle) } // Global pause state -bool startupPaused = false; +static bool s_startupPaused = false; bool getStartupPaused() { - return startupPaused; + return s_startupPaused; } void setStartupPaused(bool startupPaused) { - startupPaused = startupPaused; + s_startupPaused = startupPaused; } // Function to manually activate streaming @@ -47,4 +47,9 @@ void activateStreaming(bool disableSetup) void *serialTaskHandle = (serialHandle && *serialHandle) ? *serialHandle : nullptr; start_video_streaming(serialTaskHandle); -} \ No newline at end of file +} + +// USB handover state +static bool s_usbHandoverDone = false; +bool getUsbHandoverDone() { return s_usbHandoverDone; } +void setUsbHandoverDone(bool done) { s_usbHandoverDone = done; } \ No newline at end of file diff --git a/components/Helpers/Helpers/main_globals.hpp b/components/Helpers/Helpers/main_globals.hpp index 5602c2c..7fe93c9 100644 --- a/components/Helpers/Helpers/main_globals.hpp +++ b/components/Helpers/Helpers/main_globals.hpp @@ -21,4 +21,8 @@ void setStartupCommandReceived(bool startupCommandReceived); bool getStartupPaused(); void setStartupPaused(bool startupPaused); +// Tracks whether USB handover from usb_serial_jtag to TinyUSB was performed +bool getUsbHandoverDone(); +void setUsbHandoverDone(bool done); + #endif \ No newline at end of file diff --git a/components/SerialManager/SerialManager/SerialManager.cpp b/components/SerialManager/SerialManager/SerialManager.cpp index c666acf..8cfa168 100644 --- a/components/SerialManager/SerialManager/SerialManager.cpp +++ b/components/SerialManager/SerialManager/SerialManager.cpp @@ -24,13 +24,36 @@ void SerialManager::try_receive() int current_position = 0; int len = usb_serial_jtag_read_bytes(this->temp_data, 256, 1000 / 20); + // If driver is uninstalled or an error occurs, abort read gracefully + if (len < 0) + { + return; + } + // since we've got something on the serial port // we gotta keep reading until we've got the whole message - while (len) + while (len > 0) { - memcpy(this->data + current_position, this->temp_data, len); + // Prevent buffer overflow + if (current_position + len >= BUF_SIZE) + { + int copy_len = BUF_SIZE - 1 - current_position; + if (copy_len > 0) + { + memcpy(this->data + current_position, this->temp_data, copy_len); + current_position += copy_len; + } + // Drop the rest of the input to avoid overflow + break; + } + memcpy(this->data + current_position, this->temp_data, (size_t)len); current_position += len; len = usb_serial_jtag_read_bytes(this->temp_data, 256, 1000 / 20); + if (len < 0) + { + // Driver likely uninstalled during handover; stop processing this cycle + break; + } } if (current_position) @@ -42,9 +65,10 @@ void SerialManager::try_receive() // Notify main that a command was received during startup notify_startup_command_received(); - const auto result = this->commandManager->executeFromJson(std::string_view(reinterpret_cast(this->data))); - const auto resultMessage = result.getResult(); - usb_serial_jtag_write_bytes(resultMessage.c_str(), resultMessage.length(), 1000 / 20); + const auto result = this->commandManager->executeFromJson(std::string_view(reinterpret_cast(this->data))); + const auto resultMessage = result.getResult(); + int written = usb_serial_jtag_write_bytes(resultMessage.c_str(), resultMessage.length(), 1000 / 20); + (void)written; // ignore errors if driver already uninstalled } } @@ -79,6 +103,7 @@ void SerialManager::send_heartbeat() sprintf(heartbeat, "{\"heartbeat\":\"openiris_setup_mode\",\"serial\":\"%s\"}\n", serial_number); usb_serial_jtag_write_bytes(heartbeat, strlen(heartbeat), 1000 / 20); + // Ignore return value; if the driver was uninstalled, this is a no-op } bool SerialManager::should_send_heartbeat() @@ -123,4 +148,19 @@ void HandleSerialManagerTask(void *pvParameters) lastHeartbeat = currentTime; } } +} + +void SerialManager::shutdown() +{ + // Stop heartbeats; timer will be deleted by main if needed. + // Uninstall the USB Serial JTAG driver to free the internal USB for TinyUSB. + esp_err_t err = usb_serial_jtag_driver_uninstall(); + if (err == ESP_OK) + { + ESP_LOGI("[SERIAL]", "usb_serial_jtag driver uninstalled"); + } + else if (err != ESP_ERR_INVALID_STATE) + { + ESP_LOGW("[SERIAL]", "usb_serial_jtag_driver_uninstall returned %s", esp_err_to_name(err)); + } } \ No newline at end of file diff --git a/components/SerialManager/SerialManager/SerialManager.hpp b/components/SerialManager/SerialManager/SerialManager.hpp index 5205a69..a612957 100644 --- a/components/SerialManager/SerialManager/SerialManager.hpp +++ b/components/SerialManager/SerialManager/SerialManager.hpp @@ -27,6 +27,7 @@ public: void send_heartbeat(); bool should_send_heartbeat(); void notify_startup_command_received(); + void shutdown(); private: std::shared_ptr commandManager; diff --git a/components/UVCStream/CMakeLists.txt b/components/UVCStream/CMakeLists.txt index d748e3f..8deee2a 100644 --- a/components/UVCStream/CMakeLists.txt +++ b/components/UVCStream/CMakeLists.txt @@ -1,4 +1,4 @@ idf_component_register(SRCS "UVCStream/UVCStream.cpp" INCLUDE_DIRS "UVCStream" - REQUIRES esp_timer esp32-camera StateManager usb_device_uvc CameraManager + REQUIRES esp_timer esp32-camera StateManager usb_device_uvc CameraManager Helpers ) \ No newline at end of file diff --git a/components/UVCStream/UVCStream/UVCStream.cpp b/components/UVCStream/UVCStream/UVCStream.cpp index f0d8985..77b51e0 100644 --- a/components/UVCStream/UVCStream/UVCStream.cpp +++ b/components/UVCStream/UVCStream/UVCStream.cpp @@ -1,5 +1,9 @@ #include "UVCStream.hpp" #include // for snprintf +#include "driver/usb_serial_jtag.h" // for clean handover from COM to TinyUSB +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +// no deps on main globals here; handover is performed in main before calling setup when needed static const char *UVC_STREAM_TAG = "[UVC DEVICE]"; @@ -33,7 +37,6 @@ extern "C" { static esp_err_t UVCStreamHelpers::camera_start_cb(uvc_format_t format, int width, int height, int rate, void *cb_ctx) { - auto *mgr = static_cast(cb_ctx); ESP_LOGI(UVC_STREAM_TAG, "Camera Start"); ESP_LOGI(UVC_STREAM_TAG, "Format: %d, width: %d, height: %d, rate: %d", format, width, height, rate); framesize_t frame_size = FRAMESIZE_QVGA; @@ -79,6 +82,7 @@ static void UVCStreamHelpers::camera_stop_cb(void *cb_ctx) static uvc_fb_t *UVCStreamHelpers::camera_fb_get_cb(void *cb_ctx) { auto *mgr = static_cast(cb_ctx); + (void)mgr; s_fb.cam_fb_p = esp_camera_fb_get(); if (!s_fb.cam_fb_p) diff --git a/main/openiris_main.cpp b/main/openiris_main.cpp index 69a4139..4fbfa4a 100644 --- a/main/openiris_main.cpp +++ b/main/openiris_main.cpp @@ -98,6 +98,18 @@ void start_video_streaming(void *arg) #ifdef CONFIG_GENERAL_WIRED_MODE ESP_LOGI("[MAIN]", "Starting UVC streaming mode."); ESP_LOGI("[MAIN]", "Initializing UVC hardware..."); + // If we were given the Serial task handle, stop the task and uninstall the driver + if (arg != nullptr) + { + const auto serialTaskHandle = static_cast(arg); + vTaskDelete(serialTaskHandle); + ESP_LOGI("[MAIN]", "Serial task deleted before UVC init"); + serialManager->shutdown(); + ESP_LOGI("[MAIN]", "Serial driver uninstalled"); + // Leave a small gap for the host to see COM disappear + vTaskDelay(pdMS_TO_TICKS(200)); + setUsbHandoverDone(true); + } esp_err_t ret = uvcStream.setup(); if (ret != ESP_OK) { @@ -105,6 +117,8 @@ void start_video_streaming(void *arg) return; } uvcStream.start(); + ESP_LOGI("[MAIN]", "UVC streaming started"); + return; // UVC path complete, do not fall through to WiFi #else ESP_LOGE("[MAIN]", "UVC mode selected but the board likely does not support it."); ESP_LOGI("[MAIN]", "Falling back to WiFi mode if credentials available"); From 6e2a591348b64f4c50aeb621e91df26aed166341 Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Sun, 24 Aug 2025 22:21:06 +0200 Subject: [PATCH 14/20] Fixing small stuff --- .../CameraManager/CameraManager/CameraManager.cpp | 2 +- components/UVCStream/UVCStream/UVCStream.cpp | 4 +++- components/UVCStream/UVCStream/UVCStream.hpp | 3 ++- tools/openiris_setup.py | 13 ++++++++++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/components/CameraManager/CameraManager/CameraManager.cpp b/components/CameraManager/CameraManager/CameraManager.cpp index f31601b..a274965 100644 --- a/components/CameraManager/CameraManager/CameraManager.cpp +++ b/components/CameraManager/CameraManager/CameraManager.cpp @@ -99,7 +99,7 @@ void CameraManager::setupBasicResolution() return; } - ESP_LOGE(CAMERA_MANAGER_TAG, "PSRAM size: %u", esp_psram_get_size()); + ESP_LOGI(CAMERA_MANAGER_TAG, "PSRAM size: %u", esp_psram_get_size()); } void CameraManager::setupCameraSensor() diff --git a/components/UVCStream/UVCStream/UVCStream.cpp b/components/UVCStream/UVCStream/UVCStream.cpp index 77b51e0..4851e91 100644 --- a/components/UVCStream/UVCStream/UVCStream.cpp +++ b/components/UVCStream/UVCStream/UVCStream.cpp @@ -1,6 +1,5 @@ #include "UVCStream.hpp" #include // for snprintf -#include "driver/usb_serial_jtag.h" // for clean handover from COM to TinyUSB #include "freertos/FreeRTOS.h" #include "freertos/task.h" // no deps on main globals here; handover is performed in main before calling setup when needed @@ -35,6 +34,9 @@ extern "C" { } } +// single definition of shared framebuffer storage +UVCStreamHelpers::fb_t UVCStreamHelpers::s_fb = {}; + static esp_err_t UVCStreamHelpers::camera_start_cb(uvc_format_t format, int width, int height, int rate, void *cb_ctx) { ESP_LOGI(UVC_STREAM_TAG, "Camera Start"); diff --git a/components/UVCStream/UVCStream/UVCStream.hpp b/components/UVCStream/UVCStream/UVCStream.hpp index 786e7b8..253f29d 100644 --- a/components/UVCStream/UVCStream/UVCStream.hpp +++ b/components/UVCStream/UVCStream/UVCStream.hpp @@ -40,7 +40,8 @@ namespace UVCStreamHelpers uvc_fb_t uvc_fb; } fb_t; - static fb_t s_fb; + // single storage is defined in UVCStream.cpp + extern fb_t s_fb; static esp_err_t camera_start_cb(uvc_format_t format, int width, int height, int rate, void *cb_ctx); static void camera_stop_cb(void *cb_ctx); diff --git a/tools/openiris_setup.py b/tools/openiris_setup.py index 7c29998..681a75d 100644 --- a/tools/openiris_setup.py +++ b/tools/openiris_setup.py @@ -901,6 +901,11 @@ def switch_device_mode(device: OpenIrisDevice, args = None): def set_led_duty_cycle(device: OpenIrisDevice, args=None): + # Show current duty cycle on entry + current = device.get_led_duty_cycle() + if current is not None: + print(f"💡 Current LED duty cycle: {current}%") + while True: input_data = input("Enter LED external PWM duty cycle (0-100) or `back` to exit: \n") if input_data.lower() == "back": @@ -915,7 +920,13 @@ def set_led_duty_cycle(device: OpenIrisDevice, args=None): print("❌ Duty cycle must be between 0 and 100.") else: # Apply immediately; stay in loop for further tweaks - device.set_led_duty_cycle(duty_cycle) + if device.set_led_duty_cycle(duty_cycle): + # Read back and display current value using existing getter + updated = device.get_led_duty_cycle() + if updated is not None: + print(f"💡 Current LED duty cycle: {updated}%") + else: + print("ℹ️ Duty cycle updated, but current value could not be read back.") def monitor_logs(device: OpenIrisDevice, args = None): From 937234af6dd2c3b2c10b60720b50ee09baef8113 Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Sun, 24 Aug 2025 22:50:35 +0200 Subject: [PATCH 15/20] Update README and enhance serial number display in OpenIris setup CLI --- README.md | 63 ++++++----------------------------------- tools/openiris_setup.py | 7 +++-- 2 files changed, 12 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 9b9d5ee..27f158d 100644 --- a/README.md +++ b/README.md @@ -3,34 +3,15 @@ ## OpenIris-ESPIDF -Firmware and tools for OpenIris — Wi‑Fi, UVC streaming, and a handy Python setup CLI. +Firmware and tools for OpenIris — Wi‑Fi, UVC streaming, and a Python setup CLI. --- ## What’s inside - ESP‑IDF firmware (C/C++) with modules for Camera, Wi‑Fi, UVC, REST/Serial commands, and more -- Python tools to make setup easy over USB serial: - - `tools/switchBoardType.py` — choose a board profile (loads the right sdkconfig) +- Python tools for setup over USB serial: + - `tools/switchBoardType.py` — choose a board profile (builds the right sdkconfig) - `tools/openiris_setup.py` — interactive CLI for Wi‑Fi, MDNS/Name, Mode, LED PWM, Logs, and a Settings Summary - - `tools/wifi_scanner.py` — optional Wi‑Fi scanner - ---- - -## Prerequisites -- ESP‑IDF installed and available in your terminal (`idf.py` works) -- Python 3.10+ with `pip` (on Windows this is installed automatically when you set up the ESP‑IDF VS Code extension; see “First-time setup on Windows” below) -- USB cable to your board -- Optional: install Python dependencies for the tools - -Windows (cmd): -```cmd -python -m pip install -r tools\requirements.txt -``` -macOS/Linux (bash): -```bash -python3 -m pip install -r tools/requirements.txt -``` -Note for Windows: If emojis don’t render nicely, it’s only cosmetic — everything still works. --- @@ -62,14 +43,6 @@ code . - If you see the extension’s home page instead, click “Configure extension”, pick “EXPRESS”, choose “GitHub” as the server and version “v5.3.3”. - Then open the ESP‑IDF Explorer tab and click “Open ESP‑IDF Terminal”. We’ll use that for builds. -6) Default board profile and switching -- The project ships with multiple board profiles; one default may target internal “Project Babble” boards. -- If you have a Seeed XIAO ESP32S3 (or another board), switch the profile with the helper script: -```cmd -python .\tools\switchBoardType.py --board xiao-esp32s3 --diff -``` -- You can re‑run this anytime to switch boards; `--diff` shows the changes. - After this, you’re ready for the Quick start below. --- @@ -89,23 +62,15 @@ python3 ./tools/switchBoardType.py --board xiao-esp32s3 --diff - `--diff` shows what changed in the config ### 2) Build & flash -- Set the target (e.g., ESP32‑S3): -```cmd -idf.py set-target esp32s3 -``` -- Build, flash, and open the serial monitor: -```cmd -idf.py -p COM15 flash monitor -``` -Replace `COM15` with your port (Windows: `COM…`, Linux: `/dev/ttyUSB…`, macOS: `/dev/cu.usbmodem…`). -Exit the monitor with `Ctrl+]`. +- Set the target (e.g., ESP32‑S3). +- Build, flash, and open the serial monitor. ### 3) Use the Python setup CLI (recommended) Configure the device conveniently over USB serial. Windows (cmd): ```cmd -python .\tools\openiris_setup.py --port COM15 +python .\tools\openiris_setup.py --port COMxx ``` macOS/Linux (bash): ```bash @@ -119,8 +84,6 @@ What the CLI can do: - Show a Settings Summary (MAC, Wi‑Fi status, mode, PWM, …) - View logs -Tip: On start, the CLI keeps the device in a setup state so replies are stable. - --- ## Serial number & MAC @@ -134,7 +97,6 @@ Tip: On start, the CLI keeps the device in a setup state so replies are stable. - Fast Wi‑Fi setup: in the CLI, go to “Wi‑Fi settings” → “Automatic setup”, then check “status”. - Change name/MDNS: set the device name in the CLI, then replug USB — UVC will show the new name. - Adjust brightness/LED: set LED PWM in the CLI. -- Quick health check: run “Get settings summary” after flashing to verify the device state. --- @@ -148,18 +110,9 @@ If you want to dig deeper: commands are mapped via the `CommandManager` under `c --- ## Troubleshooting -- No device/port found? - - Pass `--port` explicitly (e.g., `--port COM15`). - - Right after reset, the device emits heartbeats for a short time; the CLI finds it fastest during that window. - UVC doesn’t appear on the host? - - Switch mode to UVC and replug USB. On Windows the first driver init can take a moment. -- Wi‑Fi won’t connect? - - Check password/channel. Use the automatic setup in the CLI and then inspect the status. -- ESP‑IDF not detected? - - Ensure the ESP‑IDF environment is active in the terminal (IDF Command Prompt or the extension’s ESP‑IDF Terminal; alternatively source `export.ps1`/`export.sh`). -- Missing Python modules? - - Run `pip install -r tools/requirements.txt`. + - Switch mode to UVC via CLI tool, replug USB and wait 20s. --- -Have fun with OpenIris! Feedback, issues, and PRs are welcome. +Feedback, issues, and PRs are welcome. \ No newline at end of file diff --git a/tools/openiris_setup.py b/tools/openiris_setup.py index 681a75d..9dc6ead 100644 --- a/tools/openiris_setup.py +++ b/tools/openiris_setup.py @@ -996,9 +996,10 @@ def get_settings(device: OpenIrisDevice, args=None): ident = summary.get("Identity", {}) serial = ident.get("serial") mac = ident.get("mac") - # print(f"🔑 Serial: {serial}") # Serial display intentionally disabled; MAC is sufficient - if mac: - print(f"🔗 MAC: {mac}") + if serial: + print(f"🔑 Serial: {serial}") + # if mac: + # print(f"🔗 MAC: {mac}") if not serial and not mac: print("🔑 Serial/MAC: unavailable") From 4fa7c02a535788a66528a5e7c533cc22dd248dbd Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Sun, 24 Aug 2025 23:20:37 +0200 Subject: [PATCH 16/20] Sdkconfig for project babble --- sdkconfig | 56 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/sdkconfig b/sdkconfig index 08e7daa..f12ff3a 100644 --- a/sdkconfig +++ b/sdkconfig @@ -497,9 +497,9 @@ CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y # CONFIG_ESPTOOLPY_NO_STUB is not set # CONFIG_ESPTOOLPY_OCT_FLASH is not set CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT=y -# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set -CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y CONFIG_ESPTOOLPY_FLASHMODE="dio" @@ -511,13 +511,13 @@ CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y CONFIG_ESPTOOLPY_FLASHFREQ="80m" # CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="8MB" +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -578,32 +578,32 @@ CONFIG_WIFI_AP_PASSWORD="12345678" # OpenIris: LED Configuration # CONFIG_LED_BLINK_GPIO=8 -CONFIG_LED_EXTERNAL_GPIO=9 +CONFIG_LED_EXTERNAL_GPIO=1 CONFIG_LED_EXTERNAL_CONTROL=y -CONFIG_LED_EXTERNAL_PWM_FREQ=20000 +CONFIG_LED_EXTERNAL_PWM_FREQ=5000 CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100 # end of OpenIris: LED Configuration # # Camera sensor pinout configuration # -CONFIG_CAMERA_MODULE_NAME="FaceFocusVR_Face" +CONFIG_CAMERA_MODULE_NAME="SWROOM_BABBLE_S3" CONFIG_PWDN_GPIO_NUM=-1 CONFIG_RESET_GPIO_NUM=-1 -CONFIG_XCLK_GPIO_NUM=10 -CONFIG_SIOD_GPIO_NUM=40 -CONFIG_SIOC_GPIO_NUM=39 -CONFIG_Y9_GPIO_NUM=48 -CONFIG_Y8_GPIO_NUM=11 -CONFIG_Y7_GPIO_NUM=12 -CONFIG_Y6_GPIO_NUM=14 -CONFIG_Y5_GPIO_NUM=16 -CONFIG_Y4_GPIO_NUM=18 -CONFIG_Y3_GPIO_NUM=17 -CONFIG_Y2_GPIO_NUM=15 -CONFIG_VSYNC_GPIO_NUM=38 -CONFIG_HREF_GPIO_NUM=47 -CONFIG_PCLK_GPIO_NUM=13 +CONFIG_XCLK_GPIO_NUM=4 +CONFIG_SIOD_GPIO_NUM=48 +CONFIG_SIOC_GPIO_NUM=47 +CONFIG_Y9_GPIO_NUM=13 +CONFIG_Y8_GPIO_NUM=5 +CONFIG_Y7_GPIO_NUM=6 +CONFIG_Y6_GPIO_NUM=15 +CONFIG_Y5_GPIO_NUM=17 +CONFIG_Y4_GPIO_NUM=8 +CONFIG_Y3_GPIO_NUM=18 +CONFIG_Y2_GPIO_NUM=16 +CONFIG_VSYNC_GPIO_NUM=21 +CONFIG_HREF_GPIO_NUM=14 +CONFIG_PCLK_GPIO_NUM=7 # end of Camera sensor pinout configuration # @@ -1121,9 +1121,11 @@ CONFIG_SPIRAM=y # # SPI RAM config # -# CONFIG_SPIRAM_MODE_QUAD is not set -CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_MODE_QUAD=y +# CONFIG_SPIRAM_MODE_OCT is not set CONFIG_SPIRAM_TYPE_AUTO=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set # CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y CONFIG_SPIRAM_CLK_IO=30 @@ -1131,10 +1133,10 @@ CONFIG_SPIRAM_CS_IO=26 # CONFIG_SPIRAM_XIP_FROM_PSRAM is not set # CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set # CONFIG_SPIRAM_RODATA is not set +# CONFIG_SPIRAM_SPEED_120M is not set CONFIG_SPIRAM_SPEED_80M=y # CONFIG_SPIRAM_SPEED_40M is not set CONFIG_SPIRAM_SPEED=80 -# CONFIG_SPIRAM_ECC_ENABLE is not set CONFIG_SPIRAM_BOOT_INIT=y # CONFIG_SPIRAM_IGNORE_NOTFOUND is not set # CONFIG_SPIRAM_USE_MEMMAP is not set @@ -2294,9 +2296,9 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y CONFIG_LOG_BOOTLOADER_LEVEL=3 # CONFIG_APP_ROLLBACK_ENABLE is not set # CONFIG_FLASH_ENCRYPTION_ENABLED is not set -# CONFIG_FLASHMODE_QIO is not set +CONFIG_FLASHMODE_QIO=y # CONFIG_FLASHMODE_QOUT is not set -CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DIO is not set # CONFIG_FLASHMODE_DOUT is not set CONFIG_MONITOR_BAUD=115200 # CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set From 8c8db170b012aba36bdc40a7cec120586cccdc49 Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Mon, 25 Aug 2025 22:52:06 +0200 Subject: [PATCH 17/20] Fixed PR comments --- README.md | 23 ++- .../LEDManager/LEDManager/LEDManager.cpp | 20 +- dependencies.lock | 2 +- sdkconfig | 191 +++++++++++++----- 4 files changed, 164 insertions(+), 72 deletions(-) diff --git a/README.md b/README.md index 27f158d..ac8bbb3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -| Supported Targets (IDK lol) | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-S3 | +| ----------------- | -------- | ## OpenIris-ESPIDF @@ -40,7 +40,7 @@ code . 5) Configure ESP‑IDF in the extension - On first launch, the extension may prompt to install ESP‑IDF and tools — follow the steps. It can take a while. -- If you see the extension’s home page instead, click “Configure extension”, pick “EXPRESS”, choose “GitHub” as the server and version “v5.3.3”. +- If you see the extension’s home page instead, click “Configure extension”, pick “EXPRESS”, choose “GitHub” as the server and version “v5.4.2”. - Then open the ESP‑IDF Explorer tab and click “Open ESP‑IDF Terminal”. We’ll use that for builds. After this, you’re ready for the Quick start below. @@ -66,16 +66,21 @@ python3 ./tools/switchBoardType.py --board xiao-esp32s3 --diff - Build, flash, and open the serial monitor. ### 3) Use the Python setup CLI (recommended) -Configure the device conveniently over USB serial. +Configure the device over USB serial. -Windows (cmd): +Before you run it: +- If you still have the serial monitor open, close it (the port must be free). +- In VS Code, open the sidebar “ESP‑IDF: Explorer” and click “Open ESP‑IDF Terminal”. We’ll run the CLI there so Python and packages are in the right environment. + +Then run: ```cmd python .\tools\openiris_setup.py --port COMxx ``` -macOS/Linux (bash): -```bash -python3 ./tools/openiris_setup.py --port /dev/ttyUSB0 -``` +Examples: +- Windows: `python .\tools\openiris_setup.py --port COM69`, … +- macOS: idk +- Linux: idk + What the CLI can do: - Wi‑Fi menu: automatic (scan → pick → password → connect → wait for IP) or manual (scan, show, configure, connect, status) - Set MDNS/Device name (also used for the UVC device name) diff --git a/components/LEDManager/LEDManager/LEDManager.cpp b/components/LEDManager/LEDManager/LEDManager.cpp index 159b750..a5b7d0a 100644 --- a/components/LEDManager/LEDManager/LEDManager.cpp +++ b/components/LEDManager/LEDManager/LEDManager.cpp @@ -152,6 +152,15 @@ void LEDManager::displayCurrentPattern() void LEDManager::updateState(const LEDStates_e newState) { + // If we've got an error state - that's it, keep repeating it indefinitely + if (ledStateMap[this->currentState].isError) + return; + + // Alternative (recoverable error states): + // Allow recovery from error states by only blocking transitions when both, current and new states are error. Uncomment to enable recovery. + // if (ledStateMap[this->currentState].isError && ledStateMap[newState].isError) + // return; + // Only update when new state differs and is known. if (!ledStateMap.contains(newState)) return; @@ -159,11 +168,6 @@ void LEDManager::updateState(const LEDStates_e newState) if (newState == this->currentState) return; - // Allow recovery from error states: if both current and new are error, ignore. - // Otherwise permit transitioning out of error when a non-error state arrives. - if (ledStateMap[this->currentState].isError && ledStateMap[newState].isError) - return; - this->currentState = newState; this->currentPatternIndex = 0; this->finishedPattern = false; @@ -181,12 +185,6 @@ void LEDManager::setExternalLEDDutyCycle(uint8_t dutyPercent) const uint32_t dutyCycle = (static_cast(dutyPercent) * 255) / 100; ESP_LOGI(LED_MANAGER_TAG, "Updating external LED duty to %u%% (raw %lu)", dutyPercent, dutyCycle); - // Persist into config immediately so it survives reboot - if (this->deviceConfig) - { - this->deviceConfig->setLEDDUtyCycleConfig(dutyPercent); - } - // Apply to LEDC hardware live // We configured channel 0 in setup with LEDC_LOW_SPEED_MODE ESP_ERROR_CHECK_WITHOUT_ABORT(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, dutyCycle)); diff --git a/dependencies.lock b/dependencies.lock index c7e209c..95f496d 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -53,7 +53,7 @@ dependencies: idf: source: type: idf - version: 5.3.3 + version: 5.4.2 direct_dependencies: - espressif/cmake_utilities - espressif/esp32-camera diff --git a/sdkconfig b/sdkconfig index f12ff3a..e88b1e2 100644 --- a/sdkconfig +++ b/sdkconfig @@ -1,6 +1,6 @@ # # Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) 5.3.3 Project Configuration +# Espressif IoT Development Framework (ESP-IDF) 5.4.2 Project Configuration # CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 @@ -138,6 +138,7 @@ CONFIG_SOC_I2C_SUPPORT_RTC=y CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y CONFIG_SOC_I2C_SLAVE_SUPPORT_BROADCAST=y CONFIG_SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS=y +CONFIG_SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE=y CONFIG_SOC_I2S_NUM=2 CONFIG_SOC_I2S_HW_VERSION_2=y CONFIG_SOC_I2S_SUPPORTS_XTAL=y @@ -151,6 +152,7 @@ CONFIG_SOC_I2S_PDM_MAX_RX_LINES=4 CONFIG_SOC_I2S_SUPPORTS_TDM=y CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y CONFIG_SOC_LEDC_SUPPORT_XTAL_CLOCK=y +CONFIG_SOC_LEDC_TIMER_NUM=4 CONFIG_SOC_LEDC_CHANNEL_NUM=8 CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=14 CONFIG_SOC_LEDC_SUPPORT_FADE_STOP=y @@ -307,6 +309,7 @@ CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y CONFIG_SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY=y CONFIG_SOC_PM_CPU_RETENTION_BY_RTCCNTL=y CONFIG_SOC_PM_MODEM_RETENTION_BY_BACKUPDMA=y +CONFIG_SOC_PM_MODEM_PD_BY_SW=y CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y @@ -368,10 +371,11 @@ CONFIG_SOC_ULP_HAS_ADC=y CONFIG_SOC_PHY_COMBO_MODULE=y CONFIG_IDF_CMAKE=y CONFIG_IDF_TOOLCHAIN="gcc" +CONFIG_IDF_TOOLCHAIN_GCC=y CONFIG_IDF_TARGET_ARCH_XTENSA=y CONFIG_IDF_TARGET_ARCH="xtensa" CONFIG_IDF_TARGET="esp32s3" -CONFIG_IDF_INIT_VERSION="5.3.3" +CONFIG_IDF_INIT_VERSION="5.4.2" CONFIG_IDF_TARGET_ESP32S3=y CONFIG_IDF_FIRMWARE_CHIP_ID=0x0009 @@ -403,6 +407,10 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set + +# +# Log +# # CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set # CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set # CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set @@ -411,6 +419,14 @@ CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y # CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set CONFIG_BOOTLOADER_LOG_LEVEL=3 +# +# Format +# +# CONFIG_BOOTLOADER_LOG_COLORS is not set +CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y +# end of Format +# end of Log + # # Serial Flash Configurations # @@ -481,6 +497,7 @@ CONFIG_ESP_ROM_HAS_CACHE_WRITEBACK_BUG=y CONFIG_ESP_ROM_HAS_SW_FLOAT=y CONFIG_ESP_ROM_HAS_VERSION=y CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y +CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y # # Boot ROM Behavior @@ -497,9 +514,9 @@ CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y # CONFIG_ESPTOOLPY_NO_STUB is not set # CONFIG_ESPTOOLPY_OCT_FLASH is not set CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT=y -CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set -# CONFIG_ESPTOOLPY_FLASHMODE_DIO is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y # CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y CONFIG_ESPTOOLPY_FLASHMODE="dio" @@ -507,17 +524,16 @@ CONFIG_ESPTOOLPY_FLASHMODE="dio" CONFIG_ESPTOOLPY_FLASHFREQ_80M=y # CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set # CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set -CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y CONFIG_ESPTOOLPY_FLASHFREQ="80m" # CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y -# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y # CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +CONFIG_ESPTOOLPY_FLASHSIZE="8MB" # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -534,6 +550,7 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 # CONFIG_PARTITION_TABLE_SINGLE_APP is not set # CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set # CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="min_spiffs.csv" CONFIG_PARTITION_TABLE_FILENAME="min_spiffs.csv" @@ -578,32 +595,32 @@ CONFIG_WIFI_AP_PASSWORD="12345678" # OpenIris: LED Configuration # CONFIG_LED_BLINK_GPIO=8 -CONFIG_LED_EXTERNAL_GPIO=1 +CONFIG_LED_EXTERNAL_GPIO=9 CONFIG_LED_EXTERNAL_CONTROL=y -CONFIG_LED_EXTERNAL_PWM_FREQ=5000 -CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100 +CONFIG_LED_EXTERNAL_PWM_FREQ=20000 +CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=50 # end of OpenIris: LED Configuration # # Camera sensor pinout configuration # -CONFIG_CAMERA_MODULE_NAME="SWROOM_BABBLE_S3" +CONFIG_CAMERA_MODULE_NAME="FaceFocusVR_Face" CONFIG_PWDN_GPIO_NUM=-1 CONFIG_RESET_GPIO_NUM=-1 -CONFIG_XCLK_GPIO_NUM=4 -CONFIG_SIOD_GPIO_NUM=48 -CONFIG_SIOC_GPIO_NUM=47 -CONFIG_Y9_GPIO_NUM=13 -CONFIG_Y8_GPIO_NUM=5 -CONFIG_Y7_GPIO_NUM=6 -CONFIG_Y6_GPIO_NUM=15 -CONFIG_Y5_GPIO_NUM=17 -CONFIG_Y4_GPIO_NUM=8 -CONFIG_Y3_GPIO_NUM=18 -CONFIG_Y2_GPIO_NUM=16 -CONFIG_VSYNC_GPIO_NUM=21 -CONFIG_HREF_GPIO_NUM=14 -CONFIG_PCLK_GPIO_NUM=7 +CONFIG_XCLK_GPIO_NUM=10 +CONFIG_SIOD_GPIO_NUM=40 +CONFIG_SIOC_GPIO_NUM=39 +CONFIG_Y9_GPIO_NUM=48 +CONFIG_Y8_GPIO_NUM=11 +CONFIG_Y7_GPIO_NUM=12 +CONFIG_Y6_GPIO_NUM=14 +CONFIG_Y5_GPIO_NUM=16 +CONFIG_Y4_GPIO_NUM=18 +CONFIG_Y3_GPIO_NUM=17 +CONFIG_Y2_GPIO_NUM=15 +CONFIG_VSYNC_GPIO_NUM=38 +CONFIG_HREF_GPIO_NUM=47 +CONFIG_PCLK_GPIO_NUM=13 # end of Camera sensor pinout configuration # @@ -616,6 +633,7 @@ CONFIG_COMPILER_OPTIMIZATION_PERF=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 # CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set @@ -626,14 +644,18 @@ CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set # CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set # CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set # CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y # CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set # CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set # CONFIG_COMPILER_DUMP_RTL_FILES is not set CONFIG_COMPILER_RT_LIB_GCCLIB=y CONFIG_COMPILER_RT_LIB_NAME="gcc" # CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING is not set CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE=y +# CONFIG_COMPILER_STATIC_ANALYZER is not set # end of Compiler options # @@ -723,6 +745,12 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations +# +# Legacy I2C Driver Configurations +# +# CONFIG_I2C_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy I2C Driver Configurations + # # Legacy PCNT Driver Configurations # @@ -810,6 +838,7 @@ CONFIG_GPTIMER_OBJ_CACHE_SAFE=y # # CONFIG_I2C_ISR_IRAM_SAFE is not set # CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set # end of ESP-Driver:I2C Configurations # @@ -934,6 +963,7 @@ CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set # CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set # CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set +CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 # end of ESP HTTP client # @@ -946,6 +976,7 @@ CONFIG_HTTPD_PURGE_BUF_LEN=32 # CONFIG_HTTPD_LOG_PURGE_DATA is not set CONFIG_HTTPD_WS_SUPPORT=y # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # end of HTTP Server # @@ -953,12 +984,14 @@ CONFIG_HTTPD_WS_SUPPORT=y # # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set # CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS OTA # # ESP HTTPS server # # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS server # @@ -1036,8 +1069,10 @@ CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y # GDMA Configurations # CONFIG_GDMA_CTRL_FUNC_IN_IRAM=y -# CONFIG_GDMA_ISR_IRAM_SAFE is not set +CONFIG_GDMA_ISR_HANDLER_IN_IRAM=y +CONFIG_GDMA_OBJ_DRAM_SAFE=y # CONFIG_GDMA_ENABLE_DEBUG_LOG is not set +# CONFIG_GDMA_ISR_IRAM_SAFE is not set # end of GDMA Configurations # @@ -1051,29 +1086,28 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # end of Hardware Settings # -# LCD and Touch Panel -# - -# -# LCD Touch Drivers are maintained in the IDF Component Registry -# - -# -# LCD Peripheral Configuration +# ESP-Driver:LCD Controller Configurations # # CONFIG_LCD_ENABLE_DEBUG_LOG is not set # CONFIG_LCD_RGB_ISR_IRAM_SAFE is not set # CONFIG_LCD_RGB_RESTART_IN_VSYNC is not set -# end of LCD Peripheral Configuration -# end of LCD and Touch Panel +# end of ESP-Driver:LCD Controller Configurations + +# +# ESP-MM: Memory Management Configurations +# +# CONFIG_ESP_MM_CACHE_MSYNC_C2M_CHUNKED_OPS is not set +# end of ESP-MM: Memory Management Configurations # # ESP NETIF Adapter # CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +# CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y # CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set # CONFIG_ESP_NETIF_L2_TAP is not set # CONFIG_ESP_NETIF_BRIDGE_EN is not set @@ -1121,23 +1155,21 @@ CONFIG_SPIRAM=y # # SPI RAM config # -CONFIG_SPIRAM_MODE_QUAD=y -# CONFIG_SPIRAM_MODE_OCT is not set +# CONFIG_SPIRAM_MODE_QUAD is not set +CONFIG_SPIRAM_MODE_OCT=y CONFIG_SPIRAM_TYPE_AUTO=y -# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set -# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set # CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set -CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y CONFIG_SPIRAM_CLK_IO=30 CONFIG_SPIRAM_CS_IO=26 # CONFIG_SPIRAM_XIP_FROM_PSRAM is not set # CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set # CONFIG_SPIRAM_RODATA is not set -# CONFIG_SPIRAM_SPEED_120M is not set CONFIG_SPIRAM_SPEED_80M=y # CONFIG_SPIRAM_SPEED_40M is not set CONFIG_SPIRAM_SPEED=80 +# CONFIG_SPIRAM_ECC_ENABLE is not set CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION=y # CONFIG_SPIRAM_IGNORE_NOTFOUND is not set # CONFIG_SPIRAM_USE_MEMMAP is not set # CONFIG_SPIRAM_USE_CAPS_ALLOC is not set @@ -1157,6 +1189,11 @@ CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set # end of ESP Ringbuf +# +# ESP Security Specific +# +# end of ESP Security Specific + # # ESP System Settings # @@ -1405,10 +1442,21 @@ CONFIG_FATFS_TIMEOUT_MS=10000 CONFIG_FATFS_PER_FILE_CACHE=y CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y # CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_USE_STRFUNC_NONE=y +# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set +# CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 # CONFIG_FATFS_IMMEDIATE_FSYNC is not set # CONFIG_FATFS_USE_LABEL is not set CONFIG_FATFS_LINK_LOCK=y +# CONFIG_FATFS_USE_DYN_BUFFERS is not set + +# +# File system free space calculation behavior +# +CONFIG_FATFS_DONT_TRUST_FREE_CLUSTER_CNT=0 +CONFIG_FATFS_DONT_TRUST_LAST_ALLOC=0 +# end of File system free space calculation behavior # end of FAT Filesystem support # @@ -1430,6 +1478,7 @@ CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 # CONFIG_FREERTOS_USE_TICK_HOOK is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 # CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_USE_TIMERS=y CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" # CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set # CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set @@ -1456,6 +1505,7 @@ CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y CONFIG_FREERTOS_ISR_STACKSIZE=1536 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# CONFIG_FREERTOS_FPU_IN_ISR is not set CONFIG_FREERTOS_TICK_SUPPORT_SYSTIMER=y CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL1=y # CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL3 is not set @@ -1464,6 +1514,12 @@ CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER=y # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # end of Port +# +# Extra +# +CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM=y +# end of Extra + CONFIG_FREERTOS_PORT=y CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y @@ -1502,7 +1558,11 @@ CONFIG_HEAP_TRACING_OFF=y # end of Heap memory debugging # -# Log output +# Log +# + +# +# Log Level # # CONFIG_LOG_DEFAULT_LEVEL_NONE is not set # CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set @@ -1515,11 +1575,29 @@ CONFIG_LOG_DEFAULT_LEVEL=3 # CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE=y CONFIG_LOG_MAXIMUM_LEVEL=5 + +# +# Level Settings +# # CONFIG_LOG_MASTER_LEVEL is not set +CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y +# CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set +# CONFIG_LOG_TAG_LEVEL_IMPL_LINKED_LIST is not set +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST=y +# CONFIG_LOG_TAG_LEVEL_CACHE_ARRAY is not set +CONFIG_LOG_TAG_LEVEL_CACHE_BINARY_MIN_HEAP=y +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 +# end of Level Settings +# end of Log Level + +# +# Format +# CONFIG_LOG_COLORS=y CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set -# end of Log output +# end of Format +# end of Log # # LWIP @@ -1558,6 +1636,8 @@ CONFIG_LWIP_ESP_MLDV6_REPORT=y CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set +# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set @@ -1572,6 +1652,7 @@ CONFIG_LWIP_DHCPS=y CONFIG_LWIP_DHCPS_LEASE_UNIT=60 CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y +CONFIG_LWIP_DHCPS_ADD_DNS=y # end of DHCP server # CONFIG_LWIP_AUTOIP is not set @@ -1630,12 +1711,12 @@ CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 # CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 # CONFIG_LWIP_SLIP_SUPPORT is not set # @@ -1756,6 +1837,7 @@ CONFIG_MBEDTLS_HAVE_TIME=y # CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA1_C=y CONFIG_MBEDTLS_SHA512_C=y # CONFIG_MBEDTLS_SHA3_C is not set CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y @@ -1811,6 +1893,8 @@ CONFIG_MBEDTLS_X509_CSR_PARSE_C=y # end of Certificates CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y +CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y # CONFIG_MBEDTLS_DHM_C is not set CONFIG_MBEDTLS_ECDH_C=y CONFIG_MBEDTLS_ECDSA_C=y @@ -1835,6 +1919,7 @@ CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM=y # CONFIG_MBEDTLS_THREADING_C is not set CONFIG_MBEDTLS_ERROR_STRINGS=y CONFIG_MBEDTLS_FS_IO=y +# CONFIG_MBEDTLS_ALLOW_WEAK_CERTIFICATE_VERIFICATION is not set # end of mbedTLS # @@ -1877,6 +1962,7 @@ CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND=y # CONFIG_NVS_ENCRYPTION is not set # CONFIG_NVS_ASSERT_ERROR_CHECK is not set # CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set +# CONFIG_NVS_ALLOCATE_CACHE_IN_SPIRAM is not set # end of NVS # @@ -1945,10 +2031,10 @@ CONFIG_SPI_FLASH_HPM_AUTO=y CONFIG_SPI_FLASH_HPM_ON=y CONFIG_SPI_FLASH_HPM_DC_AUTO=y # CONFIG_SPI_FLASH_HPM_DC_DISABLE is not set -CONFIG_SPI_FLASH_SUSPEND_QVL_SUPPORTED=y # CONFIG_SPI_FLASH_AUTO_SUSPEND is not set CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 # CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set +# CONFIG_SPI_FLASH_FORCE_ENABLE_C6_H2_SUSPEND is not set # end of Optional and Experimental Features (READ DOCS FIRST) # end of Main Flash configuration @@ -2109,6 +2195,8 @@ CONFIG_VFS_MAX_COUNT=8 # CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 # end of Host File System I/O (Semihosting) + +CONFIG_VFS_INITIALIZE_DEV_NULL=y # end of Virtual file system # @@ -2296,9 +2384,9 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y CONFIG_LOG_BOOTLOADER_LEVEL=3 # CONFIG_APP_ROLLBACK_ENABLE is not set # CONFIG_FLASH_ENCRYPTION_ENABLED is not set -CONFIG_FLASHMODE_QIO=y +# CONFIG_FLASHMODE_QIO is not set # CONFIG_FLASHMODE_QOUT is not set -# CONFIG_FLASHMODE_DIO is not set +CONFIG_FLASHMODE_DIO=y # CONFIG_FLASHMODE_DOUT is not set CONFIG_MONITOR_BAUD=115200 # CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set @@ -2431,6 +2519,7 @@ CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=2048 CONFIG_TIMER_QUEUE_LENGTH=10 # CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y # CONFIG_HAL_ASSERTION_SILIENT is not set # CONFIG_L2_TO_L3_COPY is not set CONFIG_ESP_GRATUITOUS_ARP=y From 06394f9654b873308e209562b1a8552cce7630a1 Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Mon, 25 Aug 2025 23:47:50 +0200 Subject: [PATCH 18/20] Fixed PR comments2 --- .../LEDManager/LEDManager/LEDManager.cpp | 1 - components/UVCStream/UVCStream/UVCStream.cpp | 15 +---- components/UVCStream/UVCStream/UVCStream.hpp | 2 + sdkconfig | 58 ++++++++++--------- 4 files changed, 35 insertions(+), 41 deletions(-) diff --git a/components/LEDManager/LEDManager/LEDManager.cpp b/components/LEDManager/LEDManager/LEDManager.cpp index a5b7d0a..f2e7568 100644 --- a/components/LEDManager/LEDManager/LEDManager.cpp +++ b/components/LEDManager/LEDManager/LEDManager.cpp @@ -181,7 +181,6 @@ void LEDManager::toggleLED(const bool state) const void LEDManager::setExternalLEDDutyCycle(uint8_t dutyPercent) { #ifdef CONFIG_LED_EXTERNAL_CONTROL - dutyPercent = std::min(100, dutyPercent); const uint32_t dutyCycle = (static_cast(dutyPercent) * 255) / 100; ESP_LOGI(LED_MANAGER_TAG, "Updating external LED duty to %u%% (raw %lu)", dutyPercent, dutyCycle); diff --git a/components/UVCStream/UVCStream/UVCStream.cpp b/components/UVCStream/UVCStream/UVCStream.cpp index 4851e91..7b9cc61 100644 --- a/components/UVCStream/UVCStream/UVCStream.cpp +++ b/components/UVCStream/UVCStream/UVCStream.cpp @@ -84,7 +84,6 @@ static void UVCStreamHelpers::camera_stop_cb(void *cb_ctx) static uvc_fb_t *UVCStreamHelpers::camera_fb_get_cb(void *cb_ctx) { auto *mgr = static_cast(cb_ctx); - (void)mgr; s_fb.cam_fb_p = esp_camera_fb_get(); if (!s_fb.cam_fb_p) @@ -126,16 +125,8 @@ esp_err_t UVCStreamManager::setup() #endif ESP_LOGI(UVC_STREAM_TAG, "Setting up UVC Stream"); - - // Derive transfer buffer size from configuration/descriptor settings. - // Use a conservative default if not defined elsewhere. - // For now, allocate based on commonly used max frame size or future Kconfig value. - // You can wire this to a Kconfig like CONFIG_UVC_MAX_FRAME_SIZE. - if (uvc_buffer_size == 0) - { - // default to 75 KiB if not set elsewhere - uvc_buffer_size = 75 * 1024; - } + // Allocate a fixed-size transfer buffer (compile-time constant) + uvc_buffer_size = UVCStreamManager::UVC_MAX_FRAMESIZE_SIZE; uvc_buffer = static_cast(malloc(uvc_buffer_size)); if (uvc_buffer == nullptr) { @@ -145,7 +136,7 @@ esp_err_t UVCStreamManager::setup() uvc_device_config_t config = { .uvc_buffer = uvc_buffer, - .uvc_buffer_size = uvc_buffer_size, + .uvc_buffer_size = UVCStreamManager::UVC_MAX_FRAMESIZE_SIZE, .start_cb = UVCStreamHelpers::camera_start_cb, .fb_get_cb = UVCStreamHelpers::camera_fb_get_cb, .fb_return_cb = UVCStreamHelpers::camera_fb_return_cb, diff --git a/components/UVCStream/UVCStream/UVCStream.hpp b/components/UVCStream/UVCStream/UVCStream.hpp index 253f29d..46ff69e 100644 --- a/components/UVCStream/UVCStream/UVCStream.hpp +++ b/components/UVCStream/UVCStream/UVCStream.hpp @@ -55,6 +55,8 @@ class UVCStreamManager uint32_t uvc_buffer_size = 0; public: + // Compile-time buffer size; keep conservative headroom for MJPEG QVGA + static constexpr uint32_t UVC_MAX_FRAMESIZE_SIZE = 75 * 1024; esp_err_t setup(); esp_err_t start(); uint32_t getUvcBufferSize() const { return uvc_buffer_size; } diff --git a/sdkconfig b/sdkconfig index e88b1e2..49a8791 100644 --- a/sdkconfig +++ b/sdkconfig @@ -514,9 +514,9 @@ CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y # CONFIG_ESPTOOLPY_NO_STUB is not set # CONFIG_ESPTOOLPY_OCT_FLASH is not set CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT=y -# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set -CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y CONFIG_ESPTOOLPY_FLASHMODE="dio" @@ -527,13 +527,13 @@ CONFIG_ESPTOOLPY_FLASHFREQ_80M=y CONFIG_ESPTOOLPY_FLASHFREQ="80m" # CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="8MB" +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -595,32 +595,32 @@ CONFIG_WIFI_AP_PASSWORD="12345678" # OpenIris: LED Configuration # CONFIG_LED_BLINK_GPIO=8 -CONFIG_LED_EXTERNAL_GPIO=9 +CONFIG_LED_EXTERNAL_GPIO=1 CONFIG_LED_EXTERNAL_CONTROL=y -CONFIG_LED_EXTERNAL_PWM_FREQ=20000 -CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=50 +CONFIG_LED_EXTERNAL_PWM_FREQ=5000 +CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100 # end of OpenIris: LED Configuration # # Camera sensor pinout configuration # -CONFIG_CAMERA_MODULE_NAME="FaceFocusVR_Face" +CONFIG_CAMERA_MODULE_NAME="SWROOM_BABBLE_S3" CONFIG_PWDN_GPIO_NUM=-1 CONFIG_RESET_GPIO_NUM=-1 -CONFIG_XCLK_GPIO_NUM=10 -CONFIG_SIOD_GPIO_NUM=40 -CONFIG_SIOC_GPIO_NUM=39 -CONFIG_Y9_GPIO_NUM=48 -CONFIG_Y8_GPIO_NUM=11 -CONFIG_Y7_GPIO_NUM=12 -CONFIG_Y6_GPIO_NUM=14 -CONFIG_Y5_GPIO_NUM=16 -CONFIG_Y4_GPIO_NUM=18 -CONFIG_Y3_GPIO_NUM=17 -CONFIG_Y2_GPIO_NUM=15 -CONFIG_VSYNC_GPIO_NUM=38 -CONFIG_HREF_GPIO_NUM=47 -CONFIG_PCLK_GPIO_NUM=13 +CONFIG_XCLK_GPIO_NUM=4 +CONFIG_SIOD_GPIO_NUM=48 +CONFIG_SIOC_GPIO_NUM=47 +CONFIG_Y9_GPIO_NUM=13 +CONFIG_Y8_GPIO_NUM=5 +CONFIG_Y7_GPIO_NUM=6 +CONFIG_Y6_GPIO_NUM=15 +CONFIG_Y5_GPIO_NUM=17 +CONFIG_Y4_GPIO_NUM=8 +CONFIG_Y3_GPIO_NUM=18 +CONFIG_Y2_GPIO_NUM=16 +CONFIG_VSYNC_GPIO_NUM=21 +CONFIG_HREF_GPIO_NUM=14 +CONFIG_PCLK_GPIO_NUM=7 # end of Camera sensor pinout configuration # @@ -1155,19 +1155,21 @@ CONFIG_SPIRAM=y # # SPI RAM config # -# CONFIG_SPIRAM_MODE_QUAD is not set -CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_MODE_QUAD=y +# CONFIG_SPIRAM_MODE_OCT is not set CONFIG_SPIRAM_TYPE_AUTO=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set # CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set CONFIG_SPIRAM_CLK_IO=30 CONFIG_SPIRAM_CS_IO=26 # CONFIG_SPIRAM_XIP_FROM_PSRAM is not set # CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set # CONFIG_SPIRAM_RODATA is not set +# CONFIG_SPIRAM_SPEED_120M is not set CONFIG_SPIRAM_SPEED_80M=y # CONFIG_SPIRAM_SPEED_40M is not set CONFIG_SPIRAM_SPEED=80 -# CONFIG_SPIRAM_ECC_ENABLE is not set CONFIG_SPIRAM_BOOT_INIT=y CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION=y # CONFIG_SPIRAM_IGNORE_NOTFOUND is not set @@ -2384,9 +2386,9 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y CONFIG_LOG_BOOTLOADER_LEVEL=3 # CONFIG_APP_ROLLBACK_ENABLE is not set # CONFIG_FLASH_ENCRYPTION_ENABLED is not set -# CONFIG_FLASHMODE_QIO is not set +CONFIG_FLASHMODE_QIO=y # CONFIG_FLASHMODE_QOUT is not set -CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DIO is not set # CONFIG_FLASHMODE_DOUT is not set CONFIG_MONITOR_BAUD=115200 # CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set From cb569c9e47f109a56031dead9e7444fb3a91bf12 Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Tue, 26 Aug 2025 01:39:40 +0200 Subject: [PATCH 19/20] 60fps Limit + GENERAL_DEFAULT_WIRED_MODE can be set in sdkconfig --- bootloader_components/boot_hooks.c | 2 +- .../CameraManager/CameraManager.cpp | 6 +- .../ProjectConfig/ProjectConfig/Models.hpp | 12 +++- components/UVCStream/UVCStream/UVCStream.cpp | 41 +++++++++++- main/Kconfig.projbuild | 6 +- main/openiris_main.cpp | 14 ++-- sdkconfig | 66 +++++++++---------- sdkconfig.base_defaults | 10 +-- sdkconfig.board.facefocusvr_eye | 2 +- sdkconfig.board.facefocusvr_face | 2 +- sdkconfig.board.project_babble | 2 +- sdkconfig.board.xiao-esp32s3 | 2 +- 12 files changed, 108 insertions(+), 57 deletions(-) diff --git a/bootloader_components/boot_hooks.c b/bootloader_components/boot_hooks.c index b13d3f8..c0d7cc2 100644 --- a/bootloader_components/boot_hooks.c +++ b/bootloader_components/boot_hooks.c @@ -1,6 +1,6 @@ // source: https://github.com/espressif/esp-iot-solution/blob/4730d91db70df7e6e0a3191d725ab1c5f98ff9ce/examples/usb/device/usb_webcam/bootloader_components/boot_hooks/boot_hooks.c -#ifdef CONFIG_GENERAL_WIRED_MODE +#ifdef CONFIG_GENERAL_DEFAULT_WIRED_MODE #include "esp_log.h" #include "soc/rtc_cntl_struct.h" #include "soc/usb_serial_jtag_reg.h" diff --git a/components/CameraManager/CameraManager/CameraManager.cpp b/components/CameraManager/CameraManager/CameraManager.cpp index a274965..8abb9ed 100644 --- a/components/CameraManager/CameraManager/CameraManager.cpp +++ b/components/CameraManager/CameraManager/CameraManager.cpp @@ -48,7 +48,7 @@ void CameraManager::setupCameraPinout() ESP_LOGI(CAMERA_MANAGER_TAG, "CAM_BOARD"); #endif -#if CONFIG_GENERAL_WIRED_MODE +#if CONFIG_GENERAL_DEFAULT_WIRED_MODE xclk_freq_hz = CONFIG_CAMERA_USB_XCLK_FREQ; #endif @@ -82,7 +82,7 @@ void CameraManager::setupCameraPinout() .jpeg_quality = 7, // 0-63, for OV series camera sensors, lower number means higher quality // Below 6 stability problems .fb_count = 2, // When jpeg mode is used, if fb_count more than one, the driver will work in continuous mode. .fb_location = CAMERA_FB_IN_DRAM, - .grab_mode = CAMERA_GRAB_WHEN_EMPTY, + .grab_mode = CAMERA_GRAB_LATEST, //CAMERA_GRAB_WHEN_EMPTY }; } @@ -196,7 +196,7 @@ bool CameraManager::setupCamera() return false; } -#if CONFIG_GENERAL_WIRED_MODE +#if CONFIG_GENERAL_DEFAULT_WIRED_MODE const auto temp_sensor = esp_camera_sensor_get(); // Thanks to lick_it, we discovered that OV5640 likes to overheat when diff --git a/components/ProjectConfig/ProjectConfig/Models.hpp b/components/ProjectConfig/ProjectConfig/Models.hpp index 4326344..8fb0d84 100644 --- a/components/ProjectConfig/ProjectConfig/Models.hpp +++ b/components/ProjectConfig/ProjectConfig/Models.hpp @@ -35,7 +35,17 @@ struct DeviceMode_t : BaseConfigModel void load() { - int stored_mode = this->pref->getInt("mode", 0); + // Default mode can be controlled via sdkconfig: + // - If CONFIG_GENERAL_DEFAULT_WIRED_MODE is enabled, default to UVC + // - Otherwise default to AUTO + int default_mode = +#if CONFIG_GENERAL_DEFAULT_WIRED_MODE + static_cast(StreamingMode::UVC); +#else + static_cast(StreamingMode::AUTO); +#endif + + int stored_mode = this->pref->getInt("mode", default_mode); this->mode = static_cast(stored_mode); ESP_LOGI("DeviceMode", "Loaded device mode: %d", stored_mode); } diff --git a/components/UVCStream/UVCStream/UVCStream.cpp b/components/UVCStream/UVCStream/UVCStream.cpp index 7b9cc61..96b2618 100644 --- a/components/UVCStream/UVCStream/UVCStream.cpp +++ b/components/UVCStream/UVCStream/UVCStream.cpp @@ -91,6 +91,31 @@ static uvc_fb_t *UVCStreamHelpers::camera_fb_get_cb(void *cb_ctx) return nullptr; } +//-------------------------------------------------------------------------------------------------------------- + // Pace frames to exactly 60 fps (drop extras). Uses fixed-point accumulator + // to achieve an exact average of 60.000 fps without drifting. + static int64_t next_deadline_us = 0; + static int rem_acc = 0; // remainder accumulator for 1e6 % fps distribution + constexpr int target_fps = 60; + constexpr int64_t us_per_sec = 1000000LL; + constexpr int base_interval_us = us_per_sec / target_fps; // 16666 + constexpr int rem_us = us_per_sec % target_fps; // 40 + + const int64_t now_us = esp_timer_get_time(); + if (next_deadline_us == 0) + { + // First frame: allow immediately and schedule next slot from now + next_deadline_us = now_us; + } + if (now_us < next_deadline_us) + { + // Too early for next frame: drop this camera buffer + esp_camera_fb_return(s_fb.cam_fb_p); + s_fb.cam_fb_p = nullptr; + return nullptr; + } +//-------------------------------------------------------------------------------------------------------------- + s_fb.uvc_fb.buf = s_fb.cam_fb_p->buf; s_fb.uvc_fb.len = s_fb.cam_fb_p->len; s_fb.uvc_fb.width = s_fb.cam_fb_p->width; @@ -105,6 +130,20 @@ static uvc_fb_t *UVCStreamHelpers::camera_fb_get_cb(void *cb_ctx) esp_camera_fb_return(s_fb.cam_fb_p); return nullptr; } + +//-------------------------------------------------------------------------------------------------------------- + // Schedule the next allowed frame time: base interval plus distributed remainder + rem_acc += rem_us; + int extra_us = 0; + if (rem_acc >= target_fps) + { + rem_acc -= target_fps; + extra_us = 1; + } + // Accumulate from the previous deadline to avoid drift; if we are badly late, catch up from now + const int64_t base_next = next_deadline_us + base_interval_us + extra_us; + next_deadline_us = (base_next < now_us) ? now_us : base_next; +//-------------------------------------------------------------------------------------------------------------- return &s_fb.uvc_fb; } @@ -119,7 +158,7 @@ static void UVCStreamHelpers::camera_fb_return_cb(uvc_fb_t *fb, void *cb_ctx) esp_err_t UVCStreamManager::setup() { -#ifndef CONFIG_GENERAL_WIRED_MODE +#ifndef CONFIG_GENERAL_DEFAULT_WIRED_MODE ESP_LOGE(UVC_STREAM_TAG, "The board does not support UVC, please, setup WiFi connection."); return ESP_FAIL; #endif diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 10b4d05..f447246 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -6,9 +6,13 @@ endmenu menu "OpenIris: General Configuration" - config GENERAL_WIRED_MODE + config GENERAL_DEFAULT_WIRED_MODE bool "Wired mode" default false + help + Enables UVC (wired) support in the firmware. When enabled, the + default device streaming mode will be UVC unless overridden by a + saved preference. When disabled, the default mode is AUTO. config GENERAL_UVC_DELAY int "UVC delay (s)" diff --git a/main/openiris_main.cpp b/main/openiris_main.cpp index 4fbfa4a..fc9900b 100644 --- a/main/openiris_main.cpp +++ b/main/openiris_main.cpp @@ -22,7 +22,7 @@ #include #include -#ifdef CONFIG_GENERAL_WIRED_MODE +#ifdef CONFIG_GENERAL_DEFAULT_WIRED_MODE #include #endif @@ -49,7 +49,7 @@ StreamServer streamServer(80, stateManager); auto *restAPI = new RestAPI("http://0.0.0.0:81", commandManager); -#ifdef CONFIG_GENERAL_WIRED_MODE +#ifdef CONFIG_GENERAL_DEFAULT_WIRED_MODE UVCStreamManager uvcStream; #endif @@ -95,7 +95,7 @@ void start_video_streaming(void *arg) if (deviceMode == StreamingMode::UVC) { -#ifdef CONFIG_GENERAL_WIRED_MODE +#ifdef CONFIG_GENERAL_DEFAULT_WIRED_MODE ESP_LOGI("[MAIN]", "Starting UVC streaming mode."); ESP_LOGI("[MAIN]", "Initializing UVC hardware..."); // If we were given the Serial task handle, stop the task and uninstall the driver @@ -120,7 +120,7 @@ void start_video_streaming(void *arg) ESP_LOGI("[MAIN]", "UVC streaming started"); return; // UVC path complete, do not fall through to WiFi #else - ESP_LOGE("[MAIN]", "UVC mode selected but the board likely does not support it."); + ESP_LOGE("[MAIN]", "UVC mode selected but the board likely does not support it."); ESP_LOGI("[MAIN]", "Falling back to WiFi mode if credentials available"); deviceMode = StreamingMode::WIFI; #endif @@ -207,12 +207,12 @@ void startup_timer_callback(void *arg) } else if (deviceMode == StreamingMode::UVC) { -#ifdef CONFIG_GENERAL_WIRED_MODE +#ifdef CONFIG_GENERAL_DEFAULT_WIRED_MODE ESP_LOGI("[MAIN]", "Starting UVC streaming automatically"); activate_streaming(serialTaskHandle); #else - ESP_LOGE("[MAIN]", "UVC mode selected but CONFIG_GENERAL_WIRED_MODE not enabled in build!"); - ESP_LOGI("[MAIN]", "Device will stay in setup mode. Enable CONFIG_GENERAL_WIRED_MODE and rebuild."); + ESP_LOGE("[MAIN]", "UVC mode selected but CONFIG_GENERAL_DEFAULT_WIRED_MODE not enabled in build!"); + ESP_LOGI("[MAIN]", "Device will stay in setup mode. Enable CONFIG_GENERAL_DEFAULT_WIRED_MODE and rebuild."); #endif } else diff --git a/sdkconfig b/sdkconfig index 49a8791..1d6d4cf 100644 --- a/sdkconfig +++ b/sdkconfig @@ -514,9 +514,9 @@ CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y # CONFIG_ESPTOOLPY_NO_STUB is not set # CONFIG_ESPTOOLPY_OCT_FLASH is not set CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT=y -CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set -# CONFIG_ESPTOOLPY_FLASHMODE_DIO is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y # CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y CONFIG_ESPTOOLPY_FLASHMODE="dio" @@ -527,13 +527,13 @@ CONFIG_ESPTOOLPY_FLASHFREQ_80M=y CONFIG_ESPTOOLPY_FLASHFREQ="80m" # CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y -# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y # CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +CONFIG_ESPTOOLPY_FLASHSIZE="8MB" # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -570,7 +570,7 @@ CONFIG_ENV_GPIO_OUT_RANGE_MAX=48 # # OpenIris: General Configuration # -CONFIG_GENERAL_WIRED_MODE=y +# CONFIG_GENERAL_DEFAULT_WIRED_MODE is not set CONFIG_GENERAL_UVC_DELAY=30 # end of OpenIris: General Configuration @@ -595,32 +595,32 @@ CONFIG_WIFI_AP_PASSWORD="12345678" # OpenIris: LED Configuration # CONFIG_LED_BLINK_GPIO=8 -CONFIG_LED_EXTERNAL_GPIO=1 +CONFIG_LED_EXTERNAL_GPIO=9 CONFIG_LED_EXTERNAL_CONTROL=y -CONFIG_LED_EXTERNAL_PWM_FREQ=5000 +CONFIG_LED_EXTERNAL_PWM_FREQ=20000 CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100 # end of OpenIris: LED Configuration # # Camera sensor pinout configuration # -CONFIG_CAMERA_MODULE_NAME="SWROOM_BABBLE_S3" +CONFIG_CAMERA_MODULE_NAME="FaceFocusVR_Face" CONFIG_PWDN_GPIO_NUM=-1 CONFIG_RESET_GPIO_NUM=-1 -CONFIG_XCLK_GPIO_NUM=4 -CONFIG_SIOD_GPIO_NUM=48 -CONFIG_SIOC_GPIO_NUM=47 -CONFIG_Y9_GPIO_NUM=13 -CONFIG_Y8_GPIO_NUM=5 -CONFIG_Y7_GPIO_NUM=6 -CONFIG_Y6_GPIO_NUM=15 -CONFIG_Y5_GPIO_NUM=17 -CONFIG_Y4_GPIO_NUM=8 -CONFIG_Y3_GPIO_NUM=18 -CONFIG_Y2_GPIO_NUM=16 -CONFIG_VSYNC_GPIO_NUM=21 -CONFIG_HREF_GPIO_NUM=14 -CONFIG_PCLK_GPIO_NUM=7 +CONFIG_XCLK_GPIO_NUM=10 +CONFIG_SIOD_GPIO_NUM=40 +CONFIG_SIOC_GPIO_NUM=39 +CONFIG_Y9_GPIO_NUM=48 +CONFIG_Y8_GPIO_NUM=11 +CONFIG_Y7_GPIO_NUM=12 +CONFIG_Y6_GPIO_NUM=14 +CONFIG_Y5_GPIO_NUM=16 +CONFIG_Y4_GPIO_NUM=18 +CONFIG_Y3_GPIO_NUM=17 +CONFIG_Y2_GPIO_NUM=15 +CONFIG_VSYNC_GPIO_NUM=38 +CONFIG_HREF_GPIO_NUM=47 +CONFIG_PCLK_GPIO_NUM=13 # end of Camera sensor pinout configuration # @@ -1155,21 +1155,19 @@ CONFIG_SPIRAM=y # # SPI RAM config # -CONFIG_SPIRAM_MODE_QUAD=y -# CONFIG_SPIRAM_MODE_OCT is not set +# CONFIG_SPIRAM_MODE_QUAD is not set +CONFIG_SPIRAM_MODE_OCT=y CONFIG_SPIRAM_TYPE_AUTO=y -# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set -# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set # CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set CONFIG_SPIRAM_CLK_IO=30 CONFIG_SPIRAM_CS_IO=26 # CONFIG_SPIRAM_XIP_FROM_PSRAM is not set # CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set # CONFIG_SPIRAM_RODATA is not set -# CONFIG_SPIRAM_SPEED_120M is not set CONFIG_SPIRAM_SPEED_80M=y # CONFIG_SPIRAM_SPEED_40M is not set CONFIG_SPIRAM_SPEED=80 +# CONFIG_SPIRAM_ECC_ENABLE is not set CONFIG_SPIRAM_BOOT_INIT=y CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION=y # CONFIG_SPIRAM_IGNORE_NOTFOUND is not set @@ -2242,7 +2240,7 @@ CONFIG_FRAMESIZE_QVGA=y # CONFIG_FRAMESIZE_SVGA is not set # CONFIG_FRAMESIZE_HD is not set # CONFIG_FRAMESIZE_FHD is not set -CONFIG_UVC_CAM1_FRAMERATE=90 +CONFIG_UVC_CAM1_FRAMERATE=60 CONFIG_UVC_CAM1_FRAMESIZE_WIDTH=240 CONFIG_UVC_CAM1_FRAMESIZE_HEIGT=240 CONFIG_UVC_CAM1_MULTI_FRAMESIZE=y @@ -2257,7 +2255,7 @@ CONFIG_UVC_CAM1_MULTI_FRAMESIZE=y # CONFIG_UVC_MULTI_FRAME_WIDTH_1=240 CONFIG_UVC_MULTI_FRAME_HEIGHT_1=240 -CONFIG_UVC_MULTI_FRAME_FPS_1=90 +CONFIG_UVC_MULTI_FRAME_FPS_1=60 # end of FRAME_SIZE_1 # @@ -2265,7 +2263,7 @@ CONFIG_UVC_MULTI_FRAME_FPS_1=90 # CONFIG_UVC_MULTI_FRAME_WIDTH_2=240 CONFIG_UVC_MULTI_FRAME_HEIGHT_2=240 -CONFIG_UVC_MULTI_FRAME_FPS_2=90 +CONFIG_UVC_MULTI_FRAME_FPS_2=60 # end of FRAME_SIZE_2 # @@ -2273,7 +2271,7 @@ CONFIG_UVC_MULTI_FRAME_FPS_2=90 # CONFIG_UVC_MULTI_FRAME_WIDTH_3=240 CONFIG_UVC_MULTI_FRAME_HEIGHT_3=240 -CONFIG_UVC_MULTI_FRAME_FPS_3=90 +CONFIG_UVC_MULTI_FRAME_FPS_3=60 # end of FRAME_SIZE_3 # end of UVC_MULTI_FRAME_CONFIG @@ -2386,9 +2384,9 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y CONFIG_LOG_BOOTLOADER_LEVEL=3 # CONFIG_APP_ROLLBACK_ENABLE is not set # CONFIG_FLASH_ENCRYPTION_ENABLED is not set -CONFIG_FLASHMODE_QIO=y +# CONFIG_FLASHMODE_QIO is not set # CONFIG_FLASHMODE_QOUT is not set -# CONFIG_FLASHMODE_DIO is not set +CONFIG_FLASHMODE_DIO=y # CONFIG_FLASHMODE_DOUT is not set CONFIG_MONITOR_BAUD=115200 # CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set diff --git a/sdkconfig.base_defaults b/sdkconfig.base_defaults index 98f6833..d624357 100644 --- a/sdkconfig.base_defaults +++ b/sdkconfig.base_defaults @@ -570,7 +570,7 @@ CONFIG_ENV_GPIO_OUT_RANGE_MAX=48 # # OpenIris: General Configuration # -# CONFIG_GENERAL_WIRED_MODE is not set +# CONFIG_GENERAL_DEFAULT_WIRED_MODE is not set # CONFIG_GENERAL_UVC_DELAY is not set # end of OpenIris: General Configuration @@ -2242,7 +2242,7 @@ CONFIG_FRAMESIZE_QVGA=y # CONFIG_FRAMESIZE_SVGA is not set # CONFIG_FRAMESIZE_HD is not set # CONFIG_FRAMESIZE_FHD is not set -CONFIG_UVC_CAM1_FRAMERATE=90 +CONFIG_UVC_CAM1_FRAMERATE=60 CONFIG_UVC_CAM1_FRAMESIZE_WIDTH=240 CONFIG_UVC_CAM1_FRAMESIZE_HEIGT=240 CONFIG_UVC_CAM1_MULTI_FRAMESIZE=y @@ -2257,7 +2257,7 @@ CONFIG_UVC_CAM1_MULTI_FRAMESIZE=y # CONFIG_UVC_MULTI_FRAME_WIDTH_1=240 CONFIG_UVC_MULTI_FRAME_HEIGHT_1=240 -CONFIG_UVC_MULTI_FRAME_FPS_1=90 +CONFIG_UVC_MULTI_FRAME_FPS_1=60 # end of FRAME_SIZE_1 # @@ -2265,7 +2265,7 @@ CONFIG_UVC_MULTI_FRAME_FPS_1=90 # CONFIG_UVC_MULTI_FRAME_WIDTH_2=240 CONFIG_UVC_MULTI_FRAME_HEIGHT_2=240 -CONFIG_UVC_MULTI_FRAME_FPS_2=90 +CONFIG_UVC_MULTI_FRAME_FPS_2=60 # end of FRAME_SIZE_2 # @@ -2273,7 +2273,7 @@ CONFIG_UVC_MULTI_FRAME_FPS_2=90 # CONFIG_UVC_MULTI_FRAME_WIDTH_3=240 CONFIG_UVC_MULTI_FRAME_HEIGHT_3=240 -CONFIG_UVC_MULTI_FRAME_FPS_3=90 +CONFIG_UVC_MULTI_FRAME_FPS_3=60 # end of FRAME_SIZE_3 # end of UVC_MULTI_FRAME_CONFIG diff --git a/sdkconfig.board.facefocusvr_eye b/sdkconfig.board.facefocusvr_eye index 0ee0a7e..0812a00 100644 --- a/sdkconfig.board.facefocusvr_eye +++ b/sdkconfig.board.facefocusvr_eye @@ -59,4 +59,4 @@ CONFIG_LED_EXTERNAL_GPIO=9 CONFIG_LED_EXTERNAL_PWM_FREQ=20000 CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=50 CONFIG_CAMERA_USB_XCLK_FREQ=23000000 -CONFIG_GENERAL_WIRED_MODE=y \ No newline at end of file +CONFIG_GENERAL_DEFAULT_WIRED_MODE=y \ No newline at end of file diff --git a/sdkconfig.board.facefocusvr_face b/sdkconfig.board.facefocusvr_face index 5006bae..54a80b2 100644 --- a/sdkconfig.board.facefocusvr_face +++ b/sdkconfig.board.facefocusvr_face @@ -59,4 +59,4 @@ CONFIG_LED_EXTERNAL_GPIO=9 CONFIG_LED_EXTERNAL_PWM_FREQ=20000 CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100 CONFIG_CAMERA_USB_XCLK_FREQ=23000000 -CONFIG_GENERAL_WIRED_MODE=y \ No newline at end of file +CONFIG_GENERAL_DEFAULT_WIRED_MODE=y \ No newline at end of file diff --git a/sdkconfig.board.project_babble b/sdkconfig.board.project_babble index 1ef150a..a598200 100644 --- a/sdkconfig.board.project_babble +++ b/sdkconfig.board.project_babble @@ -51,4 +51,4 @@ CONFIG_LED_EXTERNAL_PWM_FREQ=5000 CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100 CONFIG_LED_EXTERNAL_GPIO=1 CONFIG_CAMERA_USB_XCLK_FREQ=23000000 -CONFIG_GENERAL_WIRED_MODE=y \ No newline at end of file +# CONFIG_GENERAL_DEFAULT_WIRED_MODE is not set \ No newline at end of file diff --git a/sdkconfig.board.xiao-esp32s3 b/sdkconfig.board.xiao-esp32s3 index 8c11ad3..cec4efd 100644 --- a/sdkconfig.board.xiao-esp32s3 +++ b/sdkconfig.board.xiao-esp32s3 @@ -56,4 +56,4 @@ CONFIG_SPIRAM_SPEED=80 CONFIG_SPIRAM_SPEED_80M=y # CONFIG_LED_EXTERNAL_CONTROL is not set CONFIG_CAMERA_USB_XCLK_FREQ=23000000 -CONFIG_GENERAL_WIRED_MODE=y \ No newline at end of file +# CONFIG_GENERAL_DEFAULT_WIRED_MODE is not set \ No newline at end of file From 103475bc66459d30f1d4f864b0fcbce222e25f6b Mon Sep 17 00:00:00 2001 From: PhosphorosVR Date: Tue, 26 Aug 2025 01:41:12 +0200 Subject: [PATCH 20/20] sdkconfig for babble --- sdkconfig | 56 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/sdkconfig b/sdkconfig index 1d6d4cf..4489390 100644 --- a/sdkconfig +++ b/sdkconfig @@ -514,9 +514,9 @@ CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y # CONFIG_ESPTOOLPY_NO_STUB is not set # CONFIG_ESPTOOLPY_OCT_FLASH is not set CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT=y -# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set -CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y CONFIG_ESPTOOLPY_FLASHMODE="dio" @@ -527,13 +527,13 @@ CONFIG_ESPTOOLPY_FLASHFREQ_80M=y CONFIG_ESPTOOLPY_FLASHFREQ="80m" # CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="8MB" +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -595,32 +595,32 @@ CONFIG_WIFI_AP_PASSWORD="12345678" # OpenIris: LED Configuration # CONFIG_LED_BLINK_GPIO=8 -CONFIG_LED_EXTERNAL_GPIO=9 +CONFIG_LED_EXTERNAL_GPIO=1 CONFIG_LED_EXTERNAL_CONTROL=y -CONFIG_LED_EXTERNAL_PWM_FREQ=20000 +CONFIG_LED_EXTERNAL_PWM_FREQ=5000 CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100 # end of OpenIris: LED Configuration # # Camera sensor pinout configuration # -CONFIG_CAMERA_MODULE_NAME="FaceFocusVR_Face" +CONFIG_CAMERA_MODULE_NAME="SWROOM_BABBLE_S3" CONFIG_PWDN_GPIO_NUM=-1 CONFIG_RESET_GPIO_NUM=-1 -CONFIG_XCLK_GPIO_NUM=10 -CONFIG_SIOD_GPIO_NUM=40 -CONFIG_SIOC_GPIO_NUM=39 -CONFIG_Y9_GPIO_NUM=48 -CONFIG_Y8_GPIO_NUM=11 -CONFIG_Y7_GPIO_NUM=12 -CONFIG_Y6_GPIO_NUM=14 -CONFIG_Y5_GPIO_NUM=16 -CONFIG_Y4_GPIO_NUM=18 -CONFIG_Y3_GPIO_NUM=17 -CONFIG_Y2_GPIO_NUM=15 -CONFIG_VSYNC_GPIO_NUM=38 -CONFIG_HREF_GPIO_NUM=47 -CONFIG_PCLK_GPIO_NUM=13 +CONFIG_XCLK_GPIO_NUM=4 +CONFIG_SIOD_GPIO_NUM=48 +CONFIG_SIOC_GPIO_NUM=47 +CONFIG_Y9_GPIO_NUM=13 +CONFIG_Y8_GPIO_NUM=5 +CONFIG_Y7_GPIO_NUM=6 +CONFIG_Y6_GPIO_NUM=15 +CONFIG_Y5_GPIO_NUM=17 +CONFIG_Y4_GPIO_NUM=8 +CONFIG_Y3_GPIO_NUM=18 +CONFIG_Y2_GPIO_NUM=16 +CONFIG_VSYNC_GPIO_NUM=21 +CONFIG_HREF_GPIO_NUM=14 +CONFIG_PCLK_GPIO_NUM=7 # end of Camera sensor pinout configuration # @@ -1155,19 +1155,21 @@ CONFIG_SPIRAM=y # # SPI RAM config # -# CONFIG_SPIRAM_MODE_QUAD is not set -CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_MODE_QUAD=y +# CONFIG_SPIRAM_MODE_OCT is not set CONFIG_SPIRAM_TYPE_AUTO=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set # CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set CONFIG_SPIRAM_CLK_IO=30 CONFIG_SPIRAM_CS_IO=26 # CONFIG_SPIRAM_XIP_FROM_PSRAM is not set # CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set # CONFIG_SPIRAM_RODATA is not set +# CONFIG_SPIRAM_SPEED_120M is not set CONFIG_SPIRAM_SPEED_80M=y # CONFIG_SPIRAM_SPEED_40M is not set CONFIG_SPIRAM_SPEED=80 -# CONFIG_SPIRAM_ECC_ENABLE is not set CONFIG_SPIRAM_BOOT_INIT=y CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION=y # CONFIG_SPIRAM_IGNORE_NOTFOUND is not set @@ -2384,9 +2386,9 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y CONFIG_LOG_BOOTLOADER_LEVEL=3 # CONFIG_APP_ROLLBACK_ENABLE is not set # CONFIG_FLASH_ENCRYPTION_ENABLED is not set -# CONFIG_FLASHMODE_QIO is not set +CONFIG_FLASHMODE_QIO=y # CONFIG_FLASHMODE_QOUT is not set -CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DIO is not set # CONFIG_FLASHMODE_DOUT is not set CONFIG_MONITOR_BAUD=115200 # CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set