AnasSarkiz/usb-c-pd-brushed-motor

USB-C PD-powered motor controller with protected input, selectable 5/9/12 V buck supply, MCU qualification, PWM H-bridge drive, overvoltage sensing, regenerative energy-dump resistors, and safety interlocks.

Version
0.0.1-a48-cloud-pipeline9-unrouted-c41d79a-305b1e7a
License
unset
Stars
0

docs/PD-QUALIFICATION.md

# Current A22 PD qualification and voltage policy

The current implementation uses the qualification-only STM32G030. Speed PWM and
direction remain hardware controlled. SW2 selects 5 / 9 / 12 V; both sliders ON
inhibit motor power. Reset defaults to the 5 V feedback branch with motor power
and the bridge inhibited.

Only fixed 15 / 20 V source PDOs advertising 3–5 A qualify. The operating request
is 3 A and the RDO maximum follows the source advertisement. A 5 V motor prefers
an adequate 15 V contract, with 20 V as the fallback. Both 9 V and 12 V motors
require 20 V; the current policy includes a 5% reserve above the conservative
peak input-current screen. Native 12 V, PPS, variable and battery PDOs are not
used. A 5 V-only, non-PD or insufficient source cannot enable the motor.

R13 is 6.98 kΩ; the conservative eFuse current-limit interval is
2.2754–2.89465 A. The three sense-filter capacitors are 22 pF C0G. Qualified
voltage intervals include component, ADC, reference, timing and physical-profile
uncertainty; a nominal reading does not grant motor permission.

The runtime is linked into ELF/BIN with bounded transport, watchdog, ADC and GPIO
sequencing. It remains inhibited until the manufacturer-approved 40-byte NVM
image and measured RX/ADC approval profiles are available. No live charger
negotiation, physical current rating or hardware test is claimed. See
[POWER-PROTOTYPE-A22.md](POWER-PROTOTYPE-A22.md),
[STM32-RUNTIME-A22.md](STM32-RUNTIME-A22.md) and
[PD-VOLTAGE-INTERVALS.md](PD-VOLTAGE-INTERVALS.md) for the current implementation
and evidence. The older section below is retained solely as revision history.

---

# Historical A17 PD qualification and voltage policy

The following describes A17 and earlier revisions. Its 15 V / 9 V policy,
7.15 kΩ resistor, 100 nF filters and object-only firmware status are superseded
by the current A22 implementation above. Do not use these historical values
for assembly or operation.

2026-10-03. The user approved the MCU architecture. U11 is supplier-imported STM32G030F6P6TR / C529330, used only for power qualification. firmware/pd_policy.c is a portable policy library, tested on the host and compiled to a Cortex-M0+ object. It is **not a complete flashable firmware image**: STM32 startup, clocks, ADC/I2C, STUSB4500 transport, watchdog, option bytes and programming-pad implementation remain open.

## User voltage selection

SW2 / C3293142 is a two-pole DIP. Logical bits: 00=5 V, 01=9 V, 10=12 V, 11=invalid/inhibit (bit 0 is the 9 V input). The schematic note names the two bits rather than guessing physical slider numbering. Pin 1/3 connect to 3.3 V; pin 2/4 to pull-down-equipped GPIO inputs. The manufacturer depicts two independent sliders aligned with two vertical terminal pairs; its land-pattern drawing does not number pads. The official imported footprint labels left bottom/top as pin1/pin4 and right bottom/top as pin2/pin3. Each physical vertical pair has exactly one 3.3 V terminal and one input: left slider reads the 12 V bit; right slider reads the 9 V bit, viewed from the component side with ON at the top. These are footprint-local labels; do not claim they equal the unnumbered manufacturer land identifiers. Physical continuity/assembly orientation must still be tested on the prototype. See SELECTOR-MECHANICS.md.

Q7/Q8 independently ground the selected feedback branches; their gates default low. They isolate the feedback rail from unpowered MCU pins. Both off defaults to 5 V. Both on must never be commanded. Nominal regulated rails are 5.004 / 9.008 / 12.011 V. This explicitly selects a motor rating; the board does not discover it.

## Contract selection and power screen

