Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 193 additions & 0 deletions .github/workflows/build_and_run_usbh_shell_pytest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
name: Build and Run

on:
pull_request:
types: [opened, reopened, synchronize]
workflow_dispatch:

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
zephyr_ver: ["v0.29.1"]
container:
image: ghcr.io/zephyrproject-rtos/ci:${{ matrix.zephyr_ver }}

steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: ws/zephyr
fetch-depth: 0

- name: Setup Python deps (west + twister requirements)
shell: bash
run: |
python3 -m venv "$GITHUB_WORKSPACE/ws/.venv"
. "$GITHUB_WORKSPACE/ws/.venv/bin/activate"
pip install -U pip wheel
pip install -r "$GITHUB_WORKSPACE/ws/zephyr/scripts/requirements.txt" \
-r "$GITHUB_WORKSPACE/ws/zephyr/scripts/requirements-build-test.txt"

- name: West init/update/export (modules + blobs)
shell: bash
run: |
. "$GITHUB_WORKSPACE/ws/.venv/bin/activate"
cd "$GITHUB_WORKSPACE/ws"
west init -l zephyr
west update hal_espressif
west blobs fetch hal_espressif
west zephyr-export

- name: Locate Zephyr SDK in container
shell: bash
run: |
# Common locations used by Zephyr CI images; pick the first that exists.
for d in /opt/zephyr-sdk* /opt/toolchains/zephyr-sdk* /usr/local/zephyr-sdk*; do
if [ -d "$d" ]; then
echo "Found Zephyr SDK at $d"
echo "ZEPHYR_SDK_INSTALL_DIR=$d" >> $GITHUB_ENV
break
fi
done

# Debug: show what we set
echo "ZEPHYR_SDK_INSTALL_DIR=${ZEPHYR_SDK_INSTALL_DIR:-<unset>}"
ls -la /opt || true

- name: Twister build-only (ESP32S3)
shell: bash
env:
PYTEST_DISABLE_PLUGIN_AUTOLOAD: "1"
ZEPHYR_TOOLCHAIN_VARIANT: zephyr
run: |
. "$GITHUB_WORKSPACE/ws/.venv/bin/activate"
cd "$GITHUB_WORKSPACE/ws/zephyr"

west twister -T samples/subsys/usb/shell --list-tests

west twister \
-T samples/subsys/usb/shell \
-p esp32s3_devkitc/esp32s3/procpu \
-s sample.usbh.shell.hil \
--build-only \
-j 1 -v \
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why restricting to a single worker?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting question actually....I thought that if I build only one app and I don't need to make it faster, I decided to do it via single worker only.

But there was no error or anything, so it might be removed.

--outdir "$GITHUB_WORKSPACE/twister-out"

- name: Pack twister-out artifact
shell: bash
run: |
cd "$GITHUB_WORKSPACE"
tar -czf twister-out.tgz twister-out
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe you'd like to try twisters option to prepare packed artifacts? It should store only what is needed for execution --package-artifacts https://github.com/zephyrproject-rtos/zephyr/blob/main/scripts/pylib/twister/twisterlib/environment.py#L377C10-L377C29. If you need some extra files you can add --keep-artifacts https://github.com/zephyrproject-rtos/zephyr/blob/main/scripts/pylib/twister/twisterlib/environment.py#L654C10-L654C26

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, thanks a lot for a note!

Will definitely try it.


- name: Upload artifacts
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: twister-out
path: twister-out.tgz
if-no-files-found: error

run:
if: startsWith(github.head_ref, 'pr-add-')
runs-on: [self-hosted, docker, esp32s3, usb_host]
strategy:
matrix:
zephyr_ver: ["v0.29.1"]
container:
image: ghcr.io/zephyrproject-rtos/ci:${{ matrix.zephyr_ver }}
options: >-
--volume=/etc/zephyr:/etc/zephyr:ro
--device=/dev/ttyACM0
needs: [build]

steps:
- name: Checkout (workspace layout)
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: ws/zephyr
fetch-depth: 0

- name: Python venv + requirements (clean)
shell: bash
run: |
rm -rf "$GITHUB_WORKSPACE/ws/.venv"
python3 -m venv "$GITHUB_WORKSPACE/ws/.venv"
. "$GITHUB_WORKSPACE/ws/.venv/bin/activate"
pip install -U pip wheel esptool pyserial
pip install -r "$GITHUB_WORKSPACE/ws/zephyr/scripts/requirements.txt" \
-r "$GITHUB_WORKSPACE/ws/zephyr/scripts/requirements-build-test.txt"

- name: West init/update/export (runner, idempotent)
shell: bash
run: |
. "$GITHUB_WORKSPACE/ws/.venv/bin/activate"
cd "$GITHUB_WORKSPACE/ws"
if [ ! -d .west ]; then
west init -l zephyr
fi
west zephyr-export

- name: Download twister-out artifact
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
name: twister-out
path: ${{ github.workspace }}

- name: Unpack twister-out
shell: bash
run: |
cd "$GITHUB_WORKSPACE"
rm -rf twister-out
tar -xzf twister-out.tgz

- name: Locate Zephyr SDK in container
shell: bash
run: |
# Common locations used by Zephyr CI images; pick the first that exists.
for d in /opt/zephyr-sdk* /opt/toolchains/zephyr-sdk* /usr/local/zephyr-sdk*; do
if [ -d "$d" ]; then
echo "Found Zephyr SDK at $d"
echo "ZEPHYR_SDK_INSTALL_DIR=$d" >> $GITHUB_ENV
break
fi
done

