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
2 changes: 1 addition & 1 deletion .github/ci/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set -euo pipefail

export RUSTFLAGS="-D warnings"

for dir in usbpd usbpd-traits examples/embassy-nucleo-h563zi examples/embassy-stm32-g431cb examples/embassy-stm32-g431cb-epr;
for dir in usbpd usbpd-traits examples/embassy-nucleo-h563zi examples/embassy-nucleo-g474re-sink examples/embassy-nucleo-g474re-sink-epr examples/embassy-nucleo-g474re-source;
do
pushd $dir
cargo +nightly fmt --check
Expand Down
58 changes: 58 additions & 0 deletions .github/ci/hardware_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/bin/bash
set -euo pipefail

CHIP="STM32G474RE"
PROBE_A="${PROBE_SERIAL_A:?Set PROBE_SERIAL_A secret}"
PROBE_B="${PROBE_SERIAL_B:?Set PROBE_SERIAL_B secret}"
TIMEOUT_SECS=30

SINK_ELF="usbpd-g474re-sink"
SOURCE_ELF="usbpd-g474re-source"

# Sanity check: verify probes are connected
probe-rs info --probe "$PROBE_A"
probe-rs info --probe "$PROBE_B"

# Flash sink to board A
probe-rs download --chip "$CHIP" --probe "$PROBE_A" "$SINK_ELF"

# Flash source to board B
probe-rs download --chip "$CHIP" --probe "$PROBE_B" "$SOURCE_ELF"

# Reset both boards simultaneously
probe-rs reset --chip "$CHIP" --probe "$PROBE_A" &
probe-rs reset --chip "$CHIP" --probe "$PROBE_B" &
wait

# Capture RTT from source board, timeout after TIMEOUT_SECS
LOG_FILE=$(mktemp)
timeout "$TIMEOUT_SECS" probe-rs attach --chip "$CHIP" --probe "$PROBE_B" \
"$SOURCE_ELF" --target-output-file defmt="$LOG_FILE" || true

# Verify success markers
PASS=false
if grep -q "CI:PASS" "$LOG_FILE"; then
echo "CI:PASS found - contract established"
PASS=true
fi

if grep -q "CI:FAIL" "$LOG_FILE"; then
echo "CI:FAIL found in log"
PASS=false
fi

if grep -q "panic" "$LOG_FILE"; then
echo "Panic detected in log"
PASS=false
fi

if [ "$PASS" = true ]; then
echo "Hardware test PASSED"
exit 0
else
echo "Hardware test FAILED"
echo "--- RTT log ---"
cat "$LOG_FILE"
echo "--- end log ---"
exit 1
fi
43 changes: 39 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true

- run: rustup toolchain install nightly -c rustfmt

Expand All @@ -25,11 +23,48 @@ jobs:
workspaces: |
usbpd
examples/embassy-nucleo-h563zi
examples/embassy-stm32-g431cb
examples/embassy-stm32-g431cb-epr
examples/embassy-nucleo-g474re-sink
examples/embassy-nucleo-g474re-sink-epr
examples/embassy-nucleo-g474re-source

- name: Build
run: bash .github/ci/build.sh

- name: Test
run: bash .github/ci/test.sh

- name: Upload sink firmware
uses: actions/upload-artifact@v4
with:
name: sink-firmware
path: examples/embassy-nucleo-g474re-sink/target/thumbv7em-none-eabihf/release/usbpd-g474re-sink

- name: Upload source firmware
uses: actions/upload-artifact@v4
with:
name: source-firmware
path: examples/embassy-nucleo-g474re-source/target/thumbv7em-none-eabihf/release/usbpd-g474re-source

hardware_test:
needs: build_and_test
runs-on: self-hosted

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Download sink firmware
uses: actions/download-artifact@v4
with:
name: sink-firmware

- name: Download source firmware
uses: actions/download-artifact@v4
with:
name: source-firmware