Only fixed 15/20 V PDOs advertising3–5 A are accepted. The operating request remains3 A; RDO maximum current must equal the selected source advertisement, as defined by STUSB4500. REQ_SRC_CURRENT=0 is required. No native 12 V PDO is assumed; PPS/variable/battery PDOs are ignored. Mandatory source PDO1 must be fixed 5 V. Prefer the lowest adequate voltage using source current, conservative eFuse bounds and peak output power. The current screen selects 15 V for 5/9 V motors and 20 V for a 12 V motor. A 20 V-only qualified source is a valid fallback for 5/9 V. A 15 V-only source is inhibited in 12 V mode because its peak input demand exceeds the minimum eFuse current limit. A 5 V-only/non-PD source powers control circuitry only.

The 7.15 kOhm eFuse resistor gives 2.517 A nominal, 2.243 A minimum and 2.797 A maximum with the recorded IC/resistor tolerance assumptions. Auxiliary fault budget is <=2.867 A total at 15 V. A 20 V/2.25 A source is rejected even when nominal watts appear adequate, because hardware fault current could exceed that contract.

Assumptions: motor rail +5%, downstream 940 Ω worst bleeder, source -5%, series diode 0.55 V, buck 85% efficiency, hot bridge 0.36 Ohm, auxiliaries 1 W, peak motor current 2.423 A. Estimated selected-contract peak input currents are 1.347 A (5/15), 2.226 A (9/15), 2.145 A (12/20). These are engineering screens, not measured efficiency/current/temperature guarantees. The 5 V driver-limit accuracy and the narrow worst-case margin above 2 A remain qualification limits.

## Implemented portable sequence and required embedded adapter

A10 adds firmware/pd_sequence.c/.h, a host-tested power state machine. It waits for measured VM ≤1 V before changing the feedback branch, settles for 5 ms, requests a new contract with a never-reused nonzero request token, waits for matching request completion and PS_RDY provenance, then enables the eFuse. VM must remain in range with fault clear for 10 ms before releasing nSLEEP. A bounded 2 ms wake interval accommodates TI's documented nFAULT pulse; persistent fault then latches both power and bridge off. ADC validity/age, polling age, contract, generation, selector and rail are checked each step. Proposed 3 s decay, 2 s request/contract and 200 ms rail timeouts latch inhibition. Recovery requires an explicit new begin operation; old feedback selection is retained while VM may be charged.

The prior contract check incorrectly included MOTOR_FAULT_N: DRV8874 reports undervoltage while VM is off (TI §7.3.4.1), so that could prevent the eFuse ever starting. A10 contract qualification now checks PD/VBUS independently; motor qualification still rejects driver faults. The state machine checks fault after rail qualification and allows only the documented bounded wake interval. IMODE=GND uses fixed off-time chopping, so nFAULT is not the cycle-by-cycle chopping indicator. Hardware protection remains active throughout; no direction or reversal timer is added.

The adapter must apply bridge inhibition before turning power off or changing feedback, perform each token's RAM programming/soft reset once, clear stale RX/PS_RDY records at initialization, and tag PS_RDY only after the corresponding successful request. It must maintain the capability generation and capture deadline; the state machine cannot infer these from an ADC voltage. Call it at least once per millisecond with calibrated, qualified 3.3 V ADC measurements; current 5 ms maximum ages are proposed software limits, not measured hardware timing guarantees. Reset/watchdog must force the existing hardware defaults. Do not treat an output command as proof that the GPIO/eFuse/driver actually responded.

Both portable modules compile for Cortex-M0+ and the sequence has 11,506 host assertions, including slow RC decay and persistent back-drive cases. These are control-flow tests with simulated observations, not live charger tests or a flashable STM32 image. Startup/clocks/GPIO/ADC/I2C/STUSB4500 event transport/watchdog/option bytes remain to implement and review. The A9 pin-stress/brownout limitations still apply.

### Embedded operations still required

