Skip to content
This repository has been archived by the owner on Dec 10, 2024. It is now read-only.

Commit

Permalink
Add mcu example; WIP auto caps
Browse files Browse the repository at this point in the history
  • Loading branch information
iopapamanoglou committed Sep 12, 2024
1 parent d575fab commit 105afa7
Show file tree
Hide file tree
Showing 12 changed files with 203 additions and 30 deletions.
79 changes: 79 additions & 0 deletions examples/mcu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# This file is part of the faebryk project
# SPDX-License-Identifier: MIT

"""
This file contains a faebryk sample.
"""

import logging

import typer

import faebryk.library._F as F
from faebryk.core.module import Module
from faebryk.exporters.pcb.layout.extrude import LayoutExtrude
from faebryk.exporters.pcb.layout.typehierarchy import LayoutTypeHierarchy
from faebryk.libs.brightness import TypicalLuminousIntensity
from faebryk.libs.examples.buildutil import apply_design_to_pcb
from faebryk.libs.library import L
from faebryk.libs.logging import setup_basic_logging

logger = logging.getLogger(__name__)


class App(Module):
led = L.f_field(F.LEDIndicator)(use_mosfet=False)
mcu: F.RP2040_ReferenceDesign
usb_power: F.USB_C_5V_PSU

def __preinit__(self) -> None:
# Parametrize
self.led.led.led.color.merge(F.LED.Color.YELLOW)
self.led.led.led.brightness.merge(
TypicalLuminousIntensity.APPLICATION_LED_INDICATOR_INSIDE.value.value
)

self.usb_power.power_out.connect(self.mcu.usb.usb_if.buspower)
self.mcu.rp2040.gpio[25].connect(self.led.logic_in)
self.mcu.rp2040.pinmux.enable(self.mcu.rp2040.gpio[25])

self._set_layout()

def _set_layout(self):
# set center
self.add(
F.has_pcb_position_defined(
F.has_pcb_position.Point(
(50, 50, 0, F.has_pcb_position.layer_type.TOP_LAYER)
)
)
)

# distribute horizontally
layout = LayoutTypeHierarchy(
layouts=[
LayoutTypeHierarchy.Level(
mod_type=Module,
layout=LayoutExtrude((20, 0)),
)
]
)
self.add(F.has_pcb_layout_defined(layout))


# Boilerplate -----------------------------------------------------------------


def main():
logger.info("Building app")
app = App()

logger.info("Export")
apply_design_to_pcb(app)


if __name__ == "__main__":
setup_basic_logging()
logger.info("Running example")

typer.run(main)
8 changes: 4 additions & 4 deletions src/faebryk/core/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import logging
from typing import TYPE_CHECKING, Iterable

from faebryk.core.graphinterface import GraphInterface
from faebryk.core.node import Node
from faebryk.core.moduleinterface import GraphInterfaceModuleSibling
from faebryk.core.node import Node, f_field
from faebryk.core.trait import Trait
from faebryk.libs.util import unique_ref

Expand All @@ -17,8 +17,8 @@
class Module(Node):
class TraitT(Trait): ...

specializes: GraphInterface
specialized: GraphInterface
specializes = f_field(GraphInterfaceModuleSibling)(is_parent=False)
specialized = f_field(GraphInterfaceModuleSibling)(is_parent=True)

