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

Commit

Permalink
Repair arcs; Make defaults; Replace netlist
Browse files Browse the repository at this point in the history
  • Loading branch information
iopapamanoglou committed Sep 11, 2024
1 parent 1523c48 commit 3afafda
Show file tree
Hide file tree
Showing 5 changed files with 342 additions and 160 deletions.
131 changes: 68 additions & 63 deletions src/faebryk/exporters/pcb/kicad/pcb.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ def _get_footprint(
return C_kicad_footprint_file.loads(path).footprint


# TODO remove prints
# TODO use G instead of netlist intermediary


class PCB:
@staticmethod
def apply_netlist(pcb_path: Path, netlist_path: Path):
Expand Down Expand Up @@ -83,7 +87,70 @@ def apply_netlist(pcb_path: Path, netlist_path: Path):
# - components matched by ref (no fallback)
# - if pad no net, just dont put net in sexp

# Nets
nl_nets = {n.name: n for n in netlist.export.nets.nets if n.nodes}
pcb_nets = {
n.name: (
n,
[
p
for f in pcb.kicad_pcb.footprints
for p in f.pads
if p.net and p.net.name == n.name
],
)
for n in pcb.kicad_pcb.nets
if n.name
}

nets_added = nl_nets.keys() - pcb_nets.keys()
nets_removed = pcb_nets.keys() - nl_nets.keys()

# Match renamed nets by pads
matched_nets = {
nl_net_name: pcb_net_name
for nl_net_name in nets_added
if (
pcb_net_name := find_or(
nets_removed,
lambda x: _nets_same(pcb_nets[NotNone(x)], nl_nets[nl_net_name]),
default=None,
)
)
}
nets_added.difference_update(matched_nets.keys())
nets_removed.difference_update(matched_nets.values())

if nets_removed:
# TODO
raise NotImplementedError(
f"Nets removed from netlist not implemented: {nets_removed}"
)

# Rename nets
print("Renamed nets:", matched_nets)
for new_name, old_name in matched_nets.items():
pcb_net, pads = pcb_nets[old_name]
pcb_net.name = new_name
pcb_nets[new_name] = (pcb_net, pads)
del pcb_nets[old_name]
for pad in pads:
assert pad.net
pad.net.name = new_name
for zone in pcb.kicad_pcb.zones:
if zone.net_name == old_name:
zone.net_name = new_name

# Add new nets
print("New nets", nets_added)
for net_name in nets_added:
# nl_net = nl_nets[net_name]
pcb_net = C_kicad_pcb_file.C_kicad_pcb.C_net(
name=net_name,
number=len(pcb.kicad_pcb.nets),
)
pcb.kicad_pcb.nets.append(pcb_net)
pcb_nets[net_name] = (pcb_net, [])

# Components
pcb_comps = {
Expand Down Expand Up @@ -138,7 +205,7 @@ def apply_netlist(pcb_path: Path, netlist_path: Path):
C_kicad_pcb_file.C_kicad_pcb.C_pcb_footprint.C_pad(
uuid=gen_uuid(mark=""),
net=C_kicad_pcb_file.C_kicad_pcb.C_pcb_footprint.C_pad.C_net(
number=pads[p.name].code,
number=pcb_nets[pads[p.name].name][0].number,
name=pads[p.name].name,
)
if p.name in pads
Expand All @@ -164,68 +231,6 @@ def apply_netlist(pcb_path: Path, netlist_path: Path):

pcb.kicad_pcb.footprints.append(pcb_comp)

# Nets
pcb_nets = {
n.name: (
n,
[
p
for f in pcb.kicad_pcb.footprints
for p in f.pads
if p.net and p.net.name == n.name
],
)
for n in pcb.kicad_pcb.nets
if n.name
}

nets_added = nl_nets.keys() - pcb_nets.keys()
nets_removed = pcb_nets.keys() - nl_nets.keys()

# Match renamed nets by pads
matched_nets = {
nl_net_name: pcb_net_name
for nl_net_name in nets_added
if (
pcb_net_name := find_or(
nets_removed,
lambda x: _nets_same(pcb_nets[NotNone(x)], nl_nets[nl_net_name]),
default=None,
)
)
}
nets_added.difference_update(matched_nets.keys())
nets_removed.difference_update(matched_nets.values())

if nets_removed:
# TODO
raise NotImplementedError(
f"Nets removed from netlist not implemented: {nets_removed}"
)

# Rename nets
print("Renamed nets:", matched_nets)
for new_name, old_name in matched_nets.items():
pcb_nets[old_name][0].name = new_name
for pad in pcb_nets[old_name][1]:
assert pad.net
pad.net.name = new_name
for zone in pcb.kicad_pcb.zones:
if zone.net_name == old_name:
zone.net_name = new_name

# Add new nets
print("New nets", nets_added)
for net_name in nets_added:
# nl_net = nl_nets[net_name]
pcb_net = C_kicad_pcb_file.C_kicad_pcb.C_net(
name=net_name,
number=len(pcb.kicad_pcb.nets),
)
# TODO

pcb.kicad_pcb.nets.append(pcb_net)

# ---
print("Save PCB", pcb_path)
pcb.dumps(pcb_path)
6 changes: 4 additions & 2 deletions src/faebryk/library/has_descriptive_properties_defined.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@
# SPDX-License-Identifier: MIT


from typing import Mapping

import faebryk.library._F as F
from faebryk.core.node import Node
from faebryk.core.trait import TraitImpl


class has_descriptive_properties_defined(F.has_descriptive_properties.impl()):
def __init__(self, properties: dict[str, str]) -> None:
def __init__(self, properties: Mapping[str, str]) -> None:
super().__init__()
self.properties = properties
self.properties = dict(properties)

def get_properties(self) -> dict[str, str]:
return self.properties
Expand Down
34 changes: 15 additions & 19 deletions src/faebryk/libs/app/pcb.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@
C_kicad_pcb_file,
C_kicad_project_file,
)
from faebryk.libs.util import ConfigFlag

logger = logging.getLogger(__name__)

PCBNEW_AUTO = ConfigFlag(
"PCBNEW_AUTO", default=True, descr="Automatically open pcbnew when applying netlist"
)


def apply_layouts(app: Module):
if not app.has_trait(F.has_pcb_position):
Expand Down Expand Up @@ -89,6 +94,13 @@ def apply_design(
pcb.dumps(pcb_path)

print("Reopen PCB in kicad")
if PCBNEW_AUTO:
try:
open_pcb(pcb_path)
except FileNotFoundError:
print(f"PCB location: {pcb_path}")
else:
print(f"PCB location: {pcb_path}")


def include_footprints(pcb_path: Path):
Expand Down Expand Up @@ -167,6 +179,8 @@ def open_pcb(pcb_path: os.PathLike):


def apply_netlist(pcb_path: Path, netlist_path: Path, netlist_has_changed: bool = True):
from faebryk.exporters.pcb.kicad.pcb import PCB

include_footprints(pcb_path)

# Set netlist path in gui menu
Expand All @@ -184,22 +198,4 @@ def apply_netlist(pcb_path: Path, netlist_path: Path, netlist_has_changed: bool
if not netlist_has_changed:
return

print("Importing netlist manually...")

auto_mode = os.environ.get("FBRK_NETLIST_PCBNEW_AUTO", "y").lower() in [
"y",
"1",
]

if auto_mode:
try:
open_pcb(pcb_path)
except FileNotFoundError:
print(f"PCB location: {pcb_path}")
else:
print(f"PCB location: {pcb_path}")

input(
"Load the netlist in File->Import->Netlist: Update PCB\n"
"Then press ENTER to continue..."
)
PCB.apply_netlist(pcb_path, netlist_path)
Loading

0 comments on commit 3afafda

Please sign in to comment.