Schema gaps found while writing the parts library¶
A source
This page is a source of edakit – a concept, a prompt or the rules of a session –, shown as it is in the repository. Read it as such; the guides say what edakit does.
Status 2026-10-31: decided (rules-at-scale.md, decisions 10 and 11) and built – the state per item at the end. While writing the 51 library drafts in edakit/parts/ from their datasheets
(rules-at-scale.md, decision 8), seven agents reported facts the parts schema (edakit/catalog/kinds.toml) has no
field for, and places where edakit's checks judge a correct circuit wrongly. They are grouped here, with how many of
the seven groups (modules, LEDs and displays, power, switching, sensors, buses, audio) met each, and a proposal per
theme. The six block agents that built BL-1 to BL-18 on these entries added theirs (section I).
Fixed already on the way: a threshold [min, null, max] that crashed the gate check, the flyback finding on drivers
that clamp their windings themselves (pin clamp), the fix text for an unbiased RS-485 B line, the supply current
fields icc_a and i_a; and twelve false alarms the block agents met (tests/test_false_alarms.py): a negative rail's
series diode (PATH.reverse, PATH.unfed), simulation noise against a limit of 0, a V− supply pin against the −0.3 V
floor, a tristate output with its enable tied active and a net held through a resistor chain (LVL.undefined), a
termination behind a switch and the failsafe bias at the supply's minimum, an input tied to a rail, decoupling to a
net of grounds, a P-MOSFET's gate drive in its own sense, HINT.esd, HINT.gate, HINT.debounce, HINT.cable_line and
HINT.lithium where they did not fit, the load on an instrument input through a series resistor.
A. Findings that are wrong – first¶
| # | Gap | Met by | Effect today | Proposal |
|---|---|---|---|---|
| A1 | PWM (and UART, I2C …) routable to any GPIO through a matrix (ESP32, S3, C3) | modules | a net with fn: pwm on these modules: a false REQ.function error |
an entry field matrix = ["pwm", "uart", "i2c", "spi"] – functions every GPIO of the part offers |
| A2 | a bridge output (drives high, low or off) | switching | typed tristate: LVL.undefined/open_drain on every motor net | pin drive = "bridge": defines its net while enabled, contention like a push-pull output |
| A3 | an analog pin biased inside the part (PAM8403 INL/INR) | audio | LVL.undefined/analog through its coupling capacitor | pin biased = true |
| A4 | address pins with four states (GND, VS, SDA, SCL – INA219, INA226) | sensors | a pin tied to SDA reads as high: a wrong address, a false REQ.forbidden/address | address.pins maps a pin to its four values |
| A5 | a peripheral's bus pins with functions | audio | listed functions would hide an MCU pin that cannot do I2S | REQ.function counts only the functions of microcontroller and module pins |
| A6 | vin_rel_max_v per part |
power, LEDs, buses | flags pins rated above the supply (TP4056 CE, CH224K CFG1); never holds outputs and bidirectional pins | per pin v_rel_max_v with the pin it refers to (B1) |
| A7 | a multiplexed LED matrix driver (MAX7219) | LEDs | LEDs between segment and digit pins fail SIM.driver | a behaviour matrix_driver, or the LEDs exempted from SIM.driver with the reason |
B. Limits relative to a pin¶
| # | Gap | Met by | Proposal |
|---|---|---|---|
| B1 | thresholds as ratios and limits above a supply refer to a named supply pin – VLOGIC (MPU-6050), VDDIO (BME280), VCC | sensors, LEDs, buses, power | pin field ref = "<pin name>" for vih_ratio, vil_ratio, v_rel_max_v; default the part's supply as today |
| B2 | one supply never above another (VLOGIC ≤ VDD) | sensors | an entry field supply_order = [["VLOGIC", "VDD"]], judged on the declared ranges |
| B3 | a limit only while powered (RP2350 fault-tolerant 5.5 V) | modules | v_max_v stays the unpowered value; v_max_powered_v beside it |
C. Per-pin currents and negative limits¶
| # | Gap | Met by | Proposal |
|---|---|---|---|
| C1 | current per pin (PCF8574 25 mA, MAX7219 500 mA digit sink, AVR 40 mA) and per group of pins (AVR ports) | LEDs, modules, buses | pin i_max_a, entry i_group_max_a = {"name": [pins, A]} – LIM.i on the simulated pin currents |
| C2 | negative limit per pin (RS-485 −7.5 V, ACS712 −0.1 V) | buses | pin v_min_v |
| C3 | injection current through the protection diodes (PCF8574 400 µA) | LEDs | pin i_inject_max_a, with LIM.v/inject |
| C4 | minimum load resistance, maximum load capacitance of an output (ACS712, amplifiers) | buses, audio | pin r_load_min_ohm, c_load_max_f |
D. What a pin needs¶
| # | Gap | Met by | Proposal |
|---|---|---|---|
| D1 | a capacitor between two pins (charge pumps CP–VCP, thermocouple T+–T−, VCP to VM) | LEDs, switching, buses | needs.capacitor.to = "<pin>" beside the default ground |
| D2 | a crystal with its load capacitors (CH340G) | buses | needs.crystal = {f_hz, tol_ppm, c_load_f} and a kind crystal |
| D3 | tie to a supply (BME280 CSB to VDDIO), no external pull-up (DS3231 RST), must not float, never a series resistor | sensors, buses | needs.tie, needs.no_pull, float_ok = false for bidirectional pins, needs.no_series |
| D4 | the voltage rating a required capacitor needs (MPU-6050 CPOUT 50 V) | sensors | needs.capacitor.v_min_v |
| D5 | an upper bound local to a pin when the net carries more (DS3231 0.1–1 µF) | sensors | the window judged on the capacitors within the pin's layout.near, not the net's sum |
E. Behaviour in the simulation¶
| # | Gap | Met by | Proposal |
|---|---|---|---|
| E1 | a sensor, transceiver or USB-UART draws its supply current | sensors, buses, audio, LEDs | the entries use behaviour logic with icc_a (the field exists since the merge of FT-21); a pass over the drafts |
| E2 | bridge drivers (DRV8833, TB6612, L298 …) | switching | behaviour bridge: outputs follow their inputs, r_out_ohm high and low side |
| E3 | linear chargers: CC/CV, termination, precondition, UVLO | power | behaviour charger (FT-4's rest), fields from the TP4056 and MCP73831 datasheets |
| E4 | a cell protection IC and a dual MOSFET (DW01A with FS8205A) | power | behaviour protection with its thresholds; a kind dual_nmos with both channels |
| E5 | a USB PD sink (CH224K) with its VDD shunt regulator | power | behaviour pd_sink; until then sim: false for blocks that use it |
| E6 | a buck-boost regulator (the Pico's RT6150) | modules | buck_boost in the regulator enum |
F. Modes and configurations¶
| # | Gap | Met by | Proposal |
|---|---|---|---|
| F1 | supply configurations (CH340 at 5 V or 3.3 V, CP2102's three) | buses | entry configs = {name: {pins and ranges}}, the graph names the one it uses |
| F2 | pin roles that depend on the interface mode (SSD1306 D0/D1 as SCL/SDA) | LEDs | the same configs |
| F3 | needs that hold only in one mode (DS18B20 parasite power, DS3231 VBAT, HX711 VBG, INA226 Alert) | sensors | needs.when = "<config>" |
G. Values of single kinds of parts¶
Fields that one group met, for later: amplifier gain settings, minimum load and required series inductance; a
current sensor's sensitivity and isolation, and its conductor path inside the part (the simulation sees IP+ and IP−
unconnected); the clock limit of any part on a bus (f_max_hz is read for MCUs only); a PWM frequency limit and a
supply ramp rate; r_out_ohm high and low side, a bipolar output's saturation drop; ambient against junction
temperature; ADC unit and channel apart, the ADC window per attenuation; a smart LED's colour and per-channel current;
an unclocked chained output's delay; storage temperature.
H. Errors in the EasyEDA library data¶
The agents compared every pinout with the EasyEDA symbol that edakit part import caches, and found four that differ
from the manufacturer's datasheet. The library entries follow the datasheet (or keep the symbol's names with the
datasheet's roles and a hint, where handbook 4.4 asks for the symbol's names); STRUCT.entry compares a graph with the
cached symbol. A project that draws its schematic from these symbols gets a wrong netlist:
- WS2812B-V5/W (C2874885): DIN numbered 3 like VSS – DIN lands on ground, pad 4 open.
- XC6206P332MR-G (C5446): pin 2 named Vin, pin 3 Vout – Torex: pin 2 VOUT, pin 3 VIN; the regulator fed backwards.
- DRV8825PWPR (C81582): no pin for the PowerPAD (footprint pad 29).
- Raspberry Pi Pico 2 (C41407547): pins 2–6 named TP2–TP6, 41 and 43 swapped. The example project carried the swap of 41 and 43 as well; it is corrected (41 SWCLK, 43 SWDIO).
I. From the blocks¶
| # | Gap | Met by | Proposal |
|---|---|---|---|
| I1 | LIM.v judges a part's pins against GND, not against the part's own ground pin (DW01A on the cell's minus) | power blocks | pin_voltages takes each part's ground net, as stage E's at_pin does |
| I2 | a sim.json source has one plus and one minus – a ±12 V header cannot feed both rails | Eurorack | a source with several outputs {plus: [pins], minus} |
| I3 | a relay with two contact sets (DPDT) – the simulation switches the first only | guitar | roles per set (common_2, no_2, nc_2) |
| I4 | a photo-MOS (a resistance both ways when lit), an optocoupler's detector supply, a pass-gate translator (PCA9306), a multi-diode ESD array | guitar, interfaces, MCU/USB | behaviours photomos, pass_gate; the ESD array as a kind with its lines |
| I5 | a net isolated from board ground (a MIDI in loop) | interfaces | a net key isolated = true that the ground checks skip |
| I6 | a relay contact's minimum switching load (gold contacts), a DIP switch's switching against carrying current, a connector's current per contact | guitar, interfaces, MCU/USB | contact fields min_load_a, i_switch_max_a, i_contact_max_a |
| I7 | LIM.v/polarized in stage G pairs the top of one net's range with the bottom of the other's across a coupling electrolytic – states that never coincide | guitar | judged on the operating points of stage E only, or a grade the domain audio lowers |
| I8 | a block cannot set graph keys (grounds), mark a part or port optional, or remove a supply in its test |
all blocks | block keys graph, optional; the test's sim merged deeply |
| I9 | an accept on a net cannot name one designator or place – a port net's accept covers the project's rail | MCU/USB, Eurorack | accept keys code place on a net, as on the graph |
Order proposed¶
A first – each is a finding that is wrong today –, with I1 and I7. Then B1, C1 and D1, which several groups met and which make checks of existing codes hold on more pins. E1 is a pass over the drafts with fields that exist. E2 to E6, F and G when a project needs them. H goes to the owner: whether edakit should check a cached symbol against its entry beyond the pin names (STRUCT.entry), and whether the four symbols are reported to EasyEDA/LCSC.
State after the build (2026-10-31)¶
Built in seven worktrees (W1–W7) and merged; each item with a test that is red without it.
| Items | State | Where |
|---|---|---|
| A1–A5, A7 | built | entry matrix, pin drive = "bridge", pin biased, address pins {low, high, sda, scl}, REQ.function on MCU and module pins only, behaviour matrix_driver (W1) |
| A6, B1–B3, C1–C4 | built | pin ref, rel_ref, v_rel_max_v, v_max_powered_v, v_min_v, i_max_a, i_inject_max_a, r_load_min_ohm, c_load_max_f; entry supply_order, i_group_max_a; grades LIM.v/powered, LIM.v/order, LIM.i/pin, REQ.value/load (W2) |
| D1, D2, D4, D5 | built | needs.capacitor.to, needs.crystal and kind crystal, needs.capacitor.v_min_v, a capacitor window on the parts layout.near places (W3) |
| D3 | built | needs.tie, no_pull, no_series, float_ok = false; the BME280 (C92489) with configs i2c (its default), spi4 and spi3 from Bosch's datasheet: CSB tied to VDDIO (a tie with when) and SDO not floating only in I²C, the address and the roles sda/scl only there, SDO a tri-state output in 4-wire SPI and not connected in 3-wire SPI (R6); no other library entry waits for configs of this kind |
| E1 | in part | behaviour logic: an open-drain output released, a tri-state output released unless its part ties every enable pin active, a push-pull output low – or high, low or off as the pin's state or the component's states say, high from the pin's supply; icc_a at the supply pin or per supply pin by name; STRUCT.entry on states (R6). logic with icc_a from the datasheets on BME280, INA226, MPU-6050, DS3231, MAX6675, MAX31855, HX711, INMP441, MAX3485, MAX485, PCF8574, PCF8574A, CH340G, CH340C besides AT24C32D, INA219, DS18B20 – not: the ACS712 (allegromicro.com is not among the hosts this build could read, and its VIOUT is an analog output no state describes), the CP2102 (its ldo model carries its supply current), the amplifiers (PAM8403, MAX98357A), the smart LEDs (WS2812B, SK6812, SK9822) and the SSD1306 panel – not part of this pass, their outputs need more than a fixed state; internal pulls, an RS-485 driver's bus current, the HX711's regulator are not modelled |
| E2, E3, E4, E6 | built | behaviours bridge, charger, protection, buck_boost; roles gate_2/source_2/drain_2 for a dual MOSFET (W4) – not modelled: a charger's termination, the DW01A's hysteresis and delays; by decision 17 no state model – HINT.charge_termination and HINT.protection_timing name them where the part is used, edakit check --coverage lists the part as not simulated, HINT.power_path a load on the charging cell (R1) |
| E5 | built | behaviour pd_sink with REQ.value/pd_request (W5) – PG, the CC lines and the negotiation not modelled: no state model by decision 17, HINT.pd_negotiation names them where the part is used, edakit check --coverage lists the part as not simulated (R1) |
| F1–F3 | built | entry configs, config_default, a component's config, needs with when (W6) |
| I1, I7 | built | LIM.v against a part's own ground pin; LIM.v/polarized leaves signal coupling to stage E (W1) |
| I2–I4 | built | sim.json source with outputs, relay roles per contact set, behaviours photomos, pass_gate, kind esd_array (W5) |
| I5, I6, I8, I9 | built | net isolated, i_contact_max_a, i_switch_max_a, min_load_a, block keys graph, optional, block add --without, accepts "code place" (W6) |
| H | built | STRUCT.entry/symbol and symbol_differs (W7); the report upstream/issue-6-easyeda-symbols.md, not sent – the owner sends it |
| G | open | not part of decision 10 |
Decided on the owner's behalf (rules-at-scale.md, decisions 13–15): the MPU-6050's SCL/SDA stay held to VLOGIC + 0.5 V; the 10 µA a contact in a signal path may need at most stays, sourced to the Hongfa HFD4's minimum applicable load; the INA226's Alert is held to VS + 0.3 V like SCL.