imrishabh18/rp2040-motor-controller

A library of PCB component definitions covering MOSFETs, motor drivers, USB-PD control, sensors, current monitors, transistors, diodes, resistors, speakers, connectors, and mirrored bottom-side logos, with pin mappings, footprints, and 3D models.

Version
1.0.55
License
unset
Stars
5

tests/helpers/assertPdPowerGood.ts

import type { CircuitJson } from 'circuit-json';

/** Check physical pins, supply separation and the existing hardware interlock. */
export function assertPdPowerGood(json: CircuitJson) {
  const j = json as any[];
  const parent = new Map<string, string>();
  const root = (id: string): string => {
    if (!parent.has(id)) parent.set(id, id);
    if (parent.get(id) !== id) parent.set(id, root(parent.get(id)!));
    return parent.get(id)!;
  };
  for (const e of j) {
    const ids = e.type === 'source_trace' ? [...e.connected_source_port_ids, ...e.connected_source_net_ids]
      : e.type === 'source_component_internal_connection' ? e.source_port_ids : [];
    for (const id of ids.slice(1)) parent.set(root(id), root(ids[0]));
  }
  const part = (name: string) => {
    const c = j.find(e => e.type === 'source_component' && e.name === name);
    if (!c) throw new Error(`Missing ${name}`);
    return c;
  };
  const net = (name: string, pin: number) => {
    const p = j.find(e => e.type === 'source_port' && e.source_component_id === part(name).source_component_id && e.pin_number === pin);
    if (!p) throw new Error(`Missing ${name}.${pin}`);
    return root(p.source_port_id);
  };
  const same = (a: [string, number], b: [string, number]) => {
    if (net(...a) !== net(...b)) throw new Error(`Disconnected ${a.join('.')} / ${b.join('.')}`);
  };
  if (part('U_PD_PG').manufacturer_part_number !== 'SN74LVC1G97DRLR') throw new Error('PG buffer must support Ioff and Schmitt inputs');
  // TI: IN1=1, GND=2, IN0=3, Y=4, VCC=5, IN2=6.
  same(['U_PD_PG', 1], ['U_PD', 1]);
  same(['U_PD_PG', 6], ['U_PD', 10]);
  same(['U_PD_PG', 3], ['U_PD', 11]);
  same(['U_PD_PG', 2], ['U_PD', 11]);
  same(['U_PD_PG', 5], ['L_AVDD', 1]);
  same(['U_PD_PG', 4], ['U1', 9]); // RP2040 GPIO7.
  same(['R_PD_VDD_PD', 1], ['U_PD', 1]);
  same(['R_PD_VDD_PD', 2], ['U_PD', 11]);
  same(['R_PD_GOOD_PD', 1], ['U_PD_PG', 4]);
  same(['R_PD_GOOD_PD', 2], ['U_PD', 11]);
  same(['C_PD_PG', 1], ['U_PD_PG', 5]);
  same(['C_PD_PG', 2], ['U_PD', 11]);
  same(['U_PD', 10], ['Q_PD_ENABLE', 1]);
  same(['U_PD', 10], ['R_PD_ENABLE_PU', 1]);
  same(['U_PD', 1], ['R_PD_ENABLE_PU', 2]);
  same(['Q_PD_ENABLE', 2], ['U1', 34]); // GPIO22 / MCU_ENABLE.
  same(['Q_PD_ENABLE', 3], ['DRIVER', 17]); // nSLEEP.
  const separate = [net('U_PD',1), net('U_PD',10), net('U_PD',11), net('U_PD_PG',4), net('U_PD_PG',5)];
  if (new Set(separate).size !== separate.length) throw new Error('PG power domain or GPIO short');
  if (part('R_PD_VDD_PD').resistance !== 47000 || part('R_PD_GOOD_PD').resistance !== 10000) throw new Error('Incorrect PG default bias');
  if (part('C_PD_PG').capacitance !== 1e-7) throw new Error('Missing PG supply bypass');
  return {status: 'pass', gpio: 7, activeHigh: true, noPwrUsbReadsGood: false, buffered: true, hardwareInterlockPreserved: true};
}