From 221dab21d03e7e6fa335e32b2dc015b6d9a610c5 Mon Sep 17 00:00:00 2001 From: ruben-iteng <94007802+ruben-iteng@users.noreply.github.com> Date: Fri, 30 Aug 2024 15:32:10 +0200 Subject: [PATCH] Add: IsPowerSource Add: LinkIsolatedReference --- src/faebryk/library/Crystal.py | 2 +- src/faebryk/library/Crystal_Oscillator.py | 4 +- src/faebryk/library/ElectricLogic.py | 8 ++++ src/faebryk/library/LDO.py | 2 +- src/faebryk/library/Power.py | 16 ++++++- src/faebryk/library/_F.py | 14 +++---- test/core/test_hierarchy_connect.py | 51 +++++++++++++++++++++++ 7 files changed, 85 insertions(+), 12 deletions(-) diff --git a/src/faebryk/library/Crystal.py b/src/faebryk/library/Crystal.py index 006a66db..07b66107 100644 --- a/src/faebryk/library/Crystal.py +++ b/src/faebryk/library/Crystal.py @@ -23,7 +23,7 @@ class Crystal(Module): frequency_ageing: F.TBD[F.Range] equivalent_series_resistance: F.TBD[Quantity] shunt_capacitance: F.TBD[Quantity] - load_impedance: F.TBD[Quantity] + load_capacitance: F.TBD[Quantity] # ---------------------------------------- # traits diff --git a/src/faebryk/library/Crystal_Oscillator.py b/src/faebryk/library/Crystal_Oscillator.py index e1f9646b..8571f20c 100644 --- a/src/faebryk/library/Crystal_Oscillator.py +++ b/src/faebryk/library/Crystal_Oscillator.py @@ -26,11 +26,11 @@ class Crystal_Oscillator(Module): # ---------------------------------------- # https://blog.adafruit.com/2012/01/24/choosing-the-right-crystal-and-caps-for-your-design/ # http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00221665.pdf - _STRAY_CAPACITANCE = F.Range(1 * P.nF, 5 * P.nF) + _STRAY_CAPACITANCE = F.Range(1 * P.pF, 5 * P.pF) @L.rt_field def capacitance(self): - return (self.crystal.load_impedance - copy(self._STRAY_CAPACITANCE)) * 2 + return (self.crystal.load_capacitance - copy(self._STRAY_CAPACITANCE)) * 2 def __preinit__(self): for cap in self.capacitors: diff --git a/src/faebryk/library/ElectricLogic.py b/src/faebryk/library/ElectricLogic.py index 5e573ea6..759e7a82 100644 --- a/src/faebryk/library/ElectricLogic.py +++ b/src/faebryk/library/ElectricLogic.py @@ -6,6 +6,8 @@ from typing import Iterable, Self import faebryk.library._F as F +from faebryk.core.graphinterface import GraphInterface +from faebryk.core.link import LinkFilteredException, _TLinkDirectShallow from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.node import Node @@ -61,6 +63,12 @@ def pull(self, up: bool): obj.add_trait(ElectricLogic.has_pulls_defined(up_r, down_r)) return resistor + class LinkIsolatedReference(_TLinkDirectShallow): + def __init__(self, interfaces: list[GraphInterface]) -> None: + if any(isinstance(gif.node, F.ElectricPower) for gif in interfaces): + raise LinkFilteredException("All nodes are ElectricPower") + super().__init__(interfaces) + # class can_be_buffered(Trait): # @abstractmethod # def buffer(self): diff --git a/src/faebryk/library/LDO.py b/src/faebryk/library/LDO.py index eb1d046b..bd5c10ec 100644 --- a/src/faebryk/library/LDO.py +++ b/src/faebryk/library/LDO.py @@ -29,7 +29,7 @@ class OutputPolarity(Enum): enable: F.ElectricLogic power_in: F.ElectricPower - power_out: F.ElectricPower + power_out = L.d_field(lambda: F.ElectricPower().make_source()) def __preinit__(self): self.power_in.voltage.merge(self.max_input_voltage) diff --git a/src/faebryk/library/Power.py b/src/faebryk/library/Power.py index dc973407..02474593 100644 --- a/src/faebryk/library/Power.py +++ b/src/faebryk/library/Power.py @@ -4,4 +4,18 @@ from faebryk.core.moduleinterface import ModuleInterface -class Power(ModuleInterface): ... +class Power(ModuleInterface): + class PowerSourcesShortedError(Exception): ... + + class IsPowerSource(ModuleInterface.TraitT): ... + + class IsPowerSourceDefined(IsPowerSource.impl()): ... + + def make_source(self): + self.add(self.IsPowerSourceDefined()) + return self + + def _on_connect(self, other: "Power"): + print(f"Power._on_connect({self}, {other})") # TODO remove + if self.has_trait(self.IsPowerSource) and other.has_trait(self.IsPowerSource): + raise self.PowerSourcesShortedError(self, other) diff --git a/src/faebryk/library/_F.py b/src/faebryk/library/_F.py index b8e9a0eb..1947cc37 100644 --- a/src/faebryk/library/_F.py +++ b/src/faebryk/library/_F.py @@ -15,12 +15,12 @@ # flake8: noqa: I001 # flake8: noqa: E501 +from faebryk.library.has_footprint import has_footprint from faebryk.library.has_simple_value_representation import has_simple_value_representation from faebryk.library.has_descriptive_properties import has_descriptive_properties from faebryk.library.has_overriden_name import has_overriden_name -from faebryk.library.has_footprint import has_footprint -from faebryk.library.Constant import Constant from faebryk.library.Range import Range +from faebryk.library.Constant import Constant from faebryk.library.Operation import Operation from faebryk.library.TBD import TBD from faebryk.library.has_pcb_position import has_pcb_position @@ -30,8 +30,8 @@ from faebryk.library.has_pcb_layout import has_pcb_layout from faebryk.library.has_datasheet import has_datasheet from faebryk.library.has_pcb_routing_strategy import has_pcb_routing_strategy -from faebryk.library.has_esphome_config import has_esphome_config from faebryk.library.is_esphome_bus import is_esphome_bus +from faebryk.library.has_esphome_config import has_esphome_config from faebryk.library.Power import Power from faebryk.library.has_designator import has_designator from faebryk.library.has_single_connection import has_single_connection @@ -43,14 +43,14 @@ from faebryk.library.Mechanical import Mechanical from faebryk.library.is_representable_by_single_value import is_representable_by_single_value from faebryk.library.has_capacitance import has_capacitance +from faebryk.library.Footprint import Footprint from faebryk.library.has_simple_value_representation_based_on_params import has_simple_value_representation_based_on_params from faebryk.library.has_simple_value_representation_defined import has_simple_value_representation_defined from faebryk.library.has_descriptive_properties_defined import has_descriptive_properties_defined from faebryk.library.has_overriden_name_defined import has_overriden_name_defined -from faebryk.library.Footprint import Footprint -from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param -from faebryk.library.Set import Set from faebryk.library.Logic import Logic +from faebryk.library.Set import Set +from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param from faebryk.library.Electrical import Electrical from faebryk.library.ANY import ANY from faebryk.library.has_pcb_position_defined_relative import has_pcb_position_defined_relative @@ -62,8 +62,8 @@ from faebryk.library.has_pcb_layout_defined import has_pcb_layout_defined from faebryk.library.has_datasheet_defined import has_datasheet_defined from faebryk.library.has_pcb_routing_strategy_greedy_direct_line import has_pcb_routing_strategy_greedy_direct_line -from faebryk.library.has_esphome_config_defined import has_esphome_config_defined from faebryk.library.is_esphome_bus_defined import is_esphome_bus_defined +from faebryk.library.has_esphome_config_defined import has_esphome_config_defined from faebryk.library.has_designator_defined import has_designator_defined from faebryk.library.has_single_connection_impl import has_single_connection_impl from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined diff --git a/test/core/test_hierarchy_connect.py b/test/core/test_hierarchy_connect.py index 4784b0bb..3df37346 100644 --- a/test/core/test_hierarchy_connect.py +++ b/test/core/test_hierarchy_connect.py @@ -231,6 +231,57 @@ class _Link(LinkDirectShallow(lambda link, gif: True)): ... self.assertIsInstance(mifs_special[0].is_connected_to(mifs_special[2]), _Link) + def test_isolated_connect(self): + x1 = F.ElectricLogic() + x2 = F.ElectricLogic() + x1.connect(x2, linkcls=F.ElectricLogic.LinkIsolatedReference) + self.assertIsInstance( + x1.is_connected_to(x2), F.ElectricLogic.LinkIsolatedReference + ) + + self.assertIsInstance( + x1.signal.is_connected_to(x2.signal), + F.ElectricLogic.LinkIsolatedReference, + ) + + self.assertIsNone(x1.reference.is_connected_to(x2.reference)) + + self.assertIsNone(x1.reference.hv.is_connected_to(x2.reference.hv)) + + y1 = F.ElectricPower() + y2 = F.ElectricPower() + + y1.make_source() + y2.make_source() + + with self.assertRaises(F.Power.PowerSourcesShortedError): + y1.connect(y2) + + ldo1 = F.LDO() + ldo2 = F.LDO() + + with self.assertRaises(F.Power.PowerSourcesShortedError): + ldo1.power_out.connect(ldo2.power_out) + + a1 = F.I2C() + b1 = F.I2C() + + a1.connect(b1, linkcls=F.ElectricLogic.LinkIsolatedReference) + self.assertIsInstance( + a1.is_connected_to(b1), F.ElectricLogic.LinkIsolatedReference + ) + self.assertIsInstance( + a1.scl.signal.is_connected_to(b1.scl.signal), + F.ElectricLogic.LinkIsolatedReference, + ) + self.assertIsInstance( + a1.sda.signal.is_connected_to(b1.sda.signal), + F.ElectricLogic.LinkIsolatedReference, + ) + + self.assertIsNone(a1.scl.reference.is_connected_to(b1.scl.reference)) + self.assertIsNone(a1.sda.reference.is_connected_to(b1.sda.reference)) + if __name__ == "__main__": unittest.main()