Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
willpuckett committed Nov 14, 2024
0 parents commit 27d6d19
Show file tree
Hide file tree
Showing 129 changed files with 347,760 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"image": "ghcr.io/inti-cmnb/kicad8_auto_full:dev"
}
76 changes: 76 additions & 0 deletions .github/workflows/case.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env python3

# This vpype command was necessary to get build123d to work with the svg
# It's now reimported to KiCad, so the KiBot exported version will work without processing
# and be at least somewhat aligned with the drill file.
# vpype read default/ehrbl-Edge_Cuts_LEFT.svg linemerge --tolerance 3mm linesort reloop linesimplify write default/ehrbl-Edge_Cuts_LEFT_vpype.svg

# The origin shifts need to be resolved. I'm not sure how to get
# KiCad/KiBot to export the svg and drill files with the same origin, but it is
# offset by exactly 210mm, which also happens to be the height of the sheet in KiCad...

# The build123d example 'Offset Part to Create Thin Features'
# https://build123d.readthedocs.io/en/latest/introductory_examples.html#offset-part-to-create-thin-features
# seemed relevant, but I couldn't get it to work, so I had to boolean the void.

from holes import drill_points, locations
from build123d import *
# from ocp_vscode import show_object as show

# set_port(3939)

line_of_symmetry = 0
min_hole = 2
ps_height = 1.4 * MM
# pcb_thickness = 1.6 * MM
# hole_depth = 1.5 * MM

# Make the void space
with BuildPart() as pcb_void:
with BuildSketch(Plane.XY
.shift_origin((0, -210, 0) * MM)) as edge_cuts:
with BuildLine() as line:
add(import_svg("case/ehrbl-edges.svg"))
make_face()
extrude(amount = 3 * MM)

# Build the power switch hole
with BuildPart() as ps_void:
ps = locations('SW29')
with Locations(Plane.XY
.offset(ps_height / 2)
.shift_origin((ps['Mid X'], ps['Mid Y'], ps_height / 2) * MM)
.rotated((0, 0, float(ps['Rotation'])))) as locations:
Box(length=4 * MM, width=15 * MM, height=ps_height)
fillet(ps_void.edges(), radius=0.5 * MM)

# Make the case
with BuildPart() as case:
with BuildSketch(Plane.XY
.offset(-1 * MM)
.shift_origin((0, -210, -1) * MM)) as outline:
add(edge_cuts)
offset(amount=2 * MM, min_edge_length=5 * MM)
extrude(amount=4 * MM)
# Cut the pcb and power switch holes
add(pcb_void, mode=Mode.SUBTRACT)
add(ps_void, mode=Mode.SUBTRACT)

# Drill thru holes
# CounterSinkHoles seemed like the right choice, but the pcb didn't sit as neatly in them
with Locations(Plane.XY):
for tool, points in drill_points(line_of_symmetry, min_hole).items():
radius = (tool / 2) + 0.5 * MM
# counter_sink_radius = radius + 0.5
with Locations(points):
Hole(radius)
# CounterSinkHole(radius, counter_sink_radius, depth=hole_depth)

# @todo get fillets working
# top_face = case.faces().sort_by(Axis.Z)[-1]
# fillet(top_face.edges(), radius=0.5 * MM)

# show(case)
export_step(case.part, file_path="case.step")
export_stl(case.part, file_path="case.stl")
# export_stl(case.part, file_path="case_ascii.stl", ascii_format=True)
55 changes: 55 additions & 0 deletions .github/workflows/case.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Build123d

on:
push:
paths:
- ".github/workflows/case.yml"
- "*.kicad_sch"
- "*.kicad_pcb"
- "*.kibot.yaml"
pull_request:
paths:
- "*.kicad_sch"
- "*.kicad_pcb"
- "*.kibot.yaml"
- ".github/workflows/case.yml"
workflow_dispatch:

jobs:
Case:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: INTI-CMNB/KiBot@v2_dk8
with:
variant: case
skip: erc,drc
targets: EDGES CASE_DRILL
# Then run again to get power switch locations for edge cuts
- uses: INTI-CMNB/KiBot@v2_dk8
with:
skip: erc,drc
targets: JLCPCB_POSITION
- run: |
echo "Installing dependencies..."
python3 -m pip install build123d
echo "Generating case..."
python .github/workflows/case.py
echo "Done."
- uses: actions/upload-artifact@v4
with:
name: case
path: case.*

Release:
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
needs: Case
permissions:
contents: write # allow workflow to commit to the rep
steps:
- uses: actions/download-artifact@v4
- name: Release
uses: softprops/action-gh-release@v2
with:
files: case/*
42 changes: 42 additions & 0 deletions .github/workflows/holes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env python3

import os
import re
import csv

file_dir = os.environ.get("EHRBL_DIR") or os.getcwd()

def drill_points(min_x, min_hole=2):
# Define the regular expressions
regex_tools = re.compile(r"^(T\d+)C(\d+.?\d*)$") # T1C1.0
regex_drills_by_size = re.compile(r"T\d+(\nX-?\d+.\d+Y-?\d+.\d+)+") # T1\nX-1.0Y-1.0\nX1.0Y1.0
regex_point= re.compile(r"^X(-?\d+.\d+)Y(-?\d+.\d+)") # X-1.0Y-1.0

# Yay, context managers!
with open(f"{file_dir}/case/ehrbl-drill.drl", 'r') as file:
drill_text = file.read()

# Get the list of tools, enlarge small holes, and initialize drills_by_size
tools = [(str(m.group(1)), float(m.group(2)) if float(m.group(2)) > min_hole else min_hole) for l in drill_text.split('\n') for m in [regex_tools.search(l)] if m]
drills_by_size = { size: [] for tool, size in tools }

# Extract the drill points by size, and filter out any points with x < min_x
for match in regex_drills_by_size.finditer(drill_text):
lines = match.group().strip().split('\n')
tool = lines[0]
points = [(float(m.group(1)), float(m.group(2))) for line in lines[1:] for m in [regex_point.search(line)] if m ]
size = next(size for t, size in tools if t == tool)
drills_by_size[size].extend(filter(lambda p: p[0] > min_x, points))

# Remove unused sizes and deduplicate the points
return { size: list(set(points)) for size, points in drills_by_size.items() if points }

# print(drill_points(0))

def locations(ref=None):
with open(f"{file_dir}/ehrbl_cpl_jlc.csv") as file:
reader = csv.DictReader(file)
locations = dict([(x['Designator'],x) for x in reader])
return locations[ref] if ref else locations

# print(pnp_locations("SW29"))
35 changes: 35 additions & 0 deletions .github/workflows/keymap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash

PROJECT=ehrbl
LAYOUTS=('engram' 'engrammer' 'nordrassil')
COLS=8
ZMK_KEYMAP="config/boards/shields/${PROJECT}/${PROJECT}.keymap"
# See [this link](https://github.com/caksoylar/keymap-drawer/blob/main/KEYMAP_SPEC.md#colsthumbs-notation-specification)
# for info on cols-thumbs notation
COLS_THUMBS='2v33^3+2> 2<+33^32v'
# Or, pick a keyboard from https://config.qmk.fm
QMK_KEYBOARD=""
DTS_LAYOUT="config/boards/shields/${PROJECT}/${PROJECT}-layouts.dtsi"
# Store the flag and variable in an array to expand
# each element as a seperate shell word in the command later....
# https://unix.stackexchange.com/questions/444946/how-can-we-run-a-command-stored-in-a-variable
KMD_LAYOUT=(--cols-thumbs-notation "$COLS_THUMBS") &&
[[ -n $QMK_KEYBOARD ]] &&
KMD_LAYOUT=(--qmk-keyboard "$QMK_KEYBOARD") ||
[[ -n $DTS_LAYOUT ]] &&
KMD_LAYOUT=(--dts-layout $DTS_LAYOUT)

# Iterate over array keys
# https://devhints.io/bash#arrays
for i in "${!LAYOUTS[@]}"; do
echo "Rendering Layout ${LAYOUTS[$i]}"
BASE=".images/keymap_${LAYOUTS[$i]}"
YML="$BASE.yml"
# note you have to have the quotes for KMD_LAYOUT expansion
KEYMAP_zmk_preamble="#define LAYOUT $(( i + 1))" keymap parse -c $COLS -z "$ZMK_KEYMAP" > "$YML" &&
keymap draw "${KMD_LAYOUT[@]}" "$YML" > "$BASE.svg"
[[ $? -ne 0 ]] && exit 1
rm "$YML"
done


72 changes: 72 additions & 0 deletions .github/workflows/keymap.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: keymap

on:
# Needs push so it runs for tags to generate a release
push:
tags:
- "v*.*.*"
workflow_run:
workflows: ["ZMK"]
types:
- completed
workflow_dispatch:

jobs:
draw-keymaps:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' || github.event_name == 'push' }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
ref: ${{ github.head_ref }}
- run: |
python3 -m pipx install git+https://github.com/caksoylar/keymap-drawer.git
.github/workflows/keymap.sh
- uses: actions/upload-artifact@v4
with:
name: keymaps
path: ".images/keymap_*.svg"
include-hidden-files: true

push-or-release:
runs-on: ubuntu-latest
needs: draw-keymaps
permissions:
contents: write # allow workflow to commit to the repository
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
ref: ${{ github.head_ref }}
- uses: actions/download-artifact@v4
with:
name: keymaps
# run-id: ${{ github.event.workflow_run.id }}
path: ".images"
- name: get commit info
id: last_commit
run: |
echo "message=$(git log -1 --pretty=%s)" >> $GITHUB_OUTPUT
echo "author=$(git log -1 --pretty='%an <%ae>')" >> $GITHUB_OUTPUT
git config pull.rebase true
git pull || true
- uses: stefanzweifel/git-auto-commit-action@v5
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
with:
file_pattern: ".images/*.svg"
# So the previous commit is amended instead of creating a new one when desired
# See:
# - https://github.com/stefanzweifel/git-auto-commit-action#using---amend-and---no-edit-as-commit-options
# - https://github.com/stefanzweifel/git-auto-commit-action/issues/159#issuecomment-845347950
# - https://github.com/actions/checkout
commit_author: ${{ steps.last_commit.outputs.author }}
commit_message: "${{ steps.last_commit.outputs.message }}"
commit_options: "--amend --no-edit"
push_options: "--force-with-lease"
skip_fetch: true
- name: Release
uses: softprops/action-gh-release@v2
if: ${{ startsWith(github.ref, 'refs/tags/') }}
with:
files: ".images/keymap_*.svg"
72 changes: 72 additions & 0 deletions .github/workflows/kibot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: KiBot

# Controls when the action will run.
on:
push:
paths:
- "*.kicad_sch"
- "*.kicad_pcb"
- "*.kibot.yaml"
- ".github/workflows/kibot.yml"
pull_request:
paths:
- "*.kicad_sch"
- "*.kicad_pcb"
- "*.kibot.yaml"
- ".github/workflows/kibot.yml"
repository_dispatch:
types: [run_gha]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
ERC:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: INTI-CMNB/KiBot@v2_dk8
with:
skip: drc
targets: __NONE__

DRC:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: INTI-CMNB/KiBot@v2_dk8
with:
skip: erc
targets: __NONE__

BOARD:
runs-on: ubuntu-latest
needs: [ERC, DRC]
steps:
- uses: actions/checkout@v4
- uses: INTI-CMNB/KiBot@v2_dk8
with:
variant: board
skip: erc,drc
targets: SCHEMATIC ZIP_ASSEMBLY
- uses: actions/upload-artifact@v4
with:
name: schematic
path: schematic.svg
- uses: actions/upload-artifact@v4
with:
name: pcb
path: jlcpcb.zip

release:
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
permissions:
contents: write
needs: BOARD
steps:
- uses: actions/download-artifact@v4
with:
name: pcb
- name: Release
uses: softprops/action-gh-release@v2
with:
files: "jlcpcb.zip"
Loading

0 comments on commit 27d6d19

Please sign in to comment.