- name: Hardware test
env:
PROBE_SERIAL_A: ${{ secrets.PROBE_SERIAL_A }}
PROBE_SERIAL_B: ${{ secrets.PROBE_SERIAL_B }}
run: bash .github/ci/hardware_test.sh
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
[submodule "embassy"]
path = embassy
url = https://github.com/embassy-rs/embassy.git
5 changes: 3 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"usbpd/Cargo.toml",
"usbpd-traits/Cargo.toml",
"examples/embassy-nucleo-h563zi/Cargo.toml",
"examples/embassy-stm32-g431cb/Cargo.toml",
"examples/embassy-stm32-g431cb-epr/Cargo.toml",
"examples/embassy-nucleo-g474re-sink/Cargo.toml",
"examples/embassy-nucleo-g474re-sink-epr/Cargo.toml",
"examples/embassy-nucleo-g474re-source/Cargo.toml",
]
}
22,728 changes: 22,728 additions & 0 deletions USB_PD_R3_2 V1.1 2024-10.md

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion embassy
Submodule embassy deleted from 930269
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = 'probe-rs run --chip STM32G431CBTx --connect-under-reset'
runner = 'probe-rs run --chip STM32G474RETx'

[build]
target = "thumbv7em-none-eabihf"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,44 @@
[package]
edition = "2024"
name = "usbpd-epr-example"
name = "usbpd-g474re-sink-epr"
version = "0.1.0"
license = "MIT"

