Skip to content

Commit aadb750

Browse files
committed
feat(tinyusb): Added initial files to make an idf component
1 parent 933ac29 commit aadb750

File tree

7 files changed

+247
-0
lines changed

7 files changed

+247
-0
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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+
from pathlib import Path
9+
from glob import glob
10+
from idf_component_tools.manifest import ManifestManager
11+
12+
13+
def override_with_local_component(component, local_path, app):
14+
app_path = Path(app)
15+
16+
absolute_local_path = Path(local_path).absolute()
17+
if not absolute_local_path.exists():
18+
print('[Error] {} path does not exist'.format(local_path))
19+
raise Exception
20+
if not app_path.exists():
21+
print('[Error] {} path does not exist'.format(app_path))
22+
raise Exception
23+
24+
print('[Info] Processing app {}'.format(app))
25+
manager = ManifestManager(app_path / 'main', 'app')
26+
if '/' not in component:
27+
# Prepend with default namespace
28+
component_with_namespace = 'espressif/' + component
29+
30+
try:
31+
manager.manifest_tree['dependencies'][component_with_namespace] = {
32+
'version': '*',
33+
'override_path': str(absolute_local_path)
34+
}
35+
except KeyError:
36+
print('[Error] {} app does not depend on {}'.format(app, component_with_namespace))
37+
raise KeyError
38+
39+
manager.dump()
40+
41+
42+
def override_with_local_component_all(component, local_path, apps):
43+
# Process wildcard, e.g. "app_prefix_*"
44+
apps_with_glob = list()
45+
for app in apps:
46+
apps_with_glob += glob(app)
47+
48+
# Go through all collected apps
49+
for app in apps_with_glob:
50+
try:
51+
override_with_local_component(component, local_path, app)
52+
except:
53+
print("[Error] Could not process app {}".format(app))
54+
return -1
55+
return 0
56+
57+
58+
if __name__ == '__main__':
59+
parser = argparse.ArgumentParser()
60+
parser.add_argument('component', help='Existing component that the app depends on')
61+
parser.add_argument('local_path', help='Path to component that will be used instead of the managed version')
62+
parser.add_argument('apps', nargs='*', help='List of apps to process')
63+
args = parser.parse_args()
64+
sys.exit(override_with_local_component_all(args.component, args.local_path, args.apps))
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Build ESP-IDF USB examples
2+
3+
on:
4+
schedule:
5+
- cron: '0 0 * * SAT' # Saturday midnight
6+
pull_request:
7+
types: [opened, reopened, synchronize]
8+
9+
jobs:
10+
build:
11+
strategy:
12+
matrix:
13+
idf_ver: ["release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3", "release-v5.4", "latest"]
14+
runs-on: ubuntu-20.04
15+
container: espressif/idf:${{ matrix.idf_ver }}
16+
steps:
17+
- uses: actions/checkout@v4
18+
with:
19+
submodules: 'true'
20+
- name: Build ESP-IDF USB Device examples
21+
shell: bash
22+
run: |
23+
. ${IDF_PATH}/export.sh
24+
pip install idf-component-manager==1.5.2 idf-build-apps --upgrade
25+
python .github/ci/override_managed_component.py tinyusb . ${IDF_PATH}/examples/peripherals/usb/device/tusb_*
26+
cd ${IDF_PATH}
27+
idf-build-apps find --path examples/peripherals/usb/device/ --recursive --target all --manifest-file examples/peripherals/.build-test-rules.yml
28+
idf-build-apps build --path examples/peripherals/usb/device/ --recursive --target all --manifest-file examples/peripherals/.build-test-rules.yml
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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: Remove unneeded files
16+
shell: bash
17+
run: rm -rf docs tools lib/embedded-cli lib/fatfs lib/SEGGER_RTT
18+
19+
- name: Upload components to component service
20+
uses: espressif/upload-components-ci-action@v1
21+
with:
22+
name: "tinyusb"
23+
version: ${{ github.ref_name }}
24+
namespace: "espressif"
25+
api_token: ${{ secrets.IDF_COMPONENT_API_TOKEN }}