1. GPIO defaults hold HOST_ALLOW low and Q6 bridge inhibit asserted. Set PA7 as open drain: high/Hi-Z asserts inhibition; sinking its base releases it. Hardware PD_ENABLE_N/Q1 and input PG remain independent interlocks.
2. Wait for valid 3.3 V and ST NVM-load completion; verify NVM/required registers. Provision a 5 V standby PDO only, POWER_ONLY_ABOVE_5V=1 and source-current flexibility disabled. Do not rely on factory high-voltage/current profiles.
3. Capture fresh Source_Capabilities via ALERT before the RX buffer can be overwritten (ST example warns approximately 3 ms). Re-request capabilities with motor inhibited if the initial message was missed. Bound I2C retries/timeouts and fail closed.
4. Increment a connection/capability generation on detach, hard reset or changed capabilities. Decode fixed PDOs; call pd_make_plan. No candidate means HOST_ALLOW remains low and bridge remains inhibited.
5. Program the selected 15/20 V, 3 A sink PDO through RAM and request renegotiation. The manufacturer's example writes SoftReset header 0x000D to 0x51 and command 0x26 to 0x1A. Sink PDO count is 0x70, sink objects start at 0x85, RDO at 0x91. Source RX header/data are 0x31/0x33; PE state is 0x29. These are checked against the retained official ST reference source.
6. Require fresh PS_RDY, PE_SNK_READY=0x18, matching source object/generation, no capability mismatch/giveback, 3 A RDO operating current and maximum current matching the selected source advertisement(3–5 A) and valid measured VBUS. A voltage reading or POWER_OK flag alone is insufficient. The policy rejects stale/incorrect contracts, reserved RDO bits and malformed source-current fields.
7. With bridge inhibited and eFuse off, wait for VM to decay before changing feedback branch. Apply only the selected branch; enable the eFuse after contract qualification. Require actual VM in the selected acceptance window before releasing Q6. ADC dividers are 11:1; filters have approximately 0.91 ms time constants.
8. Detach, hard reset, selector change/invalid bits, lost contract, stale/invalid ADC, I2C failure, driver fault or out-of-range VM must inhibit the bridge and power path before further negotiation. A watchdog/reset must return GPIOs to the default-off hardware state. Transport must validate ADC calibration/sample age and fresh PS_RDY provenance; policy parameters are not substitutes for those checks.

R2/R3 are 4.7 kOhm. A 400 kHz rise-time calculation requires total bus capacitance <=75 pF; actual bus timing and the capability-capture deadline must be measured. ADC calibration, GPIO alternate functions/bonded aliases and safe option bytes need the actual STM32 port. No MCU firmware controls direction or adds a reversal timer.

## Evidence and remaining work

Host C tests exercise source voltage/current selection, invalid selectors, missing PD power, stale generation/PS_RDY, RDO mismatch/current, detach, I2C failure, wrong rail and driver fault. The portable library compiles with -ffreestanding -mcpu=cortex-m0plus -mthumb; this proves target compilation of the policy, not an executable firmware image or live PD negotiation. Fourteen board calculation tests pass. Actual charger negotiation, USB unplug/replug, brownout, watchdog, inrush and source faults remain prototype tests.

