AnasSarkiz/usb-c-pwm-pa25
A component library defining an AO3400A N-channel MOSFET, 47 µF polarized capacitor, 3-pin through-hole connector, and 9.1 V Zener diode with PCB footprints and 3D CAD models.
- Version
- 0.1.0-prototype.2
- License
- unset
- Stars
- 0
firmware/test_control.c
#include "control.h"
#include <assert.h>
#include <stdio.h>
static struct Inputs healthy = {.pd_valid=true,.hardware_healthy=true,.adc_valid=true,.vm_mv=12000,.temperature_mv=880};
static void tick_for(struct Controller *controller, unsigned milliseconds) {
while (milliseconds--) controller_tick(controller, &healthy);
}
static struct Controller ready_controller(void) {
struct Controller controller = {0};
healthy.forward_closed=false; healthy.reverse_closed=false;
healthy.pot_permille=0; healthy.current_ma=0; healthy.pd_valid=true;
healthy.hardware_healthy=true; healthy.vm_mv=12000; healthy.temperature_mv=880;
tick_for(&controller,1100);
assert(controller.mode==READY && controller.duty_permille==0);
return controller;
}
static void run_forward(struct Controller *controller) {
healthy.forward_closed=true;
tick_for(controller,40);
assert(controller->mode==RUNNING && controller->duty_permille==0);
healthy.pot_permille=1000;
tick_for(controller,500);
assert(controller->duty_permille==1000 && controller->applied_direction==FORWARD);
}
int main(void) {
const uint32_t pdo = (300UL<<10)|200U;
const uint32_t rdo = (2UL<<28)|(100UL<<10)|150U;
assert(pd_contract_valid(pdo,rdo));
assert(!pd_contract_valid((100UL<<10)|300U,rdo));
assert(!pd_contract_valid(pdo,rdo|(1UL<<26)));
assert(!pd_contract_valid(pdo,rdo|(1UL<<27)));
assert(!pd_contract_valid(pdo,0));
assert(!pd_contract_valid(pdo|(3UL<<30),rdo));
assert(!pd_contract_valid((300UL<<10)|100U,rdo));
struct Controller controller=ready_controller();
run_forward(&controller);
// Bounce initiates a retained ramp-down; it cannot reverse or restart the ramp.
healthy.forward_closed=false; healthy.reverse_closed=true;
tick_for(&controller,10);
assert(controller.mode==RAMP_DOWN && controller.applied_direction==FORWARD);
healthy.forward_closed=true; healthy.reverse_closed=false;
tick_for(&controller,600);
assert(controller.mode==COAST && !controller.bridge_enabled);
tick_for(&controller,2500);
assert(controller.mode==DISARMED && !controller.bridge_enabled);
healthy.forward_closed=false; healthy.pot_permille=0;
tick_for(&controller,600);
assert(controller.mode==READY);
healthy.reverse_closed=true; tick_for(&controller,40);
healthy.pot_permille=500; tick_for(&controller,300);
assert(controller.mode==RUNNING && controller.applied_direction==REVERSE);
// Unplug/reconnect with controls unchanged never restarts the motor.
healthy.pd_valid=false; tick_for(&controller,1);
assert(controller.mode==WAIT_PD && !controller.power_enabled && !controller.bridge_enabled);
healthy.pd_valid=true; tick_for(&controller,1500);
assert(controller.mode==DISARMED && controller.duty_permille==0);
controller=ready_controller(); run_forward(&controller);
healthy.current_ma=400; tick_for(&controller,99);
assert(controller.mode==RUNNING);
tick_for(&controller,1);
assert(controller.mode==FAULT && controller.fault==OVERLOAD_FAULT && !controller.power_enabled);
tick_for(&controller,1000); assert(controller.mode==FAULT);
controller=ready_controller(); run_forward(&controller);
healthy.pot_permille=0; tick_for(&controller,1);
assert(controller.duty_permille==0 && !controller.bridge_enabled);
healthy.temperature_mv=0; tick_for(&controller,1);
assert(controller.fault==TEMPERATURE_FAULT);
controller=ready_controller(); run_forward(&controller);
healthy.temperature_mv=3300; tick_for(&controller,1);
assert(controller.fault==TEMPERATURE_FAULT);
controller=ready_controller(); run_forward(&controller);
healthy.hardware_healthy=false; tick_for(&controller,1);
assert(controller.fault==HARDWARE_FAULT && !controller.bridge_enabled);
controller=ready_controller(); run_forward(&controller);
healthy.vm_mv=14000; tick_for(&controller,1);
assert(controller.fault==POWER_FAULT && !controller.bridge_enabled);
controller=ready_controller();
healthy.forward_closed=true; healthy.reverse_closed=true;
tick_for(&controller,40); assert(controller.fault==SWITCH_FAULT);
puts("PASS: PD qualification, restart interlock, sequencing, bounce, overload, thermal, supply, hardware faults, true zero");
}