CMakeLists.txt

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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+
endif()
13+
14+
set(compile_options
15+
"-DCFG_TUSB_MCU=${tusb_mcu}"
16+
)
17+
18+
idf_component_get_property(freertos_include freertos ORIG_INCLUDE_PATH)
19+
20+
set(includes_private
21+
"src/"
22+
"src/device"
23+
"lib/networking" # For RNDIS definitions
24+
)
25+
26+
set(includes_public
27+
"src/"
28+
# The FreeRTOS API include convention in tinyusb is different from esp-idf
29+
"${freertos_include}"
30+
)
31+
32+
set(srcs
33+
"src/class/cdc/cdc_device.c"
34+
"src/class/hid/hid_device.c"
35+
"src/class/midi/midi_device.c"
36+
"src/class/msc/msc_device.c"
37+
"src/class/vendor/vendor_device.c"
38+
"src/class/audio/audio_device.c"
39+
"src/class/video/video_device.c"
40+
"src/class/bth/bth_device.c"
41+
# NET class
42+
"src/class/net/ecm_rndis_device.c"
43+
"lib/networking/rndis_reports.c"
44+
"src/class/net/ncm_device.c"
45+
# DFU
46+
"src/class/dfu/dfu_device.c"
47+
"src/class/dfu/dfu_rt_device.c"
48+
# Common, device-mode related
49+
"src/portable/synopsys/dwc2/dcd_dwc2.c"
50+
"src/common/tusb_fifo.c"
51+
"src/device/usbd_control.c"
52+
"src/device/usbd.c"
53+
"src/tusb.c"
54+
)
55+
56+
idf_component_register(SRCS ${srcs}
57+
INCLUDE_DIRS ${includes_public}
58+
PRIV_INCLUDE_DIRS ${includes_private}
59+
PRIV_REQUIRES esp_netif # required by rndis_reports.c: #include "netif/ethernet.h"
60+
)
61+
62+
target_compile_options(${COMPONENT_LIB} PUBLIC ${compile_options})
63+
64+
# when no builtin class driver is enabled, an uint8_t data compared with `BUILTIN_DRIVER_COUNT` will always be false
65+
set_source_files_properties("src/device/usbd.c" PROPERTIES COMPILE_FLAGS "-Wno-type-limits")

README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Espressif TinyUSB component
2+
3+
Upstream [TinyUSB](https://github.com/hathach/tinyusb) fork with integration into ESP-IDF build system.
4+
5+
## How to use
6+
7+
There are two options of using TinyUSB component with Espressif's SoCs:
8+
9+
### 1. Use component via [Espressif TinyUSB additions](https://github.com/espressif/esp-usb/tree/master/device/esp_tinyusb)
10+
11+
[Espressif TinyUSB additions](https://github.com/espressif/esp-usb/tree/master/device/esp_tinyusb) provides several preconfigured features to use benefits of TinyUSB stack faster.
12+
13+
To use [Espressif TinyUSB additions](https://github.com/espressif/esp-usb/tree/master/device/esp_tinyusb), add ``idf_component.yml`` to your main component with the following content::
14+
15+
```yaml
16+
## IDF Component Manager Manifest File
17+
dependencies:
18+
esp_tinyusb: "^1.0.0" # Automatically update minor releases
19+
```
20+
21+
Or simply run:
22+
```
23+
idf.py add-dependency "esp_tinyusb^1.0.0"
24+
```
25+
26+
Then, the Espressif TinyUSB component will be added automatically during resolving dependencies by the component manager.
27+
28+
### 2. Use component directly
29+
30+
Use this option for custom TinyUSB applications.
31+
In this case you will have to provide configuration header file ``tusb_config.h``. More information about TinyUSB configuration can be found [in official TinyUSB documentation](https://docs.tinyusb.org/en/latest/reference/getting_started.html).
32+
33+
You will also have to tell TinyUSB where to find the configuration file. This can be achieved by adding following CMake snippet to you main component's ``CMakeLists.txt``:
34+
35+
```cmake
36+
idf_component_get_property(tusb_lib espressif__tinyusb COMPONENT_LIB)
37+
target_include_directories(${tusb_lib} PRIVATE path_to_your_tusb_config)
38+
```
39+
40+
Again, you can add this component to your project by adding ``idf_component.yml`` file:
41+
42+
```yaml
43+
## IDF Component Manager Manifest File
44+
dependencies:
45+
tinyusb: "~0.15.1" # Automatically update bugfix releases. TinyUSB does not guarantee backward compatibility
46+
```
47+
48+
Or simply run:
49+
```
50+
idf.py add-dependency "tinyusb~0.15.1"
51+
```
52+
53+
README from the upstream TinyUSB can be found in [hathach/tinyusb/README](https://github.com/hathach/tinyusb/blob/master/README.rst).

idf_component.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
description: TinyUSB ported to Espressif's SoCs
2+
url: https://docs.tinyusb.org/en/latest/
3+
documentation: "https://docs.tinyusb.org/en/latest/"
4+
repository: "https://github.com/espressif/tinyusb.git"
5+
dependencies:
6+
idf: '>=5.0' # IDF 4.x contains TinyUSB as submodule
7+
targets:
8+
- esp32s2
9+
- esp32s3
10+
- esp32p4

sbom.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
supplier: 'Organization: Espressif Systems (Shanghai) CO LTD'
2+
originator: 'Person: Ha Thach <[email protected]>'

0 commit comments

Comments
 (0)