# Debug: show what we set
echo "ZEPHYR_SDK_INSTALL_DIR=${ZEPHYR_SDK_INSTALL_DIR:-<unset>}"
ls -la /opt || true

- name: Run on hardware (test-only)
shell: bash
env:
PYTEST_DISABLE_PLUGIN_AUTOLOAD: "1"
ZEPHYR_TOOLCHAIN_VARIANT: zephyr
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE/ws/zephyr"

. "$GITHUB_WORKSPACE/ws/.venv/bin/activate"
cd "$GITHUB_WORKSPACE/ws/zephyr"

west twister \
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe you not using the artifacts, but rebuilding the image. To skip building you'd need also --test-only https://github.com/zephyrproject-rtos/zephyr/blob/main/scripts/pylib/twister/twisterlib/environment.py#L382 I suggest you add --log-level debug which will print all the cmake command etc to verify if it was rebuild or not

-T samples/subsys/usb/shell \
-p esp32s3_devkitc/esp32s3/procpu \
-s sample.usbh.shell.hil \
--test-only \
--device-testing \
--hardware-map /etc/zephyr/hardware-map-esp32s3.yml \
-j 1 -vvv \
--outdir "$GITHUB_WORKSPACE/twister-out"

- name: Upload Twister reports
if: always()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: twister-reports
path: |
twister-out/**/twister_harness.log
twister-out/twister.xml
twister-out/twister_report.xml
twister-out/twister.json
2 changes: 2 additions & 0 deletions drivers/usb/uhc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
# SPDX-License-Identifier: Apache-2.0

zephyr_library()
zephyr_library_include_directories(${ZEPHYR_BASE}/drivers/usb/common/)

zephyr_library_sources(uhc_common.c)
zephyr_library_sources_ifdef(CONFIG_UHC_DWC2 uhc_dwc2.c)
zephyr_library_sources_ifdef(CONFIG_UHC_MAX3421E uhc_max3421e.c)
zephyr_library_sources_ifdef(CONFIG_UHC_VIRTUAL uhc_virtual.c)
zephyr_library_sources_ifdef(CONFIG_UHC_NXP_EHCI uhc_mcux_common.c uhc_mcux_ehci.c)
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/uhc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ module = UHC_DRIVER
module-str = uhc drv
source "subsys/logging/Kconfig.template.log_config"

source "drivers/usb/uhc/Kconfig.dwc2"
source "drivers/usb/uhc/Kconfig.max3421e"
source "drivers/usb/uhc/Kconfig.virtual"
source "drivers/usb/uhc/Kconfig.mcux"
Expand Down
74 changes: 74 additions & 0 deletions drivers/usb/uhc/Kconfig.dwc2
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Copyright (c) 2026 Roman Leonov <jam_roma@yahoo.com>
# SPDX-License-Identifier: Apache-2.0

config UHC_DWC2
bool "DWC2 USB host controller driver"
depends on DT_HAS_SNPS_DWC2_ENABLED
default y
select EVENTS
help
DWC2 USB host controller driver.

if UHC_DWC2

config UHC_DWC2_STACK_SIZE
int "UHC DWC2 driver thread stack size"
default 512
help
DWC2 driver thread stack size.

config UHC_DWC2_THREAD_PRIORITY
int "UHC DWC2 driver thread priority"
default 8
help
DWC2 driver thread priority.

config UHC_DWC2_DEBOUNCE_DELAY_MS
int "Debounce delay in ms"
default 250
help
On connection of a USB device, the USB 2.0 specification requires
a "debounce interval with a minimum duration of 100ms" to allow the connection to stabilize
(see USB 2.0 chapter 7.1.7.3 for more details).
During the debounce interval, no new connection/disconnection events are registered.

The default value is set to 250 ms to be safe.

config UHC_DWC2_RESET_HOLD_MS
int "Reset hold in ms"
default 30
help
The reset signaling can be generated on any Hub or Host Controller port by request from
the USB System Software. The USB 2.0 specification requires that "the reset signaling must
be driven for a minimum of 10ms" (see USB 2.0 chapter 7.1.7.5 for more details).
After the reset, the hub port will transition to the Enabled state (refer to Section 11.5).

The default value is set to 30 ms to be safe.

config UHC_DWC2_RESET_RECOVERY_MS
int "Reset recovery delay in ms"
default 30
help
After a port stops driving the reset signal, the USB 2.0 specification requires that
the "USB System Software guarantees a minimum of 10 ms for reset recovery" before the
attached device is expected to respond to data transfers (see USB 2.0 chapter 7.1.7.3 for
more details).
The device may ignore any data transfers during the recovery interval.

The default value is set to 30 ms to be safe.


config UHC_DWC2_SET_ADDR_DELAY_MS
int "Delay after set device address"
default 10
help
"After successful completion of the Status stage, the device is allowed a SetAddress()
recovery interval of 2 ms. At the end of this interval, the device must be able to accept
Setup packets addressed to the new address. Also, at the end of the recovery interval, the
device must not respond to tokens sent to the old address (unless, of course, the old and new
address is the same)." See USB 2.0 chapter 9.2.6.3 for more details.

The default value is set to 10 ms to be safe.


endif # UHC_DWC2
Loading
Loading