[dependencies]
embassy-stm32 = { path = "../../embassy/embassy-stm32", features = [
embassy-stm32 = { version = "0.6.0", features = [
"defmt",
"time-driver-any",
"stm32g474re",
"memory-x",
"unstable-pac",
"time-driver-any",
"exti",
"unstable-pac",
"single-bank",
] }
embassy-sync = { path = "../../embassy/embassy-sync", features = ["defmt"] }
embassy-executor = { path = "../../embassy/embassy-executor", features = [
"arch-cortex-m",
embassy-sync = { version = "0.8.0", features = ["defmt"] }
embassy-executor = { version = "0.10.0", features = [
"platform-cortex-m",
"executor-thread",
"defmt",
] }
embassy-time = { path = "../../embassy/embassy-time", features = [
embassy-time = { version = "0.5.1", features = [
"defmt",
"defmt-timestamp-uptime",
"tick-hz-100_000",
] }
embassy-futures = { path = "../../embassy/embassy-futures" }
embassy-futures = "0.1.2"

defmt = "1.0.1"
defmt-rtt = "1.0.0"
defmt = "1.1.0"
defmt-rtt = "1.2.0"

cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
cortex-m-rt = "0.7"
embedded-hal = "1"
cortex-m = { version = "0.7.6", features = [
"inline-asm",
"critical-section-single-core",
] }
cortex-m-rt = "0.7.0"
embedded-hal = "1.0.0"
panic-probe = { version = "1.0.0", features = ["print-defmt"] }
heapless = { version = "0.9.1", default-features = false }
static_cell = "2.1.1"
heapless = { version = "0.9.3", default-features = false }
static_cell = "2"
micromath = "2.1.0"

uom = { version = "0.36.0", default-features = false, features = ["si"] }
Expand All @@ -60,8 +65,5 @@ opt-level = 3 # <-
overflow-checks = false # <-

[features]
default = ["stm32g431cb"]

stm32g431cb = ["embassy-stm32/stm32g431cb"]
# Enable AVS (Adjustable Voltage Supply) instead of Fixed EPR mode
avs = []
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use defmt::info;
use defmt_rtt as _;
use embassy_executor::Spawner;
use panic_probe as _;
use usbpd_epr_example::power::{self, UcpdResources};
use usbpd_g474re_sink_epr::power::{self, UcpdResources};

#[embassy_executor::main]
async fn main(spawner: Spawner) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = 'probe-rs run --chip STM32G431CBTx --connect-under-reset'
runner = 'probe-rs run --chip STM32G474RETx'

[build]
target = "thumbv7em-none-eabihf"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,44 @@
[package]
edition = "2024"
name = "usbpd-testing"
name = "usbpd-g474re-sink"
version = "0.1.0"
license = "MIT"

[dependencies]
embassy-stm32 = { path = "../../embassy/embassy-stm32", features = [
embassy-stm32 = { version = "0.6.0", features = [
"defmt",
"time-driver-any",
"stm32g474re",
"memory-x",
"unstable-pac",
"time-driver-any",
"exti",
"unstable-pac",
"single-bank",
] }
embassy-sync = { path = "../../embassy/embassy-sync", features = ["defmt"] }
embassy-executor = { path = "../../embassy/embassy-executor", features = [
"arch-cortex-m",
embassy-sync = { version = "0.8.0", features = ["defmt"] }
embassy-executor = { version = "0.10.0", features = [
"platform-cortex-m",
"executor-thread",
"defmt",
] }
embassy-time = { path = "../../embassy/embassy-time", features = [
embassy-time = { version = "0.5.1", features = [
"defmt",
"defmt-timestamp-uptime",
"tick-hz-100_000",
] }
embassy-futures = { path = "../../embassy/embassy-futures" }
embassy-futures = "0.1.2"

defmt = "1.0.1"
defmt-rtt = "1.0.0"
defmt = "1.1.0"
defmt-rtt = "1.2.0"

cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
cortex-m-rt = "0.7"
embedded-hal = "1"
cortex-m = { version = "0.7.6", features = [
"inline-asm",
"critical-section-single-core",
] }
cortex-m-rt = "0.7.0"
embedded-hal = "1.0.0"
panic-probe = { version = "1.0.0", features = ["print-defmt"] }
heapless = { version = "0.9.1", default-features = false }
static_cell = "2.1.1"
heapless = { version = "0.9.3", default-features = false }
static_cell = "2"
micromath = "2.1.0"

uom = { version = "0.36.0", default-features = false, features = ["si"] }
Expand All @@ -58,8 +63,3 @@ incremental = false
lto = 'fat'
opt-level = 3 # <-
overflow-checks = false # <-

[features]
default = ["stm32g431cb"]

stm32g431cb = ["embassy-stm32/stm32g431cb"]
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use defmt_rtt as _;
use embassy_executor::Spawner;
use embassy_stm32::gpio::Output;
use panic_probe as _;
use usbpd_testing::power::{self, UcpdResources};
use usbpd_g474re_sink::power::{self, UcpdResources};

#[embassy_executor::main]
async fn main(spawner: Spawner) {
Expand All @@ -17,15 +17,15 @@ async fn main(spawner: Spawner) {
// Launch UCPD task.
{
// This pin controls the dead-battery mode on the attached TCPP01-M12.
let tcpp01_m12_ndb = Output::new(p.PB5, embassy_stm32::gpio::Level::Low, embassy_stm32::gpio::Speed::Low);
let tcpp_pwren = Output::new(p.PC8, embassy_stm32::gpio::Level::Low, embassy_stm32::gpio::Speed::Low);

let ucpd_resources = UcpdResources {
pin_cc1: p.PB6,
pin_cc2: p.PB4,
ucpd: p.UCPD1,
rx_dma: p.DMA1_CH1,
tx_dma: p.DMA1_CH2,
tcpp01_m12_ndb,
tcpp_pwren,
};
spawner.spawn(unwrap!(power::ucpd_task(ucpd_resources)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub struct UcpdResources {
pub pin_cc2: Peri<'static, peripherals::PB4>,
pub rx_dma: Peri<'static, peripherals::DMA1_CH1>,
pub tx_dma: Peri<'static, peripherals::DMA1_CH2>,
pub tcpp01_m12_ndb: Output<'static>,
pub tcpp_pwren: Output<'static>,
}

#[derive(Debug, Format)]
Expand Down Expand Up @@ -158,6 +158,10 @@ impl DevicePolicyManager for Device {
.unwrap()
}

async fn transition_power(&mut self, _accepted: &request::PowerSource) {
info!("CI:PASS");
}

async fn get_event(&mut self, source_capabilities: &SourceCapabilities) -> Event {
// Periodically request another power level.
self.ticker.next().await;
Expand Down Expand Up @@ -224,7 +228,7 @@ pub async fn ucpd_task(mut ucpd_resources: UcpdResources) {
);

ucpd.cc_phy().set_pull(CcPull::Sink);
ucpd_resources.tcpp01_m12_ndb.set_high();
ucpd_resources.tcpp_pwren.set_high();

info!("Waiting for USB connection");
let cable_orientation = wait_attached(ucpd.cc_phy()).await;
Expand Down
8 changes: 8 additions & 0 deletions examples/embassy-nucleo-g474re-source/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = 'probe-rs run --chip STM32G474RETx'

[build]
target = "thumbv7em-none-eabihf"

[env]
DEFMT_LOG = "info"
Loading
Loading