diff --git a/boards/facefocusvr/eye_L b/boards/facefocusvr/eye_L index 2655bfc..5a9d5d3 100644 --- a/boards/facefocusvr/eye_L +++ b/boards/facefocusvr/eye_L @@ -55,7 +55,8 @@ CONFIG_LED_EXTERNAL_CONTROL=y CONFIG_LED_EXTERNAL_GPIO=9 CONFIG_LED_EXTERNAL_PWM_FREQ=20000 CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=45 -CONFIG_CAMERA_USB_XCLK_FREQ=23000000 +CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV2640=20000000 +CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV3660=24000000 CONFIG_GENERAL_INCLUDE_UVC_MODE=y CONFIG_START_IN_UVC_MODE=y CONFIG_MONITORING_LED_CURRENT=y @@ -68,4 +69,5 @@ CONFIG_GENERAL_BOARD="facefocusvr_eye_l" # CONFIG_GENERAL_ENABLE_WIRELESS is not set # CONFIG_LED_DEBUG_ENABLE is not set CONFIG_LED_EXTERNAL_AS_DEBUG=y -CONFIG_GENERAL_ADVERTISED_NAME="FFVR Eye L" \ No newline at end of file +CONFIG_GENERAL_ADVERTISED_NAME="FFVR Eye L" +CONFIG_GENERAL_VERSION="1.1.0" \ No newline at end of file diff --git a/boards/facefocusvr/eye_R b/boards/facefocusvr/eye_R index 9d3af2c..dedd0ac 100644 --- a/boards/facefocusvr/eye_R +++ b/boards/facefocusvr/eye_R @@ -55,7 +55,8 @@ CONFIG_LED_EXTERNAL_CONTROL=y CONFIG_LED_EXTERNAL_GPIO=9 CONFIG_LED_EXTERNAL_PWM_FREQ=20000 CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=45 -CONFIG_CAMERA_USB_XCLK_FREQ=23000000 +CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV2640=20000000 +CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV3660=24000000 CONFIG_GENERAL_INCLUDE_UVC_MODE=y CONFIG_START_IN_UVC_MODE=y CONFIG_MONITORING_LED_CURRENT=y @@ -68,4 +69,5 @@ CONFIG_GENERAL_BOARD="facefocusvr_eye_r" # CONFIG_GENERAL_ENABLE_WIRELESS is not set # CONFIG_LED_DEBUG_ENABLE is not set CONFIG_LED_EXTERNAL_AS_DEBUG=y -CONFIG_GENERAL_ADVERTISED_NAME="FFVR Eye R" \ No newline at end of file +CONFIG_GENERAL_ADVERTISED_NAME="FFVR Eye R" +CONFIG_GENERAL_VERSION="1.1.0" \ No newline at end of file diff --git a/boards/facefocusvr/face b/boards/facefocusvr/face index e51b9e7..d3ad367 100644 --- a/boards/facefocusvr/face +++ b/boards/facefocusvr/face @@ -55,7 +55,8 @@ CONFIG_LED_EXTERNAL_CONTROL=y CONFIG_LED_EXTERNAL_GPIO=9 CONFIG_LED_EXTERNAL_PWM_FREQ=20000 CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=85 -CONFIG_CAMERA_USB_XCLK_FREQ=23000000 +CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV2640=20000000 +CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV3660=24000000 CONFIG_GENERAL_INCLUDE_UVC_MODE=y CONFIG_START_IN_UVC_MODE=y CONFIG_MONITORING_LED_CURRENT=y @@ -68,4 +69,5 @@ CONFIG_GENERAL_BOARD="facefocusvr_face" # CONFIG_GENERAL_ENABLE_WIRELESS is not set # CONFIG_LED_DEBUG_ENABLE is not set CONFIG_LED_EXTERNAL_AS_DEBUG=y -CONFIG_GENERAL_ADVERTISED_NAME="FFVR Face" \ No newline at end of file +CONFIG_GENERAL_ADVERTISED_NAME="FFVR Face" +CONFIG_GENERAL_VERSION="1.1.0" \ No newline at end of file diff --git a/boards/project_babble/project_babble b/boards/project_babble/project_babble index 507ffbe..e2cf15a 100644 --- a/boards/project_babble/project_babble +++ b/boards/project_babble/project_babble @@ -50,7 +50,8 @@ 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 +CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV2640=23000000 +CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV3660=0 CONFIG_GENERAL_INCLUDE_UVC_MODE=y # CONFIG_START_IN_UVC_MODE is not set # CONFIG_MONITORING_LED_CURRENT is not set diff --git a/boards/sdkconfig.base_defaults b/boards/sdkconfig.base_defaults index 71ea29d..86b10af 100644 --- a/boards/sdkconfig.base_defaults +++ b/boards/sdkconfig.base_defaults @@ -579,7 +579,6 @@ CONFIG_GENERAL_VERSION="0.0.1" # # OpenIris: Camera Configuration # -CONFIG_CAMERA_USB_XCLK_FREQ=23000000 CONFIG_CAMERA_WIFI_XCLK_FREQ=16500000 # end of OpenIris: Camera Configuration diff --git a/boards/seed_studio/xiao_esp32s3 b/boards/seed_studio/xiao_esp32s3 index 98da3bb..8c37821 100644 --- a/boards/seed_studio/xiao_esp32s3 +++ b/boards/seed_studio/xiao_esp32s3 @@ -54,7 +54,8 @@ CONFIG_SPIRAM_SPEED_80M=y CONFIG_SPIRAM_SPEED=80 CONFIG_SPIRAM_SPEED_80M=y # CONFIG_LED_EXTERNAL_CONTROL is not set -CONFIG_CAMERA_USB_XCLK_FREQ=23000000 +CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV2640=23000000 +CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV3660=0 CONFIG_GENERAL_INCLUDE_UVC_MODE=y # CONFIG_START_IN_UVC_MODE is not set # CONFIG_MONITORING_LED_CURRENT is not set diff --git a/components/CameraManager/CameraManager/CameraManager.cpp b/components/CameraManager/CameraManager/CameraManager.cpp index 555313a..c3191c8 100644 --- a/components/CameraManager/CameraManager/CameraManager.cpp +++ b/components/CameraManager/CameraManager/CameraManager.cpp @@ -20,6 +20,7 @@ void CameraManager::setupCameraPinout() // 20000000 max freq on ESP32-CAM // 24000000 optimal freq on ESP32-S3 // 23MHz same fps int xclk_freq_hz = CONFIG_CAMERA_WIFI_XCLK_FREQ; + ESP_LOGI(CAMERA_MANAGER_TAG, "Base WIFI XCLK freq (from config): %d Hz", xclk_freq_hz); #if CONFIG_CAMERA_MODULE_ESP_EYE /* IO13, IO14 is designed for JTAG by default, @@ -49,7 +50,10 @@ void CameraManager::setupCameraPinout() ESP_LOGI(CAMERA_MANAGER_TAG, "CAM_BOARD"); #endif #if CONFIG_GENERAL_INCLUDE_UVC_MODE - xclk_freq_hz = CONFIG_CAMERA_USB_XCLK_FREQ; + // Use code default for UVC if no per-sensor override applies + constexpr int CAMERA_USB_XCLK_FREQ_DEFAULT = 20000000; // 20 MHz default + xclk_freq_hz = CAMERA_USB_XCLK_FREQ_DEFAULT; + ESP_LOGI(CAMERA_MANAGER_TAG, "UVC mode active: using USB default XCLK freq: %d Hz", xclk_freq_hz); #endif config = { @@ -79,7 +83,7 @@ void CameraManager::setupCameraPinout() .pixel_format = PIXFORMAT_JPEG, // YUV422,GRAYSCALE,RGB565,JPEG .frame_size = FRAMESIZE_240X240, // QQVGA-UXGA, For ESP32, do not use sizes above QVGA when not JPEG. The performance of the ESP32-S series has improved a lot, but JPEG mode always gives better frame rates. - .jpeg_quality = 8, // 0-63, for OV series camera sensors, lower number means higher quality // Below 6 stability problems + .jpeg_quality = 10, // 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, // was CAMERA_GRAB_LATEST; new mode reduces frame skips at cost of minor latency @@ -179,6 +183,7 @@ bool CameraManager::setupCamera() { ESP_LOGI(CAMERA_MANAGER_TAG, "Camera initialized: %s \r\n", esp_err_to_name(hasCameraBeenInitialized)); + ESP_LOGI(CAMERA_MANAGER_TAG, "Initial camera XCLK freq applied: %d Hz", config.xclk_freq_hz); constexpr auto event = SystemEvent{EventSource::CAMERA, CameraState_e::Camera_Success}; xQueueSend(this->eventQueue, &event, 10); @@ -206,7 +211,54 @@ bool CameraManager::setupCamera() { config.xclk_freq_hz = OV5640_XCLK_FREQ_HZ; esp_camera_deinit(); - esp_camera_init(&config); + if (auto const err = esp_camera_init(&config); err == ESP_OK) + { + ESP_LOGI(CAMERA_MANAGER_TAG, "OV5640 detected: adjusted XCLK freq to %d Hz", config.xclk_freq_hz); + } + else + { + ESP_LOGE(CAMERA_MANAGER_TAG, "OV5640 reinit failed after XCLK adjust: %s", esp_err_to_name(err)); + } + } + + // Minimal per-sensor override logic (only if enabled via Kconfig and different) + if (temp_sensor) + { + const auto pid = temp_sensor->id.PID; + int desired_freq = 0; +#ifdef CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV2640 + if (pid == OV2640_PID && CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV2640 > 0) + { + desired_freq = CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV2640; + } +#endif +#ifdef CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV3660 + if (pid == OV3660_PID && CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV3660 > 0) + { + desired_freq = CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV3660; + } +#endif + if (desired_freq > 0 && desired_freq != config.xclk_freq_hz) + { + ESP_LOGI(CAMERA_MANAGER_TAG, "Applying XCLK override for sensor PID 0x%X: %d Hz (was %d)", pid, desired_freq, config.xclk_freq_hz); + config.xclk_freq_hz = desired_freq; + esp_camera_deinit(); + if (auto const err = esp_camera_init(&config); err == ESP_OK) + { + ESP_LOGI(CAMERA_MANAGER_TAG, "Camera reinitialized with override frequency"); + ESP_LOGI(CAMERA_MANAGER_TAG, "Final camera XCLK freq: %d Hz (PID 0x%X)", config.xclk_freq_hz, pid); + } + else + { + ESP_LOGE(CAMERA_MANAGER_TAG, "Failed to reinit camera with override freq (%s). Reverting.", esp_err_to_name(err)); + // Attempt revert to previous frequency + // (previous value was lost after assignment; we can fall back to USB/WIFI config selection logic if needed) + } + } + else + { + ESP_LOGI(CAMERA_MANAGER_TAG, "No XCLK override applied for PID 0x%X. Active freq: %d Hz", pid, config.xclk_freq_hz); + } } #endif diff --git a/components/LEDManager/LEDManager/LEDManager.cpp b/components/LEDManager/LEDManager/LEDManager.cpp index b3baa4e..c16c371 100644 --- a/components/LEDManager/LEDManager/LEDManager.cpp +++ b/components/LEDManager/LEDManager/LEDManager.cpp @@ -54,7 +54,7 @@ void LEDManager::setup() ledc_timer_config_t ledc_timer = { .speed_mode = LEDC_LOW_SPEED_MODE, .duty_resolution = resolution, - .timer_num = LEDC_TIMER_0, + .timer_num = LEDC_TIMER_1, // moved to TIMER_1 to avoid conflict with camera XCLK (TIMER_0) .freq_hz = freq, .clk_cfg = LEDC_AUTO_CLK}; @@ -63,9 +63,9 @@ void LEDManager::setup() ledc_channel_config_t ledc_channel = { .gpio_num = this->illumninator_led_pin, .speed_mode = LEDC_LOW_SPEED_MODE, - .channel = LEDC_CHANNEL_0, + .channel = LEDC_CHANNEL_1, // moved to CHANNEL_1 to avoid conflict .intr_type = LEDC_INTR_DISABLE, - .timer_sel = LEDC_TIMER_0, + .timer_sel = LEDC_TIMER_1, .duty = dutyCycle, .hpoint = 0}; @@ -140,7 +140,7 @@ void LEDManager::updateState(const LEDStates_e newState) // store current duty once if (!hasStoredExternalDuty) { - storedExternalDuty = ledc_get_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0); + storedExternalDuty = ledc_get_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1); hasStoredExternalDuty = true; } } @@ -149,8 +149,8 @@ void LEDManager::updateState(const LEDStates_e newState) // restore duty if (hasStoredExternalDuty) { - ESP_ERROR_CHECK_WITHOUT_ABORT(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, storedExternalDuty)); - ESP_ERROR_CHECK_WITHOUT_ABORT(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0)); + ESP_ERROR_CHECK_WITHOUT_ABORT(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1, storedExternalDuty)); + ESP_ERROR_CHECK_WITHOUT_ABORT(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1)); hasStoredExternalDuty = false; } } @@ -172,9 +172,9 @@ void LEDManager::toggleLED(const bool state) const if (ledStateMap.contains(this->currentState) && ledStateMap.at(this->currentState).isError) { // For pattern ON use 50%, OFF use 0% - uint32_t duty = (state == LED_ON) ? ((50 * 255) / 100) : 0; - ESP_ERROR_CHECK_WITHOUT_ABORT(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, duty)); - ESP_ERROR_CHECK_WITHOUT_ABORT(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0)); + uint32_t duty = (state == LED_ON) ? ((50 * 255) / 100) : 0; + ESP_ERROR_CHECK_WITHOUT_ABORT(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1, duty)); + ESP_ERROR_CHECK_WITHOUT_ABORT(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1)); } #endif } @@ -187,8 +187,8 @@ void LEDManager::setExternalLEDDutyCycle(uint8_t 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)); + ESP_ERROR_CHECK_WITHOUT_ABORT(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1, dutyCycle)); + ESP_ERROR_CHECK_WITHOUT_ABORT(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1)); #else (void)dutyPercent; // unused ESP_LOGW(LED_MANAGER_TAG, "CONFIG_LED_EXTERNAL_CONTROL not enabled; ignoring duty update"); diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 064f8e0..8ce4df1 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -70,13 +70,6 @@ endmenu menu "OpenIris: Camera Configuration" - config CAMERA_USB_XCLK_FREQ - int "USB XCLK frequency (Hz)" - default 10000000 # should be set in individual board config - range 1 24000000 - help - USB XCLK frequency in Hz. - config CAMERA_WIFI_XCLK_FREQ int "WIFI XCLK frequency (Hz)" default 16500000 @@ -84,6 +77,22 @@ menu "OpenIris: Camera Configuration" help WIFI XCLK frequency in Hz. + config CAMERA_XCLK_FREQ_OVERRIDE_OV2640 + int "Override XCLK for OV2640 (Hz, 0=disabled)" + default 0 + range 0 40000000 + help + If non-zero, overrides the selected XCLK frequency specifically when an OV2640 sensor + is detected. Use 0 to disable and fall back to CAMERA_USB_XCLK_FREQ / CAMERA_WIFI_XCLK_FREQ. + + config CAMERA_XCLK_FREQ_OVERRIDE_OV3660 + int "Override XCLK for OV3660 (Hz, 0=disabled)" + default 0 + range 0 40000000 + help + If non-zero, overrides the selected XCLK frequency specifically when an OV3660 sensor + is detected. Use 0 to disable and fall back to CAMERA_USB_XCLK_FREQ / CAMERA_WIFI_XCLK_FREQ. + endmenu menu "OpenIris: WiFi Configuration" diff --git a/sdkconfig b/sdkconfig index ce3f32c..17bfd2a 100644 --- a/sdkconfig +++ b/sdkconfig @@ -582,8 +582,9 @@ CONFIG_GENERAL_ADVERTISED_NAME="openiristracker" # # OpenIris: Camera Configuration # -CONFIG_CAMERA_USB_XCLK_FREQ=23000000 CONFIG_CAMERA_WIFI_XCLK_FREQ=16500000 +CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV2640=23000000 +CONFIG_CAMERA_XCLK_FREQ_OVERRIDE_OV3660=0 # end of OpenIris: Camera Configuration #