References: [STUSB4500 datasheet](https://www.st.com/resource/en/datasheet/stusb4500.pdf); [official ST PD reference firmware](https://github.com/usb-c/STUSB4500); [STM32G0 CMSIS device definitions](https://github.com/STMicroelectronics/cmsis-device-g0). Retained source files in evidence identify the register operations reviewed. No NVM or hardware programming is claimed.

The PD-enable input has a 4.7 kOhm pull-up and 20 kOhm Q1 base resistor. The old 10 kOhm/10 kOhm network loaded the inactive signal to about 2 V, below a conservative 0.7*VDD MCU high threshold. The revised nominal inactive level is about 2.8 V while retaining sufficient transistor base drive. A resistor/supply/VBE/leakage screen is recorded in the board tests; actual startup timing remains a measurement.

A9 pin-power review: PA1_CDEN (SYSCFG_CFGR2 bit 16) resets disabled and must remain disabled; PA0/PA1 stay analog/no-pull. Above-VDD stress tolerance does not qualify ADC samples during brownout. See MCU-POWER-SEQUENCING.md for calculations and required unplug/replug measurements.


A11 adds a defined supplier-backed VM discharge path; the timeout was corrected from 1 s to 3 s using a ≤650 µF/1060 Ω screen. Actual VM measurement remains mandatory and a charged/back-driven rail never qualifies solely from time. Both C/host power calculations add +5% VM and the bleeder load; 9 V/15 V peak margin is approximately 17 mA at the combined engineering corner and requires transient qualification. RAIL-DISCHARGE.md records the limits and physical tests still required.

A12 implements bounded receive capture in firmware/stusb4500_rx.c, with 531 C assertions and a Cortex-M0+ object. A second read-to-clear status check rejects messages arriving during capture, including identical-header replacement. Zero-object controls keep old count/object bytes out of the PDO array. Deadlines, I2C faults, malformed headers and changing frames fail explicitly. No request token or fresh_ps_rdy is generated by this module. Actual SOP routing, interrupt handling, RAM-PDO transaction, fresh negotiation provenance and the STM32 peripherals remain unimplemented. Manufacturer reserved-field/reference discrepancies are documented in STUSB4500-RX.md; no encoded SOP value is guessed. The configured suite now passes 17 tests/363 expects, without live charger or flashable-firmware claims. Hardware/BOM and A11 power limitations remain unchanged.

A13 implements the portable RAM-PDO write/readback and SoftReset transaction; that operation supersedes the A12 "unimplemented RAM-PDO transaction" item above. It keeps only standby PDO1 active during rewriting, verifies fixed5 V PDO1 and the policy-selected15/20 V PDO2 byte-for-byte, activates count2, checks the SoftReset header and attachment/alarms, then issues0x26. All failure/ambiguous-write paths clear completion and latch inhibition without retry.969 host assertions and target object compilation pass; receive531 assertions are renewed. The configured suite passes18 tests/366 expects. Fresh Source_Capabilities/Accept/PS_RDY provenance, NVM provisioning, event ownership and actual STM32 peripherals still remain open; completed_request_id is not a power contract. See STUSB4500-REQUEST.md. No hardware/BOM or placement/routing change.


A15 implements portable standby initialization/capability acquisition under explicit inhibition and provenance invalidation. All documented alerts are configured with readback; ten startup status bytes are retained, one fixed5 V/3 A RAM PDO is selected and checked, and SoftReset is sent once.13,969 host assertions, Cortex-M0+ compilation and19 configured tests/369 expects pass. New responses must still be captured and associated; startup completion does not qualify power. NVM, actual event/peripheral integration and physical evidence remain open. See STUSB4500-STARTUP.md. Hardware/BOM and placement/routing are unchanged.


A16 adds bounded complete40-byte NVM readback comparison under inhibition.20,639 simulated assertions and target-object compilation pass; the separately approved manufacturer-tool image and physical programming remain missing. All20 configured tests/372 expects pass. See STUSB4500-NVM.md and pd-manufacturing-profile.json. Current datasheet review also identifies a charger-compatibility defect: RDO maximum follows advertised source current, so the existing exact3 A maximum check unnecessarily inhibits sources above3 A. That policy change remains open in A16. No placement/routing change.


A17 corrects the current-field issue identified in A16. The plan retains the exact selected source PDO; RDO operating remains3 A and maximum must equal that advertisement. Reserved RDO31/23:20, capability mismatch and GiveBack are rejected.3–5 A sources are supported by the portable policy, without increasing hardware limits.60,202 policy assertions,11,518 sequence assertions and1,037 request assertions pass; all22 configured tests/382 expects and all six Cortex-M0+ module objects pass. Source/rail/contract provenance and target integration are still required; these are simulated/compiled results. See PD-RDO-CURRENT.md.

A18 supplies the actual GPIO initialization/inhibit/input backend with preserved feedback and SWD state (STM32-SAFE-GPIO.md). A19 replaces the four ADC divider resistors with0.1% parts and screens conservative voltage intervals (ADC-SENSING.md). The ADC/peripheral/sequence-output adapter remains incomplete; nominal ADC scaling must not be used as an exact safety measurement.

A21 replaces scalar physical observations with explicit valid lower/upper voltage intervals. Complete intervals must fit the relevant±5% window; VM upper bound≤1 V is required through the PD request/contract wait. Raw ADC validity is insufficient. See PD-VOLTAGE-INTERVALS.md; the actual calibrated adapter and event owner remain pending.