aboutsummaryrefslogtreecommitdiff
path: root/clef/nix
diff options
context:
space:
mode:
Diffstat (limited to 'clef/nix')
-rw-r--r--clef/nix/board.nix37
-rw-r--r--clef/nix/default.nix58
-rw-r--r--clef/nix/fabrication.nix82
-rw-r--r--clef/nix/model.nix52
-rw-r--r--clef/nix/panel.nix46
-rw-r--r--clef/nix/schematic.nix51
-rw-r--r--clef/nix/svg.nix82
7 files changed, 408 insertions, 0 deletions
diff --git a/clef/nix/board.nix b/clef/nix/board.nix
new file mode 100644
index 0000000..d67417b
--- /dev/null
+++ b/clef/nix/board.nix
@@ -0,0 +1,37 @@
+{
+ runCommand,
+
+ svg,
+ model,
+ fabrication,
+ schematic,
+ panel,
+ panelSrc,
+
+ name,
+ outPath,
+}: let
+ pkg = runCommand name {} ''
+ set -e
+
+ mkdir -p "$out/${outPath}"
+ cd "$out/${outPath}"
+
+ echo "populating $(pwd)"
+
+ cp --reflink=auto -vr "${schematic}/share/npry/clef/schematic" ./
+ cp --reflink=auto -vr "${svg}/share/npry/clef/svg" ./
+ cp --reflink=auto -vr "${fabrication}/share/npry/clef/fab" ./
+ cp --reflink=auto -vr "${model}/share/npry/clef/model" ./
+
+ ${if panelSrc != null then ''
+ cp --reflink=auto -vr "${panelSrc}/share/npry/clef/panel" ./
+ '' else ""}
+ '';
+
+in pkg.overrideAttrs (prevAttrs: {
+ passthru = (prevAttrs.passthru or {}) // {
+ inherit schematic fabrication svg model panel panelSrc;
+ fab = fabrication;
+ };
+})
diff --git a/clef/nix/default.nix b/clef/nix/default.nix
new file mode 100644
index 0000000..4438bbe
--- /dev/null
+++ b/clef/nix/default.nix
@@ -0,0 +1,58 @@
+{
+ pkgs,
+
+ src,
+ main_pcb,
+ main_sch,
+
+ name,
+ outPath ? "share/npry/clef",
+ layers ? 2,
+
+ # set to a list of arguments to be passed to `kikit panelize -p`
+ panelizeConfigs ? null,
+}: let
+ pcb_path = main_pcb;
+ sch_path = main_sch;
+
+ pcb_args = {
+ inherit pcb_path src;
+ };
+
+ panelSrc = if panelizeConfigs != null then pkgs.callPackage ./panel.nix (pcb_args // { inherit panelizeConfigs; }) else null;
+
+ panel = if panelizeConfigs != null then
+ pkgs.callPackage ./. {
+ src = "${panelSrc}/share/npry/clef/panel";
+ main_pcb = "panel.kicad_pcb";
+
+ name = "${name}.sub.panel";
+ outPath = "${outPath}/panel";
+
+ inherit main_sch layers;
+ }
+ else null;
+
+ svg = pkgs.callPackage ./svg.nix (pcb_args // { nLayer = layers; });
+ model = pkgs.callPackage ./model.nix pcb_args;
+
+ fabrication = pkgs.callPackage ./fabrication.nix (pcb_args // {
+ inherit sch_path;
+ });
+
+ schematic = pkgs.callPackage ./schematic.nix {
+ inherit sch_path src;
+ };
+
+in pkgs.callPackage ./board.nix {
+ inherit
+ svg
+ model
+ fabrication
+ schematic
+ name
+ outPath
+ panel
+ panelSrc
+ ;
+}
diff --git a/clef/nix/fabrication.nix b/clef/nix/fabrication.nix
new file mode 100644
index 0000000..18bc6f6
--- /dev/null
+++ b/clef/nix/fabrication.nix
@@ -0,0 +1,82 @@
+{
+ kicad,
+ kikit,
+ zip,
+
+ runCommand,
+
+ nix-filter,
+ lib,
+
+ src,
+ pcb_path,
+ sch_path,
+
+ boardName ? (lib.removeSuffix ".kicad_pcb" (builtins.baseNameOf pcb_path)),
+
+ fabHouse ? "jlcpcb",
+ withAssembly ? true,
+}: let
+ sharePath = "share/npry/clef/fab";
+
+ fabSrc = nix-filter {
+ root = src;
+
+ include = [
+ (nix-filter.matchExt "kicad_sch")
+ (nix-filter.matchExt "kicad_wks")
+ (nix-filter.matchExt "kicad_pcb")
+ (nix-filter.matchExt "kicad_pro")
+
+ (_args: path: type: type == "directory")
+ ];
+ };
+
+in runCommand "${boardName}.fab" {
+ nativeBuildInputs = [
+ kicad
+ kikit
+ zip
+ ];
+
+ src = fabSrc;
+
+ allowedRequisites = [];
+} ''
+ set -e
+
+ export HOME=$(mktemp -d)
+
+ echo "board: '${boardName}'" >&2
+
+ mkdir -p "$out/${sharePath}"
+ cd "$src"
+
+ kikit fab ${fabHouse} \
+ ${if withAssembly then "--assembly" else ""} \
+ --no-drc \
+ --schematic "${sch_path}" \
+ --field 'LCSC Part #,LCSC Part No' \
+ --missingError \
+ "${pcb_path}" \
+ "$out/${sharePath}"
+
+ cd "$out/${sharePath}"
+ rm -vf "gerbers.zip"
+
+ pushd gerber
+
+ # normalize
+ for f in ${boardName}-*; do
+ mv -nv "$f" "''${f#${boardName}-}"
+ done
+
+ for f in ${boardName}.*; do
+ mv -nv "$f" "board''${f#${boardName}}"
+ done
+
+ popd
+
+ zip -vj "gerbers.zip" gerber/*
+ rm -vrf gerber
+''
diff --git a/clef/nix/model.nix b/clef/nix/model.nix
new file mode 100644
index 0000000..04bf1b1
--- /dev/null
+++ b/clef/nix/model.nix
@@ -0,0 +1,52 @@
+{
+ kicad,
+ runCommand,
+
+ nix-filter,
+ lib,
+
+ withTracks ? false,
+ withZones ? false,
+
+ src,
+ pcb_path,
+
+ boardName ? (lib.removeSuffix ".kicad_pcb" (builtins.baseNameOf pcb_path)),
+}: let
+ zonesArg = if withZones then "--include-zones" else "";
+ tracksArg = if withTracks then "--include-tracks" else "";
+ sharePath = "share/npry/clef/model";
+
+in runCommand "${boardName}.model" {
+ nativeBuildInputs = [
+ kicad
+ ];
+
+ src = nix-filter {
+ root = src;
+
+ include = [
+ (nix-filter.matchExt "kicad_pcb")
+
+ (nix-filter.matchExt "stp")
+ (nix-filter.matchExt "step")
+ (nix-filter.matchExt "wrl")
+ ];
+ };
+
+ allowedRequisites = [];
+
+ KICAD8_3DMODEL_DIR = "${kicad.libraries.packages3d}/share/kicad/3dmodels";
+} ''
+ set -e
+
+ export HOME=$(mktemp -d)
+
+ echo "board: '${boardName}'" >&2
+
+ mkdir -p $out/${sharePath}
+ cd "$out/${sharePath}"
+
+ kicad-cli pcb export step --subst-models --no-dnp ${tracksArg} ${zonesArg} "$src/${pcb_path}" -o "${boardName}.step"
+ kicad-cli pcb export glb --subst-models --no-dnp ${tracksArg} ${zonesArg} "$src/${pcb_path}" -o "${boardName}.glb"
+''
diff --git a/clef/nix/panel.nix b/clef/nix/panel.nix
new file mode 100644
index 0000000..1d88d46
--- /dev/null
+++ b/clef/nix/panel.nix
@@ -0,0 +1,46 @@
+{
+ kikit,
+ runCommand,
+
+ nix-filter,
+ lib,
+
+ panelizeConfigs,
+ src,
+ pcb_path,
+
+ boardName ? (lib.removeSuffix ".kicad_pcb" (builtins.baseNameOf pcb_path)),
+}: let
+ sharePath = "share/npry/clef/panel";
+
+ panelSrc = nix-filter {
+ root = src;
+
+ include = [
+ (nix-filter.matchExt "kicad_pcb")
+ ];
+ };
+
+in runCommand "${boardName}.panel" {
+ nativeBuildInputs = [
+ kikit
+ ];
+
+ allowedRequisites = [];
+} ''
+ set -e
+ export HOME=$(mktemp -d)
+
+ mkdir -p "$out/${sharePath}"
+
+ # do the panelize here rather than in $out because it creates junk we don't want
+ cd $HOME
+
+ kikit panelize \
+ ${lib.concatMapStrings (conf: "-p ${conf} \\\n") panelizeConfigs} \
+ "${panelSrc}/${pcb_path}" \
+ "panel.kicad_pcb"
+
+ cp -v panel.kicad_{pcb,pro} "$out/${sharePath}"
+ cp -v "${src}/"*.kicad_{sch,pro} "$out/${sharePath}"
+''
diff --git a/clef/nix/schematic.nix b/clef/nix/schematic.nix
new file mode 100644
index 0000000..acc136f
--- /dev/null
+++ b/clef/nix/schematic.nix
@@ -0,0 +1,51 @@
+{
+ kicad,
+ runCommand,
+
+ nix-filter,
+ lib,
+
+ src,
+ sch_path,
+
+ schName ? (lib.removeSuffix ".kicad_sch" (builtins.baseNameOf sch_path)),
+}: let
+ sharePath = "share/npry/clef/schematic";
+
+in runCommand "${schName}.schematic" {
+ nativeBuildInputs = [
+ kicad
+ ];
+
+ src = nix-filter {
+ root = src;
+
+ include = [
+ (nix-filter.matchExt "kicad_sch")
+ (nix-filter.matchExt "kicad_pro")
+ ];
+ };
+} ''
+ set -e
+ export HOME=$(mktemp -d)
+
+ echo "schematic: '${schName}'" >&2
+
+ mkdir -p "$out/${sharePath}/svg"
+ cd "$out/${sharePath}"
+
+ kicad-cli sch export pdf -o schematic.pdf $src/${sch_path}
+ kicad-cli sch export svg -n -o svg $src/${sch_path}
+
+ cd svg
+
+ # normalize
+ for f in *.svg; do
+ if [ "$f" = "${schName}.svg" ]; then
+ mv -nv "$f" "root.svg"
+ continue
+ fi
+
+ mv -nv "$f" "''${f#${schName}-}"
+ done
+''
diff --git a/clef/nix/svg.nix b/clef/nix/svg.nix
new file mode 100644
index 0000000..fc1a404
--- /dev/null
+++ b/clef/nix/svg.nix
@@ -0,0 +1,82 @@
+{
+ runCommand,
+ kicad,
+
+ nix-filter,
+ lib,
+
+ pcb_path,
+ src,
+
+ withSilk ? true,
+ withEdgeCuts ? true,
+ withMirrors ? true,
+ nLayer ? 2,
+
+ boardName ? (lib.removeSuffix ".kicad_pcb" (builtins.baseNameOf pcb_path)),
+}: let
+ sharePath = "share/npry/clef/svg";
+
+in runCommand "${boardName}.svg" {
+ nativeBuildInputs = [
+ kicad
+ ];
+
+ src = nix-filter {
+ root = src;
+
+ include = [
+ (nix-filter.matchExt "kicad_pcb")
+ ];
+ };
+
+ nInnerLayer = if nLayer < 2 then 0 else nLayer - 2;
+
+ allowedRequisites = [];
+} ''
+ set -e
+
+ export HOME=$(mktemp -d)
+
+ echo "board: '${boardName}'" >&2
+
+ mkdir -p $out/${sharePath}
+ cd "$out/${sharePath}"
+
+ mksvg() {
+ local infile=$1
+ local layers=$2
+ local outfile=$3
+
+ kicad-cli pcb export svg \
+ "$infile" \
+ -l "$layers" \
+ -o "$outfile.svg" \
+ --page-size-mode 2 \
+ --exclude-drawing-sheet
+
+ ${if withMirrors then ''
+ kicad-cli pcb export svg \
+ "$infile" \
+ -m \
+ -l "$layers" \
+ -o "$outfile.mirror.svg" \
+ --page-size-mode 2 \
+ --exclude-drawing-sheet
+ '' else ""}
+ }
+
+ mksvg "$src/${pcb_path}" \
+ "F.Cu,${if withSilk then "F.Silkscreen," else ""}${if withEdgeCuts then "Edge.Cuts," else ""}" \
+ front
+
+ mksvg "$src/${pcb_path}" \
+ "B.Cu,${if withSilk then "B.Silkscreen," else ""}${if withEdgeCuts then "Edge.Cuts," else ""}" \
+ back
+
+ for i in $(seq 1 $nInnerLayer); do
+ mksvg "$src/${pcb_path}" \
+ "In$i.Cu,${if withEdgeCuts then "Edge.Cuts," else ""}" \
+ "in$i"
+ done
+''