def get_most_special(self) -> "Module":
specialers = {
Expand Down
8 changes: 4 additions & 4 deletions src/faebryk/core/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,11 @@ class Node(FaebrykLibObject, metaclass=PostInitCaller):
specialized: list["Node"]

self_gif: GraphInterfaceSelf
children: GraphInterfaceHierarchical = d_field(
lambda: GraphInterfaceHierarchical(is_parent=True)
children: GraphInterfaceHierarchical = f_field(GraphInterfaceHierarchical)(
is_parent=True
)
parent: GraphInterfaceHierarchical = d_field(
lambda: GraphInterfaceHierarchical(is_parent=False)
parent: GraphInterfaceHierarchical = f_field(GraphInterfaceHierarchical)(
is_parent=False
)

_init: bool = False
Expand Down
43 changes: 30 additions & 13 deletions src/faebryk/exporters/pcb/layout/heuristic_decoupling.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import faebryk.library._F as F
from faebryk.core.module import Module
from faebryk.core.node import Node
from faebryk.core.trait import TraitNotFound
from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer
from faebryk.exporters.pcb.layout.layout import Layout
from faebryk.libs.kicad.fileformats import C_kicad_pcb_file, C_wh
Expand Down Expand Up @@ -190,25 +191,41 @@ def place_next_to(
params: Params,
route: bool = False,
):
pads_intf = parent_intf.get_trait(F.has_linked_pad).get_pads()
try:
pads_intf = parent_intf.get_trait(F.has_linked_pad).get_pads()
except TraitNotFound:
logger.warning(
f"No linked pads found for interface {parent_intf}."
" Make sure the footprint is properly attached."
" And that the component is attached "
"to an interface of a module with a footprint."
)
return

if len(pads_intf) == 0:
raise KeyErrorNotFound()
if len(pads_intf) > 1:
# raise KeyErrorAmbiguous(list(pads_intf))
pads_intf = sorted(pads_intf, key=lambda x: x.get_name())

parent_pad = next(iter(pads_intf))
if child.has_trait(F.is_multi_module):
children = child.get_trait(F.is_multi_module).get_children()
parent_pads = zip(pads_intf, children)
else:
parent_pads = next(sorted(pads_intf, key=lambda x: x.get_name()))
else:
parent_pads = [(next(iter(pads_intf)), child)]

intf = find(
child.get_children(direct_only=True, types=F.Electrical),
lambda x: x.is_connected_to(parent_intf) is not None,
)
for parent_pad, child in parent_pads:
intf = find(
child.get_children(direct_only=True, types=F.Electrical),
lambda x: x.is_connected_to(parent_intf) is not None,
)

logger.debug(f"Placing {intf} next to {parent_pad}")
place_next_to_pad(child, parent_pad, params)
logger.debug(f"Placing {intf} next to {parent_pad}")
place_next_to_pad(child, parent_pad, params)

if route:
intf.add(F.has_pcb_routing_strategy_greedy_direct_line(extra_pads=[parent_pad]))
if route:
intf.add(
F.has_pcb_routing_strategy_greedy_direct_line(extra_pads=[parent_pad])
)


class LayoutHeuristicElectricalClosenessDecouplingCaps(Layout):
Expand Down
2 changes: 2 additions & 0 deletions src/faebryk/library/MultiCapacitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ def __init__(self, count: int):
def capacitors(self) -> list[F.Capacitor]:
return times(self._count, F.Capacitor)

multi_module = L.f_field(F.is_multi_module_defined_by_type)(F.Capacitor)

def __preinit__(self):
# ------------------------------------
# connections
Expand Down
3 changes: 3 additions & 0 deletions src/faebryk/library/PowerSwitchStatic.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# This file is part of the faebryk project
# SPDX-License-Identifier: MIT
import faebryk.library._F as F
from faebryk.libs.picker.picker import has_part_picked_remove


class PowerSwitchStatic(F.PowerSwitch):
Expand All @@ -13,6 +14,8 @@ class PowerSwitchStatic(F.PowerSwitch):
def __init__(self) -> None:
super().__init__(normally_closed=False)

part_removed: has_part_picked_remove

def __preinit__(self):
self.power_in.connect(self.switched_power_out)
self.logic_in.connect_reference(self.power_in)
Expand Down
28 changes: 20 additions & 8 deletions src/faebryk/library/RP2040_ReferenceDesign.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
from faebryk.libs.library import L # noqa: F401
from faebryk.libs.picker.picker import DescriptiveProperties
from faebryk.libs.units import P # noqa: F401
from faebryk.exporters.pcb.layout.heuristic_decoupling import (
LayoutHeuristicElectricalClosenessDecouplingCaps,

Check failure on line 12 in src/faebryk/library/RP2040_ReferenceDesign.py

View workflow job for this annotation

GitHub Actions / test

Ruff (F401)

src/faebryk/library/RP2040_ReferenceDesign.py:12:5: F401 `faebryk.exporters.pcb.layout.heuristic_decoupling.LayoutHeuristicElectricalClosenessDecouplingCaps` imported but unused
)
from faebryk.exporters.pcb.layout.heuristic_pulls import (
LayoutHeuristicElectricalClosenessPullResistors,

Check failure on line 15 in src/faebryk/library/RP2040_ReferenceDesign.py

View workflow job for this annotation

GitHub Actions / test

Ruff (F401)

src/faebryk/library/RP2040_ReferenceDesign.py:15:5: F401 `faebryk.exporters.pcb.layout.heuristic_pulls.LayoutHeuristicElectricalClosenessPullResistors` imported but unused
)

logger = logging.getLogger(__name__)

Check failure on line 18 in src/faebryk/library/RP2040_ReferenceDesign.py

View workflow job for this annotation

GitHub Actions / test

Ruff (I001)

src/faebryk/library/RP2040_ReferenceDesign.py:4:1: I001 Import block is un-sorted or un-formatted

Expand All @@ -30,13 +36,11 @@ def __preinit__(self):
[self.resistor, self.switch], self.logic_out.reference.lv
)

self.switch.add(
self.switch.attach_to_footprint.attach(
# TODO this is not nice
F.has_footprint_defined(
F.KicadFootprint(
"Connector_PinHeader_2.54mm:PinHeader_1x02_P2.54mm_Vertical",
pin_names=["1", "2"],
)
F.KicadFootprint(
"Connector_PinHeader_2.54mm:PinHeader_1x02_P2.54mm_Vertical",
pin_names=["1", "2"],
)
)

Expand Down Expand Up @@ -67,7 +71,7 @@ def __preinit__(self):
# ----------------------------------------
# aliasess
# ----------------------------------------
power_3v3 = F.ElectricPower()
power_3v3 = self.add(F.ElectricPower())
power_vbus = self.usb.usb_if.buspower

# ----------------------------------------
Expand Down Expand Up @@ -153,6 +157,14 @@ def __preinit__(self):

self.rp2040.xtal_if.connect(self.clock_source.xtal_if)

# TODO reenable
# LayoutHeuristicElectricalClosenessDecouplingCaps.add_to_all_suitable_modules(
# self
# )
# LayoutHeuristicElectricalClosenessPullResistors.add_to_all_suitable_modules(
# self
# )

@L.rt_field
def pcb_layout(self):
from faebryk.exporters.pcb.layout.absolute import LayoutAbsolute
Expand Down Expand Up @@ -185,7 +197,7 @@ def pcb_layout(self):
LayoutTypeHierarchy.Level(
mod_type=type(self.flash),
layout=LayoutAbsolute(
Point((-1.95, -6.5, 0, L.NONE)),
Point((-1.95, -10, 0, L.NONE)),
),
),
LayoutTypeHierarchy.Level(
Expand Down
2 changes: 1 addition & 1 deletion src/faebryk/library/TI_CD4011BE.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def __preinit__(self):
self.add(
F.has_descriptive_properties_defined(
{
DescriptiveProperties.manufacturer: "Texas Instruments",
DescriptiveProperties.manufacturer.value: "Texas Instruments",
DescriptiveProperties.partno: "CD4011BE",
},
)
Expand Down
3 changes: 3 additions & 0 deletions src/faebryk/library/_F.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from faebryk.library.has_construction_dependency import has_construction_dependency
from faebryk.library.has_footprint import has_footprint
from faebryk.library.Mechanical import Mechanical
from faebryk.library.is_multi_module_defined_by_type import is_multi_module_defined_by_type
from faebryk.library.has_overriden_name import has_overriden_name
from faebryk.library.Operation import Operation
from faebryk.library.has_linked_pad import has_linked_pad
Expand All @@ -44,6 +45,8 @@
from faebryk.library.has_pcb_routing_strategy import has_pcb_routing_strategy
from faebryk.library.has_resistance import has_resistance
from faebryk.library.has_single_connection import has_single_connection
from faebryk.library.is_multi_module import is_multi_module
from faebryk.library.is_multi_module_defined import is_multi_module_defined
from faebryk.library.is_representable_by_single_value import is_representable_by_single_value
from faebryk.library.ANY import ANY
from faebryk.library.Electrical import Electrical
Expand Down
23 changes: 23 additions & 0 deletions src/faebryk/library/is_multi_module.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# This file is part of the faebryk project
# SPDX-License-Identifier: MIT

import logging
from abc import abstractmethod

from faebryk.core.module import Module
from faebryk.core.trait import Trait

logger = logging.getLogger(__name__)


class is_multi_module(Trait):
"""
Docstring describing your module
"""

@abstractmethod
def get(self) -> list[Module]:
"""
Docstring describing the function
"""
pass
17 changes: 17 additions & 0 deletions src/faebryk/library/is_multi_module_defined.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# This file is part of the faebryk project
# SPDX-License-Identifier: MIT

import logging

from faebryk.core.module import Module
from faebryk.library.is_multi_module import is_multi_module

logger = logging.getLogger(__name__)


class is_multi_module_defined(is_multi_module.impl()):
def __init__(self, children: list[Module]):
self._children = children

def get(self) -> list[Module]:
return self._children
17 changes: 17 additions & 0 deletions src/faebryk/library/is_multi_module_defined_by_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# This file is part of the faebryk project
# SPDX-License-Identifier: MIT

import logging

from faebryk.core.module import Module
from faebryk.library.is_multi_module import is_multi_module

logger = logging.getLogger(__name__)


class is_multi_module_defined_by_type(is_multi_module.impl()):
def __init__(self, children_type: type[Module]):
self._children_type = children_type

def get(self) -> list[Module]:
return self.obj.get_children(direct_only=False, types=self._children_type)

0 comments on commit 105afa7

Please sign in to comment.