From da7d62f7008ad628311a3a28da99361fc84b543d Mon Sep 17 00:00:00 2001 From: Richard Lin Date: Mon, 18 May 2026 22:54:44 -0700 Subject: [PATCH 1/9] add reversal to pin pair --- edg/parts/PassiveConnector_Header.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/edg/parts/PassiveConnector_Header.py b/edg/parts/PassiveConnector_Header.py index 4a494f144..c44e1731f 100644 --- a/edg/parts/PassiveConnector_Header.py +++ b/edg/parts/PassiveConnector_Header.py @@ -53,15 +53,29 @@ def part_footprint_mfr_name(self, length: int) -> Tuple[str, str, str]: ) -class PinSocket254Pair(SubboardConnectorPair): +class PinSocket254Pair(SubboardConnectorPair, GeneratorBlock): """2.54mm pin socket (external) - header (internal) pair for sub-board connectors, - matching same pin-number to pin-number.""" + matching same pin-number to pin-number. - def __init__(self, length: IntLike = 0) -> None: + Optionally can be reversed, with the header being on the external side and the socket being on the internal side.""" + + def __init__(self, length: IntLike = 0, reversed: BoolLike = False) -> None: super().__init__() - self.ext = self.Block(PinSocket254(length), external=True) - self.int = self.Block(PinHeader254(length)) - self.pins = self.Export(self.int.pins) + self.length = self.ArgParameter(length) + self.reversed = self.ArgParameter(reversed) + self.generator_param(self.reversed) + + self.pins = self.Port(Vector(Passive.empty())) + + def generate(self) -> None: + super().generate() + if not self.get(self.reversed): + self.ext = self.Block(PinSocket254(self.length), external=True) + self.int = self.Block(PinHeader254(self.length)) + else: + self.ext = self.Block(PinHeader254(self.length), external=True) + self.int = self.Block(PinSocket254(self.length)) + self.connect(self.pins, self.int.pins) self.export_tap(self.pins, self.ext.pins) From 4b29a8fb9a9d474ec316ed802105e2d7d65fd5f9 Mon Sep 17 00:00:00 2001 From: Richard Lin Date: Mon, 18 May 2026 22:57:05 -0700 Subject: [PATCH 2/9] Update PassiveConnector_Header.py --- edg/parts/PassiveConnector_Header.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edg/parts/PassiveConnector_Header.py b/edg/parts/PassiveConnector_Header.py index c44e1731f..0afb41a36 100644 --- a/edg/parts/PassiveConnector_Header.py +++ b/edg/parts/PassiveConnector_Header.py @@ -59,7 +59,7 @@ class PinSocket254Pair(SubboardConnectorPair, GeneratorBlock): Optionally can be reversed, with the header being on the external side and the socket being on the internal side.""" - def __init__(self, length: IntLike = 0, reversed: BoolLike = False) -> None: + def __init__(self, length: IntLike = 0, *, reversed: BoolLike = False) -> None: super().__init__() self.length = self.ArgParameter(length) self.reversed = self.ArgParameter(reversed) From 81d8833402fa2bb19f71a94fc9fa3785d4d5a66f Mon Sep 17 00:00:00 2001 From: Richard Lin Date: Mon, 18 May 2026 23:03:48 -0700 Subject: [PATCH 3/9] Update Microcontroller_Stm32f103.py --- edg/parts/Microcontroller_Stm32f103.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edg/parts/Microcontroller_Stm32f103.py b/edg/parts/Microcontroller_Stm32f103.py index 37732e89e..85dad754a 100644 --- a/edg/parts/Microcontroller_Stm32f103.py +++ b/edg/parts/Microcontroller_Stm32f103.py @@ -268,7 +268,7 @@ class Stm32f103_48_Device(Stm32f103Base_Device): } PACKAGE = "Package_QFP:LQFP-48_7x7mm_P0.5mm" PART = "STM32F103xxT6" - LCSC_PART = "C8734" # C8T6 variant - basic part + LCSC_PART = "C8304" # max memory CBT6 variant # C77994 for GD32F103C8T6, probably mostly drop-in compatible, NOT basic part LCSC_BASIC_PART = True From 53f6496e9fd0781b95735adfc0d605dc6dee0643 Mon Sep 17 00:00:00 2001 From: Richard Lin Date: Mon, 18 May 2026 23:11:28 -0700 Subject: [PATCH 4/9] Update Microcontroller_Stm32f103.py --- edg/parts/Microcontroller_Stm32f103.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edg/parts/Microcontroller_Stm32f103.py b/edg/parts/Microcontroller_Stm32f103.py index 85dad754a..dd6da2038 100644 --- a/edg/parts/Microcontroller_Stm32f103.py +++ b/edg/parts/Microcontroller_Stm32f103.py @@ -298,7 +298,7 @@ class Stm32f103Base( GeneratorBlock, ): DEVICE: Type[Stm32f103Base_Device] = Stm32f103Base_Device - DEFAULT_CRYSTAL_FREQUENCY = 12 * MHertz(tol=0.005) + DEFAULT_CRYSTAL_FREQUENCY = 8 * MHertz(tol=0.005) # as in common dev boards / eval boards def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) From 94aaaf30dbfa93491568e65e33233b73d320ce94 Mon Sep 17 00:00:00 2001 From: Richard Lin Date: Mon, 18 May 2026 23:18:41 -0700 Subject: [PATCH 5/9] fix diode circular dependencies --- edg/parts/PassiveConnector_Header.py | 5 ++-- edg/parts/PowerConditioning.py | 34 ++++++++++------------------ 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/edg/parts/PassiveConnector_Header.py b/edg/parts/PassiveConnector_Header.py index 0afb41a36..584cbec11 100644 --- a/edg/parts/PassiveConnector_Header.py +++ b/edg/parts/PassiveConnector_Header.py @@ -67,11 +67,12 @@ def __init__(self, length: IntLike = 0, *, reversed: BoolLike = False) -> None: self.pins = self.Port(Vector(Passive.empty())) + @override def generate(self) -> None: super().generate() if not self.get(self.reversed): - self.ext = self.Block(PinSocket254(self.length), external=True) - self.int = self.Block(PinHeader254(self.length)) + self.ext: PassiveConnector = self.Block(PinSocket254(self.length), external=True) + self.int: PassiveConnector = self.Block(PinHeader254(self.length)) else: self.ext = self.Block(PinHeader254(self.length), external=True) self.int = self.Block(PinSocket254(self.length)) diff --git a/edg/parts/PowerConditioning.py b/edg/parts/PowerConditioning.py index 950ba0680..bafaa8d69 100644 --- a/edg/parts/PowerConditioning.py +++ b/edg/parts/PowerConditioning.py @@ -16,7 +16,11 @@ def __init__(self, voltage_drop: RangeLike, reverse_recovery_time: RangeLike = R self.pwr_in = self.Port(VoltageSink(current_draw=RangeExpr())) # high-priority source self.pwr_in_diode = self.Port(VoltageSink(current_draw=RangeExpr())) # low-priority source - self.pwr_out = self.Port(VoltageSource(voltage_out=RangeExpr())) + self.pwr_out = self.Port( + VoltageSource( # use the spec voltage drop to avoid circular dependencies downstream + voltage_out=self.pwr_in.link().voltage.hull(self.pwr_in_diode.link().voltage - voltage_drop), + ) + ) self.diode = self.Block( Diode( @@ -33,15 +37,6 @@ def __init__(self, voltage_drop: RangeLike, reverse_recovery_time: RangeLike = R ) self.assign(self.pwr_in.current_draw, self.pwr_out.link().current_drawn) self.assign(self.pwr_in_diode.current_draw, self.pwr_out.link().current_drawn) - self.assign( - self.pwr_out.voltage_out, - self.pwr_in.link().voltage.hull( - ( - self.pwr_in_diode.link().voltage.lower() - self.diode.voltage_drop.upper(), - self.pwr_in_diode.link().voltage.upper() - self.diode.voltage_drop.lower(), - ) - ), - ) self.connect(self.pwr_in_diode.net, self.diode.anode) self.connect(self.pwr_out.net, self.pwr_in.net, self.diode.cathode) @@ -55,7 +50,13 @@ def __init__(self, voltage_drop: RangeLike, reverse_recovery_time: RangeLike = ( self.pwr_in1 = self.Port(VoltageSink(current_draw=RangeExpr())) self.pwr_in2 = self.Port(VoltageSink(current_draw=RangeExpr())) - self.pwr_out = self.Port(VoltageSource(voltage_out=RangeExpr())) + self.pwr_out = self.Port( + VoltageSource( # use the spec voltage drop to avoid circular dependencies downstream + voltage_out=(self.pwr_in1.link().voltage - voltage_drop).hull( + self.pwr_in2.link().voltage - voltage_drop + ) + ) + ) output_lower = ( self.pwr_in1.link().voltage.lower().min(self.pwr_in2.link().voltage.lower()) @@ -78,17 +79,6 @@ def __init__(self, voltage_drop: RangeLike, reverse_recovery_time: RangeLike = ( ) ) - self.assign( - self.pwr_out.voltage_out, - ( - (self.pwr_in1.link().voltage.lower() - self.diode1.actual_voltage_drop.upper()).min( - self.pwr_in2.link().voltage.lower() - self.diode2.actual_voltage_drop.upper() - ), - (self.pwr_in1.link().voltage.upper() - self.diode1.actual_voltage_drop.lower()).max( - self.pwr_in2.link().voltage.upper() - self.diode2.actual_voltage_drop.lower() - ), - ), - ) self.assign(self.pwr_in1.current_draw, self.pwr_out.link().current_drawn) self.assign(self.pwr_in2.current_draw, self.pwr_out.link().current_drawn) From 6afd596f8e23c8b006ddcea316faa4f4df16b4e0 Mon Sep 17 00:00:00 2001 From: Richard Lin Date: Mon, 18 May 2026 23:35:30 -0700 Subject: [PATCH 6/9] update swd to remove crystal --- examples/test_swd_debugger.py | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/test_swd_debugger.py b/examples/test_swd_debugger.py index 4804776a9..4b5fcdf8a 100644 --- a/examples/test_swd_debugger.py +++ b/examples/test_swd_debugger.py @@ -170,7 +170,6 @@ def refinements(self) -> Refinements: ], instance_values=[ (["refdes_prefix"], "S"), # unique refdes for panelization - (["mcu", "crystal", "frequency"], Range.from_tolerance(8000000, 0.005)), ( ["mcu", "pin_assigns"], [ From a74b2650a1a00db6f671bf98ba4cd0d4540ff362 Mon Sep 17 00:00:00 2001 From: Richard Lin Date: Mon, 18 May 2026 23:43:25 -0700 Subject: [PATCH 7/9] cleam outputs --- examples/Keyboard/Keyboard.net.ref | 12 ++++++------ examples/test_tofarray.py | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/examples/Keyboard/Keyboard.net.ref b/examples/Keyboard/Keyboard.net.ref index ed0f715cf..c3eb5ade0 100644 --- a/examples/Keyboard/Keyboard.net.ref +++ b/examples/Keyboard/Keyboard.net.ref @@ -188,8 +188,8 @@ (property (name "edg_path") (value "mcu.crystal.package")) (property (name "edg_short_path") (value "mcu.crystal.package")) (property (name "edg_refdes") (value "X1")) - (property (name "edg_part") (value "X322512MSB4SI (Yangxing Tech)")) - (property (name "edg_value") (value "12MHz SMD Crystal Resonator 20pF ±10ppm ±30ppm -40℃~+85℃ SMD3225-4P Crystals ROHS")) + (property (name "edg_part") (value "X32258MOB4SI (Yangxing Tech)")) + (property (name "edg_value") (value "8MHz SMD Crystal Resonator 12pF ±10ppm ±30ppm -40℃~+85℃ SMD3225-4P Crystals ROHS")) (sheetpath (names "/mcu/crystal/") (tstamps "/02850146/0c1b0303/")) (tstamps "0b4e02cd")) (comp (ref "C9") @@ -200,8 +200,8 @@ (property (name "edg_path") (value "mcu.crystal.cap_a")) (property (name "edg_short_path") (value "mcu.crystal.cap_a")) (property (name "edg_refdes") (value "C9")) - (property (name "edg_part") (value "CL10C220JB8NNNC (Samsung Electro-Mechanics)")) - (property (name "edg_value") (value "50V 22pF C0G ±5% 0603 Multilayer Ceramic Capacitors MLCC - SMD/SMT ROHS")) + (property (name "edg_part") (value "CL10C100JB8NNNC (Samsung Electro-Mechanics)")) + (property (name "edg_value") (value "50V 10pF C0G ±5% 0603 Multilayer Ceramic Capacitors MLCC - SMD/SMT ROHS")) (sheetpath (names "/mcu/crystal/") (tstamps "/02850146/0c1b0303/")) (tstamps "05e701f5")) (comp (ref "C10") @@ -212,8 +212,8 @@ (property (name "edg_path") (value "mcu.crystal.cap_b")) (property (name "edg_short_path") (value "mcu.crystal.cap_b")) (property (name "edg_refdes") (value "C10")) - (property (name "edg_part") (value "CL10C220JB8NNNC (Samsung Electro-Mechanics)")) - (property (name "edg_value") (value "50V 22pF C0G ±5% 0603 Multilayer Ceramic Capacitors MLCC - SMD/SMT ROHS")) + (property (name "edg_part") (value "CL10C100JB8NNNC (Samsung Electro-Mechanics)")) + (property (name "edg_value") (value "50V 10pF C0G ±5% 0603 Multilayer Ceramic Capacitors MLCC - SMD/SMT ROHS")) (sheetpath (names "/mcu/crystal/") (tstamps "/02850146/0c1b0303/")) (tstamps "05e801f6")) (comp (ref "SW1") diff --git a/examples/test_tofarray.py b/examples/test_tofarray.py index ca0d20ada..ee2180137 100644 --- a/examples/test_tofarray.py +++ b/examples/test_tofarray.py @@ -136,6 +136,7 @@ def refinements(self) -> Refinements: (["can", "conn"], MolexSl), ], instance_values=[ + (["mcu", "crystal", "frequency"], Range.from_tolerance(12000000, 0.005)), # legacy default crystal ( ["mcu", "pin_assigns"], [ From ff1e155426b70bdb1526643d0c1e0fa72d06bb97 Mon Sep 17 00:00:00 2001 From: Richard Lin Date: Mon, 18 May 2026 23:49:24 -0700 Subject: [PATCH 8/9] Update UsbPort.py --- edg/electronics_model/UsbPort.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/edg/electronics_model/UsbPort.py b/edg/electronics_model/UsbPort.py index 7edf62b05..59eb2b1da 100644 --- a/edg/electronics_model/UsbPort.py +++ b/edg/electronics_model/UsbPort.py @@ -26,8 +26,30 @@ def contents(self) -> None: ) +class UsbHostBridge(PortBridge): + def __init__(self) -> None: + super().__init__() + self.outer_port = self.Port(UsbHostPort.empty()) + self.inner_link = self.Port(UsbDevicePort.empty()) + + @override + def contents(self) -> None: + from .DigitalPorts import DigitalBidirBridge + + super().contents() + + self.dm_bridge = self.Block(DigitalBidirBridge()) + self.connect(self.outer_port.dm, self.dm_bridge.outer_port) + self.connect(self.dm_bridge.inner_link, self.inner_link.dm) + + self.dp_bridge = self.Block(DigitalBidirBridge()) + self.connect(self.outer_port.dp, self.dp_bridge.outer_port) + self.connect(self.dp_bridge.inner_link, self.inner_link.dp) + + class UsbHostPort(Port[UsbLink]): link_type = UsbLink + bridge_type = UsbHostBridge def __init__(self) -> None: super().__init__() From 14b921c1c08de52bac32ccdd09e2301efc55e4c4 Mon Sep 17 00:00:00 2001 From: Richard Lin Date: Mon, 18 May 2026 23:59:18 -0700 Subject: [PATCH 9/9] Update PassiveConnector_Header.py --- edg/parts/PassiveConnector_Header.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/edg/parts/PassiveConnector_Header.py b/edg/parts/PassiveConnector_Header.py index 584cbec11..2ce410436 100644 --- a/edg/parts/PassiveConnector_Header.py +++ b/edg/parts/PassiveConnector_Header.py @@ -59,18 +59,18 @@ class PinSocket254Pair(SubboardConnectorPair, GeneratorBlock): Optionally can be reversed, with the header being on the external side and the socket being on the internal side.""" - def __init__(self, length: IntLike = 0, *, reversed: BoolLike = False) -> None: + def __init__(self, length: IntLike = 0, *, reverse: BoolLike = False) -> None: super().__init__() self.length = self.ArgParameter(length) - self.reversed = self.ArgParameter(reversed) - self.generator_param(self.reversed) + self.reverse = self.ArgParameter(reverse) + self.generator_param(self.reverse) self.pins = self.Port(Vector(Passive.empty())) @override def generate(self) -> None: super().generate() - if not self.get(self.reversed): + if not self.get(self.reverse): self.ext: PassiveConnector = self.Block(PinSocket254(self.length), external=True) self.int: PassiveConnector = self.Block(PinHeader254(self.length)) else: