Skip to content

Commit e7d7e3b

Browse files
Merge pull request #60 from espressif/feat/tinyusb_0.19
Prepare release/v0.19 branch
2 parents 331c263 + d2cdc3d commit e7d7e3b

11 files changed

+480
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Config file for build_idf_examples.yml workflow
2+
3+
paths = [
4+
"examples/peripherals/usb/device", # USB Device examples
5+
#"examples/network/sta2eth", # USB Network example
6+
]
7+
8+
manifest_files = [
9+
"examples/peripherals/.build-test-rules.yml",
10+
"examples/network/.build-test-rules.yml",
11+
]
12+
13+
recursive = true
14+
check_warnings = true
15+
target = "all"
16+
#enable_preview_targets = true
17+
18+
# build related options
19+
build_dir = "build_@t"
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/usr/bin/env python
2+
#
3+
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
import sys
7+
import argparse
8+
import yaml
9+
from pathlib import Path
10+
from glob import glob
11+
from idf_component_tools.manager import ManifestManager
12+
13+
14+
def override_with_local_component(component, local_path, app):
15+
app_path = Path(app)
16+
17+
absolute_local_path = Path(local_path).absolute()
18+
if not absolute_local_path.exists():
19+
print('[Error] {} path does not exist'.format(local_path))
20+
raise Exception
21+
if not app_path.exists():
22+
print('[Error] {} path does not exist'.format(app_path))
23+
raise Exception
24+
25+
print('[Info] Processing app {}'.format(app))
26+
manager = ManifestManager(app_path / 'main', 'app')
27+
if '/' not in component:
28+
# Prepend with default namespace
29+
component = 'espressif/' + component
30+
31+
try:
32+
manifest_tree = yaml.safe_load(Path(manager.path).read_text())
33+
manifest_tree['dependencies'][component] = {
34+
'version': '*',
35+
'override_path': str(absolute_local_path)
36+
}
37+
with open(manager.path, 'w') as f:
38+
yaml.dump(manifest_tree, f, allow_unicode=True, Dumper=yaml.SafeDumper)
39+
except KeyError:
40+
print('[Error] {} app does not depend on {}'.format(app, component))
41+
raise KeyError
42+
43+
def override_with_local_component_all(component, local_path, apps):
44+
# Process wildcard, e.g. "app_prefix_*"
45+
apps_with_glob = list()
46+
for app in apps:
47+
apps_with_glob += glob(app)
48+
49+
# Go through all collected apps
50+
for app in apps_with_glob:
51+
try:
52+
override_with_local_component(component, local_path, app)
53+
except:
54+
print("[Error] Could not process app {}".format(app))
55+
return -1
56+
return 0
57+
58+
59+
if __name__ == '__main__':
60+
parser = argparse.ArgumentParser()
61+
parser.add_argument('component', help='Existing component that the app depends on')
62+
parser.add_argument('local_path', help='Path to component that will be used instead of the managed version')
63+
parser.add_argument('apps', nargs='*', help='List of apps to process')
64+
args = parser.parse_args()
65+
sys.exit(override_with_local_component_all(args.component, args.local_path, args.apps))
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
name: ESP-USB Test Apps
2+
3+
on:
4+
pull_request:
5+
types: [opened, reopened, synchronize]
6+
7+
jobs:
8+
build:
9+
name: Build
10+
strategy:
11+
matrix:
12+
idf_ver: ["release-v5.1", "release-v5.2", "release-v5.3", "release-v5.4", "release-v5.5", "latest"]
13+
runs-on: ubuntu-latest
14+
container: espressif/idf:${{ matrix.idf_ver }}
15+
env:
16+
ESP_TINYUSB_TEST_APPS: ./esp-usb/device/esp_tinyusb/test_apps
17+
steps:
18+
- uses: actions/checkout@v4
19+
with:
20+
submodules: 'true'
21+
- name: Clone esp-usb repository
22+
run: |
23+
git clone https://github.com/espressif/esp-usb.git
24+
- name: Build
25+
shell: bash
26+
run: |
27+
. ${IDF_PATH}/export.sh
28+
pip install --no-cache-dir idf-component-manager>=2.1.2 idf-build-apps==2.13.1 pyyaml --upgrade
29+
export PEDANTIC_FLAGS="-DIDF_CI_BUILD -Werror -Werror=deprecated-declarations -Werror=unused-variable -Werror=unused-but-set-variable -Werror=unused-function"
30+
export EXTRA_CFLAGS="${PEDANTIC_FLAGS} -Wstrict-prototypes"
31+
export EXTRA_CXXFLAGS="${PEDANTIC_FLAGS}"
32+
python .github/ci/override_managed_component.py tinyusb . ${{ env.ESP_TINYUSB_TEST_APPS }}/*/
33+
cd esp-usb
34+
idf-build-apps find --path ./device/esp_tinyusb/test_apps/
35+
idf-build-apps build --path ./device/esp_tinyusb/test_apps/
36+
- uses: actions/upload-artifact@v4
37+
with:
38+
name: usb_test_app_bin_${{ matrix.idf_ver }}
39+
path: |
40+
${{env.ESP_TINYUSB_TEST_APPS}}/**/build_*/bootloader/bootloader.bin
41+
${{env.ESP_TINYUSB_TEST_APPS}}/**/build_*/partition_table/partition-table.bin
42+
${{env.ESP_TINYUSB_TEST_APPS}}/**/build_*/test_app_*.bin
43+
${{env.ESP_TINYUSB_TEST_APPS}}/**/build_*/test_app_*.elf
44+
${{env.ESP_TINYUSB_TEST_APPS}}/**/build_*/flasher_args.json
45+
${{env.ESP_TINYUSB_TEST_APPS}}/**/build_*/config/sdkconfig.json
46+
if-no-files-found: error
47+
48+
# run-target:
49+
# name: Run
50+
# if: ${{ github.repository_owner == 'espressif' }}
51+
# needs: build
52+
# strategy:
53+
# matrix:
54+
# idf_ver: ["release-v5.1", "release-v5.2", "release-v5.3", "release-v5.4", "release-v5.5", "latest"]
55+
# idf_target: ["esp32s2"]
56+
# runner_tag: ["usb_device"]
57+
# runs-on: [self-hosted, linux, docker, "${{ matrix.idf_target }}", "${{ matrix.runner_tag }}"]
58+
# container:
59+
# image: python:3.11-bookworm
60+
# options: --privileged --device-cgroup-rule="c 188:* rmw" --device-cgroup-rule="c 166:* rmw"
61+
# env:
62+
# ESP_TINYUSB_TEST_APPS: ./esp-usb/device/esp_tinyusb/test_apps
63+
# steps:
64+
# - uses: actions/checkout@v4
65+
# - name: Clone esp-usb repository
66+
# run: |
67+
# git clone https://github.com/espressif/esp-usb.git
68+
# - name: ⚙️ Install System tools
69+
# run: |
70+
# apt update
71+
# apt install -y usbutils
72+
# - name: Install Python packages
73+
# env:
74+
# PIP_EXTRA_INDEX_URL: "https://dl.espressif.com/pypi/"
75+
# run: pip install --only-binary cryptography pytest-embedded pytest-embedded-serial-esp pytest-embedded-idf pyserial pyusb
76+
# - uses: actions/download-artifact@v4
77+
# with:
78+
# name: usb_test_app_bin_${{ matrix.idf_ver }}
79+
# path: ${{env.ESP_TINYUSB_TEST_APPS}}
80+
# - name: Run USB Test App on target
81+
# run: pytest ${{env.ESP_TINYUSB_TEST_APPS}} --embedded-services esp,idf --target=${{ matrix.idf_target }} -m ${{ matrix.runner_tag }} --build-dir=build_${{ matrix.idf_target }}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: ESP-IDF USB Device examples
2+
3+
on:
4+
pull_request:
5+
types: [opened, reopened, synchronize]
6+
7+
jobs:
8+
build:
9+
strategy:
10+
matrix:
11+
idf_ver: ["release-v5.1", "release-v5.2", "release-v5.3", "release-v5.4", "release-v5.5", "latest"]
12+
fail-fast: false
13+
runs-on: ubuntu-latest
14+
container: espressif/idf:${{ matrix.idf_ver }}
15+
env:
16+
CONFIG_PATH: ${{ github.workspace }}/.github/ci/.idf_build_examples_config.toml
17+
steps:
18+
- uses: actions/checkout@v4
19+
- name: Install Python dependencies
20+
shell: bash
21+
run: |
22+
. ${IDF_PATH}/export.sh
23+
pip install --no-cache-dir idf-component-manager>=2.1.2 idf-build-apps==2.13.1 pyyaml --upgrade
24+
- name: Build USB Device examples
25+
shell: bash
26+
run: |
27+
. ${IDF_PATH}/export.sh
28+
python .github/ci/override_managed_component.py tinyusb . ${IDF_PATH}/examples/peripherals/usb/device/tusb_*
29+
python .github/ci/override_managed_component.py tinyusb . ${IDF_PATH}/examples/network/sta2eth
30+
cd ${IDF_PATH}
31+
idf-build-apps find --config-file ${CONFIG_PATH}
32+
idf-build-apps build --config-file ${CONFIG_PATH}
33+
- uses: actions/upload-artifact@v4
34+
with:
35+
# We upload only the USB Device example binaries to run them on the target
36+
name: usb_device_tusb_apps_bin_${{ matrix.idf_ver }}
37+
path: |
38+
/opt/esp/idf/examples/peripherals/usb/device/tusb_*/build_*/bootloader/bootloader.bin
39+
/opt/esp/idf/examples/peripherals/usb/device/tusb_*/build_*/partition_table/partition-table.bin
40+
/opt/esp/idf/examples/peripherals/usb/device/tusb_*/build_*/tusb_*.bin
41+
/opt/esp/idf/examples/peripherals/usb/device/tusb_*/build_*/tusb_*.elf
42+
/opt/esp/idf/examples/peripherals/usb/device/tusb_*/build_*/flasher_args.json
43+
/opt/esp/idf/examples/peripherals/usb/device/tusb_*/build_*/config/sdkconfig.json
44+
if-no-files-found: error
45+
run-target:
46+
name: Run USB Device examples
47+
if: ${{ github.repository_owner == 'espressif' }}
48+
needs: build
49+
strategy:
50+
fail-fast: false
51+
matrix:
52+
idf_ver: ["release-v5.3", "release-v5.4", "release-v5.5" , "latest"]
53+
idf_target: ["esp32s2"]
54+
runner_tag: ["usb_device"]
55+
runs-on: [self-hosted, linux, docker, "${{ matrix.idf_target }}", "${{ matrix.runner_tag }}"]
56+
container:
57+
image: espressif/idf:${{ matrix.idf_ver }}
58+
options: --privileged --device-cgroup-rule="c 188:* rmw" --device-cgroup-rule="c 166:* rmw"
59+
steps:
60+
- name: ⚙️ Install System tools
61+
run: |
62+
apt update
63+
apt install net-tools
64+
- name: ⚙️ Install Python packages
65+
env:
66+
PIP_EXTRA_INDEX_URL: "https://dl.espressif.com/pypi/"
67+
run: |
68+
cd ${IDF_PATH}
69+
. ./export.sh
70+
pip install --no-cache-dir --only-binary cryptography pytest-embedded pytest-embedded-serial-esp pytest-embedded-jtag pytest-embedded-idf pyserial pyusb python-gitlab minio idf-build-apps idf_ci pytest_ignore_test_results pytest-timeout netifaces
71+
- uses: actions/download-artifact@v4
72+
with:
73+
name: usb_device_tusb_apps_bin_${{ matrix.idf_ver }}
74+
path: /opt/esp/idf/examples/peripherals/usb/device
75+
- name: Run USB Test App on target
76+
run: |
77+
cd ${IDF_PATH}
78+
. ./export.sh
79+
export EXAMPLES_PATH="${IDF_PATH}/examples/peripherals/usb/device"
80+
pytest ${EXAMPLES_PATH} --target ${{ matrix.idf_target }} -m ${{ matrix.runner_tag }} --ignore-result-cases=*ncm_example
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: ESP IoT Solution - USB Device Examples
2+
3+
on:
4+
pull_request:
5+
types: [opened, reopened, synchronize]
6+
7+
jobs:
8+
build:
9+
strategy:
10+
matrix:
11+
idf_ver: ["release-v5.3", "release-v5.4", "release-v5.5", "latest"]
12+
name: ["usb_uart_bridge"]
13+
runs-on: ubuntu-latest
14+
container: espressif/idf:${{ matrix.idf_ver }}
15+
env:
16+
ESP_IOT_PATH: esp-iot-solution
17+
MANIFEST_PATH: esp-iot-solution/examples/.build-rules.yml
18+
EXAMPLE_PATH: esp-iot-solution/examples/usb/device/${{ matrix.name }}
19+
steps:
20+
- uses: actions/checkout@v4
21+
with:
22+
submodules: 'true'
23+
- name: Clone esp-iot-solution repository
24+
run: |
25+
git clone https://github.com/espressif/esp-iot-solution.git
26+
- name: Build
27+
shell: bash
28+
run: |
29+
. ${IDF_PATH}/export.sh
30+
pip install --no-cache-dir idf-component-manager>=2.1.2 idf-build-apps==2.13.1 pyyaml --upgrade
31+
python .github/ci/override_managed_component.py tinyusb . ${{ env.EXAMPLE_PATH }}/
32+
idf-build-apps find --paths ${{ env.EXAMPLE_PATH }} --manifest-file ${{ env.MANIFEST_PATH }} --manifest-rootpath ${{ env.ESP_IOT_PATH }}
33+
idf-build-apps build --paths ${{ env.EXAMPLE_PATH }} --manifest-file ${{ env.MANIFEST_PATH }} --manifest-rootpath ${{ env.ESP_IOT_PATH }}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Push TinyUSB to Espressif Component Service
2+
3+
# If the commit is tagged, it will be uploaded. Other scenario silently fail.
4+
on:
5+
push:
6+
tags:
7+
- v*
8+
9+
jobs:
10+
upload_components:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Upload components to component service
16+
uses: espressif/upload-components-ci-action@v2
17+
with:
18+
components: "tinyusb: ."
19+
version: ${{ github.ref_name }}
20+
namespace: "espressif"
21+
api_token: ${{ secrets.IDF_COMPONENT_API_TOKEN }}

