diff --git a/components/UVCStream/UVCStream/UVCStream.cpp b/components/UVCStream/UVCStream/UVCStream.cpp index ffc370c..f97db5f 100644 --- a/components/UVCStream/UVCStream/UVCStream.cpp +++ b/components/UVCStream/UVCStream/UVCStream.cpp @@ -3,6 +3,30 @@ constexpr int UVC_MAX_FRAMESIZE_SIZE(75 * 1024); static const char *UVC_STREAM_TAG = "[UVC DEVICE]"; +extern "C" { + static char serial_number_str[13]; + + const char *get_uvc_device_name() { + return deviceConfig->getMDNSConfig().hostname.c_str(); + } + + const char *get_serial_number(void) { + if (serial_number_str[0] == '\0') { + uint8_t mac_address[6]; + esp_err_t result = esp_efuse_mac_get_default(mac_address); + if (result != ESP_OK) { + ESP_LOGE(UVC_STREAM_TAG, "Failed to get MAC address of the board, returning default serial number"); + 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] + ); + } + return serial_number_str; + } +} + static esp_err_t UVCStreamHelpers::camera_start_cb(uvc_format_t format, int width, int height, int rate, void *cb_ctx) { (void)cb_ctx; diff --git a/components/UVCStream/UVCStream/UVCStream.hpp b/components/UVCStream/UVCStream/UVCStream.hpp index 34a4d92..614972b 100644 --- a/components/UVCStream/UVCStream/UVCStream.hpp +++ b/components/UVCStream/UVCStream/UVCStream.hpp @@ -2,6 +2,7 @@ #ifndef UVCSTREAM_HPP #define UVCSTREAM_HPP #include "esp_timer.h" +#include "esp_mac.h" #include "esp_camera.h" #include #include @@ -13,6 +14,18 @@ // we need access to the camera manager // in order to update the frame settings extern std::shared_ptr cameraHandler; +extern std::shared_ptr deviceConfig; + +#ifdef __cplusplus +extern "C" { +#endif + + const char *get_uvc_device_name(); + const char *get_serial_number(void); + +#ifdef __cplusplus +} +#endif // we also need a way to inform the rest of the system of what's happening extern QueueHandle_t eventQueue; diff --git a/components/usb_device_uvc/CMakeLists.txt b/components/usb_device_uvc/CMakeLists.txt new file mode 100644 index 0000000..08ce8e6 --- /dev/null +++ b/components/usb_device_uvc/CMakeLists.txt @@ -0,0 +1,11 @@ +idf_component_register(SRCS usb_device_uvc.c + INCLUDE_DIRS "include" + REQUIRES usb esp_timer) + +idf_component_get_property(tusb_lib espressif__tinyusb COMPONENT_LIB) + +target_include_directories(${tusb_lib} PUBLIC "${COMPONENT_DIR}/tusb") +target_sources(${tusb_lib} PUBLIC "${COMPONENT_DIR}/tusb/usb_descriptors.c") + +include(package_manager) +cu_pkg_define_version(${CMAKE_CURRENT_LIST_DIR}) diff --git a/components/usb_device_uvc/Kconfig b/components/usb_device_uvc/Kconfig new file mode 100644 index 0000000..2025c79 --- /dev/null +++ b/components/usb_device_uvc/Kconfig @@ -0,0 +1,265 @@ +menu "USB Device UVC" + + config TUSB_VID + hex "USB Device VID" + default 0x303A + config TUSB_PID + hex "USB Device PID" + default 0x8000 + config TUSB_MANUFACTURER + string "USB Device Manufacture" + default "Espressif" + config TUSB_PRODUCT + string "Product Name" + default "ESP UVC Device" + config TUSB_SERIAL_NUM + string "Product ID" + default "12345678" + + config UVC_SUPPORT_TWO_CAM + bool "Support two cameras" + default n + help + If enable, support two cameras + + choice TINYUSB_RHPORT + depends on IDF_TARGET_ESP32P4 + prompt "TinyUSB PHY" + default TINYUSB_RHPORT_HS + help + Allows set the USB PHY Controller for TinyUSB: HS (USB OTG2.0 PHY for HighSpeed) + + config TINYUSB_RHPORT_HS + bool "HS" + endchoice + + menu "USB Cam1 Config" + + choice UVC_CAM1_FORMAT + bool "UVC Cam1 Format" + default FORMAT_MJPEG_CAM1 + config FORMAT_MJPEG_CAM1 + bool "MJPEG" + config FORMAT_H264_CAM1 + bool "H264" + config FORMAT_UNCOMPR_CAM1 + bool "uncompressed" + endchoice + + choice UVC_CAM1_XFER_MODE + bool "UVC cam1 transfer mode" + default UVC_MODE_ISOC_CAM1 + config UVC_MODE_ISOC_CAM1 + bool "Isochronous" + config UVC_MODE_BULK_CAM1 + bool "Bulk" + endchoice + + choice UVC_CAM1_FRAMESIZE + bool "UVC Default Resolution" + default FRAMESIZE_HD + config FRAMESIZE_QVGA + bool "QVGA 320x240" + config FRAMESIZE_HVGA + bool "HVGA 480x320" + config FRAMESIZE_VGA + bool "VGA 640x480" + config FRAMESIZE_SVGA + bool "SVGA 800x600" + config FRAMESIZE_HD + bool "HD 1280x720" + config FRAMESIZE_FHD + bool "FHD 1920x1080" + endchoice + + config UVC_CAM1_FRAMERATE + int "Frame Rate (FPS)" + default 30 if FRAMESIZE_QVGA + default 30 if FRAMESIZE_HVGA + default 15 if FRAMESIZE_VGA + default 15 if FRAMESIZE_SVGA + default 15 if FRAMESIZE_HD + default 15 if FRAMESIZE_FHD + + config UVC_CAM1_FRAMESIZE_WIDTH + int "Cam1 Frame Width" + default 320 if FRAMESIZE_QVGA + default 480 if FRAMESIZE_HVGA + default 640 if FRAMESIZE_VGA + default 800 if FRAMESIZE_SVGA + default 1280 if FRAMESIZE_HD + default 1920 if FRAMESIZE_FHD + + config UVC_CAM1_FRAMESIZE_HEIGT + int "Cam1 Frame Height" + default 240 if FRAMESIZE_QVGA + default 320 if FRAMESIZE_HVGA + default 480 if FRAMESIZE_VGA + default 600 if FRAMESIZE_SVGA + default 720 if FRAMESIZE_HD + default 1080 if FRAMESIZE_FHD + + config UVC_CAM1_MULTI_FRAMESIZE + bool "Enable cam1 multiple frames sizes" + default y + help + If enable, add VGA and HVGA to list + endmenu + + menu "USB Cam2 Config" + depends on UVC_SUPPORT_TWO_CAM + + choice UVC_CAM2_FORMAT + bool "UVC Cam2 Format" + default FORMAT_MJPEG_CAM2 + config FORMAT_MJPEG_CAM2 + bool "MJPEG" + config FORMAT_H264_CAM2 + bool "H264" + config FORMAT_UNCOMPR_CAM2 + bool "uncompressed" + endchoice + + choice UVC_CAM2_XFER_MODE + bool "UVC cam2 transfer mode" + default UVC_MODE_ISOC_CAM2 + config UVC_MODE_ISOC_CAM2 + bool "Isochronous" + config UVC_MODE_BULK_CAM2 + bool "Bulk" + endchoice + + choice UVC_CAM2_FRAMESIZE + bool "UVC Default Resolution" + default FRAMESIZE_HD_2 + config FRAMESIZE_QVGA_2 + bool "QVGA 320x240" + config FRAMESIZE_HVGA_2 + bool "HVGA 480x320" + config FRAMESIZE_VGA_2 + bool "VGA 640x480" + config FRAMESIZE_SVGA_2 + bool "SVGA 800x600" + config FRAMESIZE_HD_2 + bool "HD 1280x720" + config FRAMESIZE_FHD_2 + bool "FHD 1920x1080" + endchoice + + config UVC_CAM2_FRAMERATE + int "Frame Rate (FPS)" + default 30 if FRAMESIZE_QVGA_2 + default 30 if FRAMESIZE_HVGA_2 + default 15 if FRAMESIZE_VGA_2 + default 15 if FRAMESIZE_SVGA_2 + default 15 if FRAMESIZE_HD_2 + default 15 if FRAMESIZE_FHD_2 + + config UVC_CAM2_FRAMESIZE_WIDTH + int "Cam2 Frame Width" + default 320 if FRAMESIZE_QVGA_2 + default 480 if FRAMESIZE_HVGA_2 + default 640 if FRAMESIZE_VGA_2 + default 800 if FRAMESIZE_SVGA_2 + default 1280 if FRAMESIZE_HD_2 + default 1920 if FRAMESIZE_FHD_2 + + config UVC_CAM2_FRAMESIZE_HEIGT + int "Cam2 Frame Height" + default 240 if FRAMESIZE_QVGA_2 + default 320 if FRAMESIZE_HVGA_2 + default 480 if FRAMESIZE_VGA_2 + default 600 if FRAMESIZE_SVGA_2 + default 720 if FRAMESIZE_HD_2 + default 1080 if FRAMESIZE_FHD_2 + + + config UVC_CAM2_MULTI_FRAMESIZE + bool "Enable cam2 multiple frames sizes" + default y + help + If enable, add VGA and HVGA to list + + endmenu + + menu "UVC_MULTI_FRAME_CONFIG" + + menu "FRAME_SIZE_1" + config UVC_MULTI_FRAME_WIDTH_1 + int "Enable Multi Frame Size 1" + default 640 + + config UVC_MULTI_FRAME_HEIGHT_1 + int "Enable Multi Frame Size 1" + default 480 + + config UVC_MULTI_FRAME_FPS_1 + int "Enable Multi Frame Size 1" + default 15 + endmenu + + menu "FRAME_SIZE_2" + config UVC_MULTI_FRAME_WIDTH_2 + int "Enable Multi Frame Size 2" + default 480 + + config UVC_MULTI_FRAME_HEIGHT_2 + int "Enable Multi Frame Size 2" + default 320 + + config UVC_MULTI_FRAME_FPS_2 + int "Enable Multi Frame Size 2" + default 30 + endmenu + + menu "FRAME_SIZE_3" + config UVC_MULTI_FRAME_WIDTH_3 + int "Enable Multi Frame Size 3" + default 320 + + config UVC_MULTI_FRAME_HEIGHT_3 + int "Enable Multi Frame Size 3" + default 240 + + config UVC_MULTI_FRAME_FPS_3 + int "Enable Multi Frame Size 3" + default 30 + endmenu + + endmenu + + menu "UVC Task Config" + config UVC_TINYUSB_TASK_PRIORITY + int "Tinyusb task priority" + default 5 + range 1 15 + + config UVC_TINYUSB_TASK_CORE + int "Tinyusb task core" + default -1 + range -1 1 + + config UVC_CAM1_TASK_PRIORITY + int "Cam1 task priority" + default 4 + range 1 15 + + config UVC_CAM1_TASK_CORE + int "Cam1 task core" + default -1 + range -1 1 + + config UVC_CAM2_TASK_PRIORITY + int "Cam2 task priority" + default 4 + range 1 15 + depends on UVC_SUPPORT_TWO_CAM + + config UVC_CAM2_TASK_CORE + int "Cam2 task core" + default -1 + range -1 1 + depends on UVC_SUPPORT_TWO_CAM + endmenu + +endmenu diff --git a/components/usb_device_uvc/README.md b/components/usb_device_uvc/README.md new file mode 100644 index 0000000..01707c3 --- /dev/null +++ b/components/usb_device_uvc/README.md @@ -0,0 +1,23 @@ +[![Component Registry](https://components.espressif.com/components/espressif/usb_device_uvc/badge.svg)](https://components.espressif.com/components/espressif/usb_device_uvc) +# NOTE. This is a modified version of the original esp-idf component, suited to our needs. +## USB Device UVC Component + +`usb_device_uvc` is a USB `UVC` device driver for ESP32-S2/ESP32-S3, which supports streaming JPEG frames to the USB Host. User can wrapper the Camera or any devices as a UVC standard device through the callback functions. + +Features: + +1. Support video stream through the UVC Stream interface +2. Support both isochronous and bulk mode +2. Support multiple resolutions and frame rates + +### Add component to your project + +Please use the component manager command `add-dependency` to add the `usb_device_uvc` to your project's dependency, during the `CMake` step the component will be downloaded automatically + +``` +idf.py add-dependency "espressif/usb_device_uvc=*" +``` + +### Examples + +* [USB WebCamera: Make ESP32-S3-EYE as a USB Camera Device](https://github.com/espressif/esp-iot-solution/tree/master/examples/usb/device/usb_webcam) diff --git a/components/usb_device_uvc/idf_component.yml b/components/usb_device_uvc/idf_component.yml new file mode 100644 index 0000000..4456f24 --- /dev/null +++ b/components/usb_device_uvc/idf_component.yml @@ -0,0 +1,20 @@ +dependencies: + cmake_utilities: + version: '*' + espressif/tinyusb: + version: '>=0.15.0~10' + idf: + version: '>=5.0' +description: USB Device UVC, Streaming Video to Host +documentation: https://docs.espressif.com/projects/esp-iot-solution/en/latest/usb/usb_device/usb_device_uvc.html +issues: https://github.com/espressif/esp-iot-solution/issues +repository: git://github.com/espressif/esp-iot-solution.git +repository_info: + commit_sha: e2529ce3b0aa6362663b4c53d7e9ba21ff307f49 + path: components/usb/usb_device_uvc +targets: +- esp32s2 +- esp32s3 +- esp32p4 +url: https://github.com/espressif/esp-iot-solution/tree/master/components/usb/usb_device_uvc +version: 1.1.0 diff --git a/components/usb_device_uvc/include/usb_device_uvc.h b/components/usb_device_uvc/include/usb_device_uvc.h new file mode 100644 index 0000000..eec9aa5 --- /dev/null +++ b/components/usb_device_uvc/include/usb_device_uvc.h @@ -0,0 +1,100 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief UVC format + */ +typedef enum { + UVC_FORMAT_JPEG, /*!< JPEG format */ + UVC_FORMAT_H264, /*!< H264 format */ +} uvc_format_t; + +/** + * @brief Frame buffer structure + */ +typedef struct { + uint8_t *buf; /*!< Pointer to the frame data */ + size_t len; /*!< Length of the buffer in bytes */ + size_t width; /*!< Width of the image frame in pixels */ + size_t height; /*!< Height of the image frame in pixels */ + uvc_format_t format; /*!< Format of the frame data */ + struct timeval timestamp; /*!< Timestamp since boot of the frame */ +} uvc_fb_t; + +/** + * @brief type of callback function when host open the UVC device + */ +typedef esp_err_t (*uvc_input_start_cb_t)(uvc_format_t format, int width, int height, int rate, void *cb_ctx); + +/** + * @brief type of callback function when host request a new frame buffer + */ +typedef uvc_fb_t* (*uvc_input_fb_get_cb_t)(void *cb_ctx); + +/** + * @brief type of callback function when the frame buffer is no longer used + */ +typedef void (*uvc_input_fb_return_cb_t)(uvc_fb_t *fb, void *cb_ctx); + +/** + * @brief type of callback function when host close the UVC device + */ +typedef void (*uvc_input_stop_cb_t)(void *cb_ctx); + +/** + * @brief Configuration for the UVC device + */ +typedef struct { + uint8_t *uvc_buffer; /*!< UVC transfer buffer */ + uint32_t uvc_buffer_size; /*!< UVC transfer buffer size, should bigger than one frame size */ + uvc_input_start_cb_t start_cb; /*!< callback function of host open the UVC device with the specific format and resolution */ + uvc_input_fb_get_cb_t fb_get_cb; /*!< callback function of host request a new frame buffer */ + uvc_input_fb_return_cb_t fb_return_cb; /*!< callback function of the frame buffer is no longer used */ + uvc_input_stop_cb_t stop_cb; /*!< callback function of host close the UVC device */ + void *cb_ctx; /*!< callback context, for user specific usage */ +} uvc_device_config_t; + +/** + * @brief Configure the UVC device by uvc device number + * + * @param index UVC device index number [0,1] + * @param config Configuration for the UVC device + * @return ESP_OK on success + * ESP_ERR_INVALID_ARG if the configuration is invalid + * ESP_FAIL if the UVC device could not be initialized + */ +esp_err_t uvc_device_config(int index, uvc_device_config_t *config); + +/** + * @brief Initialize the UVC device, after this function is called, the UVC device will be visible to the host + * and the host can open the UVC device with the specific format and resolution. + * + * @return ESP_OK on success + * ESP_FAIL if the UVC device could not be initialized + */ +esp_err_t uvc_device_init(void); + +/** + * @brief Deinitialize the UVC device + * @note This function is not implemented yet because tinyusb does not support deinitialization + * @return ESP_OK on success + * ESP_FAIL if the UVC device could not be deinitialized + */ +//esp_err_t uvc_device_deinit(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/usb_device_uvc/license.txt b/components/usb_device_uvc/license.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/components/usb_device_uvc/license.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/components/usb_device_uvc/tusb/tusb_config.h b/components/usb_device_uvc/tusb/tusb_config.h new file mode 100644 index 0000000..41aa694 --- /dev/null +++ b/components/usb_device_uvc/tusb/tusb_config.h @@ -0,0 +1,155 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * 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. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#include "uvc_frame_config.h" +#ifdef __cplusplus +extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Board Specific Configuration +//--------------------------------------------------------------------+ + +#ifdef CONFIG_TINYUSB_RHPORT_HS +# define CFG_TUSB_RHPORT1_MODE OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED +#else +# define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE | OPT_MODE_FULL_SPEED +#endif + +//-------------------------------------------------------------------- +// Common Configuration +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU +#error CFG_TUSB_MCU must be defined +#endif + +#ifndef ESP_PLATFORM +#define ESP_PLATFORM 1 +#endif + +#ifndef CFG_TUSB_OS +#define CFG_TUSB_OS OPT_OS_FREERTOS +#endif + +// Espressif IDF requires "freertos/" prefix in include path +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_ESP32P4) +#define CFG_TUSB_OS_INC_PATH freertos/ +#endif + +#ifndef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG 0 +#endif + +// Enable Device stack +#define CFG_TUD_ENABLED 1 + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 +#endif + +//------------- CLASS -------------// + +// The number of video control interfaces +// The number of video streaming interfaces +#if CONFIG_UVC_SUPPORT_TWO_CAM +#define CFG_TUD_VIDEO 2 +#define CFG_TUD_VIDEO_STREAMING 2 +#else +#define CFG_TUD_VIDEO 1 +#define CFG_TUD_VIDEO_STREAMING 1 +#endif + +// video streaming endpoint size +#ifdef UVC_CAM1_BULK_MODE +#if CONFIG_TINYUSB_RHPORT_HS +#define CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE 512 +#else +#define CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE 64 +#endif +#define CFG_TUD_CAM1_VIDEO_STREAMING_BULK 1 +#else +#define CFG_TUD_CAM1_VIDEO_STREAMING_BULK 0 +#if CONFIG_TINYUSB_RHPORT_HS +#define CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE 1023 +#else +#define CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE 512 +#endif +#endif + +#define CFG_EXAMPLE_VIDEO_DISABLE_MJPEG (!FORMAT_MJPEG) + +#if CONFIG_UVC_SUPPORT_TWO_CAM +#ifdef UVC_CAM2_BULK_MODE +#if CONFIG_TINYUSB_RHPORT_HS +#define CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE 512 +#else +#define CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE 64 +#endif +#define CFG_TUD_CAM2_VIDEO_STREAMING_BULK 1 +#else +#define CFG_TUD_CAM2_VIDEO_STREAMING_BULK 0 +#if CONFIG_TINYUSB_RHPORT_HS +#define CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE 1023 +#else +#define CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE 512 +#endif +#endif +#endif + +#if CONFIG_UVC_SUPPORT_TWO_CAM +#define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE (CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE > CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE?CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE:CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE) +#else +#define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/components/usb_device_uvc/tusb/usb_descriptors.c b/components/usb_device_uvc/tusb/usb_descriptors.c new file mode 100644 index 0000000..0b1f0a4 --- /dev/null +++ b/components/usb_device_uvc/tusb/usb_descriptors.c @@ -0,0 +1,343 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2023 Espressif + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * 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. + * + */ + +#include "tusb.h" +#include "usb_descriptors.h" + +//--------------------------------------------------------------------+ +// Device Descriptors +//--------------------------------------------------------------------+ +tusb_desc_device_t const desc_device = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + + // Use Interface Association Descriptor (IAD) for Video + // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = CONFIG_TUSB_VID, + .idProduct = CONFIG_TUSB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01}; + +// Invoked when received GET DEVICE DESCRIPTOR +// Application return pointer to descriptor +uint8_t const *tud_descriptor_device_cb(void) +{ + return (uint8_t const *)&desc_device; +} + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ +#if CFG_TUD_CAM1_VIDEO_STREAMING_BULK + +#if CONFIG_UVC_CAM1_MULTI_FRAMESIZE +#if CONFIG_FORMAT_MJPEG_CAM1 +#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MULTI_MJPEG_BULK_LEN(4)) +#elif CONFIG_FORMAT_H264_CAM1 +#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MULTI_FRAME_BASED_BULK_LEN(4)) +#endif +#else +#if CONFIG_FORMAT_MJPEG_CAM1 +#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MJPEG_BULK_LEN) +#elif CONFIG_FORMAT_H264_CAM1 +#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_FRAME_BASED_BULK_LEN) +#else +#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_UNCOMPR_BULK_LEN) +#endif +#endif // CONFIG_UVC_CAM1_MULTI_FRAMESIZE + +#else + +#if CONFIG_UVC_CAM1_MULTI_FRAMESIZE +#if CONFIG_FORMAT_MJPEG_CAM1 +#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MULTI_MJPEG_LEN(4)) +#elif CONFIG_FORMAT_H264_CAM1 +#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MULTI_FRAME_BASED_LEN(4)) +#endif +#else +#if CONFIG_FORMAT_MJPEG_CAM1 +#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN) +#elif CONFIG_FORMAT_H264_CAM1 +#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_FRAME_BASED_LEN) +#else +#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN) +#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 +#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 + 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), +#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), +#endif +#else +#if CONFIG_FORMAT_MJPEG_CAM1 + TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(4, 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, + 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, + 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 +#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), +#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), +#endif +#else +#if CONFIG_FORMAT_MJPEG_CAM1 + TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(4, 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, + 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, + 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 +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const *tud_descriptor_configuration_cb(uint8_t index) +{ + (void)index; // for multiple configurations + + return desc_fs_configuration; +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +// array of pointer to string descriptors +char const *string_desc_arr[] = { + (const char[]){0x09, 0x04}, // 0: is supported language is 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 +}; + +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 + 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 + return CONFIG_TUSB_SERIAL_NUM; +} + +// Invoked when received GET STRING DESCRIPTOR request +// 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; + + if (index == 0) + { + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + } + else + { + // 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]))) + { + return NULL; + } + + const char *str = string_desc_arr[index]; + if (index == 3) + str = get_serial_number(); + if (index == 4) + str = get_uvc_device_name(); + if (str == NULL) + str = string_desc_arr[index]; + + // Cap at max char + chr_count = (uint8_t)strlen(str); + if (chr_count > 31) + { + chr_count = 31; + } + + // Convert ASCII string into UTF-16 + for (uint8_t i = 0; i < chr_count; i++) + { + _desc_str[1 + i] = str[i]; + } + } + + // first byte is length (including header), second byte is string type + _desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); + + return _desc_str; +} diff --git a/components/usb_device_uvc/tusb/usb_descriptors.h b/components/usb_device_uvc/tusb/usb_descriptors.h new file mode 100644 index 0000000..42574cb --- /dev/null +++ b/components/usb_device_uvc/tusb/usb_descriptors.h @@ -0,0 +1,620 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Jerzy Kasenbreg + * Copyright (c) 2021 Koji KITAYAMA + * Copyright (c) 2023 Espressif + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * 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. + * + */ + +#ifndef _USB_DESCRIPTORS_H_ +#define _USB_DESCRIPTORS_H_ + +#include "uvc_frame_config.h" +/* Time stamp base clock. It is a deprecated parameter. */ +#define UVC_CLOCK_FREQUENCY 27000000 +/* video capture path */ +#define UVC_ENTITY_CAP_INPUT_TERMINAL 0x01 +#define UVC_ENTITY_CAP_OUTPUT_TERMINAL 0x02 + +enum { +#if (CFG_TUD_VIDEO) + ITF_NUM_VIDEO_CONTROL, + ITF_NUM_VIDEO_STREAMING, +#if CONFIG_UVC_SUPPORT_TWO_CAM + ITF_NUM_VIDEO_CONTROL_2, + ITF_NUM_VIDEO_STREAMING_2, +#endif +#endif + ITF_NUM_TOTAL +}; + +#if (CFG_TUD_VIDEO) +#define TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + /* Interface 1, Alternate 1 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + 7/* Endpoint */\ + ) + +#define TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + /* Interface 1, Alternate 1 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + 7/* Endpoint */\ + ) + +#define TUD_VIDEO_CAPTURE_DESC_MULTI_MJPEG_LEN(n) (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + + (n*TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN)\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + /* Interface 1, Alternate 1 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + 7/* Endpoint */\ + ) + +#define TUD_VIDEO_CAPTURE_DESC_UNCOMPR_BULK_LEN (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + + 7/* Endpoint */\ + ) + +#define TUD_VIDEO_CAPTURE_DESC_MJPEG_BULK_LEN (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + + 7/* Endpoint */\ + ) + +#define TUD_VIDEO_CAPTURE_DESC_MULTI_MJPEG_BULK_LEN(n) (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + + (n*TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN)\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + + 7/* Endpoint */\ + ) + +#define TUD_VIDEO_CAPTURE_DESC_MULTI_FRAME_BASED_BULK_LEN(n) (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN\ + + (n*TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN)\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + + 7/* Endpoint */\ + ) + +#define TUD_VIDEO_CAPTURE_DESC_FRAME_BASED_BULK_LEN (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + + 7/* Endpoint */\ + ) + +#define TUD_VIDEO_CAPTURE_DESC_FRAME_BASED_LEN (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + /* Interface 1, Alternate 1 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + 7/* Endpoint */\ + ) + +#define TUD_VIDEO_CAPTURE_DESC_MULTI_FRAME_BASED_LEN(n) (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN\ + + (n*TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN)\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + /* Interface 1, Alternate 1 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + 7/* Endpoint */\ + ) + +/* Windows support YUY2 and NV12 + * https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/usb-video-class-driver-overview */ + +#define TUD_VIDEO_DESC_CS_VS_FMT_YUY2(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_YUY2, 16, _frmidx, _asrx, _asry, _interlace, _cp) +#define TUD_VIDEO_DESC_CS_VS_FMT_NV12(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_NV12, 12, _frmidx, _asrx, _asry, _interlace, _cp) +#define TUD_VIDEO_DESC_CS_VS_FMT_M420(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_M420, 12, _frmidx, _asrx, _asry, _interlace, _cp) +#define TUD_VIDEO_DESC_CS_VS_FMT_I420(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_I420, 12, _frmidx, _asrx, _asry, _interlace, _cp) + +#define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(bCamIndex ,bFrameIndex) \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(bFrameIndex, 0, UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].width, UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].height, \ + UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].width * UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].height * 16, UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].width * UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].height * 16 * UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate, \ + UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].width * UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].height * 16 / 8, \ + (10000000/UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate), (10000000/UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate), (10000000/UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate), (10000000/UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate)) + +#define TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(bCamIndex ,bFrameIndex) \ + TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT(bFrameIndex, 0, UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].width, UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].height, \ + UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].width * UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].height * 16, UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].width * UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].height * 16 * UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate, \ + (10000000/UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate), /*bytesPreLine*/ 0, (10000000/UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate), (10000000/UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate), (10000000/UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate)) + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(_stridx, _itf,_epin, _width, _height, _fps, _epsize) \ + TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \ + TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ + /* wTotalLength - bLength */ \ + TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ + UVC_CLOCK_FREQUENCY, _itf + 1), \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ + /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ + /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 0, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */\ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_YUY2(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ + /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ + _width * _height * 16, _width * _height * 16 * _fps, \ + _width * _height * 16, \ + (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + /* VS alt 1 */\ + TUD_VIDEO_DESC_STD_VS(_itf + 1, 1, 1, _stridx), \ + /* EP */ \ + TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1) + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(_stridx, _itf, _epin, _width, _height, _fps, _epsize) \ + TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \ + TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ + /* wTotalLength - bLength */ \ + TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ + UVC_CLOCK_FREQUENCY, _itf + 1), \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ + /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ + /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 0, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */\ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ + /*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \ + _width * _height * 16, _width * _height * 16 * _fps, \ + _width * _height * 16 / 8, \ + (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + /* VS alt 1 */\ + TUD_VIDEO_DESC_STD_VS(_itf + 1, 1, 1, _stridx), \ + /* EP */ \ + TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1) + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_MJPEG(_stridx, _itf, _epin, _epsize) \ + TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \ + TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ + /* wTotalLength - bLength */ \ + TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ + UVC_CLOCK_FREQUENCY, _itf + 1), \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ + /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ + /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 0, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */\ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + + (UVC_FRAME_NUM*TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN)\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/UVC_FRAME_NUM, \ + /*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(_itf/2, 1), \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(_itf/2, 2), \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(_itf/2, 3), \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(_itf/2, 4), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + /* VS alt 1 */\ + TUD_VIDEO_DESC_STD_VS(_itf + 1, 1, 1, _stridx), \ + /* EP */ \ + TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1) + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(_stridx, _itf, _epin, _width, _height, _fps, _epsize) \ + TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \ + TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ + /* wTotalLength - bLength */ \ + TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ + UVC_CLOCK_FREQUENCY, _itf + 1), \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ + /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ + /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 1, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */\ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_YUY2(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ + /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ + _width * _height * 16, _width * _height * 16 * _fps, \ + _width * _height * 16, \ + (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1) + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(_stridx, _itf, _epin, _width, _height, _fps, _epsize) \ + TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \ + TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ + /* wTotalLength - bLength */ \ + TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ + UVC_CLOCK_FREQUENCY, _itf + 1), \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ + /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ + /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 1, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */\ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ + /*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \ + _width * _height * 16, _width * _height * 16 * _fps, \ + _width * _height * 16 / 8, \ + (10000000/_fps), (10000000/_fps), (10000000/_fps), (10000000/_fps)), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + /* EP */ \ + TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1) + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_MJPEG_BULK(_stridx, _itf, _epin, _epsize) \ + TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \ + TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ + /* wTotalLength - bLength */ \ + TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ + UVC_CLOCK_FREQUENCY, _itf + 1), \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ + /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ + /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 1, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */\ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + + (UVC_FRAME_NUM*TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN)\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/UVC_FRAME_NUM, \ + /*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(_itf/2, 1), \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(_itf/2, 2), \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(_itf/2, 3), \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(_itf/2, 4), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + /* EP */ \ + TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1) + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_H264(_stridx, _itf, _epin, _width, _height, _fps, _epsize) \ + TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \ + TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ + /* wTotalLength - bLength */ \ + TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ + UVC_CLOCK_FREQUENCY, _itf + 1), \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ + /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ + /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 0, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */\ + TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ + /*guid*/TUD_VIDEO_GUID_H264, /*bitsPerPix*/16, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0, /*variableSize*/1), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT(/*bFrameIndex */1, 0, _width, _height, \ + _width * _height * 16, _width * _height * 16 * _fps, \ + (10000000/_fps), /*bytesPreLine*/ 0, \ + (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + /* VS alt 1 */\ + TUD_VIDEO_DESC_STD_VS(_itf + 1, 1, 1, _stridx), \ + /* EP */ \ + TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1) + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_H264_BULK(_stridx, _itf, _epin, _width, _height, _fps, _epsize) \ + TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \ + TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ + /* wTotalLength - bLength */ \ + TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ + UVC_CLOCK_FREQUENCY, _itf + 1), \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ + /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ + /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 1, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */\ + TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ + /*guid*/TUD_VIDEO_GUID_H264, /*bitsPerPix*/16, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0, /*variableSize*/1), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT(/*bFrameIndex */1, 0, _width, _height, \ + _width * _height * 16, _width * _height * 16 * _fps, \ + (10000000/_fps), /*bytesPreLine*/ 0, \ + (10000000/_fps), (10000000/_fps), (10000000/_fps)), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + /* EP */ \ + TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1) + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_H264(_stridx, _itf, _epin, _epsize) \ + TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \ + TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ + /* wTotalLength - bLength */ \ + TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ + UVC_CLOCK_FREQUENCY, _itf + 1), \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ + /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ + /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 0, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */\ + TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN\ + + (UVC_FRAME_NUM*TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN)\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED(/*bFormatIndex*/1, /*bNumFrameDescriptors*/UVC_FRAME_NUM, \ + /*guid*/TUD_VIDEO_GUID_H264, /*bitsPerPix*/16, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0, /*variableSize*/1), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(_itf/2, 1), \ + TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(_itf/2, 2), \ + TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(_itf/2, 3), \ + TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(_itf/2, 4), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + /* VS alt 1 */\ + TUD_VIDEO_DESC_STD_VS(_itf + 1, 1, 1, _stridx), \ + /* EP */ \ + TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1) + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_H264_BULK(_stridx, _itf, _epin, _epsize) \ + TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \ + TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ + /* wTotalLength - bLength */ \ + TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ + UVC_CLOCK_FREQUENCY, _itf + 1), \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ + /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ + /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 1, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */\ + TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN\ + + (UVC_FRAME_NUM*TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN)\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED(/*bFormatIndex*/1, /*bNumFrameDescriptors*/UVC_FRAME_NUM, \ + /*guid*/TUD_VIDEO_GUID_H264, /*bitsPerPix*/16, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0, /*variableSize*/1), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(_itf/2, 1), \ + TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(_itf/2, 2), \ + TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(_itf/2, 3), \ + TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(_itf/2, 4), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + /* EP */ \ + TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1) + +#endif //CFG_TUD_VIDEO + +/** + * ETVR Custom implementation + * + * @brief get_uvc_device_name() is hacky, way for us to let users specify + * a custom device name right after flashing their boards with a way to update it + */ +const char *get_uvc_device_name(); + +/** + * ETVR Custom implementation + * + * @brief get_serial_number() is a way for us to specify a per-board serial number + */ +const char *get_serial_number(); + +#endif diff --git a/components/usb_device_uvc/tusb/uvc_frame_config.h b/components/usb_device_uvc/tusb/uvc_frame_config.h new file mode 100644 index 0000000..556223f --- /dev/null +++ b/components/usb_device_uvc/tusb/uvc_frame_config.h @@ -0,0 +1,76 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include "sdkconfig.h" + +#ifdef CONFIG_FORMAT_MJPEG_CAM1 +#define FORMAT_MJPEG_CAM1 1 +#endif + +#ifdef CONFIG_UVC_CAM1_MULTI_FRAMESIZE +//If enable, add VGA and HVGA to list +#define UVC_CAM1_FRAME_MULTI 1 +#endif + +#define UVC_CAM1_FRAME_WIDTH CONFIG_UVC_CAM1_FRAMESIZE_WIDTH +#define UVC_CAM1_FRAME_HEIGHT CONFIG_UVC_CAM1_FRAMESIZE_HEIGT +#define UVC_CAM1_FRAME_RATE CONFIG_UVC_CAM1_FRAMERATE + +#ifdef CONFIG_UVC_MODE_BULK_CAM1 +#define UVC_CAM1_BULK_MODE +#endif + +#if CONFIG_UVC_SUPPORT_TWO_CAM +#ifdef CONFIG_FORMAT_MJPEG_CAM2 +#define FORMAT_MJPEG_CAM2 1 +#endif + +#ifdef CONFIG_UVC_CAM2_MULTI_FRAMESIZE +//If enable, add VGA and HVGA to list +#define UVC_CAM2_FRAME_MULTI 1 +#endif + +#define UVC_CAM2_FRAME_WIDTH CONFIG_UVC_CAM2_FRAMESIZE_WIDTH +#define UVC_CAM2_FRAME_HEIGHT CONFIG_UVC_CAM2_FRAMESIZE_HEIGT +#define UVC_CAM2_FRAME_RATE CONFIG_UVC_CAM2_FRAMERATE + +#ifdef CONFIG_UVC_MODE_BULK_CAM2 +#define UVC_CAM2_BULK_MODE +#endif +#endif + +#ifndef UVC_CAM2_FRAME_WIDTH +#define UVC_CAM2_FRAME_WIDTH UVC_CAM1_FRAME_WIDTH +#endif + +#ifndef UVC_CAM2_FRAME_HEIGHT +#define UVC_CAM2_FRAME_HEIGHT UVC_CAM1_FRAME_HEIGHT +#endif + +#ifndef UVC_CAM2_FRAME_RATE +#define UVC_CAM2_FRAME_RATE UVC_CAM1_FRAME_RATE +#endif + +static const struct { + int width; + int height; + int rate; +} UVC_FRAMES_INFO[][4] = {{ + {UVC_CAM1_FRAME_WIDTH, UVC_CAM1_FRAME_HEIGHT, UVC_CAM1_FRAME_RATE}, + {CONFIG_UVC_MULTI_FRAME_WIDTH_1, CONFIG_UVC_MULTI_FRAME_HEIGHT_1, CONFIG_UVC_MULTI_FRAME_FPS_1}, + {CONFIG_UVC_MULTI_FRAME_WIDTH_2, CONFIG_UVC_MULTI_FRAME_HEIGHT_2, CONFIG_UVC_MULTI_FRAME_FPS_2}, + {CONFIG_UVC_MULTI_FRAME_WIDTH_3, CONFIG_UVC_MULTI_FRAME_HEIGHT_3, CONFIG_UVC_MULTI_FRAME_FPS_3}, + }, { + {UVC_CAM2_FRAME_WIDTH, UVC_CAM2_FRAME_HEIGHT, UVC_CAM2_FRAME_RATE}, + {CONFIG_UVC_MULTI_FRAME_WIDTH_1, CONFIG_UVC_MULTI_FRAME_HEIGHT_1, CONFIG_UVC_MULTI_FRAME_FPS_1}, + {CONFIG_UVC_MULTI_FRAME_WIDTH_2, CONFIG_UVC_MULTI_FRAME_HEIGHT_2, CONFIG_UVC_MULTI_FRAME_FPS_2}, + {CONFIG_UVC_MULTI_FRAME_WIDTH_3, CONFIG_UVC_MULTI_FRAME_HEIGHT_3, CONFIG_UVC_MULTI_FRAME_FPS_3}, + } +}; + +#define UVC_FRAME_NUM (sizeof(UVC_FRAMES_INFO[0]) / sizeof(UVC_FRAMES_INFO[0][0])) +_Static_assert(UVC_FRAME_NUM == 4, "UVC_FRAME_NUM must be 4"); diff --git a/components/usb_device_uvc/usb_device_uvc.c b/components/usb_device_uvc/usb_device_uvc.c new file mode 100644 index 0000000..fe793a6 --- /dev/null +++ b/components/usb_device_uvc/usb_device_uvc.c @@ -0,0 +1,345 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_timer.h" +#include "esp_check.h" +#if CONFIG_TINYUSB_RHPORT_HS +#include "soc/hp_sys_clkrst_reg.h" +#include "soc/hp_system_reg.h" +#else +#include "esp_private/usb_phy.h" +#endif +#include "tusb.h" +#include "usb_device_uvc.h" + +static const char *TAG = "usbd_uvc"; + +#if CONFIG_UVC_SUPPORT_TWO_CAM +#define UVC_CAM_NUM 2 +#else +#define UVC_CAM_NUM 1 +#endif + +typedef struct +{ +#if !CONFIG_TINYUSB_RHPORT_HS + usb_phy_handle_t phy_hdl; +#endif + bool uvc_init[UVC_CAM_NUM]; + uvc_format_t format[UVC_CAM_NUM]; + uvc_device_config_t user_config[UVC_CAM_NUM]; + TaskHandle_t uvc_task_hdl[UVC_CAM_NUM]; + uint32_t interval_ms[UVC_CAM_NUM]; +} uvc_device_t; + +static uvc_device_t s_uvc_device; + +static void usb_phy_init(void) +{ +#if !CONFIG_TINYUSB_RHPORT_HS + // Configure USB PHY + usb_phy_config_t phy_conf = { + .controller = USB_PHY_CTRL_OTG, + .otg_mode = USB_OTG_MODE_DEVICE, + .target = USB_PHY_TARGET_INT, + }; + usb_new_phy(&phy_conf, &s_uvc_device.phy_hdl); +#endif +} + +static inline uint32_t get_time_millis(void) +{ + return (uint32_t)(esp_timer_get_time() / 1000); +} + +static void tusb_device_task(void *arg) +{ + while (1) + { + tud_task(); + } +} + +void tud_mount_cb(void) +{ + ESP_LOGI(TAG, "Mount"); +} + +// Invoked when device is unmounted +void tud_umount_cb(void) +{ + ESP_LOGI(TAG, "UN-Mount"); +} + +void tud_suspend_cb(bool remote_wakeup_en) +{ + (void)remote_wakeup_en; + + if (s_uvc_device.user_config[0].stop_cb) + { + s_uvc_device.user_config[0].stop_cb(s_uvc_device.user_config[0].cb_ctx); + } +#if CONFIG_UVC_SUPPORT_TWO_CAM + if (s_uvc_device.user_config[1].stop_cb) + { + s_uvc_device.user_config[1].stop_cb(s_uvc_device.user_config[1].cb_ctx); + } +#endif + ESP_LOGI(TAG, "Suspend"); +} + +// Invoked when usb bus is resumed +void tud_resume_cb(void) +{ + ESP_LOGI(TAG, "Resume"); +} + +#if (CFG_TUD_VIDEO) +//--------------------------------------------------------------------+ +// USB Video +//--------------------------------------------------------------------+ +static void video_task(void *arg) +{ + uint32_t start_ms = 0; + uint32_t frame_num = 0; + uint32_t frame_len = 0; + uint32_t already_start = 0; + uint32_t tx_busy = 0; + uint8_t *uvc_buffer = s_uvc_device.user_config[0].uvc_buffer; + uint32_t uvc_buffer_size = s_uvc_device.user_config[0].uvc_buffer_size; + uvc_fb_t *pic = NULL; + + while (1) + { + if (!tud_video_n_streaming(0, 0)) + { + already_start = 0; + frame_num = 0; + tx_busy = 0; + vTaskDelay(1); + continue; + } + + if (!already_start) + { + already_start = 1; + start_ms = get_time_millis(); + } + + uint32_t cur = get_time_millis(); + if (cur - start_ms < s_uvc_device.interval_ms[0]) + { + vTaskDelay(1); + continue; + } + + if (tx_busy) + { + uint32_t xfer_done = ulTaskNotifyTake(pdTRUE, 1); + if (xfer_done == 0) + { + continue; + } + ++frame_num; + tx_busy = 0; + } + + start_ms += s_uvc_device.interval_ms[0]; + ESP_LOGD(TAG, "frame %" PRIu32 " taking picture...", frame_num); + pic = s_uvc_device.user_config[0].fb_get_cb(s_uvc_device.user_config[0].cb_ctx); + if (pic) + { + ESP_LOGD(TAG, "Picture taken! Its size was: %zu bytes", pic->len); + } + else + { + ESP_LOGE(TAG, "Failed to capture picture"); + continue; + } + + if (pic->len > uvc_buffer_size) + { + ESP_LOGW(TAG, "frame size is too big, dropping frame"); + s_uvc_device.user_config[0].fb_return_cb(pic, s_uvc_device.user_config[0].cb_ctx); + continue; + } + frame_len = pic->len; + memcpy(uvc_buffer, pic->buf, frame_len); + s_uvc_device.user_config[0].fb_return_cb(pic, s_uvc_device.user_config[0].cb_ctx); + tx_busy = 1; + tud_video_n_frame_xfer(0, 0, (void *)uvc_buffer, frame_len); + ESP_LOGD(TAG, "frame %" PRIu32 " transfer start, size %" PRIu32, frame_num, frame_len); + } +} + +#if CONFIG_UVC_SUPPORT_TWO_CAM +static void video_task2(void *arg) +{ + uint32_t start_ms = 0; + uint32_t frame_num = 0; + uint32_t frame_len = 0; + uint32_t already_start = 0; + uint32_t tx_busy = 0; + uint8_t *uvc_buffer = s_uvc_device.user_config[1].uvc_buffer; + uint32_t uvc_buffer_size = s_uvc_device.user_config[1].uvc_buffer_size; + uvc_fb_t *pic = NULL; + + while (1) + { + if (!tud_video_n_streaming(1, 0)) + { + already_start = 0; + frame_num = 0; + tx_busy = 0; + vTaskDelay(1); + continue; + } + + if (!already_start) + { + already_start = 1; + start_ms = get_time_millis(); + } + + uint32_t cur = get_time_millis(); + if (cur - start_ms < s_uvc_device.interval_ms[1]) + { + vTaskDelay(1); + continue; + } + + if (tx_busy) + { + uint32_t xfer_done = ulTaskNotifyTake(pdTRUE, 1); + if (xfer_done == 0) + { + continue; + } + ++frame_num; + tx_busy = 0; + } + + start_ms += s_uvc_device.interval_ms[1]; + ESP_LOGD(TAG, "frame %" PRIu32 " taking picture...", frame_num); + pic = s_uvc_device.user_config[1].fb_get_cb(s_uvc_device.user_config[1].cb_ctx); + if (pic) + { + ESP_LOGD(TAG, "Picture taken! Its size was: %zu bytes", pic->len); + } + else + { + ESP_LOGE(TAG, "Failed to capture picture"); + continue; + } + + if (pic->len > uvc_buffer_size) + { + ESP_LOGW(TAG, "frame size is too big, dropping frame"); + s_uvc_device.user_config[1].fb_return_cb(pic, s_uvc_device.user_config[1].cb_ctx); + continue; + } + frame_len = pic->len; + memcpy(uvc_buffer, pic->buf, frame_len); + s_uvc_device.user_config[1].fb_return_cb(pic, s_uvc_device.user_config[1].cb_ctx); + tx_busy = 1; + tud_video_n_frame_xfer(1, 0, (void *)uvc_buffer, frame_len); + ESP_LOGD(TAG, "frame %" PRIu32 " transfer start, size %" PRIu32, frame_num, frame_len); + } +} +#endif + +void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) +{ + (void)ctl_idx; + (void)stm_idx; + xTaskNotifyGive(s_uvc_device.uvc_task_hdl[ctl_idx]); +} + +int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, + video_probe_and_commit_control_t const *parameters) +{ + (void)ctl_idx; + (void)stm_idx; + /* convert unit to ms from 100 ns */ + ESP_LOGI(TAG, "bFrameIndex: %u", parameters->bFrameIndex); + ESP_LOGI(TAG, "dwFrameInterval: %" PRIu32 "", parameters->dwFrameInterval); + if (parameters->bFrameIndex > UVC_FRAME_NUM) + { + return VIDEO_ERROR_OUT_OF_RANGE; + } + s_uvc_device.interval_ms[ctl_idx] = parameters->dwFrameInterval / 10000; + int frame_index = parameters->bFrameIndex - 1; + esp_err_t ret = s_uvc_device.user_config[ctl_idx].start_cb(s_uvc_device.format[ctl_idx], UVC_FRAMES_INFO[ctl_idx][frame_index].width, + UVC_FRAMES_INFO[ctl_idx][frame_index].height, UVC_FRAMES_INFO[ctl_idx][frame_index].rate, s_uvc_device.user_config[ctl_idx].cb_ctx); + + if (ret != ESP_OK) + { + ESP_LOGE(TAG, "camera init failed"); + return VIDEO_ERROR_OUT_OF_RANGE; + } + return VIDEO_ERROR_NONE; +} +#endif + +esp_err_t uvc_device_config(int index, uvc_device_config_t *config) +{ + ESP_RETURN_ON_FALSE(index < UVC_CAM_NUM, ESP_ERR_INVALID_ARG, TAG, "index is invalid"); + ESP_RETURN_ON_FALSE(config != NULL, ESP_ERR_INVALID_ARG, TAG, "config is NULL"); + ESP_RETURN_ON_FALSE(config->start_cb != NULL, ESP_ERR_INVALID_ARG, TAG, "start_cb is NULL"); + ESP_RETURN_ON_FALSE(config->fb_get_cb != NULL, ESP_ERR_INVALID_ARG, TAG, "fb_get_cb is NULL"); + ESP_RETURN_ON_FALSE(config->fb_return_cb != NULL, ESP_ERR_INVALID_ARG, TAG, "fb_return_cb is NULL"); + ESP_RETURN_ON_FALSE(config->stop_cb != NULL, ESP_ERR_INVALID_ARG, TAG, "stop_cb is NULL"); + ESP_RETURN_ON_FALSE(config->uvc_buffer != NULL, ESP_ERR_INVALID_ARG, TAG, "uvc_buffer is NULL"); + ESP_RETURN_ON_FALSE(config->uvc_buffer_size > 0, ESP_ERR_INVALID_ARG, TAG, "uvc_buffer_size is 0"); + + s_uvc_device.user_config[index] = *config; + s_uvc_device.interval_ms[index] = 1000 / (index == 0 ? UVC_CAM1_FRAME_RATE : UVC_CAM2_FRAME_RATE); + s_uvc_device.uvc_init[index] = true; + return ESP_OK; +} + +esp_err_t uvc_device_init(void) +{ + ESP_RETURN_ON_FALSE(s_uvc_device.uvc_init[0], ESP_ERR_INVALID_STATE, TAG, "uvc device 0 not init"); +#if CONFIG_UVC_SUPPORT_TWO_CAM + ESP_RETURN_ON_FALSE(s_uvc_device.uvc_init[1], ESP_ERR_INVALID_STATE, TAG, "uvc device 1 not init, if not use, please disable CONFIG_UVC_SUPPORT_TWO_CAM"); +#endif + +#ifdef CONFIG_FORMAT_MJPEG_CAM1 + s_uvc_device.format[0] = UVC_FORMAT_JPEG; +#endif + +#if CONFIG_UVC_SUPPORT_TWO_CAM +#ifdef CONFIG_FORMAT_MJPEG_CAM2 + s_uvc_device.format[1] = UVC_FORMAT_JPEG; +#endif +#endif + + // init device stack on configured roothub port + usb_phy_init(); + bool usb_init = tusb_init(); + if (!usb_init) + { + ESP_LOGE(TAG, "USB Device Stack Init Fail"); + return ESP_FAIL; + } + + BaseType_t core_id = (CONFIG_UVC_TINYUSB_TASK_CORE < 0) ? tskNO_AFFINITY : CONFIG_UVC_TINYUSB_TASK_CORE; + xTaskCreatePinnedToCore(tusb_device_task, "TinyUSB", 4096, NULL, CONFIG_UVC_TINYUSB_TASK_PRIORITY, NULL, core_id); +#if (CFG_TUD_VIDEO) + core_id = (CONFIG_UVC_CAM1_TASK_CORE < 0) ? tskNO_AFFINITY : CONFIG_UVC_CAM1_TASK_CORE; + xTaskCreatePinnedToCore(video_task, "UVC", 4096, NULL, CONFIG_UVC_CAM1_TASK_PRIORITY, &s_uvc_device.uvc_task_hdl[0], core_id); +#if CONFIG_UVC_SUPPORT_TWO_CAM + core_id = (CONFIG_UVC_CAM2_TASK_CORE < 0) ? tskNO_AFFINITY : CONFIG_UVC_CAM2_TASK_CORE; + xTaskCreatePinnedToCore(video_task2, "UVC2", 4096, NULL, CONFIG_UVC_CAM2_TASK_PRIORITY, &s_uvc_device.uvc_task_hdl[1], core_id); +#endif +#endif + ESP_LOGI(TAG, "UVC Device Start, Version: %d.%d.%d", USB_DEVICE_UVC_VER_MAJOR, USB_DEVICE_UVC_VER_MINOR, USB_DEVICE_UVC_VER_PATCH); + return ESP_OK; +} diff --git a/dependencies.lock b/dependencies.lock index 77a7abe..2d73027 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -1,6 +1,6 @@ dependencies: espressif/cmake_utilities: - component_hash: 7e20811092150b668a710cfbf43164721b23bac766811f4e68036450a3265fba + component_hash: 05165f30922b422b4b90c08845e6d449329b97370fbd06309803d8cb539d79e3 dependencies: - name: idf require: private @@ -8,7 +8,7 @@ dependencies: source: registry_url: https://components.espressif.com/ type: service - version: 1.0.0 + version: 1.1.1 espressif/esp32-camera: component_hash: a82de4ee0b383bd34695935385c6a6c720129084580c2bbb55dce76eb2a3788f dependencies: [] @@ -20,7 +20,6 @@ dependencies: component_hash: 28c6509a727ef74925b372ed404772aeedf11cce10b78c3f69b3c66799095e2d dependencies: - name: idf - registry_url: https://components.espressif.com require: private version: '>=4.4' source: @@ -38,7 +37,7 @@ dependencies: type: service version: 1.4.0 espressif/tinyusb: - component_hash: 214989d502fc168241a4a4f83b097d8ac44a93cd6f1787b4ac10069a8b3bebd3 + component_hash: 10703da2c3cd39a944711ee3d320c6dda54debabf13b4b933a7c90daf102372b dependencies: - name: idf require: private @@ -50,40 +49,18 @@ dependencies: - esp32s2 - esp32s3 - esp32p4 - version: 0.15.0~10 - espressif/usb_device_uvc: - component_hash: f86ee44e64f3914474919a14ac4d47082d6a2888a62c239e6e9dc58c32da4682 - dependencies: - - name: espressif/cmake_utilities - registry_url: https://components.espressif.com/ - require: private - version: '*' - - name: espressif/tinyusb - registry_url: https://components.espressif.com/ - require: private - version: '>=0.15.0~10' - - name: idf - registry_url: https://components.espressif.com - require: private - version: '>=5.0' - source: - registry_url: https://components.espressif.com/ - type: service - targets: - - esp32s2 - - esp32s3 - - esp32p4 - version: 1.1.0 + version: 0.18.0~2 idf: source: type: idf version: 5.3.2 direct_dependencies: +- espressif/cmake_utilities - espressif/esp32-camera - espressif/led_strip - espressif/mdns -- espressif/usb_device_uvc +- espressif/tinyusb - idf -manifest_hash: dfe29d524d2f5acb426e21118042ac1c021e44e8e7072b700d872ac75499cd6c +manifest_hash: 1f812e7723bfe7dc357c54a3f01b77580502ba368553b7d186d3a0fbc2a82bab target: esp32s3 version: 2.0.0 diff --git a/main/idf_component.yml b/main/idf_component.yml index 96b7ec1..ce489ae 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -3,4 +3,5 @@ dependencies: espressif/led_strip: "^2.4.1" idf: "^5.0" espressif/esp32-camera: "^2.0.0" - espressif/usb_device_uvc: "1.1.0" +# disabled on purpose, we've overwritten some components +# espressif/usb_device_uvc: "1.1.0" diff --git a/main/openiris_main.cpp b/main/openiris_main.cpp index e2d1498..688e2c3 100644 --- a/main/openiris_main.cpp +++ b/main/openiris_main.cpp @@ -39,7 +39,7 @@ auto commandManager = std::make_shared(dependencyRegistry); WebSocketLogger webSocketLogger; Preferences preferences; -auto deviceConfig = std::make_shared(&preferences); +std::shared_ptr deviceConfig = std::make_shared(&preferences); WiFiManager wifiManager(deviceConfig, eventQueue, stateManager); MDNSManager mdnsManager(deviceConfig, eventQueue); @@ -55,25 +55,21 @@ UVCStreamManager uvcStream; auto *ledManager = new LEDManager(BLINK_GPIO, CONFIG_LED_C_PIN_GPIO, ledStateQueue); auto *serialManager = new SerialManager(commandManager, &timerHandle); -static void initNVSStorage() -{ +static void initNVSStorage() { esp_err_t ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) - { + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); } -int test_log(const char *format, va_list args) -{ +int test_log(const char *format, va_list args) { webSocketLogger.log_message(format, args); return vprintf(format, args); } -void disable_serial_manager_task(TaskHandle_t serialManagerHandle) -{ +void disable_serial_manager_task(TaskHandle_t serialManagerHandle) { vTaskDelete(serialManagerHandle); } @@ -84,8 +80,7 @@ void disable_serial_manager_task(TaskHandle_t serialManagerHandle) // // todo: check the initial PR by Summer and port the device mode from that, should be useful // but we'll have to rethink it -void start_video_streaming(void *arg) -{ +void start_video_streaming(void *arg) { if (!deviceConfig->getWifiConfigs().empty() || strcmp(CONFIG_WIFI_SSID, "") != 0) { // make sure the server runs on a separate core ESP_LOGI("[MAIN]", "WiFi setup detected, starting WiFi streaming."); @@ -104,24 +99,22 @@ void start_video_streaming(void *arg) disable_serial_manager_task(serialTaskHandle); } -esp_timer_handle_t createStartVideoStreamingTimer(void *pvParameter) -{ +esp_timer_handle_t createStartVideoStreamingTimer(void *pvParameter) { esp_timer_handle_t handle; const esp_timer_create_args_t args = { .callback = &start_video_streaming, .arg = pvParameter, - .name = "startVideoStreaming"}; + .name = "startVideoStreaming" + }; - if (const auto result = esp_timer_create(&args, &handle); result != ESP_OK) - { + if (const auto result = esp_timer_create(&args, &handle); result != ESP_OK) { ESP_LOGE("[MAIN]", "Failed to create timer: %s", esp_err_to_name(result)); } return handle; } -extern "C" void app_main(void) -{ +extern "C" void app_main(void) { TaskHandle_t *serialManagerHandle = nullptr; dependencyRegistry->registerService(DependencyType::project_config, deviceConfig); dependencyRegistry->registerService(DependencyType::camera_manager, cameraHandler); @@ -219,8 +212,7 @@ extern "C" void app_main(void) nullptr); timerHandle = createStartVideoStreamingTimer(serialManagerHandle); - if (timerHandle != nullptr) - { + if (timerHandle != nullptr) { esp_timer_start_once(timerHandle, 30000000); // 30s } } diff --git a/sdkconfig b/sdkconfig index fdb88a9..1d2a05b 100644 --- a/sdkconfig +++ b/sdkconfig @@ -1,6 +1,7 @@ # # Automatically generated file. DO NOT EDIT. # Espressif IoT Development Framework (ESP-IDF) 5.3.2 Project Configuration +# CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 CONFIG_SOC_ADC_SUPPORTED=y @@ -369,7 +370,9 @@ CONFIG_IDF_INIT_VERSION="5.3.2" CONFIG_IDF_TARGET_ESP32S3=y CONFIG_IDF_FIRMWARE_CHIP_ID=0x0009 +# # Build type +# CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y # CONFIG_APP_BUILD_TYPE_RAM is not set CONFIG_APP_BUILD_GENERATE_BINARIES=y @@ -378,11 +381,18 @@ CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y # CONFIG_APP_REPRODUCIBLE_BUILD is not set # CONFIG_APP_NO_BLOBS is not set # end of Build type + +# # Bootloader config +# + +# # Bootloader manager +# CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y CONFIG_BOOTLOADER_PROJECT_VER=1 # end of Bootloader manager + CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x0 CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set @@ -395,10 +405,14 @@ CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y # CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set # CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set CONFIG_BOOTLOADER_LOG_LEVEL=3 + +# # Serial Flash Configurations +# # CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y # end of Serial Flash Configurations + CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y # CONFIG_BOOTLOADER_FACTORY_RESET is not set # CONFIG_BOOTLOADER_APP_TEST is not set @@ -413,7 +427,10 @@ CONFIG_BOOTLOADER_WDT_TIME_MS=9000 CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 # CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set # end of Bootloader config + +# # Security features +# CONFIG_SECURE_BOOT_V2_RSA_SUPPORTED=y CONFIG_SECURE_BOOT_V2_PREFERRED=y # CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set @@ -421,13 +438,17 @@ CONFIG_SECURE_BOOT_V2_PREFERRED=y # CONFIG_SECURE_FLASH_ENC_ENABLED is not set CONFIG_SECURE_ROM_DL_MODE_ENABLED=y # end of Security features + +# # Application manager +# CONFIG_APP_COMPILE_TIME_DATE=y # CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set # CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set # CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 # end of Application manager + CONFIG_ESP_ROM_HAS_CRC_LE=y CONFIG_ESP_ROM_HAS_CRC_BE=y CONFIG_ESP_ROM_HAS_MZ_CRC32=y @@ -455,13 +476,19 @@ 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 + +# # Boot ROM Behavior +# CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y # CONFIG_BOOT_ROM_LOG_ALWAYS_OFF is not set # CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH is not set # CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW is not set # end of Boot ROM Behavior + +# # Serial flasher config +# # CONFIG_ESPTOOLPY_NO_STUB is not set # CONFIG_ESPTOOLPY_OCT_FLASH is not set CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT=y @@ -495,7 +522,10 @@ CONFIG_ESPTOOLPY_AFTER_RESET=y CONFIG_ESPTOOLPY_AFTER="hard_reset" CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 # end of Serial flasher config + +# # Partition Table +# # 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 @@ -505,12 +535,17 @@ CONFIG_PARTITION_TABLE_FILENAME="min_spiffs.csv" CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table + +# # OpenIris basic configuration +# CONFIG_ENV_GPIO_RANGE_MIN=0 CONFIG_ENV_GPIO_RANGE_MAX=48 CONFIG_ENV_GPIO_IN_RANGE_MAX=48 CONFIG_ENV_GPIO_OUT_RANGE_MAX=48 CONFIG_BLINK_GPIO=38 +CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL=y +CONFIG_LED_C_PIN=1 CONFIG_BLINK_PERIOD=1000 CONFIG_WIRED_MODE=y CONFIG_MDNS_HOSTNAME="openiristracker" @@ -518,10 +553,11 @@ CONFIG_WIFI_SSID="" CONFIG_WIFI_PASSWORD="" CONFIG_AP_WIFI_SSID="EyeTrackVR" CONFIG_AP_WIFI_PASSWORD="12345678" -# CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL is not set -CONFIG_LED_C_PIN=1 # end of OpenIris basic configuration + +# # Camera sensor pinout configuration +# CONFIG_CAMERA_MODULE_NAME="SWROOM_BABBLE_S3" CONFIG_PWDN_GPIO_NUM=-1 CONFIG_RESET_GPIO_NUM=-1 @@ -540,7 +576,10 @@ CONFIG_VSYNC_GPIO_NUM=21 CONFIG_HREF_GPIO_NUM=14 CONFIG_PCLK_GPIO_NUM=7 # end of Camera sensor pinout configuration + +# # Compiler options +# # CONFIG_COMPILER_OPTIMIZATION_DEBUG is not set # CONFIG_COMPILER_OPTIMIZATION_SIZE is not set CONFIG_COMPILER_OPTIMIZATION_PERF=y @@ -567,8 +606,14 @@ CONFIG_COMPILER_RT_LIB_NAME="gcc" # CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING is not set CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE=y # end of Compiler options + +# # Component config +# + +# # Application Level Tracing +# # CONFIG_APPTRACE_DEST_JTAG is not set CONFIG_APPTRACE_DEST_NONE=y # CONFIG_APPTRACE_DEST_UART1 is not set @@ -578,52 +623,97 @@ CONFIG_APPTRACE_DEST_UART_NONE=y CONFIG_APPTRACE_UART_TASK_PRIO=1 CONFIG_APPTRACE_LOCK_ENABLE=y # end of Application Level Tracing + +# # Bluetooth +# # CONFIG_BT_ENABLED is not set CONFIG_BT_ALARM_MAX_NUM=50 # end of Bluetooth + +# # Console Library +# # CONFIG_CONSOLE_SORTED_HELP is not set # end of Console Library + +# # Driver Configurations +# + +# # TWAI Configuration +# # CONFIG_TWAI_ISR_IN_IRAM is not set CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # end of TWAI Configuration + +# # Legacy ADC Driver Configuration +# # CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set + +# # Legacy ADC Calibration Configuration +# # CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set # end of Legacy ADC Calibration Configuration # end of Legacy ADC Driver Configuration + +# # Legacy MCPWM Driver Configurations +# # CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set # end of Legacy MCPWM Driver Configurations + +# # Legacy Timer Group Driver Configurations +# # CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set # end of Legacy Timer Group Driver Configurations + +# # Legacy RMT Driver Configurations +# # CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set # end of Legacy RMT Driver Configurations + +# # Legacy I2S Driver Configurations +# # CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set # end of Legacy I2S Driver Configurations + +# # Legacy PCNT Driver Configurations +# # CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set # end of Legacy PCNT Driver Configurations + +# # Legacy SDM Driver Configurations +# # CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set # end of Legacy SDM Driver Configurations + +# # Legacy Temperature Sensor Driver Configurations +# # CONFIG_TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN is not set # end of Legacy Temperature Sensor Driver Configurations # end of Driver Configurations + +# # eFuse Bit Manager +# # CONFIG_EFUSE_CUSTOM_TABLE is not set # CONFIG_EFUSE_VIRTUAL is not set CONFIG_EFUSE_MAX_BLK_LEN=256 # end of eFuse Bit Manager + +# # ESP-TLS +# CONFIG_ESP_TLS_USING_MBEDTLS=y CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y # CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set @@ -633,80 +723,134 @@ CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y # CONFIG_ESP_TLS_PSK_VERIFICATION is not set # CONFIG_ESP_TLS_INSECURE is not set # end of ESP-TLS + +# # ADC and ADC Calibration +# # CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set # CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set # CONFIG_ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3 is not set # CONFIG_ADC_ENABLE_DEBUG_LOG is not set # end of ADC and ADC Calibration + +# # Wireless Coexistence +# CONFIG_ESP_COEX_ENABLED=y # CONFIG_ESP_COEX_EXTERNAL_COEXIST_ENABLE is not set # CONFIG_ESP_COEX_GPIO_DEBUG is not set # end of Wireless Coexistence + +# # Common ESP-related +# CONFIG_ESP_ERR_TO_NAME_LOOKUP=y # end of Common ESP-related + +# # ESP-Driver:GPIO Configurations +# # CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:GPIO Configurations + +# # ESP-Driver:GPTimer Configurations +# CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y # CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set # CONFIG_GPTIMER_ISR_IRAM_SAFE is not set # CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:GPTimer Configurations + +# # ESP-Driver:I2C Configurations +# # CONFIG_I2C_ISR_IRAM_SAFE is not set # CONFIG_I2C_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:I2C Configurations + +# # ESP-Driver:I2S Configurations +# # CONFIG_I2S_ISR_IRAM_SAFE is not set # CONFIG_I2S_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:I2S Configurations + +# # ESP-Driver:LEDC Configurations +# # CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:LEDC Configurations + +# # ESP-Driver:MCPWM Configurations +# # CONFIG_MCPWM_ISR_IRAM_SAFE is not set # CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set # CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:MCPWM Configurations + +# # ESP-Driver:PCNT Configurations +# # CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set # CONFIG_PCNT_ISR_IRAM_SAFE is not set # CONFIG_PCNT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:PCNT Configurations + +# # ESP-Driver:RMT Configurations +# # CONFIG_RMT_ISR_IRAM_SAFE is not set # CONFIG_RMT_RECV_FUNC_IN_IRAM is not set # CONFIG_RMT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:RMT Configurations + +# # ESP-Driver:Sigma Delta Modulator Configurations +# # CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set # CONFIG_SDM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Sigma Delta Modulator Configurations + +# # ESP-Driver:SPI Configurations +# # CONFIG_SPI_MASTER_IN_IRAM is not set CONFIG_SPI_MASTER_ISR_IN_IRAM=y # CONFIG_SPI_SLAVE_IN_IRAM is not set CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # end of ESP-Driver:SPI Configurations + +# # ESP-Driver:Touch Sensor Configurations +# # CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set # CONFIG_TOUCH_ISR_IRAM_SAFE is not set # CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Touch Sensor Configurations + +# # ESP-Driver:Temperature Sensor Configurations +# # CONFIG_TEMP_SENSOR_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Temperature Sensor Configurations + +# # ESP-Driver:UART Configurations +# # CONFIG_UART_ISR_IN_IRAM is not set # end of ESP-Driver:UART Configurations + +# # ESP-Driver:USB Serial/JTAG Configuration +# CONFIG_USJ_ENABLE_USB_SERIAL_JTAG=y # end of ESP-Driver:USB Serial/JTAG Configuration + +# # Ethernet +# CONFIG_ETH_ENABLED=y CONFIG_ETH_USE_SPI_ETHERNET=y # CONFIG_ETH_SPI_ETHERNET_DM9051 is not set @@ -715,24 +859,36 @@ CONFIG_ETH_USE_SPI_ETHERNET=y # CONFIG_ETH_USE_OPENETH is not set # CONFIG_ETH_TRANSMIT_MUTEX is not set # end of Ethernet + +# # Event Loop Library +# # CONFIG_ESP_EVENT_LOOP_PROFILING is not set CONFIG_ESP_EVENT_POST_FROM_ISR=y CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y # end of Event Loop Library + +# # GDB Stub +# CONFIG_ESP_GDBSTUB_ENABLED=y # CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y CONFIG_ESP_GDBSTUB_MAX_TASKS=32 # end of GDB Stub + +# # ESP HTTP client +# 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 # end of ESP HTTP client + +# # HTTP Server +# CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 CONFIG_HTTPD_MAX_URI_LEN=512 CONFIG_HTTPD_ERR_RESP_NO_DELAY=y @@ -741,28 +897,49 @@ CONFIG_HTTPD_PURGE_BUF_LEN=32 CONFIG_HTTPD_WS_SUPPORT=y # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set # end of HTTP Server + +# # ESP HTTPS OTA +# # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set # CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set # end of ESP HTTPS OTA + +# # ESP HTTPS server +# # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set # end of ESP HTTPS server + +# # Hardware Settings +# + +# # Chip revision +# CONFIG_ESP32S3_REV_MIN_0=y # CONFIG_ESP32S3_REV_MIN_1 is not set # CONFIG_ESP32S3_REV_MIN_2 is not set CONFIG_ESP32S3_REV_MIN_FULL=0 CONFIG_ESP_REV_MIN_FULL=0 + +# # Maximum Supported ESP32-S3 Revision (Rev v0.99) +# CONFIG_ESP32S3_REV_MAX_FULL=99 CONFIG_ESP_REV_MAX_FULL=99 CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL=0 CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL=199 + +# # Maximum Supported ESP32-S3 eFuse Block Revision (eFuse Block Rev v1.99) +# # end of Chip revision + +# # MAC Config +# CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y @@ -774,7 +951,10 @@ CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES_FOUR=y CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES=4 # CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set # end of MAC Config + +# # Sleep Config +# CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND=y CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU=y @@ -785,36 +965,61 @@ CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 # CONFIG_ESP_SLEEP_DEBUG is not set CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y # end of Sleep Config + +# # RTC Clock Config +# CONFIG_RTC_CLK_SRC_INT_RC=y # CONFIG_RTC_CLK_SRC_EXT_CRYS is not set # CONFIG_RTC_CLK_SRC_EXT_OSC is not set # CONFIG_RTC_CLK_SRC_INT_8MD256 is not set CONFIG_RTC_CLK_CAL_CYCLES=1024 # end of RTC Clock Config + +# # Peripheral Control +# CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y # end of Peripheral Control + +# # GDMA Configurations +# CONFIG_GDMA_CTRL_FUNC_IN_IRAM=y # CONFIG_GDMA_ISR_IRAM_SAFE is not set # CONFIG_GDMA_ENABLE_DEBUG_LOG is not set # end of GDMA Configurations + +# # Main XTAL Config +# CONFIG_XTAL_FREQ_40=y CONFIG_XTAL_FREQ=40 # end of Main XTAL Config + 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 +# # 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 + +# # ESP NETIF Adapter +# CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set @@ -824,9 +1029,15 @@ CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y # CONFIG_ESP_NETIF_BRIDGE_EN is not set # CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set # end of ESP NETIF Adapter + +# # Partition API Configuration +# # end of Partition API Configuration + +# # PHY +# CONFIG_ESP_PHY_ENABLED=y CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y # CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set @@ -841,15 +1052,24 @@ CONFIG_ESP_PHY_RF_CAL_PARTIAL=y CONFIG_ESP_PHY_CALIBRATION_MODE=0 # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set # end of PHY + +# # Power Management +# # CONFIG_PM_ENABLE is not set # CONFIG_PM_SLP_IRAM_OPT is not set CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=y CONFIG_PM_RESTORE_CACHE_TAGMEM_AFTER_LIGHT_SLEEP=y # end of Power Management + +# # ESP PSRAM +# CONFIG_SPIRAM=y + +# # SPI RAM config +# CONFIG_SPIRAM_MODE_QUAD=y # CONFIG_SPIRAM_MODE_OCT is not set CONFIG_SPIRAM_TYPE_AUTO=y @@ -879,15 +1099,24 @@ CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 # CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set # end of SPI RAM config # end of ESP PSRAM + +# # ESP Ringbuf +# # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set # end of ESP Ringbuf + +# # ESP System Settings +# # CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set # CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160 is not set CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240 + +# # Cache config +# CONFIG_ESP32S3_INSTRUCTION_CACHE_16KB=y # CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB is not set CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE=0x4000 @@ -909,14 +1138,21 @@ CONFIG_ESP32S3_DATA_CACHE_LINE_32B=y # CONFIG_ESP32S3_DATA_CACHE_LINE_64B is not set CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE=32 # end of Cache config + +# # Memory +# # CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM is not set # CONFIG_ESP32S3_USE_FIXED_STATIC_RAM_SIZE is not set # end of Memory + +# # Trace memory +# # CONFIG_ESP32S3_TRAX is not set CONFIG_ESP32S3_TRACEMEM_RESERVE_DRAM=0x0 # end of Trace memory + # CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set @@ -924,10 +1160,14 @@ CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y + +# # Memory protection +# CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=y CONFIG_ESP_SYSTEM_MEMPROT_FEATURE_LOCK=y # end of Memory protection + CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 @@ -961,7 +1201,10 @@ CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y # CONFIG_ESP_DEBUG_STUBS_ENABLE is not set CONFIG_ESP_DEBUG_OCDAWARE=y CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y + +# # Brownout Detector +# CONFIG_ESP_BROWNOUT_DET=y CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7=y # CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set @@ -972,15 +1215,22 @@ CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7=y # CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set CONFIG_ESP_BROWNOUT_DET_LVL=7 # end of Brownout Detector + CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y CONFIG_ESP_SYSTEM_BBPLL_RECALIB=y # end of ESP System Settings + +# # IPC (Inter-Processor Call) +# CONFIG_ESP_IPC_TASK_STACK_SIZE=1280 CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y CONFIG_ESP_IPC_ISR_ENABLE=y # end of IPC (Inter-Processor Call) + +# # ESP Timer (High Resolution Timer) +# # CONFIG_ESP_TIMER_PROFILING is not set CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y @@ -993,7 +1243,10 @@ CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y # CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set CONFIG_ESP_TIMER_IMPL_SYSTIMER=y # end of ESP Timer (High Resolution Timer) + +# # Wi-Fi +# CONFIG_ESP_WIFI_ENABLED=y CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 @@ -1043,21 +1296,31 @@ CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y # CONFIG_ESP_WIFI_DPP_SUPPORT is not set # CONFIG_ESP_WIFI_11R_SUPPORT is not set # CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set + +# # WPS Configuration Options +# # CONFIG_ESP_WIFI_WPS_STRICT is not set # CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set # end of WPS Configuration Options + # CONFIG_ESP_WIFI_DEBUG_PRINT is not set # CONFIG_ESP_WIFI_TESTING_OPTIONS is not set CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y # CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set # end of Wi-Fi + +# # Core dump +# # CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set # CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y # end of Core dump + +# # FAT Filesystem support +# CONFIG_FATFS_VOLUME_COUNT=2 CONFIG_FATFS_LFN_NONE=y # CONFIG_FATFS_LFN_HEAP is not set @@ -1097,8 +1360,14 @@ CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 # CONFIG_FATFS_USE_LABEL is not set CONFIG_FATFS_LINK_LOCK=y # end of FAT Filesystem support + +# # FreeRTOS +# + +# # Kernel +# # CONFIG_FREERTOS_SMP is not set # CONFIG_FREERTOS_UNICORE is not set CONFIG_FREERTOS_HZ=1000 @@ -1126,7 +1395,10 @@ CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set # CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set # end of Kernel + +# # Port +# # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y # CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set @@ -1141,6 +1413,7 @@ CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER=y # CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # end of Port + CONFIG_FREERTOS_PORT=y CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y @@ -1149,7 +1422,10 @@ CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y CONFIG_FREERTOS_NUMBER_OF_CORES=2 # end of FreeRTOS + +# # Hardware Abstraction Layer (HAL) and Low Level (LL) +# CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y # CONFIG_HAL_ASSERTION_DISABLE is not set # CONFIG_HAL_ASSERTION_SILENT is not set @@ -1160,7 +1436,10 @@ CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y # CONFIG_HAL_ECDSA_GEN_SIG_CM is not set # end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# # Heap memory debugging +# CONFIG_HEAP_POISONING_DISABLED=y # CONFIG_HEAP_POISONING_LIGHT is not set # CONFIG_HEAP_POISONING_COMPREHENSIVE is not set @@ -1172,7 +1451,10 @@ CONFIG_HEAP_TRACING_OFF=y # CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set # CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set # end of Heap memory debugging + +# # Log output +# # CONFIG_LOG_DEFAULT_LEVEL_NONE is not set # CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set # CONFIG_LOG_DEFAULT_LEVEL_WARN is not set @@ -1189,7 +1471,10 @@ CONFIG_LOG_COLORS=y CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set # end of Log output + +# # LWIP +# CONFIG_LWIP_ENABLE=y CONFIG_LWIP_LOCAL_HOSTNAME="espressif" # CONFIG_LWIP_NETIF_API is not set @@ -1230,12 +1515,16 @@ CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y CONFIG_LWIP_DHCP_OPTIONS_LEN=68 CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# # DHCP server +# CONFIG_LWIP_DHCPS=y CONFIG_LWIP_DHCPS_LEASE_UNIT=60 CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y # end of DHCP server + # CONFIG_LWIP_AUTOIP is not set CONFIG_LWIP_IPV4=y CONFIG_LWIP_IPV6=y @@ -1245,7 +1534,10 @@ CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 # CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set CONFIG_LWIP_NETIF_LOOPBACK=y CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# # TCP +# CONFIG_LWIP_MAX_ACTIVE_TCP=16 CONFIG_LWIP_MAX_LISTENING_TCP=16 CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y @@ -1268,15 +1560,22 @@ CONFIG_LWIP_TCP_OVERSIZE_MSS=y # CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set CONFIG_LWIP_TCP_RTO_TIME=1500 # end of TCP + +# # UDP +# CONFIG_LWIP_MAX_UDP_PCBS=16 CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 # end of UDP + +# # Checksums +# # CONFIG_LWIP_CHECKSUM_CHECK_IP is not set # CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums + CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set @@ -1289,30 +1588,46 @@ CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 # CONFIG_LWIP_SLIP_SUPPORT is not set + +# # ICMP +# CONFIG_LWIP_ICMP=y # CONFIG_LWIP_MULTICAST_PING is not set # CONFIG_LWIP_BROADCAST_PING is not set # end of ICMP + +# # LWIP RAW API +# CONFIG_LWIP_MAX_RAW_PCBS=16 # end of LWIP RAW API + +# # SNTP +# CONFIG_LWIP_SNTP_MAX_SERVERS=1 # CONFIG_LWIP_DHCP_GET_NTP_SRV is not set CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 CONFIG_LWIP_SNTP_STARTUP_DELAY=y CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 # end of SNTP + +# # DNS +# CONFIG_LWIP_DNS_MAX_HOST_IP=1 CONFIG_LWIP_DNS_MAX_SERVERS=3 # CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set # CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set # end of DNS + CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# # Hooks +# # CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y # CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set @@ -1334,9 +1649,13 @@ CONFIG_LWIP_HOOK_IP6_INPUT_NONE=y # CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT is not set # CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set # end of Hooks + # CONFIG_LWIP_DEBUG is not set # end of LWIP + +# # mbedTLS +# CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y # CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC is not set # CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set @@ -1346,7 +1665,10 @@ CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 # CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set # CONFIG_MBEDTLS_DEBUG is not set + +# # mbedTLS v3.x related +# # CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set # CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set # CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set @@ -1354,7 +1676,10 @@ CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y CONFIG_MBEDTLS_PKCS7_C=y # end of mbedTLS v3.x related + +# # Certificate Bundle +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set @@ -1363,6 +1688,7 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 # end of Certificate Bundle + # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set CONFIG_MBEDTLS_CMAC_C=y CONFIG_MBEDTLS_HARDWARE_AES=y @@ -1390,7 +1716,10 @@ CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y CONFIG_MBEDTLS_TLS_SERVER=y CONFIG_MBEDTLS_TLS_CLIENT=y CONFIG_MBEDTLS_TLS_ENABLED=y + +# # TLS Key Exchange Methods +# # CONFIG_MBEDTLS_PSK_MODES is not set CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y @@ -1399,6 +1728,7 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y # end of TLS Key Exchange Methods + CONFIG_MBEDTLS_SSL_RENEGOTIATION=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y # CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set @@ -1406,7 +1736,10 @@ CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# # Symmetric Ciphers +# CONFIG_MBEDTLS_AES_C=y # CONFIG_MBEDTLS_CAMELLIA_C is not set # CONFIG_MBEDTLS_DES_C is not set @@ -1416,13 +1749,18 @@ CONFIG_MBEDTLS_CCM_C=y CONFIG_MBEDTLS_GCM_C=y # CONFIG_MBEDTLS_NIST_KW_C is not set # end of Symmetric Ciphers + # CONFIG_MBEDTLS_RIPEMD160_C is not set + +# # Certificates +# CONFIG_MBEDTLS_PEM_PARSE_C=y CONFIG_MBEDTLS_PEM_WRITE_C=y CONFIG_MBEDTLS_X509_CRL_PARSE_C=y CONFIG_MBEDTLS_X509_CSR_PARSE_C=y # end of Certificates + CONFIG_MBEDTLS_ECP_C=y # CONFIG_MBEDTLS_DHM_C is not set CONFIG_MBEDTLS_ECDH_C=y @@ -1449,7 +1787,10 @@ CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM=y CONFIG_MBEDTLS_ERROR_STRINGS=y CONFIG_MBEDTLS_FS_IO=y # end of mbedTLS + +# # ESP-MQTT Configurations +# CONFIG_MQTT_PROTOCOL_311=y # CONFIG_MQTT_PROTOCOL_5 is not set CONFIG_MQTT_TRANSPORT_SSL=y @@ -1462,7 +1803,10 @@ CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y # CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set # CONFIG_MQTT_CUSTOM_OUTBOX is not set # end of ESP-MQTT Configurations + +# # Newlib +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y # CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set # CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set @@ -1475,15 +1819,25 @@ CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set # CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set # end of Newlib + CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND=y + +# # NVS +# # CONFIG_NVS_ENCRYPTION is not set # CONFIG_NVS_ASSERT_ERROR_CHECK is not set # CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set # end of NVS + +# # OpenThread +# # CONFIG_OPENTHREAD_ENABLED is not set + +# # Thread Operational Dataset +# CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP" CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX="fd00:db8:a0:0::/64" CONFIG_OPENTHREAD_NETWORK_CHANNEL=15 @@ -1492,18 +1846,28 @@ CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe" CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" # end of Thread Operational Dataset + CONFIG_OPENTHREAD_XTAL_ACCURACY=130 # CONFIG_OPENTHREAD_SPINEL_ONLY is not set CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE=y + +# # Thread Address Query Config +# # end of Thread Address Query Config # end of OpenThread + +# # Protocomm +# CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y # end of Protocomm + +# # PThreads +# CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 CONFIG_PTHREAD_STACK_MIN=768 @@ -1513,18 +1877,33 @@ CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" # end of PThreads + +# # MMU Config +# CONFIG_MMU_PAGE_SIZE_64KB=y CONFIG_MMU_PAGE_MODE="64KB" CONFIG_MMU_PAGE_SIZE=0x10000 # end of MMU Config + +# # Main Flash configuration +# + +# # SPI Flash behavior when brownout +# CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y CONFIG_SPI_FLASH_BROWNOUT_RESET=y # end of SPI Flash behavior when brownout + +# # Optional and Experimental Features (READ DOCS FIRST) +# + +# # Features here require specific hardware (READ DOCS FIRST!) +# # CONFIG_SPI_FLASH_HPM_ENA is not set CONFIG_SPI_FLASH_HPM_AUTO=y # CONFIG_SPI_FLASH_HPM_DIS is not set @@ -1537,7 +1916,10 @@ CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 # CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set # end of Optional and Experimental Features (READ DOCS FIRST) # end of Main Flash configuration + +# # SPI Flash driver +# # CONFIG_SPI_FLASH_VERIFY_WRITE is not set # CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y @@ -1553,7 +1935,10 @@ CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 # CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set # CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set # CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# # Auto-detect flash chips +# CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y @@ -1569,15 +1954,23 @@ CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP=y CONFIG_SPI_FLASH_SUPPORT_TH_CHIP=y CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP=y # end of Auto-detect flash chips + CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y # end of SPI Flash driver + +# # SPIFFS Configuration +# CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# # SPIFFS Cache Configuration +# CONFIG_SPIFFS_CACHE=y CONFIG_SPIFFS_CACHE_WR=y # CONFIG_SPIFFS_CACHE_STATS is not set # end of SPIFFS Cache Configuration + CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 # CONFIG_SPIFFS_GC_STATS is not set @@ -1588,7 +1981,10 @@ CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y CONFIG_SPIFFS_META_LENGTH=4 CONFIG_SPIFFS_USE_MTIME=y + +# # Debug Configuration +# # CONFIG_SPIFFS_DBG is not set # CONFIG_SPIFFS_API_DBG is not set # CONFIG_SPIFFS_GC_DBG is not set @@ -1597,19 +1993,34 @@ CONFIG_SPIFFS_USE_MTIME=y # CONFIG_SPIFFS_TEST_VISUALISATION is not set # end of Debug Configuration # end of SPIFFS Configuration + +# # TCP Transport +# + +# # Websocket +# CONFIG_WS_TRANSPORT=y CONFIG_WS_BUFFER_SIZE=1024 # CONFIG_WS_DYNAMIC_BUFFER is not set # end of Websocket # end of TCP Transport + +# # Ultra Low Power (ULP) Co-processor +# # CONFIG_ULP_COPROC_ENABLED is not set + +# # ULP Debugging Options +# # end of ULP Debugging Options # end of Ultra Low Power (ULP) Co-processor + +# # Unity unit testing library +# CONFIG_UNITY_ENABLE_FLOAT=y CONFIG_UNITY_ENABLE_DOUBLE=y # CONFIG_UNITY_ENABLE_64BIT is not set @@ -1618,24 +2029,38 @@ CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y # CONFIG_UNITY_ENABLE_FIXTURE is not set # CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set # end of Unity unit testing library + +# # USB-OTG +# CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE=256 CONFIG_USB_HOST_HW_BUFFER_BIAS_BALANCED=y # CONFIG_USB_HOST_HW_BUFFER_BIAS_IN is not set # CONFIG_USB_HOST_HW_BUFFER_BIAS_PERIODIC_OUT is not set + +# # Hub Driver Configuration +# + +# # Root Port configuration +# CONFIG_USB_HOST_DEBOUNCE_DELAY_MS=250 CONFIG_USB_HOST_RESET_HOLD_MS=30 CONFIG_USB_HOST_RESET_RECOVERY_MS=30 CONFIG_USB_HOST_SET_ADDR_RECOVERY_MS=10 # end of Root Port configuration + # CONFIG_USB_HOST_HUBS_SUPPORTED is not set # end of Hub Driver Configuration + # CONFIG_USB_HOST_ENABLE_ENUM_FILTER_CALLBACK is not set CONFIG_USB_OTG_SUPPORTED=y # end of USB-OTG + +# # Virtual file system +# CONFIG_VFS_SUPPORT_IO=y CONFIG_VFS_SUPPORT_DIR=y CONFIG_VFS_SUPPORT_SELECT=y @@ -1643,22 +2068,103 @@ CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y # CONFIG_VFS_SELECT_IN_RAM is not set CONFIG_VFS_SUPPORT_TERMIOS=y CONFIG_VFS_MAX_COUNT=8 + +# # Host File System I/O (Semihosting) +# CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 # end of Host File System I/O (Semihosting) # end of Virtual file system + +# # Wear Levelling +# # CONFIG_WL_SECTOR_SIZE_512 is not set CONFIG_WL_SECTOR_SIZE_4096=y CONFIG_WL_SECTOR_SIZE=4096 # end of Wear Levelling + +# # Wi-Fi Provisioning Manager +# CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set # end of Wi-Fi Provisioning Manager + +# +# USB Device UVC +# +CONFIG_TUSB_VID=0x303A +CONFIG_TUSB_PID=0x8000 +CONFIG_TUSB_MANUFACTURER="ETVR" +CONFIG_TUSB_PRODUCT="OpenIris Camera" +CONFIG_TUSB_SERIAL_NUM="12345678" +# CONFIG_UVC_SUPPORT_TWO_CAM is not set + +# +# USB Cam1 Config +# +CONFIG_FORMAT_MJPEG_CAM1=y +# CONFIG_FORMAT_H264_CAM1 is not set +# CONFIG_FORMAT_UNCOMPR_CAM1 is not set +# CONFIG_UVC_MODE_ISOC_CAM1 is not set +CONFIG_UVC_MODE_BULK_CAM1=y +CONFIG_FRAMESIZE_QVGA=y +# CONFIG_FRAMESIZE_HVGA is not set +# CONFIG_FRAMESIZE_VGA is not set +# 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_FRAMESIZE_WIDTH=240 +CONFIG_UVC_CAM1_FRAMESIZE_HEIGT=240 +CONFIG_UVC_CAM1_MULTI_FRAMESIZE=y +# end of USB Cam1 Config + +# +# UVC_MULTI_FRAME_CONFIG +# + +# +# FRAME_SIZE_1 +# +CONFIG_UVC_MULTI_FRAME_WIDTH_1=240 +CONFIG_UVC_MULTI_FRAME_HEIGHT_1=240 +CONFIG_UVC_MULTI_FRAME_FPS_1=90 +# end of FRAME_SIZE_1 + +# +# FRAME_SIZE_2 +# +CONFIG_UVC_MULTI_FRAME_WIDTH_2=240 +CONFIG_UVC_MULTI_FRAME_HEIGHT_2=240 +CONFIG_UVC_MULTI_FRAME_FPS_2=90 +# end of FRAME_SIZE_2 + +# +# FRAME_SIZE_3 +# +CONFIG_UVC_MULTI_FRAME_WIDTH_3=240 +CONFIG_UVC_MULTI_FRAME_HEIGHT_3=240 +CONFIG_UVC_MULTI_FRAME_FPS_3=90 +# end of FRAME_SIZE_3 +# end of UVC_MULTI_FRAME_CONFIG + +# +# UVC Task Config +# +CONFIG_UVC_TINYUSB_TASK_PRIORITY=3 +CONFIG_UVC_TINYUSB_TASK_CORE=-1 +CONFIG_UVC_CAM1_TASK_PRIORITY=2 +CONFIG_UVC_CAM1_TASK_CORE=-1 +# end of UVC Task Config +# end of USB Device UVC + +# # CMake Utilities +# # CONFIG_CU_RELINKER_ENABLE is not set # CONFIG_CU_DIAGNOSTICS_COLOR_NEVER is not set CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y @@ -1666,7 +2172,10 @@ CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y # CONFIG_CU_GCC_LTO_ENABLE is not set # CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set # end of CMake Utilities + +# # Camera configuration +# # CONFIG_OV7670_SUPPORT is not set # CONFIG_OV7725_SUPPORT is not set # CONFIG_NT99141_SUPPORT is not set @@ -1694,7 +2203,10 @@ CONFIG_CAMERA_JPEG_MODE_FRAME_SIZE_AUTO=y # CONFIG_CAMERA_CONVERTER_ENABLED is not set # CONFIG_LCD_CAM_ISR_IRAM_SAFE is not set # end of Camera configuration + +# # mDNS +# CONFIG_MDNS_MAX_INTERFACES=3 CONFIG_MDNS_MAX_SERVICES=10 CONFIG_MDNS_TASK_PRIORITY=1 @@ -1712,62 +2224,19 @@ CONFIG_MDNS_TIMER_PERIOD_MS=100 CONFIG_MDNS_ENABLE_CONSOLE_CLI=y # CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set CONFIG_MDNS_MULTIPLE_INSTANCE=y + +# # MDNS Predefined interfaces +# CONFIG_MDNS_PREDEF_NETIF_STA=y CONFIG_MDNS_PREDEF_NETIF_AP=y CONFIG_MDNS_PREDEF_NETIF_ETH=y # end of MDNS Predefined interfaces # end of mDNS -# USB Device UVC -CONFIG_TUSB_VID=0x303A -CONFIG_TUSB_PID=0x8000 -CONFIG_TUSB_MANUFACTURER="ETVR" -CONFIG_TUSB_PRODUCT="OpenIris Camera" -CONFIG_TUSB_SERIAL_NUM="12345678" -# CONFIG_UVC_SUPPORT_TWO_CAM is not set -# USB Cam1 Config -CONFIG_FORMAT_MJPEG_CAM1=y -# CONFIG_FORMAT_H264_CAM1 is not set -# CONFIG_FORMAT_UNCOMPR_CAM1 is not set -# CONFIG_UVC_MODE_ISOC_CAM1 is not set -CONFIG_UVC_MODE_BULK_CAM1=y -CONFIG_FRAMESIZE_QVGA=y -# CONFIG_FRAMESIZE_HVGA is not set -# CONFIG_FRAMESIZE_VGA is not set -# 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_FRAMESIZE_WIDTH=240 -CONFIG_UVC_CAM1_FRAMESIZE_HEIGT=240 -CONFIG_UVC_CAM1_MULTI_FRAMESIZE=y -# end of USB Cam1 Config -# UVC_MULTI_FRAME_CONFIG -# FRAME_SIZE_1 -CONFIG_UVC_MULTI_FRAME_WIDTH_1=240 -CONFIG_UVC_MULTI_FRAME_HEIGHT_1=240 -CONFIG_UVC_MULTI_FRAME_FPS_1=60 -# end of FRAME_SIZE_1 -# FRAME_SIZE_2 -CONFIG_UVC_MULTI_FRAME_WIDTH_2=240 -CONFIG_UVC_MULTI_FRAME_HEIGHT_2=240 -CONFIG_UVC_MULTI_FRAME_FPS_2=60 -# end of FRAME_SIZE_2 -# FRAME_SIZE_3 -CONFIG_UVC_MULTI_FRAME_WIDTH_3=240 -CONFIG_UVC_MULTI_FRAME_HEIGHT_3=240 -CONFIG_UVC_MULTI_FRAME_FPS_3=60 -# end of FRAME_SIZE_3 -# end of UVC_MULTI_FRAME_CONFIG -# UVC Task Config -CONFIG_UVC_TINYUSB_TASK_PRIORITY=4 -CONFIG_UVC_TINYUSB_TASK_CORE=-1 -CONFIG_UVC_CAM1_TASK_PRIORITY=3 -CONFIG_UVC_CAM1_TASK_CORE=-1 -# end of UVC Task Config -# end of USB Device UVC # end of Component config + # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set + # Deprecated options for backward compatibility # CONFIG_APP_BUILD_TYPE_ELF_RAM is not set # CONFIG_NO_BLOBS is not set @@ -1857,6 +2326,7 @@ CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y CONFIG_ESP32S3_DEBUG_OCDAWARE=y CONFIG_BROWNOUT_DET=y CONFIG_ESP32S3_BROWNOUT_DET=y +CONFIG_ESP32S3_BROWNOUT_DET=y CONFIG_BROWNOUT_DET_LVL_SEL_7=y CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_7=y # CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set @@ -1886,6 +2356,8 @@ CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=6 CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 CONFIG_ESP32_WIFI_RX_BA_WIN=6 # CONFIG_ESP32_WIFI_AMSDU_TX_ENABLED is not set CONFIG_ESP32_WIFI_NVS_ENABLED=y @@ -1960,4 +2432,3 @@ CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 # End of deprecated options -CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL=y