diff --git a/.gitlab/ci/dependencies/dependencies.yml b/.gitlab/ci/dependencies/dependencies.yml index 81e16ef15e..ca235d25eb 100644 --- a/.gitlab/ci/dependencies/dependencies.yml +++ b/.gitlab/ci/dependencies/dependencies.yml @@ -128,6 +128,7 @@ build:integration_test: - wifi # example_test_002, example_test*wifi* - ethernet # example_test*ethernet* - sdio # UT_044, UT_045 + - usb # USB Device & Host tests - adc # component_ut_pytest_esp32x_adc patterns: - "{0}-{1}-{2}" diff --git a/.gitlab/ci/rules.yml b/.gitlab/ci/rules.yml index e5606273c7..582ea63a4e 100644 --- a/.gitlab/ci/rules.yml +++ b/.gitlab/ci/rules.yml @@ -224,6 +224,15 @@ - "components/driver/**/*" - "components/sdmmc/**/*" +# for jobs: example_test_pytest_esp32s3_usb_device and test_app_test_pytest_esp32s2_usb_host: +.patterns-example_test-usb: &patterns-example_test-usb + - "components/hal/usb*.c" + - "components/hal/esp32s*/include/hal/usb*.h" + - "components/tinyusb/**/**/*" + - "components/usb/**/*" + - "examples/peripherals/usb/host/**/**/**/*" + - "examples/peripherals/usb/device/**/**/*" + # for jobs: component_ut_pytest_esp32x_adc: .patterns-component_ut-adc: &patterns-component_ut-adc - "components/esp_adc/**/*" @@ -232,6 +241,7 @@ - "components/esp_hw_support/**/*" - "components/efuse/**/*" + ############## # if anchors # ############## @@ -824,6 +834,8 @@ changes: *patterns-example_test-bt - <<: *if-dev-push changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-usb - <<: *if-dev-push changes: *patterns-example_test-wifi - <<: *if-dev-push @@ -852,6 +864,8 @@ changes: *patterns-example_test-bt - <<: *if-dev-push changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-usb - <<: *if-dev-push changes: *patterns-example_test-wifi - <<: *if-dev-push @@ -878,6 +892,8 @@ changes: *patterns-example_test-bt - <<: *if-dev-push changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-usb - <<: *if-dev-push changes: *patterns-example_test-wifi - <<: *if-dev-push @@ -905,6 +921,8 @@ changes: *patterns-example_test-bt - <<: *if-dev-push changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-usb - <<: *if-dev-push changes: *patterns-example_test-wifi - <<: *if-dev-push @@ -931,6 +949,8 @@ changes: *patterns-example_test-bt - <<: *if-dev-push changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-usb - <<: *if-dev-push changes: *patterns-example_test-wifi - <<: *if-dev-push @@ -957,6 +977,8 @@ changes: *patterns-example_test-bt - <<: *if-dev-push changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-usb - <<: *if-dev-push changes: *patterns-example_test-wifi - <<: *if-dev-push @@ -983,6 +1005,8 @@ changes: *patterns-example_test-bt - <<: *if-dev-push changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-usb - <<: *if-dev-push changes: *patterns-example_test-wifi - <<: *if-dev-push @@ -1080,6 +1104,8 @@ changes: *patterns-example_test-bt - <<: *if-dev-push changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-usb - <<: *if-dev-push changes: *patterns-example_test-wifi - <<: *if-dev-push @@ -1345,6 +1371,17 @@ - <<: *if-label-component_ut_esp32 - <<: *if-label-target_test +.rules:test:component_ut-esp32-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-component_ut + - <<: *if-label-component_ut_esp32 + - <<: *if-label-target_test + .rules:test:component_ut-esp32-wifi: rules: - <<: *if-revert-branch @@ -1419,6 +1456,17 @@ - <<: *if-label-component_ut_esp32c2 - <<: *if-label-target_test +.rules:test:component_ut-esp32c2-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-component_ut + - <<: *if-label-component_ut_esp32c2 + - <<: *if-label-target_test + .rules:test:component_ut-esp32c2-wifi: rules: - <<: *if-revert-branch @@ -1493,6 +1541,17 @@ - <<: *if-label-component_ut_esp32c3 - <<: *if-label-target_test +.rules:test:component_ut-esp32c3-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-component_ut + - <<: *if-label-component_ut_esp32c3 + - <<: *if-label-target_test + .rules:test:component_ut-esp32c3-wifi: rules: - <<: *if-revert-branch @@ -1567,6 +1626,17 @@ - <<: *if-label-component_ut_esp32h2 - <<: *if-label-target_test +.rules:test:component_ut-esp32h2-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-component_ut + - <<: *if-label-component_ut_esp32h2 + - <<: *if-label-target_test + .rules:test:component_ut-esp32h2-wifi: rules: - <<: *if-revert-branch @@ -1641,6 +1711,17 @@ - <<: *if-label-component_ut_esp32s2 - <<: *if-label-target_test +.rules:test:component_ut-esp32s2-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-component_ut + - <<: *if-label-component_ut_esp32s2 + - <<: *if-label-target_test + .rules:test:component_ut-esp32s2-wifi: rules: - <<: *if-revert-branch @@ -1715,6 +1796,17 @@ - <<: *if-label-component_ut_esp32s3 - <<: *if-label-target_test +.rules:test:component_ut-esp32s3-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-component_ut + - <<: *if-label-component_ut_esp32s3 + - <<: *if-label-target_test + .rules:test:component_ut-esp32s3-wifi: rules: - <<: *if-revert-branch @@ -1785,6 +1877,17 @@ - <<: *if-label-custom_test_esp32 - <<: *if-label-target_test +.rules:test:custom_test-esp32-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-custom_test + - <<: *if-label-custom_test_esp32 + - <<: *if-label-target_test + .rules:test:custom_test-esp32-wifi: rules: - <<: *if-revert-branch @@ -1855,6 +1958,17 @@ - <<: *if-label-custom_test_esp32c2 - <<: *if-label-target_test +.rules:test:custom_test-esp32c2-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-custom_test + - <<: *if-label-custom_test_esp32c2 + - <<: *if-label-target_test + .rules:test:custom_test-esp32c2-wifi: rules: - <<: *if-revert-branch @@ -1925,6 +2039,17 @@ - <<: *if-label-custom_test_esp32c3 - <<: *if-label-target_test +.rules:test:custom_test-esp32c3-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-custom_test + - <<: *if-label-custom_test_esp32c3 + - <<: *if-label-target_test + .rules:test:custom_test-esp32c3-wifi: rules: - <<: *if-revert-branch @@ -1995,6 +2120,17 @@ - <<: *if-label-custom_test_esp32h2 - <<: *if-label-target_test +.rules:test:custom_test-esp32h2-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-custom_test + - <<: *if-label-custom_test_esp32h2 + - <<: *if-label-target_test + .rules:test:custom_test-esp32h2-wifi: rules: - <<: *if-revert-branch @@ -2065,6 +2201,17 @@ - <<: *if-label-custom_test_esp32s2 - <<: *if-label-target_test +.rules:test:custom_test-esp32s2-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-custom_test + - <<: *if-label-custom_test_esp32s2 + - <<: *if-label-target_test + .rules:test:custom_test-esp32s2-wifi: rules: - <<: *if-revert-branch @@ -2135,6 +2282,17 @@ - <<: *if-label-custom_test_esp32s3 - <<: *if-label-target_test +.rules:test:custom_test-esp32s3-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-custom_test + - <<: *if-label-custom_test_esp32s3 + - <<: *if-label-target_test + .rules:test:custom_test-esp32s3-wifi: rules: - <<: *if-revert-branch @@ -2220,6 +2378,19 @@ - <<: *if-label-example_test_esp32 - <<: *if-label-target_test +.rules:test:example_test-esp32-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-example_test + - <<: *if-label-example_test_esp32 + - <<: *if-label-target_test + - <<: *if-dev-push + changes: *patterns-example_test-usb + .rules:test:example_test-esp32-wifi: rules: - <<: *if-revert-branch @@ -2298,6 +2469,19 @@ - <<: *if-label-example_test_esp32c2 - <<: *if-label-target_test +.rules:test:example_test-esp32c2-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-example_test + - <<: *if-label-example_test_esp32c2 + - <<: *if-label-target_test + - <<: *if-dev-push + changes: *patterns-example_test-usb + .rules:test:example_test-esp32c2-wifi: rules: - <<: *if-revert-branch @@ -2385,6 +2569,19 @@ - <<: *if-label-example_test_esp32c3 - <<: *if-label-target_test +.rules:test:example_test-esp32c3-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-example_test + - <<: *if-label-example_test_esp32c3 + - <<: *if-label-target_test + - <<: *if-dev-push + changes: *patterns-example_test-usb + .rules:test:example_test-esp32c3-wifi: rules: - <<: *if-revert-branch @@ -2463,6 +2660,19 @@ - <<: *if-label-example_test_esp32h2 - <<: *if-label-target_test +.rules:test:example_test-esp32h2-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-example_test + - <<: *if-label-example_test_esp32h2 + - <<: *if-label-target_test + - <<: *if-dev-push + changes: *patterns-example_test-usb + .rules:test:example_test-esp32h2-wifi: rules: - <<: *if-revert-branch @@ -2541,6 +2751,19 @@ - <<: *if-label-example_test_esp32s2 - <<: *if-label-target_test +.rules:test:example_test-esp32s2-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-example_test + - <<: *if-label-example_test_esp32s2 + - <<: *if-label-target_test + - <<: *if-dev-push + changes: *patterns-example_test-usb + .rules:test:example_test-esp32s2-wifi: rules: - <<: *if-revert-branch @@ -2619,6 +2842,19 @@ - <<: *if-label-example_test_esp32s3 - <<: *if-label-target_test +.rules:test:example_test-esp32s3-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-example_test + - <<: *if-label-example_test_esp32s3 + - <<: *if-label-target_test + - <<: *if-dev-push + changes: *patterns-example_test-usb + .rules:test:example_test-esp32s3-wifi: rules: - <<: *if-revert-branch @@ -2761,6 +2997,17 @@ - <<: *if-dev-push changes: *patterns-unit_test-sdio +.rules:test:unit_test-esp32-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-target_test + - <<: *if-label-unit_test + - <<: *if-label-unit_test_esp32 + .rules:test:unit_test-esp32-wifi: rules: - <<: *if-revert-branch @@ -2833,6 +3080,17 @@ - <<: *if-dev-push changes: *patterns-unit_test-sdio +.rules:test:unit_test-esp32c2-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-target_test + - <<: *if-label-unit_test + - <<: *if-label-unit_test_esp32c2 + .rules:test:unit_test-esp32c2-wifi: rules: - <<: *if-revert-branch @@ -2905,6 +3163,17 @@ - <<: *if-dev-push changes: *patterns-unit_test-sdio +.rules:test:unit_test-esp32c3-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-target_test + - <<: *if-label-unit_test + - <<: *if-label-unit_test_esp32c3 + .rules:test:unit_test-esp32c3-wifi: rules: - <<: *if-revert-branch @@ -2977,6 +3246,17 @@ - <<: *if-dev-push changes: *patterns-unit_test-sdio +.rules:test:unit_test-esp32h2-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-target_test + - <<: *if-label-unit_test + - <<: *if-label-unit_test_esp32h2 + .rules:test:unit_test-esp32h2-wifi: rules: - <<: *if-revert-branch @@ -3049,6 +3329,17 @@ - <<: *if-dev-push changes: *patterns-unit_test-sdio +.rules:test:unit_test-esp32s2-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-target_test + - <<: *if-label-unit_test + - <<: *if-label-unit_test_esp32s2 + .rules:test:unit_test-esp32s2-wifi: rules: - <<: *if-revert-branch @@ -3121,6 +3412,17 @@ - <<: *if-dev-push changes: *patterns-unit_test-sdio +.rules:test:unit_test-esp32s3-usb: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-target_test + - <<: *if-label-unit_test + - <<: *if-label-unit_test_esp32s3 + .rules:test:unit_test-esp32s3-wifi: rules: - <<: *if-revert-branch diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index 2262bc30c6..e77e68b280 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -396,6 +396,14 @@ component_ut_pytest_esp32c3_flash_encryption: - build_pytest_components_esp32c3 tags: [ esp32c3, flash_encryption ] +component_ut_pytest_esp32s3_usb_host: + extends: + - .pytest_components_dir_template + - .rules:test:component_ut-esp32s3-usb + needs: + - build_pytest_components_esp32s3 + tags: [ esp32s3, usb_host_flash_disk ] + .pytest_test_apps_dir_template: extends: .pytest_template variables: diff --git a/docs/en/api-reference/peripherals/usb_device.rst b/docs/en/api-reference/peripherals/usb_device.rst index 6e3574abc3..9a3d9b091a 100644 --- a/docs/en/api-reference/peripherals/usb_device.rst +++ b/docs/en/api-reference/peripherals/usb_device.rst @@ -11,7 +11,7 @@ USB Device Driver Overview -------- -The driver allows users to use {IDF_TARGET_NAME} chips to develop USB devices on a top of the TinyUSB stack. TinyUSB is integrated with ESP-IDF to provide USB features of the framework. Using this driver the chip works as a composite device supporting several USB devices simultaneously. Currently, only the Communications Device Class (CDC) type of the device with the Abstract Control Model (ACM) subclass and the Musical Instrument Digital Interface (MIDI) are supported. +The driver allows you to use {IDF_TARGET_NAME} chips to develop USB devices on a top of TinyUSB stack. TinyUSB is integrated with ESP-IDF to provide USB features of the framework. Using this driver the chip works as simple or composite device supporting several USB devices simultaneously. TinyUSB stack is distributed via `IDF Component Registry `_. @@ -38,7 +38,7 @@ On {IDF_TARGET_NAME}, connect GPIO {IDF_TARGET_USB_DP_GPIO_NUM} and {IDF_TARGET_ .. figure:: ../../../_static/usb-board-connection.png :align: center - :alt: Connection of an ESP board to a USB host + :alt: Connection of an ESP board to a USB host :figclass: align-center Self-powered devices must also connect VBUS through voltage divider or comparator, more details in :ref:`self-powered-device` subchapter. @@ -68,9 +68,9 @@ Via Menuconfig options you can specify: Descriptors Configuration ^^^^^^^^^^^^^^^^^^^^^^^^^ -The driver's descriptors are provided by the :cpp:type:`tinyusb_config_t` structure's :cpp:member:`descriptor` and :cpp:member:`string_descriptor` members. Therefore, users should initialize :cpp:type:`tinyusb_config_t` to their desired descriptor before calling :cpp:func:`tinyusb_driver_install` to install driver. +The driver's descriptors are provided by :cpp:type:`tinyusb_config_t` structure's :cpp:member:`device_descriptor`, :cpp:member:`configuration_descriptor` and :cpp:member:`string_descriptor` members. Therefore, you should initialize :cpp:type:`tinyusb_config_t` with your desired descriptors before calling :cpp:func:`tinyusb_driver_install` to install the driver. -However, the driver also provides a default descriptor. The driver can be installed with the default descriptor by setting the :cpp:member:`descriptor` and :cpp:member:`string_descriptor` members of :cpp:type:`tinyusb_config_t` to `NULL` before calling :cpp:func:`tinyusb_driver_install`. The driver's default descriptor is specified using Menuconfig, where the following fields should be configured: +However, the driver also provides default descriptors. You can install the driver with default device and string descriptors by setting the :cpp:member:`device_descriptor` and :cpp:member:`string_descriptor` members of :cpp:type:`tinyusb_config_t` to `NULL` before calling :cpp:func:`tinyusb_driver_install`. To lower your development effort we also provide default configuration descriptor for CDC and MSC class, as these classes rarely require custom configuration. The driver's default device descriptor is specified using Menuconfig, where the following fields should be configured: - PID - VID @@ -87,14 +87,15 @@ Install Driver To initialize the driver, users should call :cpp:func:`tinyusb_driver_install`. The driver's configuration is specified in a :cpp:type:`tinyusb_config_t` structure that is passed as an argument to :cpp:func:`tinyusb_driver_install`. - Note that the :cpp:type:`tinyusb_config_t` structure can be zero initialized (e.g. ``tinyusb_config_t tusb_cfg = { 0 }``) or partially (as shown below). For any member that is initialized to `0` or `NULL`, the driver will use its default configuration values for that member (see example below) + Note that the :cpp:type:`tinyusb_config_t` structure can be zero initialized (e.g. ``const tinyusb_config_t tusb_cfg = { 0 };``) or partially (as shown below). For any member that is initialized to `0` or `NULL`, the driver will use its default configuration values for that member (see example below) .. code-block:: c const tinyusb_config_t partial_init = { - .descriptor = NULL; //Uses default descriptor specified in Menuconfig - .string_descriptor = NULL; //Uses default string specified in Menuconfig - .external_phy = false; + .device_descriptor = NULL, // Use default device descriptor specified in Menuconfig + .string_descriptor = NULL, // Use default string descriptors specified in Menuconfig + .external_phy = false, // Use internal USB PHY + .configuration_descriptor = NULL, // Use default configuration descriptor according to settings in Menuconfig }; .. _self-powered-device: @@ -118,11 +119,11 @@ To use this feature, in :cpp:type:`tinyusb_config_t` you must set :cpp:member:`s USB Serial Device (CDC-ACM) --------------------------- -If the CDC option is enabled in Menuconfig, the USB Serial Device could be initialized with :cpp:func:`tusb_cdc_acm_init` according to the settings from :cpp:type:`tinyusb_config_cdcacm_t` (see example below). +If the CDC option is enabled in Menuconfig, the USB Serial Device can be initialized with :cpp:func:`tusb_cdc_acm_init` according to the settings from :cpp:type:`tinyusb_config_cdcacm_t` (see example below). .. code-block:: c - tinyusb_config_cdcacm_t acm_cfg = { + const tinyusb_config_cdcacm_t acm_cfg = { .usb_dev = TINYUSB_USBDEV_0, .cdc_port = TINYUSB_CDC_ACM_0, .rx_unread_buf_sz = 64, diff --git a/examples/peripherals/usb/device/.build-test-rules.yml b/examples/peripherals/usb/device/.build-test-rules.yml new file mode 100644 index 0000000000..2e88c76571 --- /dev/null +++ b/examples/peripherals/usb/device/.build-test-rules.yml @@ -0,0 +1,9 @@ +# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps + +examples/peripherals/usb/device: + enable: + - if: SOC_USB_OTG_SUPPORTED == 1 + disable_test: + - if: IDF_TARGET == "esp32s3" + temporary: true + reason: lack of runners diff --git a/examples/peripherals/usb/device/tusb_console/pytest_usb_device_console.py b/examples/peripherals/usb/device/tusb_console/pytest_usb_device_console.py new file mode 100644 index 0000000000..aa383f6a2b --- /dev/null +++ b/examples/peripherals/usb/device/tusb_console/pytest_usb_device_console.py @@ -0,0 +1,35 @@ +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +from time import sleep + +import pytest +from pytest_embedded import Dut +from serial import Serial +from serial.tools.list_ports import comports + + +@pytest.mark.esp32s2 +@pytest.mark.usb_device +def test_usb_device_console_example(dut: Dut) -> None: + dut.expect_exact('USB initialization DONE') + dut.expect_exact('example: log -> UART') + dut.expect_exact('example: print -> stdout') + dut.expect_exact('example: print -> stderr') + + # Find device with Espressif TinyUSB VID/PID + sleep(2) # Some time for the OS to enumerate our USB device + ports = comports() + for port, _, hwid in ports: + if '303A:4001' in hwid: + with Serial(port) as s: + # Assert TinyUSB output: Read 3 lines and check their content + serial_output = list() + serial_output.append(s.readline()) + serial_output.append(s.readline()) + serial_output.append(s.readline()) + assert any(b'example: log -> USB' in out for out in serial_output) + assert any(b'example: print -> stdout' in out for out in serial_output) + assert any(b'example: print -> stderr' in out for out in serial_output) + return + + raise Exception('TinyUSB COM port not found') diff --git a/examples/peripherals/usb/device/tusb_hid/pytest_usb_device_hid.py b/examples/peripherals/usb/device/tusb_hid/pytest_usb_device_hid.py new file mode 100644 index 0000000000..d99e1f7778 --- /dev/null +++ b/examples/peripherals/usb/device/tusb_hid/pytest_usb_device_hid.py @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32s2 +@pytest.mark.usb_device +def test_usb_device_hid_example(dut: Dut) -> None: + dut.expect_exact('USB initialization DONE') + dut.expect_exact('Sending Keyboard report') + dut.expect_exact('Sending Mouse report') diff --git a/examples/peripherals/usb/device/tusb_midi/main/tusb_midi_main.c b/examples/peripherals/usb/device/tusb_midi/main/tusb_midi_main.c index 231393e5ef..55692b050f 100644 --- a/examples/peripherals/usb/device/tusb_midi/main/tusb_midi_main.c +++ b/examples/peripherals/usb/device/tusb_midi/main/tusb_midi_main.c @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: MIT * - * SPDX-FileContributor: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2022-2023 Espressif Systems (Shanghai) CO LTD */ #include @@ -57,6 +57,7 @@ static void periodic_midi_write_example_cb(void *arg) } // Send Note On for current position at full velocity (127) on channel 1. + ESP_LOGI(TAG, "Writing MIDI data %d", note_sequence[note_pos]); uint8_t note_on[3] = {0x90 | channel, note_sequence[note_pos], 127}; tud_midi_stream_write(cable_num, note_on, 3); diff --git a/examples/peripherals/usb/device/tusb_midi/pytest_usb_device_midi.py b/examples/peripherals/usb/device/tusb_midi/pytest_usb_device_midi.py new file mode 100644 index 0000000000..bba3d965c9 --- /dev/null +++ b/examples/peripherals/usb/device/tusb_midi/pytest_usb_device_midi.py @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32s2 +@pytest.mark.usb_device +def test_usb_device_midi_example(dut: Dut) -> None: + dut.expect_exact('USB initialization DONE') + dut.expect_exact('MIDI write task init') + dut.expect_exact('MIDI read task init') + dut.expect_exact('Writing MIDI data 74') diff --git a/examples/peripherals/usb/device/tusb_serial_device/pytest_usb_device_serial.py b/examples/peripherals/usb/device/tusb_serial_device/pytest_usb_device_serial.py new file mode 100644 index 0000000000..e1a6713b50 --- /dev/null +++ b/examples/peripherals/usb/device/tusb_serial_device/pytest_usb_device_serial.py @@ -0,0 +1,29 @@ +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +from time import sleep + +import pytest +from pytest_embedded import Dut +from serial import Serial +from serial.tools.list_ports import comports + + +@pytest.mark.esp32s2 +@pytest.mark.usb_device +def test_usb_device_serial_example(dut: Dut) -> None: + dut.expect_exact('USB initialization DONE') + sleep(2) # Some time for the OS to enumerate our USB device + + # Find device with Espressif TinyUSB VID/PID + ports = comports() + for port, _, hwid in ports: + if '303A:4001' in hwid: + with Serial(port) as s: + s.write('text\r\n'.encode()) # Write dummy text to COM port + dut.expect_exact('Data from channel 0:') # Check ESP log + dut.expect_exact('|text..|') + res = s.readline() # Check COM echo + assert b'text\r\n' in res + return + + raise Exception('TinyUSB COM port not found') diff --git a/examples/peripherals/usb/device/tusb_serial_device/sdkconfig.ci b/examples/peripherals/usb/device/tusb_serial_device/sdkconfig.ci new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pytest.ini b/pytest.ini index cfa8a9b546..16d6d3ac65 100644 --- a/pytest.ini +++ b/pytest.ini @@ -37,6 +37,7 @@ markers = quad_psram: runners with quad psram octal_psram: runners with octal psram usb_host: usb host runners + usb_device: usb device runners ethernet_ota: ethernet OTA runners flash_encryption: Flash Encryption runners flash_encryption_f4r8: Flash Encryption runners with 4-line flash and 8-line psram diff --git a/tools/ci/check_copyright_config.yaml b/tools/ci/check_copyright_config.yaml index 65cb7c10f5..0349e2195f 100644 --- a/tools/ci/check_copyright_config.yaml +++ b/tools/ci/check_copyright_config.yaml @@ -153,7 +153,9 @@ tinyusb: - 'examples/peripherals/usb/device/tusb_midi/' allowed_licenses: - Apache-2.0 - - MIT + - MIT # Example derived from TinyUSB code by HaThach + - Unlicense + - CC0-1.0 # files matching this section do not perform the check # file patterns starting with ! are negated, meaning files matching them won't match the section.