CMakeLists.txt

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
idf_build_get_property(target IDF_TARGET)
2+
3+
if(${target} STREQUAL "esp32s3")
4+
set(tusb_mcu "OPT_MCU_ESP32S3")
5+
set(tusb_family "esp32sx")
6+
elseif(${target} STREQUAL "esp32s2")
7+
set(tusb_mcu "OPT_MCU_ESP32S2")
8+
set(tusb_family "esp32sx")
9+
elseif(${target} STREQUAL "esp32p4")
10+
set(tusb_mcu "OPT_MCU_ESP32P4")
11+
set(tusb_family "esp32px")
12+
elseif(${target} STREQUAL "esp32h4")
13+
set(tusb_mcu "OPT_MCU_ESP32H4")
14+
set(tusb_family "esp32sx")
15+
endif()
16+
17+
set(compile_options
18+
"-DCFG_TUSB_MCU=${tusb_mcu}"
19+
)
20+
21+
idf_component_get_property(freertos_include freertos ORIG_INCLUDE_PATH)
22+
23+
set(includes_private
24+
"src/"
25+
"src/device"
26+
"lib/networking" # For RNDIS definitions
27+
)
28+
29+
set(includes_public
30+
"src/"
31+
# The FreeRTOS API include convention in tinyusb is different from esp-idf
32+
"${freertos_include}"
33+
)
34+
35+
set(srcs
36+
"src/class/cdc/cdc_device.c"
37+
"src/class/hid/hid_device.c"
38+
"src/class/midi/midi_device.c"
39+
"src/class/msc/msc_device.c"
40+
"src/class/vendor/vendor_device.c"
41+
"src/class/audio/audio_device.c"
42+
"src/class/video/video_device.c"
43+
"src/class/bth/bth_device.c"
44+
"src/class/usbtmc/usbtmc_device.c"
45+
# NET class
46+
"src/class/net/ecm_rndis_device.c"
47+
"lib/networking/rndis_reports.c"
48+
"src/class/net/ncm_device.c"
49+
# DFU
50+
"src/class/dfu/dfu_device.c"
51+
"src/class/dfu/dfu_rt_device.c"
52+
# Common, device-mode related
53+
"src/portable/synopsys/dwc2/dcd_dwc2.c"
54+
"src/portable/synopsys/dwc2/dwc2_common.c"
55+
"src/common/tusb_fifo.c"
56+
"src/device/usbd_control.c"
57+
"src/device/usbd.c"
58+
"src/tusb.c"
59+
)
60+
61+
set(requirements_private
62+
esp_netif # required by rndis_reports.c: #include "netif/ethernet.h"
63+
)
64+
65+
if(${target} STREQUAL "esp32p4")
66+
list(APPEND requirements_private
67+
esp_mm # required by dcd_dwc2.c: #include "esp_cache.h"
68+
)
69+
endif()
70+
71+
idf_component_register(SRCS ${srcs}
72+
INCLUDE_DIRS ${includes_public}
73+
PRIV_INCLUDE_DIRS ${includes_private}
74+
PRIV_REQUIRES ${requirements_private}
75+
)
76+
77+
target_compile_options(${COMPONENT_LIB} PUBLIC ${compile_options})
78+
79+
# when no builtin class driver is enabled, an uint8_t data compared with `BUILTIN_DRIVER_COUNT` will always be false
80+
set_source_files_properties("src/device/usbd.c" PROPERTIES COMPILE_FLAGS "-Wno-type-limits")

0 commit comments

Comments
 (0)