Skip to main content

v2n-gd32-bridge-functional

Single-pass functional validation of the V2N module's GD32G553 supervisor-MCU bridge, followed by a forever PWM7 duty staircase as a live oscilloscope observable.

Where v2n-gd32-bridge-hil-soak proves the link (every opcode answers, forever), this app proves the functions: each test drives a bridge surface with a known stimulus and asserts the value that comes back. sqrt(4) is 2.0. sin(π/2) is 1.0. A TRNG pull has entropy. An invalid ADC configuration is rejected. A PWM setpoint reads back within tolerance.

Source: examples/v2n/v2n-gd32-bridge-functional/.

Like the soak and v2n-gd32-bridge-ping, this is a maintainer bench tool in example form. It exercises the gd32g553 chip driver directly — the documented exception to the portable-API rule for dedicated bridge demos.

What it tests (one pass, in table order)

  1. TMU math — every native CORDIC primitive value-asserted in F32 (sqrt, sin, cos, atan, atan2, hypot, log, sinh, cosh) plus a Q31 sqrt. tan / exp / tanh must answer ALP_ERR_NOSUPPORT — there is no native mode for them, so a wrong value here would be a defect.
  2. TRNG — two 16-byte pulls with the documented one-retry fault-recover tolerance. Asserts non-constant bytes, and that the second pull differs from the first.
  3. PWM — 1 kHz / 50 % setpoint on channel 7 with readback within one tick. pwm_configure defaults must answer OK; the center-aligned knob may answer NOSUPPORT (a documented partial).
  4. ADC — the illegal 14-bit / no-oversampling combination must be rejected (INVAL / NOSUPPORT), then all 8 channels are swept against the physical ceiling.
  5. DSP chain pool — lifecycle open, accepting the documented pre-wave-2 NOSUPPORT contract.
  6. IdentityGET_VERSION twice (must be stable), and the DA9292 status forward returns the 0xFF "no nets on this HW rev" sentinel.

Reading the verdict — there is no console on this SoM

The M33 target has no console. Results publish to a RAM verdict block: find the func_results symbol in zephyr.map and read it over the DAP.

WordMeaning
[0]0xF07C7E57 magic
[1]State: 1 = testing, 2 = staircase running (tests done), 0xDEAD = link never came up
[2]Pass count
[3]Fail count
[4+i]Per-test result: 0 = PASS, 0x7E = value assertion failed (status was OK), anything else = the failing alp_status_t
[40]Staircase: current duty per-mille (live)
[41]Staircase: step counter (liveness)

The 0x7E code is the interesting one — it separates "the wire worked but the answer was wrong" from "the transport failed."

The scope observable

After the suite the app parks in a forever PWM7 duty staircase: a 1 kHz carrier whose duty walks 10 % → 90 % in 10-point steps, 2 s per step, then wraps.

PWM7 doubles as the EVK LED pad, so a scope probe shows the high time visibly widening every 2 s — and the naked eye sees a brightness ramp. Every step is a fresh PWM_SET + PWM_GET pair over the bridge, so the staircase doubles as a slow link soak.

board.yaml

som:
sku: E1M-V2M101

preset: e1m-x-evk

cores:
a55_cluster:
os: "off"
m33_sm:
app: ./src
# SPI is the 25 MHz fast path under test; I2C is enabled so the
# driver's hybrid surface compiles (the suite passes i2c = NULL --
# BRD_I2C correctness has its own HIL coverage).
peripherals:
- spi
- i2c

chips:
- gd32g553

diagnostics:
log_level: info

Status

build_only: true on native_sim/native/64 — there is no GD32 to answer off-silicon, so CI proves compile + link only. Every value assertion is a bench signal.

See also

Questions about this page? Discuss in Community Forum