mirror of
https://github.com/System-End/hackpad.git
synced 2026-04-19 21:05:15 +00:00
refactor(woagpad): replace git submodule with raw src take 2
This commit is contained in:
parent
b3f094c737
commit
9a3822458e
49 changed files with 779844 additions and 1 deletions
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 45ad0acfb75f09cad6c23c3f9da03b5283886215
|
||||
1
hackpads/woagpad/.envrc
Normal file
1
hackpads/woagpad/.envrc
Normal file
|
|
@ -0,0 +1 @@
|
|||
use flake
|
||||
1
hackpads/woagpad/.gitignore
vendored
Normal file
1
hackpads/woagpad/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
.direnv/
|
||||
6
hackpads/woagpad/.gitmodules
vendored
Normal file
6
hackpads/woagpad/.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[submodule "scottokeebs"]
|
||||
path = PCB/scottokeebs
|
||||
url = https://github.com/joe-scotto/scottokeebs.git
|
||||
[submodule "PCB/scottokeebs"]
|
||||
path = PCB/scottokeebs
|
||||
url = https://github.com/joe-scotto/scottokeebs.git
|
||||
1649
hackpads/woagpad/CAD/Bottom.step
Normal file
1649
hackpads/woagpad/CAD/Bottom.step
Normal file
File diff suppressed because it is too large
Load diff
14055
hackpads/woagpad/CAD/Top.step
Normal file
14055
hackpads/woagpad/CAD/Top.step
Normal file
File diff suppressed because it is too large
Load diff
BIN
hackpads/woagpad/CAD/Woagpad-Case.f3z
Normal file
BIN
hackpads/woagpad/CAD/Woagpad-Case.f3z
Normal file
Binary file not shown.
568681
hackpads/woagpad/CAD/Woagpad.step
Normal file
568681
hackpads/woagpad/CAD/Woagpad.step
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,370 @@
|
|||
(footprint "MODULE_DM-OLED096-636"
|
||||
(version 20240108)
|
||||
(generator "pcbnew")
|
||||
(generator_version "8.0")
|
||||
(layer "F.Cu")
|
||||
(property "Reference" "REF**"
|
||||
(at -9.525 -13.97 0)
|
||||
(layer "F.SilkS")
|
||||
(uuid "7e7212f9-e047-40a7-957d-9d75dff2839c")
|
||||
(effects
|
||||
(font
|
||||
(size 1 1)
|
||||
(thickness 0.15)
|
||||
)
|
||||
)
|
||||
)
|
||||
(property "Value" "MODULE_DM-OLED096-636"
|
||||
(at 0.635 13.97 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "b4d4ccf0-8fa9-449e-8875-0f43c4ccb85c")
|
||||
(effects
|
||||
(font
|
||||
(size 1 1)
|
||||
(thickness 0.15)
|
||||
)
|
||||
)
|
||||
)
|
||||
(property "Footprint" ""
|
||||
(at 0 0 0)
|
||||
(layer "F.Fab")
|
||||
(hide yes)
|
||||
(uuid "327d7d67-4cc6-496f-aae4-d8a52e3ad33f")
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
(thickness 0.15)
|
||||
)
|
||||
)
|
||||
)
|
||||
(property "Datasheet" ""
|
||||
(at 0 0 0)
|
||||
(layer "F.Fab")
|
||||
(hide yes)
|
||||
(uuid "44d966ca-b591-43fa-abd7-084ca15b9340")
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
(thickness 0.15)
|
||||
)
|
||||
)
|
||||
)
|
||||
(property "Description" ""
|
||||
(at 0 0 0)
|
||||
(layer "F.Fab")
|
||||
(hide yes)
|
||||
(uuid "55c5ce1c-04ca-4599-a868-8ec72d21b7b0")
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
(thickness 0.15)
|
||||
)
|
||||
)
|
||||
)
|
||||
(attr through_hole)
|
||||
(fp_line
|
||||
(start -13 -13)
|
||||
(end 13 -13)
|
||||
(stroke
|
||||
(width 0.127)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
(uuid "9c62812f-bfbd-4b3c-a3a1-46e18d680177")
|
||||
)
|
||||
(fp_line
|
||||
(start -13 13)
|
||||
(end -13 -13)
|
||||
(stroke
|
||||
(width 0.127)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
(uuid "b723a164-4c49-4b0d-9496-67031f78638b")
|
||||
)
|
||||
(fp_line
|
||||
(start -7 11)
|
||||
(end -7 13)
|
||||
(stroke
|
||||
(width 0.127)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
(uuid "7ddb0cd8-3715-419a-8c4b-c28165d9b8fa")
|
||||
)
|
||||
(fp_line
|
||||
(start -7 13)
|
||||
(end -13 13)
|
||||
(stroke
|
||||
(width 0.127)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
(uuid "92969aee-7932-4a43-8e5a-f0c790a30fe1")
|
||||
)
|
||||
(fp_line
|
||||
(start 7 11)
|
||||
(end -7 11)
|
||||
(stroke
|
||||
(width 0.127)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
(uuid "f53e6c35-61c0-4fc8-b9c1-10b0272ae1cc")
|
||||
)
|
||||
(fp_line
|
||||
(start 7 13)
|
||||
(end 7 11)
|
||||
(stroke
|
||||
(width 0.127)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
(uuid "2ec3b725-8068-4545-9d37-d6cc81f827cd")
|
||||
)
|
||||
(fp_line
|
||||
(start 13 -13)
|
||||
(end 13 13)
|
||||
(stroke
|
||||
(width 0.127)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
(uuid "d7c454bd-b567-455f-9101-26e8ab46a350")
|
||||
)
|
||||
(fp_line
|
||||
(start 13 13)
|
||||
(end 7 13)
|
||||
(stroke
|
||||
(width 0.127)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
(uuid "0d7aedf2-90ce-42f6-bd4f-f56cc2228e90")
|
||||
)
|
||||
(fp_circle
|
||||
(center -4 -13.5)
|
||||
(end -3.9 -13.5)
|
||||
(stroke
|
||||
(width 0.2)
|
||||
(type solid)
|
||||
)
|
||||
(fill none)
|
||||
(layer "F.SilkS")
|
||||
(uuid "604bc2c2-0646-44e5-a562-16bf01eff296")
|
||||
)
|
||||
(fp_line
|
||||
(start -13.25 -13.25)
|
||||
(end 13.25 -13.25)
|
||||
(stroke
|
||||
(width 0.05)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.CrtYd")
|
||||
(uuid "c27c2d7c-fde7-42b1-a691-6e1340bf957b")
|
||||
)
|
||||
(fp_line
|
||||
(start -13.25 13.25)
|
||||
(end -13.25 -13.25)
|
||||
(stroke
|
||||
(width 0.05)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.CrtYd")
|
||||
(uuid "747ffc5e-a76e-4c01-b869-c69053f62497")
|
||||
)
|
||||
(fp_line
|
||||
(start 13.25 -13.25)
|
||||
(end 13.25 13.25)
|
||||
(stroke
|
||||
(width 0.05)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.CrtYd")
|
||||
(uuid "74dc61d1-6cb0-42bf-9e15-5d92e7782e64")
|
||||
)
|
||||
(fp_line
|
||||
(start 13.25 13.25)
|
||||
(end -13.25 13.25)
|
||||
(stroke
|
||||
(width 0.05)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.CrtYd")
|
||||
(uuid "e92eb786-c889-4c2d-8c6d-09a9c5df5d48")
|
||||
)
|
||||
(fp_line
|
||||
(start -13 -13)
|
||||
(end 13 -13)
|
||||
(stroke
|
||||
(width 0.127)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.Fab")
|
||||
(uuid "eac64748-33df-4bb1-b917-51611c93b902")
|
||||
)
|
||||
(fp_line
|
||||
(start -13 13)
|
||||
(end -13 -13)
|
||||
(stroke
|
||||
(width 0.127)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.Fab")
|
||||
(uuid "7c5f815c-7233-45fe-abb5-3a0f30199754")
|
||||
)
|
||||
(fp_line
|
||||
(start -7 11)
|
||||
(end 7 11)
|
||||
(stroke
|
||||
(width 0.127)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.Fab")
|
||||
(uuid "7c2d9fa3-0ce8-4f74-a37a-efa8eab80054")
|
||||
)
|
||||
(fp_line
|
||||
(start -7 13)
|
||||
(end -13 13)
|
||||
(stroke
|
||||
(width 0.127)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.Fab")
|
||||
(uuid "4713d769-0495-42fc-9bb0-6ca438fc0fff")
|
||||
)
|
||||
(fp_line
|
||||
(start -7 13)
|
||||
(end -7 11)
|
||||
(stroke
|
||||
(width 0.127)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.Fab")
|
||||
(uuid "10182d28-39e8-4cf0-99de-7de692dfe285")
|
||||
)
|
||||
(fp_line
|
||||
(start 7 11)
|
||||
(end 7 13)
|
||||
(stroke
|
||||
(width 0.127)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.Fab")
|
||||
(uuid "c42c9119-f089-4ec8-b6ed-f4d51b48eb44")
|
||||
)
|
||||
(fp_line
|
||||
(start 13 -13)
|
||||
(end 13 13)
|
||||
(stroke
|
||||
(width 0.127)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.Fab")
|
||||
(uuid "c5ef328d-a690-4bb3-adda-1d00b28bff06")
|
||||
)
|
||||
(fp_line
|
||||
(start 13 13)
|
||||
(end 7 13)
|
||||
(stroke
|
||||
(width 0.127)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.Fab")
|
||||
(uuid "6d6707f6-9b6b-4d50-8275-f72a8e17755f")
|
||||
)
|
||||
(fp_circle
|
||||
(center -4 -13.5)
|
||||
(end -3.9 -13.5)
|
||||
(stroke
|
||||
(width 0.2)
|
||||
(type solid)
|
||||
)
|
||||
(fill none)
|
||||
(layer "F.Fab")
|
||||
(uuid "d0c4d446-2b4d-434c-9fe3-16f23045638a")
|
||||
)
|
||||
(pad "1" thru_hole rect
|
||||
(at -3.81 -11.5)
|
||||
(size 1.508 1.508)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
(solder_mask_margin 0.102)
|
||||
(uuid "74b4afec-2c0f-441c-b0e3-c5eccc477669")
|
||||
)
|
||||
(pad "2" thru_hole circle
|
||||
(at -1.27 -11.5)
|
||||
(size 1.508 1.508)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
(solder_mask_margin 0.102)
|
||||
(uuid "79003ed0-b938-4ac5-854b-9537b33e66a2")
|
||||
)
|
||||
(pad "3" thru_hole circle
|
||||
(at 1.27 -11.5)
|
||||
(size 1.508 1.508)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
(solder_mask_margin 0.102)
|
||||
(uuid "456c3e03-51e1-4a58-9b8e-68d30b2a2070")
|
||||
)
|
||||
(pad "4" thru_hole circle
|
||||
(at 3.81 -11.5)
|
||||
(size 1.508 1.508)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
(solder_mask_margin 0.102)
|
||||
(uuid "90bb6b7c-156c-44bb-8fd0-bc8a1d30431f")
|
||||
)
|
||||
(pad "MP" thru_hole circle
|
||||
(at -11 -11)
|
||||
(size 3 3)
|
||||
(drill 2)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
(solder_mask_margin 0.102)
|
||||
(uuid "8d34444f-8f15-4d3e-af4a-adffde6c55a9")
|
||||
)
|
||||
(pad "MP" thru_hole circle
|
||||
(at -11 11)
|
||||
(size 3 3)
|
||||
(drill 2)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
(solder_mask_margin 0.102)
|
||||
(uuid "b73989a4-ad2b-4544-b5db-180d47bca05d")
|
||||
)
|
||||
(pad "MP" thru_hole circle
|
||||
(at 11 -11)
|
||||
(size 3 3)
|
||||
(drill 2)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
(solder_mask_margin 0.102)
|
||||
(uuid "abb9a1f6-2b7d-40a0-a47d-92cdb9b14a3c")
|
||||
)
|
||||
(pad "MP" thru_hole circle
|
||||
(at 11 11)
|
||||
(size 3 3)
|
||||
(drill 2)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
(solder_mask_margin 0.102)
|
||||
(uuid "0c54fc9d-1728-4e08-82f8-71a253490e82")
|
||||
)
|
||||
(model "/Users/taranmittal/Documents/MITTAL1/PCB/CUSTOM LIBRARY.pretty/DM-OLED096-636/DM-OLED096-636.step"
|
||||
(offset
|
||||
(xyz 0 0 0)
|
||||
)
|
||||
(scale
|
||||
(xyz 1 1 1)
|
||||
)
|
||||
(rotate
|
||||
(xyz 90 180 180)
|
||||
)
|
||||
)
|
||||
)
|
||||
105960
hackpads/woagpad/PCB/fp-info-cache
Normal file
105960
hackpads/woagpad/PCB/fp-info-cache
Normal file
File diff suppressed because it is too large
Load diff
18
hackpads/woagpad/PCB/fp-lib-table
Normal file
18
hackpads/woagpad/PCB/fp-lib-table
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
(fp_lib_table
|
||||
(version 7)
|
||||
(lib (name "ScottoKeebs_Alps")(type "KiCad")(uri "${KIPRJMOD}/scottokeebs/Extras/ScottoKicad/footprints/ScottoKeebs_Alps.pretty")(options "")(descr ""))
|
||||
(lib (name "ScottoKeebs_CAD")(type "KiCad")(uri "${KIPRJMOD}/scottokeebs/Extras/ScottoKicad/footprints/ScottoKeebs_CAD.pretty")(options "")(descr ""))
|
||||
(lib (name "ScottoKeebs_Choc")(type "KiCad")(uri "${KIPRJMOD}/scottokeebs/Extras/ScottoKicad/footprints/ScottoKeebs_Choc.pretty")(options "")(descr ""))
|
||||
(lib (name "ScottoKeebs_Components")(type "KiCad")(uri "${KIPRJMOD}/scottokeebs/Extras/ScottoKicad/footprints/ScottoKeebs_Components.pretty")(options "")(descr ""))
|
||||
(lib (name "ScottoKeebs_Cutout")(type "KiCad")(uri "${KIPRJMOD}/scottokeebs/Extras/ScottoKicad/footprints/ScottoKeebs_Cutout.pretty")(options "")(descr ""))
|
||||
(lib (name "ScottoKeebs_Hotswap")(type "KiCad")(uri "${KIPRJMOD}/scottokeebs/Extras/ScottoKicad/footprints/ScottoKeebs_Hotswap.pretty")(options "")(descr ""))
|
||||
(lib (name "ScottoKeebs_Hybrid")(type "KiCad")(uri "${KIPRJMOD}/scottokeebs/Extras/ScottoKicad/footprints/ScottoKeebs_Hybrid.pretty")(options "")(descr ""))
|
||||
(lib (name "ScottoKeebs_KH")(type "KiCad")(uri "${KIPRJMOD}/scottokeebs/Extras/ScottoKicad/footprints/ScottoKeebs_KH.pretty")(options "")(descr ""))
|
||||
(lib (name "ScottoKeebs_MCU")(type "KiCad")(uri "${KIPRJMOD}/scottokeebs/Extras/ScottoKicad/footprints/ScottoKeebs_MCU.pretty")(options "")(descr ""))
|
||||
(lib (name "ScottoKeebs_Miscellaneous")(type "KiCad")(uri "${KIPRJMOD}/scottokeebs/Extras/ScottoKicad/footprints/ScottoKeebs_Miscellaneous.pretty")(options "")(descr ""))
|
||||
(lib (name "ScottoKeebs_MX")(type "KiCad")(uri "${KIPRJMOD}/scottokeebs/Extras/ScottoKicad/footprints/ScottoKeebs_MX.pretty")(options "")(descr ""))
|
||||
(lib (name "ScottoKeebs_NB")(type "KiCad")(uri "${KIPRJMOD}/scottokeebs/Extras/ScottoKicad/footprints/ScottoKeebs_NB.pretty")(options "")(descr ""))
|
||||
(lib (name "ScottoKeebs_Scotto")(type "KiCad")(uri "${KIPRJMOD}/scottokeebs/Extras/ScottoKicad/footprints/ScottoKeebs_Scotto.pretty")(options "")(descr ""))
|
||||
(lib (name "ScottoKeebs_Stabilizer")(type "KiCad")(uri "${KIPRJMOD}/scottokeebs/Extras/ScottoKicad/footprints/ScottoKeebs_Stabilizer.pretty")(options "")(descr ""))
|
||||
(lib (name "Library")(type "KiCad")(uri "${KIPRJMOD}/Library.pretty")(options "")(descr ""))
|
||||
)
|
||||
5
hackpads/woagpad/PCB/sym-lib-table
Normal file
5
hackpads/woagpad/PCB/sym-lib-table
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
(sym_lib_table
|
||||
(version 7)
|
||||
(lib (name "Seeed_Studio_XIAO_Series")(type "KiCad")(uri "${KIPRJMOD}/OPL_Kicad_Library/Seeed Studio XIAO Series Library/Seeed_Studio_XIAO_Series.kicad_sym")(options "")(descr ""))
|
||||
(lib (name "ScottoKeebs")(type "KiCad")(uri "${KIPRJMOD}/scottokeebs/Extras/ScottoKicad/symbols/ScottoKeebs.kicad_sym")(options "")(descr ""))
|
||||
)
|
||||
179
hackpads/woagpad/PCB/woagpad.kicad_dru
Normal file
179
hackpads/woagpad/PCB/woagpad.kicad_dru
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
(version 1)
|
||||
#Kicad 7
|
||||
|
||||
# ----------------------------------- Minimum trace width and spacing (PICK ONE) --------------------
|
||||
|
||||
# 2-layer, 1oz copper
|
||||
(rule "Minimum Trace Width and Spacing (outer layer)"
|
||||
(constraint track_width (min 0.127mm))
|
||||
(constraint clearance (min 0.127mm))
|
||||
(condition "A.Type == 'track'"))
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------
|
||||
|
||||
# Drill/hole size - listed here to maintain order of rule application. Must not override rule set in Via hole/diameter size below.
|
||||
(rule "drill hole size (mechanical)"
|
||||
(constraint hole_size (min 0.15mm) (max 6.3mm)))
|
||||
|
||||
# ----------------------------------- Via hole/diameter size (PICK ONE) ------------------------------------
|
||||
|
||||
# 2-layer standard
|
||||
(rule "Minimum Via Diameter and Hole Size"
|
||||
(constraint hole_size (min 0.3mm))
|
||||
(constraint via_diameter (min 0.5mm))
|
||||
(constraint disallow buried_via)
|
||||
(condition "A.Type == 'via'"))
|
||||
|
||||
# ----------------------------------- Drill/hole size ------------------------------------
|
||||
|
||||
(rule "PTH Hole Size"
|
||||
(constraint hole_size (min 0.2mm) (max 6.35mm))
|
||||
(condition "A.Type != 'Via' && A.isPlated()"))
|
||||
|
||||
(rule "Minimum Non-plated Hole Size"
|
||||
(constraint hole_size (min 0.5mm))
|
||||
(condition "A.Type == 'pad' && !A.isPlated()"))
|
||||
|
||||
(rule "Pad Size"
|
||||
(constraint hole_size (min 0.5mm))
|
||||
(constraint annular_width (min 0.22mm))
|
||||
(condition "A.Type == 'Pad' && A.isPlated()"))
|
||||
|
||||
(rule "Minimum Castellated Hole Size"
|
||||
(constraint hole_size (min 0.6mm))
|
||||
(condition "A.Type == 'pad' && A.Fabrication_Property == 'Castellated pad'"))
|
||||
|
||||
(rule "Min. Plated Slot Width"
|
||||
(constraint hole_size (min 0.5mm))
|
||||
(condition "(A.Hole_Size_X != A.Hole_Size_Y) && A.isPlated()"))
|
||||
|
||||
(rule "Min. Non-Plated Slot Width"
|
||||
(constraint hole_size (min 1.0mm))
|
||||
(condition "(A.Hole_Size_X != A.Hole_Size_Y) && !A.isPlated()"))
|
||||
|
||||
# ----------------------------------- Minimum clearance ----------------------------------
|
||||
(rule "hole to hole clearance (different nets)"
|
||||
(constraint hole_to_hole (min 0.5mm))
|
||||
(condition "A.Net != B.Net"))
|
||||
|
||||
(rule "via to track clearance"
|
||||
(constraint hole_clearance (min 0.254mm))
|
||||
(condition "A.Type == 'via' && B.Type == 'track'"))
|
||||
|
||||
(rule "via to via clearance (same nets)"
|
||||
(constraint hole_to_hole (min 0.254mm))
|
||||
(condition "A.Type == 'via' && B.Type == A.Type && A.Net == B.Net"))
|
||||
|
||||
(rule "pad to pad clearance (with hole, different nets)"
|
||||
(constraint hole_to_hole (min 0.5mm))
|
||||
(condition "A.Type == 'pad' && B.Type == A.Type && A.Net != B.Net"))
|
||||
|
||||
(rule "pad to pad clearance (without hole, different nets)"
|
||||
(constraint clearance (min 0.127mm))
|
||||
(condition "A.Type == 'Pad' && B.Type == 'Pad'"))
|
||||
|
||||
(rule "NPTH to Track clearance"
|
||||
(constraint hole_clearance (min 0.254mm))
|
||||
(condition "A.Pad_Type == 'NPTH, mechanical' && B.Type == 'track'"))
|
||||
|
||||
(rule "NPTH with copper around"
|
||||
(constraint hole_clearance (min 0.20mm))
|
||||
(condition "A.Pad_Type == 'NPTH, mechanical' && B.Type != 'track'"))
|
||||
|
||||
(rule "PTH to Track clearance"
|
||||
(constraint hole_clearance (min 0.33mm))
|
||||
(condition "A.isPlated() && A.Type != 'Via' && B.Type == 'track'"))
|
||||
|
||||
(rule "Pad to Track clearance"
|
||||
(constraint clearance (min 0.2mm))
|
||||
(condition "A.isPlated() && A.Type != 'Via' && B.Type == 'track'"))
|
||||
|
||||
# ----------------------------------- Board Outlines (PICK ONE) -------------------------------------
|
||||
#Default Routed Edge Clearance
|
||||
(rule "Trace to Outline"
|
||||
(constraint edge_clearance (min 0.3mm))
|
||||
(condition "A.Type == 'track'"))
|
||||
|
||||
# ----------------------------------- silkscreen (Kicad 7 only) --------------------------
|
||||
(rule "Minimum Text"
|
||||
(constraint text_thickness (min 0.15mm))
|
||||
(constraint text_height (min 1mm))
|
||||
(layer "?.Silkscreen"))
|
||||
|
||||
#JLCPCB pad to silkscreen clearance rule is actually 0.15mm, but KiCad libraries violate that slightly, so JLC will have to deal with it.
|
||||
(rule "Pad to Silkscreen"
|
||||
(constraint silk_clearance (min 0.14mm))
|
||||
(layer outer)
|
||||
(condition "A.Type == 'pad' && (B.Type == 'text' || B.Type == 'graphic')"))
|
||||
|
||||
# 2-layer, 1oz copper
|
||||
(rule "Minimum Trace Width (outer layer)"
|
||||
(constraint track_width (min 5mil))
|
||||
(layer outer)
|
||||
(condition "A.Type == 'track'"))
|
||||
|
||||
(rule "Minimum Trace Spacing (outer layer)"
|
||||
(constraint clearance (min 5mil))
|
||||
(layer outer)
|
||||
(condition "A.Type == 'track' && B.Type == A.Type"))
|
||||
|
||||
(rule "Trace to Outline"
|
||||
(constraint edge_clearance (min 0.3mm))
|
||||
(condition "A.Type == 'track'"))
|
||||
|
||||
# drill/hole size
|
||||
(rule "drill hole size (mechanical)"
|
||||
(constraint hole_size (min 0.2mm) (max 6.3mm)))
|
||||
|
||||
(rule "Minimum Via Hole Size"
|
||||
(constraint hole_size (min 0.2mm))
|
||||
(condition "A.Type == 'via'"))
|
||||
|
||||
(rule "Minimum Via Diameter"
|
||||
(constraint via_diameter (min 0.45mm))
|
||||
(condition "A.Type == 'via'"))
|
||||
|
||||
(rule "PTH Hole Size"
|
||||
(constraint hole_size (min 0.2mm) (max 6.35mm))
|
||||
(condition "A.isPlated()"))
|
||||
|
||||
(rule "Minimum Non-plated Hole Size"
|
||||
(constraint hole_size (min 0.5mm))
|
||||
(condition "A.Type == 'pad' && !A.isPlated()"))
|
||||
|
||||
(rule "Minimum Castellated Hole Size"
|
||||
(constraint hole_size (min 0.6mm))
|
||||
(condition "A.Type == 'pad' && A.Fabrication_Property == 'Castellated pad'"))
|
||||
|
||||
# clearance
|
||||
(rule "hole to hole clearance (different nets)"
|
||||
(constraint hole_to_hole (min 0.5mm))
|
||||
(condition "A.Net != B.Net"))
|
||||
|
||||
(rule "via to track clearance"
|
||||
(constraint hole_clearance (min 0.254mm))
|
||||
(condition "A.Type == 'via' && B.Type == 'track'"))
|
||||
|
||||
(rule "via to via clearance (same nets)"
|
||||
(constraint hole_to_hole (min 0.254mm))
|
||||
(condition "A.Type == 'via' && B.Type == A.Type && A.Net == B.Net"))
|
||||
|
||||
(rule "pad to pad clearance (with hole, different nets)"
|
||||
(constraint hole_to_hole (min 0.5mm))
|
||||
(condition "A.Type == 'pad' && B.Type == A.Type && A.Net != B.Net"))
|
||||
|
||||
(rule "pad to pad clearance (without hole, different nets)"
|
||||
(constraint clearance (min 0.127mm))
|
||||
(condition "A.Type == 'pad' && B.Type == A.Type && A.Net != B.Net"))
|
||||
|
||||
(rule "NPTH to Track clearance)"
|
||||
(constraint hole_clearance (min 0.254mm))
|
||||
(condition "A.Pad_Type == 'NPTH, mechanical' && B.Type == 'track'"))
|
||||
|
||||
(rule "PTH to Track clearance)"
|
||||
(constraint hole_clearance (min 0.33mm))
|
||||
(condition "A.isPlated() && B.Type == 'track'"))
|
||||
|
||||
(rule "Pad to Track clearance)"
|
||||
(constraint clearance (min 0.2mm))
|
||||
(condition "A.isPlated() && B.Type == 'track'"))
|
||||
17666
hackpads/woagpad/PCB/woagpad.kicad_pcb
Normal file
17666
hackpads/woagpad/PCB/woagpad.kicad_pcb
Normal file
File diff suppressed because it is too large
Load diff
83
hackpads/woagpad/PCB/woagpad.kicad_prl
Normal file
83
hackpads/woagpad/PCB/woagpad.kicad_prl
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
{
|
||||
"board": {
|
||||
"active_layer": 0,
|
||||
"active_layer_preset": "All Layers",
|
||||
"auto_track_width": true,
|
||||
"hidden_netclasses": [],
|
||||
"hidden_nets": [],
|
||||
"high_contrast_mode": 0,
|
||||
"net_color_mode": 1,
|
||||
"opacity": {
|
||||
"images": 0.6,
|
||||
"pads": 1.0,
|
||||
"tracks": 1.0,
|
||||
"vias": 1.0,
|
||||
"zones": 0.6
|
||||
},
|
||||
"selection_filter": {
|
||||
"dimensions": true,
|
||||
"footprints": true,
|
||||
"graphics": true,
|
||||
"keepouts": true,
|
||||
"lockedItems": false,
|
||||
"otherItems": true,
|
||||
"pads": true,
|
||||
"text": true,
|
||||
"tracks": true,
|
||||
"vias": true,
|
||||
"zones": true
|
||||
},
|
||||
"visible_items": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
32,
|
||||
33,
|
||||
34,
|
||||
35,
|
||||
36,
|
||||
39,
|
||||
40
|
||||
],
|
||||
"visible_layers": "fffffff_ffffffff",
|
||||
"zone_display_mode": 0
|
||||
},
|
||||
"git": {
|
||||
"repo_password": "",
|
||||
"repo_type": "",
|
||||
"repo_username": "",
|
||||
"ssh_key": ""
|
||||
},
|
||||
"meta": {
|
||||
"filename": "woagpad.kicad_prl",
|
||||
"version": 3
|
||||
},
|
||||
"project": {
|
||||
"files": []
|
||||
}
|
||||
}
|
||||
592
hackpads/woagpad/PCB/woagpad.kicad_pro
Normal file
592
hackpads/woagpad/PCB/woagpad.kicad_pro
Normal file
|
|
@ -0,0 +1,592 @@
|
|||
{
|
||||
"board": {
|
||||
"3dviewports": [],
|
||||
"design_settings": {
|
||||
"defaults": {
|
||||
"apply_defaults_to_fp_fields": false,
|
||||
"apply_defaults_to_fp_shapes": false,
|
||||
"apply_defaults_to_fp_text": false,
|
||||
"board_outline_line_width": 0.05,
|
||||
"copper_line_width": 0.2,
|
||||
"copper_text_italic": false,
|
||||
"copper_text_size_h": 1.5,
|
||||
"copper_text_size_v": 1.5,
|
||||
"copper_text_thickness": 0.3,
|
||||
"copper_text_upright": false,
|
||||
"courtyard_line_width": 0.05,
|
||||
"dimension_precision": 4,
|
||||
"dimension_units": 3,
|
||||
"dimensions": {
|
||||
"arrow_length": 1270000,
|
||||
"extension_offset": 500000,
|
||||
"keep_text_aligned": true,
|
||||
"suppress_zeroes": false,
|
||||
"text_position": 0,
|
||||
"units_format": 1
|
||||
},
|
||||
"fab_line_width": 0.1,
|
||||
"fab_text_italic": false,
|
||||
"fab_text_size_h": 1.0,
|
||||
"fab_text_size_v": 1.0,
|
||||
"fab_text_thickness": 0.15,
|
||||
"fab_text_upright": false,
|
||||
"other_line_width": 0.1,
|
||||
"other_text_italic": false,
|
||||
"other_text_size_h": 1.0,
|
||||
"other_text_size_v": 1.0,
|
||||
"other_text_thickness": 0.15,
|
||||
"other_text_upright": false,
|
||||
"pads": {
|
||||
"drill": 9.4,
|
||||
"height": 9.4,
|
||||
"width": 9.4
|
||||
},
|
||||
"silk_line_width": 0.1,
|
||||
"silk_text_italic": false,
|
||||
"silk_text_size_h": 1.0,
|
||||
"silk_text_size_v": 1.0,
|
||||
"silk_text_thickness": 0.1,
|
||||
"silk_text_upright": false,
|
||||
"zones": {
|
||||
"min_clearance": 0.5
|
||||
}
|
||||
},
|
||||
"diff_pair_dimensions": [],
|
||||
"drc_exclusions": [],
|
||||
"meta": {
|
||||
"version": 2
|
||||
},
|
||||
"rule_severities": {
|
||||
"annular_width": "error",
|
||||
"clearance": "error",
|
||||
"connection_width": "warning",
|
||||
"copper_edge_clearance": "error",
|
||||
"copper_sliver": "warning",
|
||||
"courtyards_overlap": "error",
|
||||
"diff_pair_gap_out_of_range": "error",
|
||||
"diff_pair_uncoupled_length_too_long": "error",
|
||||
"drill_out_of_range": "error",
|
||||
"duplicate_footprints": "warning",
|
||||
"extra_footprint": "warning",
|
||||
"footprint": "error",
|
||||
"footprint_symbol_mismatch": "warning",
|
||||
"footprint_type_mismatch": "ignore",
|
||||
"hole_clearance": "error",
|
||||
"hole_near_hole": "error",
|
||||
"holes_co_located": "warning",
|
||||
"invalid_outline": "error",
|
||||
"isolated_copper": "warning",
|
||||
"item_on_disabled_layer": "error",
|
||||
"items_not_allowed": "error",
|
||||
"length_out_of_range": "error",
|
||||
"lib_footprint_issues": "warning",
|
||||
"lib_footprint_mismatch": "warning",
|
||||
"malformed_courtyard": "error",
|
||||
"microvia_drill_out_of_range": "error",
|
||||
"missing_courtyard": "ignore",
|
||||
"missing_footprint": "warning",
|
||||
"net_conflict": "warning",
|
||||
"npth_inside_courtyard": "ignore",
|
||||
"padstack": "warning",
|
||||
"pth_inside_courtyard": "ignore",
|
||||
"shorting_items": "error",
|
||||
"silk_edge_clearance": "warning",
|
||||
"silk_over_copper": "warning",
|
||||
"silk_overlap": "warning",
|
||||
"skew_out_of_range": "error",
|
||||
"solder_mask_bridge": "error",
|
||||
"starved_thermal": "ignore",
|
||||
"text_height": "warning",
|
||||
"text_thickness": "warning",
|
||||
"through_hole_pad_without_hole": "error",
|
||||
"too_many_vias": "error",
|
||||
"track_dangling": "warning",
|
||||
"track_width": "error",
|
||||
"tracks_crossing": "error",
|
||||
"unconnected_items": "error",
|
||||
"unresolved_variable": "error",
|
||||
"via_dangling": "warning",
|
||||
"zones_intersect": "error"
|
||||
},
|
||||
"rules": {
|
||||
"max_error": 0.005,
|
||||
"min_clearance": 0.0,
|
||||
"min_connection": 0.0,
|
||||
"min_copper_edge_clearance": 0.5,
|
||||
"min_hole_clearance": 0.25,
|
||||
"min_hole_to_hole": 0.25,
|
||||
"min_microvia_diameter": 0.2,
|
||||
"min_microvia_drill": 0.1,
|
||||
"min_resolved_spokes": 2,
|
||||
"min_silk_clearance": 0.0,
|
||||
"min_text_height": 0.8,
|
||||
"min_text_thickness": 0.08,
|
||||
"min_through_hole_diameter": 0.3,
|
||||
"min_track_width": 0.0,
|
||||
"min_via_annular_width": 0.1,
|
||||
"min_via_diameter": 0.5,
|
||||
"solder_mask_to_copper_clearance": 0.0,
|
||||
"use_height_for_length_calcs": true
|
||||
},
|
||||
"teardrop_options": [
|
||||
{
|
||||
"td_onpadsmd": true,
|
||||
"td_onroundshapesonly": false,
|
||||
"td_ontrackend": false,
|
||||
"td_onviapad": true
|
||||
}
|
||||
],
|
||||
"teardrop_parameters": [
|
||||
{
|
||||
"td_allow_use_two_tracks": true,
|
||||
"td_curve_segcount": 0,
|
||||
"td_height_ratio": 1.0,
|
||||
"td_length_ratio": 0.5,
|
||||
"td_maxheight": 2.0,
|
||||
"td_maxlen": 1.0,
|
||||
"td_on_pad_in_zone": false,
|
||||
"td_target_name": "td_round_shape",
|
||||
"td_width_to_size_filter_ratio": 0.9
|
||||
},
|
||||
{
|
||||
"td_allow_use_two_tracks": true,
|
||||
"td_curve_segcount": 0,
|
||||
"td_height_ratio": 1.0,
|
||||
"td_length_ratio": 0.5,
|
||||
"td_maxheight": 2.0,
|
||||
"td_maxlen": 1.0,
|
||||
"td_on_pad_in_zone": false,
|
||||
"td_target_name": "td_rect_shape",
|
||||
"td_width_to_size_filter_ratio": 0.9
|
||||
},
|
||||
{
|
||||
"td_allow_use_two_tracks": true,
|
||||
"td_curve_segcount": 0,
|
||||
"td_height_ratio": 1.0,
|
||||
"td_length_ratio": 0.5,
|
||||
"td_maxheight": 2.0,
|
||||
"td_maxlen": 1.0,
|
||||
"td_on_pad_in_zone": false,
|
||||
"td_target_name": "td_track_end",
|
||||
"td_width_to_size_filter_ratio": 0.9
|
||||
}
|
||||
],
|
||||
"track_widths": [],
|
||||
"tuning_pattern_settings": {
|
||||
"diff_pair_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 1.0
|
||||
},
|
||||
"diff_pair_skew_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 0.6
|
||||
},
|
||||
"single_track_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 0.6
|
||||
}
|
||||
},
|
||||
"via_dimensions": [],
|
||||
"zones_allow_external_fillets": false
|
||||
},
|
||||
"ipc2581": {
|
||||
"dist": "",
|
||||
"distpn": "",
|
||||
"internal_id": "",
|
||||
"mfg": "",
|
||||
"mpn": ""
|
||||
},
|
||||
"layer_presets": [],
|
||||
"viewports": []
|
||||
},
|
||||
"boards": [],
|
||||
"cvpcb": {
|
||||
"equivalence_files": []
|
||||
},
|
||||
"erc": {
|
||||
"erc_exclusions": [],
|
||||
"meta": {
|
||||
"version": 0
|
||||
},
|
||||
"pin_map": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
]
|
||||
],
|
||||
"rule_severities": {
|
||||
"bus_definition_conflict": "error",
|
||||
"bus_entry_needed": "error",
|
||||
"bus_to_bus_conflict": "error",
|
||||
"bus_to_net_conflict": "error",
|
||||
"conflicting_netclasses": "error",
|
||||
"different_unit_footprint": "error",
|
||||
"different_unit_net": "error",
|
||||
"duplicate_reference": "error",
|
||||
"duplicate_sheet_names": "error",
|
||||
"endpoint_off_grid": "warning",
|
||||
"extra_units": "error",
|
||||
"global_label_dangling": "warning",
|
||||
"hier_label_mismatch": "error",
|
||||
"label_dangling": "error",
|
||||
"lib_symbol_issues": "warning",
|
||||
"missing_bidi_pin": "warning",
|
||||
"missing_input_pin": "warning",
|
||||
"missing_power_pin": "error",
|
||||
"missing_unit": "warning",
|
||||
"multiple_net_names": "warning",
|
||||
"net_not_bus_member": "warning",
|
||||
"no_connect_connected": "warning",
|
||||
"no_connect_dangling": "warning",
|
||||
"pin_not_connected": "error",
|
||||
"pin_not_driven": "error",
|
||||
"pin_to_pin": "warning",
|
||||
"power_pin_not_driven": "error",
|
||||
"similar_labels": "warning",
|
||||
"simulation_model_issue": "ignore",
|
||||
"unannotated": "error",
|
||||
"unit_value_mismatch": "error",
|
||||
"unresolved_variable": "error",
|
||||
"wire_dangling": "error"
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"pinned_footprint_libs": [],
|
||||
"pinned_symbol_libs": []
|
||||
},
|
||||
"meta": {
|
||||
"filename": "woagpad.kicad_pro",
|
||||
"version": 1
|
||||
},
|
||||
"net_settings": {
|
||||
"classes": [
|
||||
{
|
||||
"bus_width": 12,
|
||||
"clearance": 0.2,
|
||||
"diff_pair_gap": 0.25,
|
||||
"diff_pair_via_gap": 0.25,
|
||||
"diff_pair_width": 0.2,
|
||||
"line_style": 0,
|
||||
"microvia_diameter": 0.3,
|
||||
"microvia_drill": 0.1,
|
||||
"name": "Default",
|
||||
"pcb_color": "rgba(0, 0, 0, 0.000)",
|
||||
"schematic_color": "rgba(0, 0, 0, 0.000)",
|
||||
"track_width": 0.2,
|
||||
"via_diameter": 0.6,
|
||||
"via_drill": 0.3,
|
||||
"wire_width": 6
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"version": 3
|
||||
},
|
||||
"net_colors": null,
|
||||
"netclass_assignments": null,
|
||||
"netclass_patterns": []
|
||||
},
|
||||
"pcbnew": {
|
||||
"last_paths": {
|
||||
"gencad": "",
|
||||
"idf": "",
|
||||
"netlist": "",
|
||||
"plot": "plots/",
|
||||
"pos_files": "",
|
||||
"specctra_dsn": "",
|
||||
"step": "woagpad.step",
|
||||
"svg": "",
|
||||
"vrml": ""
|
||||
},
|
||||
"page_layout_descr_file": ""
|
||||
},
|
||||
"schematic": {
|
||||
"annotate_start_num": 0,
|
||||
"bom_export_filename": "",
|
||||
"bom_fmt_presets": [],
|
||||
"bom_fmt_settings": {
|
||||
"field_delimiter": ",",
|
||||
"keep_line_breaks": false,
|
||||
"keep_tabs": false,
|
||||
"name": "CSV",
|
||||
"ref_delimiter": ",",
|
||||
"ref_range_delimiter": "",
|
||||
"string_delimiter": "\""
|
||||
},
|
||||
"bom_presets": [],
|
||||
"bom_settings": {
|
||||
"exclude_dnp": false,
|
||||
"fields_ordered": [
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Reference",
|
||||
"name": "Reference",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Value",
|
||||
"name": "Value",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Datasheet",
|
||||
"name": "Datasheet",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Footprint",
|
||||
"name": "Footprint",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Qty",
|
||||
"name": "${QUANTITY}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "DNP",
|
||||
"name": "${DNP}",
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"filter_string": "",
|
||||
"group_symbols": true,
|
||||
"name": "Grouped By Value",
|
||||
"sort_asc": true,
|
||||
"sort_field": "Reference"
|
||||
},
|
||||
"connection_grid_size": 50.0,
|
||||
"drawing": {
|
||||
"dashed_lines_dash_length_ratio": 12.0,
|
||||
"dashed_lines_gap_length_ratio": 3.0,
|
||||
"default_line_thickness": 6.0,
|
||||
"default_text_size": 50.0,
|
||||
"field_names": [],
|
||||
"intersheets_ref_own_page": false,
|
||||
"intersheets_ref_prefix": "",
|
||||
"intersheets_ref_short": false,
|
||||
"intersheets_ref_show": false,
|
||||
"intersheets_ref_suffix": "",
|
||||
"junction_size_choice": 3,
|
||||
"label_size_ratio": 0.375,
|
||||
"operating_point_overlay_i_precision": 3,
|
||||
"operating_point_overlay_i_range": "~A",
|
||||
"operating_point_overlay_v_precision": 3,
|
||||
"operating_point_overlay_v_range": "~V",
|
||||
"overbar_offset_ratio": 1.23,
|
||||
"pin_symbol_size": 25.0,
|
||||
"text_offset_ratio": 0.15
|
||||
},
|
||||
"legacy_lib_dir": "",
|
||||
"legacy_lib_list": [],
|
||||
"meta": {
|
||||
"version": 1
|
||||
},
|
||||
"net_format_name": "",
|
||||
"ngspice": {
|
||||
"fix_include_paths": true,
|
||||
"meta": {
|
||||
"version": 0
|
||||
},
|
||||
"model_mode": 4,
|
||||
"workbook_filename": ""
|
||||
},
|
||||
"page_layout_descr_file": "",
|
||||
"plot_directory": "",
|
||||
"spice_current_sheet_as_root": false,
|
||||
"spice_external_command": "spice \"%I\"",
|
||||
"spice_model_current_sheet_as_root": true,
|
||||
"spice_save_all_currents": false,
|
||||
"spice_save_all_dissipations": false,
|
||||
"spice_save_all_voltages": false,
|
||||
"subpart_first_id": 65,
|
||||
"subpart_id_separator": 0
|
||||
},
|
||||
"sheets": [
|
||||
[
|
||||
"648b3d94-76ed-481b-b946-3ec0ab4b1f4d",
|
||||
"Root"
|
||||
]
|
||||
],
|
||||
"text_variables": {}
|
||||
}
|
||||
4881
hackpads/woagpad/PCB/woagpad.kicad_sch
Normal file
4881
hackpads/woagpad/PCB/woagpad.kicad_sch
Normal file
File diff suppressed because it is too large
Load diff
70
hackpads/woagpad/README.md
Normal file
70
hackpads/woagpad/README.md
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
# The Woagpad
|
||||
|
||||
## A macropad of all time
|
||||
|
||||

|
||||
|
||||
The woagpad is a board I decided to create because a macropad
|
||||
kinda just sounds fun. I really also wanted the rotary encoders
|
||||
to be able to change volume and control media playback (although RMK doesn't support it yet. Eventually:tm:).
|
||||
|
||||
## Features
|
||||
|
||||
- **Rust based firmware**: Through the power of [RMK](https://haobogu.github.io/rmk), the firmware is written in 100% Rust. Crab gaming :crab:
|
||||
- [VIAL](https://get.vial.today/) support OOTB
|
||||
- **128x64 OLED Display**: Display whatever the hell you want*
|
||||
- **2 EC11 Rotary Encoders**: Control your volume or scroll through pages with these*
|
||||
- **3x3 key matrix**: Keypad, macro, media controls, whatever the hell you want. You have 9 keys to mess around with (this includes the push buttons on the rotary encoders)
|
||||
|
||||
*The default rmk firmware does not support OLED display or rotary encoders yet.
|
||||
Once those are implemented, the firmware will be updated to support them.
|
||||
Write your own firmware to take advantage of these features!
|
||||
|
||||
## Design
|
||||
|
||||
### PCB
|
||||

|
||||
|
||||
Bog standard PCB Schematic for a macropad.
|
||||
This is actually my first design that uses a matrix
|
||||
and an OLED display so that's fun.
|
||||
|
||||
Also yes, 2 encoders can share a pin! Neat.
|
||||
|
||||
|Front|Back|
|
||||
|---|---|
|
||||
|||
|
||||
|
||||
First PCB with actual mounting holes.
|
||||
although in this case, the mounting holes are used
|
||||
for mounting the top and bottom of the case.
|
||||
See the case design for more details.
|
||||
|
||||
### Case
|
||||

|
||||
|
||||
Top integrated plate + frame. Bottom half with standoffs
|
||||
for heat inserts to screw the two halves together.
|
||||
|
||||
Also yes, the encoder holes are slightly larger than the encoders.
|
||||
I have no idea how well they'll actually fit so I decided for
|
||||
more tolerance than normal. It'll be fine... right?
|
||||
|
||||
### BOM
|
||||
- 1x PCB
|
||||
- see production/gerber.zip
|
||||
- 1x Case
|
||||
- see production/Top.step
|
||||
- see production/Bottom.step
|
||||
- 7X Cherry MX Switches
|
||||
- 7X DSA Keycaps
|
||||
- 2X Rotary Encoders
|
||||
- 9X 1N4148 Diodes
|
||||
- 3X M3x5mx4mm Heatset inserts
|
||||
- 3X M3x16mm Bolts
|
||||
- 1x XIAO RP2040
|
||||
- 1x 0.91" 128x64 OLED Display
|
||||
|
||||
## Extras
|
||||
First time using [RMK](https://haobogu.github.io/rmk) for firmware. It was WAY easier compared to other firmware options.
|
||||
Highly reccomend if you don't need additional features.
|
||||
BIN
hackpads/woagpad/assets/PCB-Back.png
Normal file
BIN
hackpads/woagpad/assets/PCB-Back.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 85 KiB |
BIN
hackpads/woagpad/assets/PCB-Front.png
Normal file
BIN
hackpads/woagpad/assets/PCB-Front.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 98 KiB |
BIN
hackpads/woagpad/assets/Schematic.png
Normal file
BIN
hackpads/woagpad/assets/Schematic.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 59 KiB |
BIN
hackpads/woagpad/assets/Woagpad-Construct.png
Normal file
BIN
hackpads/woagpad/assets/Woagpad-Construct.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 494 KiB |
BIN
hackpads/woagpad/assets/Woagpad-Render.png
Normal file
BIN
hackpads/woagpad/assets/Woagpad-Render.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 987 KiB |
9
hackpads/woagpad/firmware/.cargo/config.toml
Normal file
9
hackpads/woagpad/firmware/.cargo/config.toml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
||||
runner = "probe-rs run --chip RP2040"
|
||||
# runner = "elf2uf2-rs -d"
|
||||
|
||||
[build]
|
||||
target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
|
||||
|
||||
[env]
|
||||
DEFMT_LOG = "debug"
|
||||
10
hackpads/woagpad/firmware/.gitignore
vendored
Normal file
10
hackpads/woagpad/firmware/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
target
|
||||
|
||||
*.bin
|
||||
*.elf
|
||||
*.hex
|
||||
*.uf2
|
||||
|
||||
.embuild
|
||||
|
||||
.DS_Store
|
||||
2133
hackpads/woagpad/firmware/Cargo.lock
generated
Normal file
2133
hackpads/woagpad/firmware/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
62
hackpads/woagpad/firmware/Cargo.toml
Normal file
62
hackpads/woagpad/firmware/Cargo.toml
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
[package]
|
||||
name = "firmware"
|
||||
version = "0.1.0"
|
||||
authors = ["Haobo Gu <haobogu@outlook.com>"]
|
||||
description = "Keyboard firmware written in Rust"
|
||||
homepage = "https://github.com/haobogu/rmk"
|
||||
repository = "https://github.com/haobogu/rmk"
|
||||
readme = "../../README.md"
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[dependencies]
|
||||
rmk = { version = "0.5" }
|
||||
embassy-time = { version = "0.4", features = ["defmt"] }
|
||||
embassy-rp = { version = "0.3", features = [
|
||||
"rp2040",
|
||||
"defmt",
|
||||
"time-driver",
|
||||
"critical-section-impl",
|
||||
] }
|
||||
embassy-executor = { version = "0.7", features = [
|
||||
"defmt",
|
||||
"arch-cortex-m",
|
||||
"executor-thread",
|
||||
"task-arena-size-32768",
|
||||
] }
|
||||
cortex-m-rt = "0.7.3"
|
||||
portable-atomic = { version = "1.5", features = ["critical-section"] }
|
||||
defmt = "0.3"
|
||||
defmt-rtt = "0.4"
|
||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
||||
embassy-futures = { version = "0.1.1", features = ["defmt"] }
|
||||
|
||||
# [features]
|
||||
# avoid having to use --allow-multiple-definition linker flag
|
||||
# on macOS with Apple Silicon at least
|
||||
# default = ["rp-pico/disable-intrinsics"]
|
||||
|
||||
[build-dependencies]
|
||||
xz2 = "0.1.7"
|
||||
json = "0.12"
|
||||
const-gen = "1.6"
|
||||
|
||||
[[bin]]
|
||||
name = "firmware"
|
||||
test = false
|
||||
bench = false
|
||||
|
||||
[profile.dev]
|
||||
codegen-units = 1 # better optimizations
|
||||
debug = true
|
||||
opt-level = 1
|
||||
overflow-checks = true
|
||||
lto = false
|
||||
panic = 'unwind'
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1 # better optimizations
|
||||
debug = true # no overhead for bare-metal
|
||||
opt-level = "z" # optimize for binary size
|
||||
overflow-checks = false
|
||||
lto = "fat"
|
||||
33
hackpads/woagpad/firmware/Makefile.toml
Normal file
33
hackpads/woagpad/firmware/Makefile.toml
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
[tasks.install-llvm-tools]
|
||||
install_crate = { rustup_component_name = "llvm-tools" }
|
||||
|
||||
[tasks.flip-link]
|
||||
install_crate = { crate_name = "flip-link", binary = "flip-link", test_arg = [
|
||||
"-h",
|
||||
] }
|
||||
|
||||
[tasks.objcopy]
|
||||
install_crate = { crate_name = "cargo-binutils", binary = "cargo", test_arg = [
|
||||
"objcopy",
|
||||
"--help",
|
||||
] }
|
||||
command = "cargo"
|
||||
args = ["objcopy", "--release", "--", "-O", "ihex", "firmware.hex"]
|
||||
dependencies = ["install-llvm-tools", "flip-link"]
|
||||
|
||||
[tasks.uf2]
|
||||
install_crate = { crate_name = "cargo-hex-to-uf2", binary = "cargo", test_arg = [
|
||||
"hex-to-uf2",
|
||||
"--help",
|
||||
] }
|
||||
command = "cargo"
|
||||
args = [
|
||||
"hex-to-uf2",
|
||||
"--input-path",
|
||||
"firmware.hex",
|
||||
"--output-path",
|
||||
"firmware.uf2",
|
||||
"--family",
|
||||
"rp2040",
|
||||
]
|
||||
dependencies = ["objcopy"]
|
||||
53
hackpads/woagpad/firmware/README.md
Normal file
53
hackpads/woagpad/firmware/README.md
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
# RMK
|
||||
|
||||
RMK is a feature-rich and easy-to-use keyboard firmware.
|
||||
|
||||
## Use the template
|
||||
|
||||
1. Install [probe-rs](https://github.com/probe-rs/probe-rs)
|
||||
|
||||
```shell
|
||||
# Linux/macOS
|
||||
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/probe-rs/probe-rs/releases/latest/download/probe-rs-tools-installer.sh | sh
|
||||
|
||||
# Windows
|
||||
irm https://github.com/probe-rs/probe-rs/releases/latest/download/probe-rs-tools-installer.ps1 | iex
|
||||
```
|
||||
|
||||
2. Build the firmware
|
||||
|
||||
```shell
|
||||
cargo build --release
|
||||
```
|
||||
|
||||
3. Flash using debug probe
|
||||
|
||||
If you have a debug probe connected to your rp2040 board, flashing is quite simple: run the following command to automatically compile and flash RMK firmware to the board:
|
||||
|
||||
```shell
|
||||
cargo run --release
|
||||
```
|
||||
|
||||
4. (Optional) Flash using USB
|
||||
|
||||
If you don't have a debug probe, you can use `elf2uf2-rs` to flash your rp2040 firmware via USB. There are several additional steps you have to do:
|
||||
|
||||
1. Install `elf2uf2-rs`: `cargo install elf2uf2-rs`
|
||||
2. Update `.cargo/config.toml`, use `elf2uf2` as the flashing tool
|
||||
```diff
|
||||
- runner = "probe-rs run --chip RP2040"
|
||||
+ runner = "elf2uf2-rs -d"
|
||||
```
|
||||
3. Connect your rp2040 board holding the BOOTSEL key, ensure that rp's USB drive appears
|
||||
4. Flash
|
||||
```shell
|
||||
cargo run --release
|
||||
```
|
||||
Then, you will see logs like if everything goes right:
|
||||
```shell
|
||||
Finished release [optimized + debuginfo] target(s) in 0.21s
|
||||
Running `elf2uf2-rs -d 'target\thumbv6m-none-eabi\release\rmk-rp2040'`
|
||||
Found pico uf2 disk G:\
|
||||
Transfering program to pico
|
||||
173.00 KB / 173.00 KB [=======================] 100.00 % 193.64 KB/s
|
||||
```
|
||||
85
hackpads/woagpad/firmware/build.rs
Normal file
85
hackpads/woagpad/firmware/build.rs
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
//! This build script copies the `memory.x` file from the crate root into
|
||||
//! a directory where the linker can always find it at build time.
|
||||
//! For many projects this is optional, as the linker always searches the
|
||||
//! project root directory -- wherever `Cargo.toml` is. However, if you
|
||||
//! are using a workspace or have a more complicated build setup, this
|
||||
//! build script becomes required. Additionally, by requesting that
|
||||
//! Cargo re-run the build script whenever `memory.x` is changed,
|
||||
//! updating `memory.x` ensures a rebuild of the application with the
|
||||
//! new memory settings.
|
||||
//!
|
||||
//! The build script also sets the linker flags to tell it which link script to use.
|
||||
|
||||
use const_gen::*;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{env, fs};
|
||||
use xz2::read::XzEncoder;
|
||||
|
||||
fn main() {
|
||||
// Generate vial config at the root of project
|
||||
println!("cargo:rerun-if-changed=vial.json");
|
||||
generate_vial_config();
|
||||
|
||||
// Put `memory.x` in our output directory and ensure it's
|
||||
// on the linker search path.
|
||||
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||
File::create(out.join("memory.x"))
|
||||
.unwrap()
|
||||
.write_all(include_bytes!("memory.x"))
|
||||
.unwrap();
|
||||
println!("cargo:rustc-link-search={}", out.display());
|
||||
|
||||
// By default, Cargo will re-run a build script whenever
|
||||
// any file in the project changes. By specifying `memory.x`
|
||||
// here, we ensure the build script is only re-run when
|
||||
// `memory.x` is changed.
|
||||
println!("cargo:rerun-if-changed=memory.x");
|
||||
|
||||
println!("cargo:rerun-if-changed=keyboard.toml");
|
||||
|
||||
// Specify linker arguments.
|
||||
|
||||
// `--nmagic` is required if memory section addresses are not aligned to 0x10000,
|
||||
// for example the FLASH and RAM sections in your `memory.x`.
|
||||
// See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
|
||||
println!("cargo:rustc-link-arg=--nmagic");
|
||||
|
||||
// Set the linker script to the one provided by cortex-m-rt.
|
||||
println!("cargo:rustc-link-arg=-Tlink.x");
|
||||
|
||||
// Set the linker script of the defmt
|
||||
println!("cargo:rustc-link-arg=-Tdefmt.x");
|
||||
|
||||
println!("cargo:rustc-linker=flip-link");
|
||||
}
|
||||
|
||||
fn generate_vial_config() {
|
||||
// Generated vial config file
|
||||
let out_file = Path::new(&env::var_os("OUT_DIR").unwrap()).join("config_generated.rs");
|
||||
|
||||
let p = Path::new("vial.json");
|
||||
let mut content = String::new();
|
||||
match File::open(p) {
|
||||
Ok(mut file) => {
|
||||
file.read_to_string(&mut content)
|
||||
.expect("Cannot read vial.json");
|
||||
}
|
||||
Err(e) => println!("Cannot find vial.json {:?}: {}", p, e),
|
||||
};
|
||||
|
||||
let vial_cfg = json::stringify(json::parse(&content).unwrap());
|
||||
let mut keyboard_def_compressed: Vec<u8> = Vec::new();
|
||||
XzEncoder::new(vial_cfg.as_bytes(), 6)
|
||||
.read_to_end(&mut keyboard_def_compressed)
|
||||
.unwrap();
|
||||
|
||||
let keyboard_id: Vec<u8> = vec![0xB9, 0xBC, 0x09, 0xB2, 0x9D, 0x37, 0x4C, 0xEA];
|
||||
let const_declarations = [
|
||||
const_declaration!(pub VIAL_KEYBOARD_DEF = keyboard_def_compressed),
|
||||
const_declaration!(pub VIAL_KEYBOARD_ID = keyboard_id),
|
||||
]
|
||||
.join("\n");
|
||||
fs::write(out_file, const_declarations).unwrap();
|
||||
}
|
||||
34
hackpads/woagpad/firmware/keyboard-layout.json
Normal file
34
hackpads/woagpad/firmware/keyboard-layout.json
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[
|
||||
[
|
||||
"0,0\n\n\n\n\n\n\n\n\ne",
|
||||
{
|
||||
"x": 1
|
||||
},
|
||||
"1,0\n\n\n\n\n\n\n\n\ne"
|
||||
],
|
||||
[
|
||||
"0,1\n\n\n\n\n\n\n\n\ne",
|
||||
{
|
||||
"x": 1
|
||||
},
|
||||
"1,1\n\n\n\n\n\n\n\n\ne"
|
||||
],
|
||||
[
|
||||
{
|
||||
"y": 0.25
|
||||
},
|
||||
"0,0",
|
||||
"0,1",
|
||||
"0,2"
|
||||
],
|
||||
[
|
||||
"1,0",
|
||||
"1,1",
|
||||
"1,2"
|
||||
],
|
||||
[
|
||||
"2,0",
|
||||
"2,1",
|
||||
"2,2"
|
||||
]
|
||||
]
|
||||
48
hackpads/woagpad/firmware/keyboard.toml
Normal file
48
hackpads/woagpad/firmware/keyboard.toml
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
[keyboard]
|
||||
name = "firmware"
|
||||
product_name = "firmware"
|
||||
vendor_id = 0x4c4b
|
||||
product_id = 0x4643
|
||||
manufacturer = "rmk"
|
||||
chip = "rp2040"
|
||||
|
||||
[matrix]
|
||||
# Input and output pins are mandatory
|
||||
input_pins = ["PIN_6", "PIN_7", "PIN_8", "PIN_9"]
|
||||
output_pins = ["PIN_19", "PIN_20", "PIN_21"]
|
||||
# WARNING: Currently row2col/col2row is set in RMK's feature gate, configs here do nothing actually
|
||||
# row2col = true
|
||||
|
||||
[layout]
|
||||
rows = 4
|
||||
cols = 3
|
||||
layers = 2
|
||||
keymap = [
|
||||
[
|
||||
["A", "B", "C"],
|
||||
["Kc1", "Kc2", "Kc3"],
|
||||
["LCtrl", "MO(1)", "LShift"],
|
||||
["OSL(1)", "LT(2, Kc9)", "LM(1, LShift | LGui)"]
|
||||
],
|
||||
[
|
||||
["_", "TT(1)", "TG(2)"],
|
||||
["_", "_", "_"],
|
||||
["_", "_", "_"],
|
||||
["_", "_", "_"]
|
||||
],
|
||||
]
|
||||
|
||||
[light]
|
||||
# All light pins are high-active by default, uncomment if you want it to be low-active
|
||||
# capslock.pin = "PB2"
|
||||
# capslock.low_active = true
|
||||
# scrolllock.pin = "PA3"
|
||||
# scrolllock.low_active = true
|
||||
# Just ignore if no light pin is used for it
|
||||
# numslock.pin = "PA5"
|
||||
# numslock.low_active = true
|
||||
|
||||
|
||||
[storage]
|
||||
# Storage feature is enabled by default
|
||||
# enabled = false
|
||||
15
hackpads/woagpad/firmware/memory.x
Normal file
15
hackpads/woagpad/firmware/memory.x
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
MEMORY {
|
||||
BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100
|
||||
FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100
|
||||
RAM : ORIGIN = 0x20000000, LENGTH = 256K
|
||||
}
|
||||
|
||||
EXTERN(BOOT2_FIRMWARE)
|
||||
|
||||
SECTIONS {
|
||||
/* ### Boot loader */
|
||||
.boot2 ORIGIN(BOOT2) :
|
||||
{
|
||||
KEEP(*(.boot2));
|
||||
} > BOOT2
|
||||
} INSERT BEFORE .text;
|
||||
6
hackpads/woagpad/firmware/openocd.cfg
Normal file
6
hackpads/woagpad/firmware/openocd.cfg
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
source [find interface/cmsis-dap.cfg]
|
||||
transport select swd
|
||||
|
||||
source [find target/rp2040.cfg]
|
||||
|
||||
adapter speed 10000
|
||||
46401
hackpads/woagpad/firmware/rp2040.svd
Normal file
46401
hackpads/woagpad/firmware/rp2040.svd
Normal file
File diff suppressed because it is too large
Load diff
6
hackpads/woagpad/firmware/rust-toolchain.toml
Normal file
6
hackpads/woagpad/firmware/rust-toolchain.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[toolchain]
|
||||
channel = "stable"
|
||||
components = ["rust-src", "rustfmt", "llvm-tools"]
|
||||
targets = [
|
||||
"thumbv6m-none-eabi",
|
||||
]
|
||||
704
hackpads/woagpad/firmware/scripts/uf2conv.py
Normal file
704
hackpads/woagpad/firmware/scripts/uf2conv.py
Normal file
|
|
@ -0,0 +1,704 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import struct
|
||||
import subprocess
|
||||
import re
|
||||
import os
|
||||
import os.path
|
||||
import argparse
|
||||
import json
|
||||
from time import sleep
|
||||
|
||||
chip_families = [
|
||||
{
|
||||
"id": "0x16573617",
|
||||
"short_name": "ATMEGA32",
|
||||
"description": "Microchip (Atmel) ATmega32"
|
||||
},
|
||||
{
|
||||
"id": "0x1851780a",
|
||||
"short_name": "SAML21",
|
||||
"description": "Microchip (Atmel) SAML21"
|
||||
},
|
||||
{
|
||||
"id": "0x1b57745f",
|
||||
"short_name": "NRF52",
|
||||
"description": "Nordic NRF52"
|
||||
},
|
||||
{
|
||||
"id": "0x1c5f21b0",
|
||||
"short_name": "ESP32",
|
||||
"description": "ESP32"
|
||||
},
|
||||
{
|
||||
"id": "0x1e1f432d",
|
||||
"short_name": "STM32L1",
|
||||
"description": "ST STM32L1xx"
|
||||
},
|
||||
{
|
||||
"id": "0x202e3a91",
|
||||
"short_name": "STM32L0",
|
||||
"description": "ST STM32L0xx"
|
||||
},
|
||||
{
|
||||
"id": "0x21460ff0",
|
||||
"short_name": "STM32WL",
|
||||
"description": "ST STM32WLxx"
|
||||
},
|
||||
{
|
||||
"id": "0x22e0d6fc",
|
||||
"short_name": "RTL8710B",
|
||||
"description": "Realtek AmebaZ RTL8710B"
|
||||
},
|
||||
{
|
||||
"id": "0x2abc77ec",
|
||||
"short_name": "LPC55",
|
||||
"description": "NXP LPC55xx"
|
||||
},
|
||||
{
|
||||
"id": "0x300f5633",
|
||||
"short_name": "STM32G0",
|
||||
"description": "ST STM32G0xx"
|
||||
},
|
||||
{
|
||||
"id": "0x31d228c6",
|
||||
"short_name": "GD32F350",
|
||||
"description": "GD32F350"
|
||||
},
|
||||
{
|
||||
"id": "0x3379CFE2",
|
||||
"short_name": "RTL8720D",
|
||||
"description": "Realtek AmebaD RTL8720D"
|
||||
},
|
||||
{
|
||||
"id": "0x04240bdf",
|
||||
"short_name": "STM32L5",
|
||||
"description": "ST STM32L5xx"
|
||||
},
|
||||
{
|
||||
"id": "0x4c71240a",
|
||||
"short_name": "STM32G4",
|
||||
"description": "ST STM32G4xx"
|
||||
},
|
||||
{
|
||||
"id": "0x4fb2d5bd",
|
||||
"short_name": "MIMXRT10XX",
|
||||
"description": "NXP i.MX RT10XX"
|
||||
},
|
||||
{
|
||||
"id": "0x51e903a8",
|
||||
"short_name": "XR809",
|
||||
"description": "Xradiotech 809"
|
||||
},
|
||||
{
|
||||
"id": "0x53b80f00",
|
||||
"short_name": "STM32F7",
|
||||
"description": "ST STM32F7xx"
|
||||
},
|
||||
{
|
||||
"id": "0x55114460",
|
||||
"short_name": "SAMD51",
|
||||
"description": "Microchip (Atmel) SAMD51"
|
||||
},
|
||||
{
|
||||
"id": "0x57755a57",
|
||||
"short_name": "STM32F4",
|
||||
"description": "ST STM32F4xx"
|
||||
},
|
||||
{
|
||||
"id": "0x5a18069b",
|
||||
"short_name": "FX2",
|
||||
"description": "Cypress FX2"
|
||||
},
|
||||
{
|
||||
"id": "0x5d1a0a2e",
|
||||
"short_name": "STM32F2",
|
||||
"description": "ST STM32F2xx"
|
||||
},
|
||||
{
|
||||
"id": "0x5ee21072",
|
||||
"short_name": "STM32F1",
|
||||
"description": "ST STM32F103"
|
||||
},
|
||||
{
|
||||
"id": "0x621e937a",
|
||||
"short_name": "NRF52833",
|
||||
"description": "Nordic NRF52833"
|
||||
},
|
||||
{
|
||||
"id": "0x647824b6",
|
||||
"short_name": "STM32F0",
|
||||
"description": "ST STM32F0xx"
|
||||
},
|
||||
{
|
||||
"id": "0x675a40b0",
|
||||
"short_name": "BK7231U",
|
||||
"description": "Beken 7231U/7231T"
|
||||
},
|
||||
{
|
||||
"id": "0x68ed2b88",
|
||||
"short_name": "SAMD21",
|
||||
"description": "Microchip (Atmel) SAMD21"
|
||||
},
|
||||
{
|
||||
"id": "0x6a82cc42",
|
||||
"short_name": "BK7251",
|
||||
"description": "Beken 7251/7252"
|
||||
},
|
||||
{
|
||||
"id": "0x6b846188",
|
||||
"short_name": "STM32F3",
|
||||
"description": "ST STM32F3xx"
|
||||
},
|
||||
{
|
||||
"id": "0x6d0922fa",
|
||||
"short_name": "STM32F407",
|
||||
"description": "ST STM32F407"
|
||||
},
|
||||
{
|
||||
"id": "0x6db66082",
|
||||
"short_name": "STM32H7",
|
||||
"description": "ST STM32H7xx"
|
||||
},
|
||||
{
|
||||
"id": "0x70d16653",
|
||||
"short_name": "STM32WB",
|
||||
"description": "ST STM32WBxx"
|
||||
},
|
||||
{
|
||||
"id": "0x7b3ef230",
|
||||
"short_name": "BK7231N",
|
||||
"description": "Beken 7231N"
|
||||
},
|
||||
{
|
||||
"id": "0x7eab61ed",
|
||||
"short_name": "ESP8266",
|
||||
"description": "ESP8266"
|
||||
},
|
||||
{
|
||||
"id": "0x7f83e793",
|
||||
"short_name": "KL32L2",
|
||||
"description": "NXP KL32L2x"
|
||||
},
|
||||
{
|
||||
"id": "0x8fb060fe",
|
||||
"short_name": "STM32F407VG",
|
||||
"description": "ST STM32F407VG"
|
||||
},
|
||||
{
|
||||
"id": "0x9fffd543",
|
||||
"short_name": "RTL8710A",
|
||||
"description": "Realtek Ameba1 RTL8710A"
|
||||
},
|
||||
{
|
||||
"id": "0xada52840",
|
||||
"short_name": "NRF52840",
|
||||
"description": "Nordic NRF52840"
|
||||
},
|
||||
{
|
||||
"id": "0xbfdd4eee",
|
||||
"short_name": "ESP32S2",
|
||||
"description": "ESP32-S2"
|
||||
},
|
||||
{
|
||||
"id": "0xc47e5767",
|
||||
"short_name": "ESP32S3",
|
||||
"description": "ESP32-S3"
|
||||
},
|
||||
{
|
||||
"id": "0xd42ba06c",
|
||||
"short_name": "ESP32C3",
|
||||
"description": "ESP32-C3"
|
||||
},
|
||||
{
|
||||
"id": "0x2b88d29c",
|
||||
"short_name": "ESP32C2",
|
||||
"description": "ESP32-C2"
|
||||
},
|
||||
{
|
||||
"id": "0x332726f6",
|
||||
"short_name": "ESP32H2",
|
||||
"description": "ESP32-H2"
|
||||
},
|
||||
{
|
||||
"id": "0x540ddf62",
|
||||
"short_name": "ESP32C6",
|
||||
"description": "ESP32-C6"
|
||||
},
|
||||
{
|
||||
"id": "0x3d308e94",
|
||||
"short_name": "ESP32P4",
|
||||
"description": "ESP32-P4"
|
||||
},
|
||||
{
|
||||
"id": "0xf71c0343",
|
||||
"short_name": "ESP32C5",
|
||||
"description": "ESP32-C5"
|
||||
},
|
||||
{
|
||||
"id": "0x77d850c4",
|
||||
"short_name": "ESP32C61",
|
||||
"description": "ESP32-C61"
|
||||
},
|
||||
{
|
||||
"id": "0xde1270b7",
|
||||
"short_name": "BL602",
|
||||
"description": "Boufallo 602"
|
||||
},
|
||||
{
|
||||
"id": "0xe08f7564",
|
||||
"short_name": "RTL8720C",
|
||||
"description": "Realtek AmebaZ2 RTL8720C"
|
||||
},
|
||||
{
|
||||
"id": "0xe48bff56",
|
||||
"short_name": "RP2040",
|
||||
"description": "Raspberry Pi RP2040"
|
||||
},
|
||||
{
|
||||
"id": "0xe48bff57",
|
||||
"short_name": "RP2XXX_ABSOLUTE",
|
||||
"description": "Raspberry Pi Microcontrollers: Absolute (unpartitioned) download"
|
||||
},
|
||||
{
|
||||
"id": "0xe48bff58",
|
||||
"short_name": "RP2XXX_DATA",
|
||||
"description": "Raspberry Pi Microcontrollers: Data partition download"
|
||||
},
|
||||
{
|
||||
"id": "0xe48bff59",
|
||||
"short_name": "RP2350_ARM_S",
|
||||
"description": "Raspberry Pi RP2350, Secure Arm image"
|
||||
},
|
||||
{
|
||||
"id": "0xe48bff5a",
|
||||
"short_name": "RP2350_RISCV",
|
||||
"description": "Raspberry Pi RP2350, RISC-V image"
|
||||
},
|
||||
{
|
||||
"id": "0xe48bff5b",
|
||||
"short_name": "RP2350_ARM_NS",
|
||||
"description": "Raspberry Pi RP2350, Non-secure Arm image"
|
||||
},
|
||||
{
|
||||
"id": "0x00ff6919",
|
||||
"short_name": "STM32L4",
|
||||
"description": "ST STM32L4xx"
|
||||
},
|
||||
{
|
||||
"id": "0x9af03e33",
|
||||
"short_name": "GD32VF103",
|
||||
"description": "GigaDevice GD32VF103"
|
||||
},
|
||||
{
|
||||
"id": "0x4f6ace52",
|
||||
"short_name": "CSK4",
|
||||
"description": "LISTENAI CSK300x/400x"
|
||||
},
|
||||
{
|
||||
"id": "0x6e7348a8",
|
||||
"short_name": "CSK6",
|
||||
"description": "LISTENAI CSK60xx"
|
||||
},
|
||||
{
|
||||
"id": "0x11de784a",
|
||||
"short_name": "M0SENSE",
|
||||
"description": "M0SENSE BL702"
|
||||
},
|
||||
{
|
||||
"id": "0x4b684d71",
|
||||
"short_name": "MaixPlay-U4",
|
||||
"description": "Sipeed MaixPlay-U4(BL618)"
|
||||
},
|
||||
{
|
||||
"id": "0x9517422f",
|
||||
"short_name": "RZA1LU",
|
||||
"description": "Renesas RZ/A1LU (R7S7210xx)"
|
||||
},
|
||||
{
|
||||
"id": "0x2dc309c5",
|
||||
"short_name": "STM32F411xE",
|
||||
"description": "ST STM32F411xE"
|
||||
},
|
||||
{
|
||||
"id": "0x06d1097b",
|
||||
"short_name": "STM32F411xC",
|
||||
"description": "ST STM32F411xC"
|
||||
},
|
||||
{
|
||||
"id": "0x72721d4e",
|
||||
"short_name": "NRF52832xxAA",
|
||||
"description": "Nordic NRF52832xxAA"
|
||||
},
|
||||
{
|
||||
"id": "0x6f752678",
|
||||
"short_name": "NRF52832xxAB",
|
||||
"description": "Nordic NRF52832xxAB"
|
||||
},
|
||||
{
|
||||
"id": "0xa0c97b8e",
|
||||
"short_name": "AT32F415",
|
||||
"description": "ArteryTek AT32F415"
|
||||
},
|
||||
{
|
||||
"id": "0x699b62ec",
|
||||
"short_name": "CH32V",
|
||||
"description": "WCH CH32V2xx and CH32V3xx"
|
||||
},
|
||||
{
|
||||
"id": "0x7be8976d",
|
||||
"short_name": "RA4M1",
|
||||
"description": "Renesas RA4M1"
|
||||
}
|
||||
]
|
||||
|
||||
UF2_MAGIC_START0 = 0x0A324655 # "UF2\n"
|
||||
UF2_MAGIC_START1 = 0x9E5D5157 # Randomly selected
|
||||
UF2_MAGIC_END = 0x0AB16F30 # Ditto
|
||||
|
||||
INFO_FILE = "/INFO_UF2.TXT"
|
||||
|
||||
appstartaddr = 0x2000
|
||||
familyid = 0x0
|
||||
|
||||
|
||||
def is_uf2(buf):
|
||||
w = struct.unpack("<II", buf[0:8])
|
||||
return w[0] == UF2_MAGIC_START0 and w[1] == UF2_MAGIC_START1
|
||||
|
||||
def is_hex(buf):
|
||||
try:
|
||||
w = buf[0:30].decode("utf-8")
|
||||
except UnicodeDecodeError:
|
||||
return False
|
||||
if w[0] == ':' and re.match(rb"^[:0-9a-fA-F\r\n]+$", buf):
|
||||
return True
|
||||
return False
|
||||
|
||||
def convert_from_uf2(buf):
|
||||
global appstartaddr
|
||||
global familyid
|
||||
numblocks = len(buf) // 512
|
||||
curraddr = None
|
||||
currfamilyid = None
|
||||
families_found = {}
|
||||
prev_flag = None
|
||||
all_flags_same = True
|
||||
outp = []
|
||||
for blockno in range(numblocks):
|
||||
ptr = blockno * 512
|
||||
block = buf[ptr:ptr + 512]
|
||||
hd = struct.unpack(b"<IIIIIIII", block[0:32])
|
||||
if hd[0] != UF2_MAGIC_START0 or hd[1] != UF2_MAGIC_START1:
|
||||
print("Skipping block at " + ptr + "; bad magic")
|
||||
continue
|
||||
if hd[2] & 1:
|
||||
# NO-flash flag set; skip block
|
||||
continue
|
||||
datalen = hd[4]
|
||||
if datalen > 476:
|
||||
assert False, "Invalid UF2 data size at " + ptr
|
||||
newaddr = hd[3]
|
||||
if (hd[2] & 0x2000) and (currfamilyid == None):
|
||||
currfamilyid = hd[7]
|
||||
if curraddr == None or ((hd[2] & 0x2000) and hd[7] != currfamilyid):
|
||||
currfamilyid = hd[7]
|
||||
curraddr = newaddr
|
||||
if familyid == 0x0 or familyid == hd[7]:
|
||||
appstartaddr = newaddr
|
||||
padding = newaddr - curraddr
|
||||
if padding < 0:
|
||||
assert False, "Block out of order at " + ptr
|
||||
if padding > 10*1024*1024:
|
||||
assert False, "More than 10M of padding needed at " + ptr
|
||||
if padding % 4 != 0:
|
||||
assert False, "Non-word padding size at " + ptr
|
||||
while padding > 0:
|
||||
padding -= 4
|
||||
outp.append(b"\x00\x00\x00\x00")
|
||||
if familyid == 0x0 or ((hd[2] & 0x2000) and familyid == hd[7]):
|
||||
outp.append(block[32 : 32 + datalen])
|
||||
curraddr = newaddr + datalen
|
||||
if hd[2] & 0x2000:
|
||||
if hd[7] in families_found.keys():
|
||||
if families_found[hd[7]] > newaddr:
|
||||
families_found[hd[7]] = newaddr
|
||||
else:
|
||||
families_found[hd[7]] = newaddr
|
||||
if prev_flag == None:
|
||||
prev_flag = hd[2]
|
||||
if prev_flag != hd[2]:
|
||||
all_flags_same = False
|
||||
if blockno == (numblocks - 1):
|
||||
print("--- UF2 File Header Info ---")
|
||||
families = load_families()
|
||||
for family_hex in families_found.keys():
|
||||
family_short_name = ""
|
||||
for name, value in families.items():
|
||||
if value == family_hex:
|
||||
family_short_name = name
|
||||
print("Family ID is {:s}, hex value is 0x{:08x}".format(family_short_name,family_hex))
|
||||
print("Target Address is 0x{:08x}".format(families_found[family_hex]))
|
||||
if all_flags_same:
|
||||
print("All block flag values consistent, 0x{:04x}".format(hd[2]))
|
||||
else:
|
||||
print("Flags were not all the same")
|
||||
print("----------------------------")
|
||||
if len(families_found) > 1 and familyid == 0x0:
|
||||
outp = []
|
||||
appstartaddr = 0x0
|
||||
return b"".join(outp)
|
||||
|
||||
def convert_to_carray(file_content):
|
||||
outp = "const unsigned long bindata_len = %d;\n" % len(file_content)
|
||||
outp += "const unsigned char bindata[] __attribute__((aligned(16))) = {"
|
||||
for i in range(len(file_content)):
|
||||
if i % 16 == 0:
|
||||
outp += "\n"
|
||||
outp += "0x%02x, " % file_content[i]
|
||||
outp += "\n};\n"
|
||||
return bytes(outp, "utf-8")
|
||||
|
||||
def convert_to_uf2(file_content):
|
||||
global familyid
|
||||
datapadding = b""
|
||||
while len(datapadding) < 512 - 256 - 32 - 4:
|
||||
datapadding += b"\x00\x00\x00\x00"
|
||||
numblocks = (len(file_content) + 255) // 256
|
||||
outp = []
|
||||
for blockno in range(numblocks):
|
||||
ptr = 256 * blockno
|
||||
chunk = file_content[ptr:ptr + 256]
|
||||
flags = 0x0
|
||||
if familyid:
|
||||
flags |= 0x2000
|
||||
hd = struct.pack(b"<IIIIIIII",
|
||||
UF2_MAGIC_START0, UF2_MAGIC_START1,
|
||||
flags, ptr + appstartaddr, 256, blockno, numblocks, familyid)
|
||||
while len(chunk) < 256:
|
||||
chunk += b"\x00"
|
||||
block = hd + chunk + datapadding + struct.pack(b"<I", UF2_MAGIC_END)
|
||||
assert len(block) == 512
|
||||
outp.append(block)
|
||||
return b"".join(outp)
|
||||
|
||||
class Block:
|
||||
def __init__(self, addr):
|
||||
self.addr = addr
|
||||
self.bytes = bytearray(256)
|
||||
|
||||
def encode(self, blockno, numblocks):
|
||||
global familyid
|
||||
flags = 0x0
|
||||
if familyid:
|
||||
flags |= 0x2000
|
||||
hd = struct.pack("<IIIIIIII",
|
||||
UF2_MAGIC_START0, UF2_MAGIC_START1,
|
||||
flags, self.addr, 256, blockno, numblocks, familyid)
|
||||
hd += self.bytes[0:256]
|
||||
while len(hd) < 512 - 4:
|
||||
hd += b"\x00"
|
||||
hd += struct.pack("<I", UF2_MAGIC_END)
|
||||
return hd
|
||||
|
||||
def convert_from_hex_to_uf2(buf):
|
||||
global appstartaddr
|
||||
appstartaddr = None
|
||||
upper = 0
|
||||
currblock = None
|
||||
blocks = []
|
||||
for line in buf.split('\n'):
|
||||
if line[0] != ":":
|
||||
continue
|
||||
i = 1
|
||||
rec = []
|
||||
while i < len(line) - 1:
|
||||
rec.append(int(line[i:i+2], 16))
|
||||
i += 2
|
||||
tp = rec[3]
|
||||
if tp == 4:
|
||||
upper = ((rec[4] << 8) | rec[5]) << 16
|
||||
elif tp == 2:
|
||||
upper = ((rec[4] << 8) | rec[5]) << 4
|
||||
elif tp == 1:
|
||||
break
|
||||
elif tp == 0:
|
||||
addr = upper + ((rec[1] << 8) | rec[2])
|
||||
if appstartaddr == None:
|
||||
appstartaddr = addr
|
||||
i = 4
|
||||
while i < len(rec) - 1:
|
||||
if not currblock or currblock.addr & ~0xff != addr & ~0xff:
|
||||
currblock = Block(addr & ~0xff)
|
||||
blocks.append(currblock)
|
||||
currblock.bytes[addr & 0xff] = rec[i]
|
||||
addr += 1
|
||||
i += 1
|
||||
numblocks = len(blocks)
|
||||
resfile = b""
|
||||
for i in range(0, numblocks):
|
||||
resfile += blocks[i].encode(i, numblocks)
|
||||
return resfile
|
||||
|
||||
def to_str(b):
|
||||
return b.decode("utf-8")
|
||||
|
||||
def get_drives():
|
||||
drives = []
|
||||
if sys.platform == "win32":
|
||||
r = subprocess.check_output(["wmic", "PATH", "Win32_LogicalDisk",
|
||||
"get", "DeviceID,", "VolumeName,",
|
||||
"FileSystem,", "DriveType"])
|
||||
for line in to_str(r).split('\n'):
|
||||
words = re.split(r'\s+', line)
|
||||
if len(words) >= 3 and words[1] == "2" and words[2] == "FAT":
|
||||
drives.append(words[0])
|
||||
else:
|
||||
searchpaths = ["/media"]
|
||||
if sys.platform == "darwin":
|
||||
searchpaths = ["/Volumes"]
|
||||
elif sys.platform == "linux":
|
||||
searchpaths += ["/media/" + os.environ["USER"], '/run/media/' + os.environ["USER"]]
|
||||
|
||||
for rootpath in searchpaths:
|
||||
if os.path.isdir(rootpath):
|
||||
for d in os.listdir(rootpath):
|
||||
if os.path.isdir(rootpath):
|
||||
drives.append(os.path.join(rootpath, d))
|
||||
|
||||
|
||||
def has_info(d):
|
||||
try:
|
||||
return os.path.isfile(d + INFO_FILE)
|
||||
except:
|
||||
return False
|
||||
|
||||
return list(filter(has_info, drives))
|
||||
|
||||
|
||||
def board_id(path):
|
||||
with open(path + INFO_FILE, mode='r') as file:
|
||||
file_content = file.read()
|
||||
return re.search(r"Board-ID: ([^\r\n]*)", file_content).group(1)
|
||||
|
||||
|
||||
def list_drives():
|
||||
for d in get_drives():
|
||||
print(d, board_id(d))
|
||||
|
||||
|
||||
def write_file(name, buf):
|
||||
with open(name, "wb") as f:
|
||||
f.write(buf)
|
||||
print("Wrote %d bytes to %s" % (len(buf), name))
|
||||
|
||||
|
||||
def load_families():
|
||||
# The expectation is that the `uf2families.json` file is in the same
|
||||
# directory as this script. Make a path that works using `__file__`
|
||||
# which contains the full path to this script.
|
||||
# filename = "uf2families.json"
|
||||
# pathname = os.path.join(os.path.dirname(os.path.abspath(__file__)), filename)
|
||||
# with open(pathname) as f:
|
||||
# chip_families = json.load(f)
|
||||
|
||||
families = {}
|
||||
for family in chip_families:
|
||||
families[family["short_name"]] = int(family["id"], 0)
|
||||
|
||||
return families
|
||||
|
||||
|
||||
def main():
|
||||
global appstartaddr, familyid
|
||||
def error(msg):
|
||||
print(msg, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
parser = argparse.ArgumentParser(description='Convert to UF2 or flash directly.')
|
||||
parser.add_argument('input', metavar='INPUT', type=str, nargs='?',
|
||||
help='input file (HEX, BIN or UF2)')
|
||||
parser.add_argument('-b', '--base', dest='base', type=str,
|
||||
default="0x2000",
|
||||
help='set base address of application for BIN format (default: 0x2000)')
|
||||
parser.add_argument('-f', '--family', dest='family', type=str,
|
||||
default="0x0",
|
||||
help='specify familyID - number or name (default: 0x0)')
|
||||
parser.add_argument('-o', '--output', metavar="FILE", dest='output', type=str,
|
||||
help='write output to named file; defaults to "flash.uf2" or "flash.bin" where sensible')
|
||||
parser.add_argument('-d', '--device', dest="device_path",
|
||||
help='select a device path to flash')
|
||||
parser.add_argument('-l', '--list', action='store_true',
|
||||
help='list connected devices')
|
||||
parser.add_argument('-c', '--convert', action='store_true',
|
||||
help='do not flash, just convert')
|
||||
parser.add_argument('-D', '--deploy', action='store_true',
|
||||
help='just flash, do not convert')
|
||||
parser.add_argument('-w', '--wait', action='store_true',
|
||||
help='wait for device to flash')
|
||||
parser.add_argument('-C', '--carray', action='store_true',
|
||||
help='convert binary file to a C array, not UF2')
|
||||
parser.add_argument('-i', '--info', action='store_true',
|
||||
help='display header information from UF2, do not convert')
|
||||
args = parser.parse_args()
|
||||
appstartaddr = int(args.base, 0)
|
||||
|
||||
families = load_families()
|
||||
|
||||
if args.family.upper() in families:
|
||||
familyid = families[args.family.upper()]
|
||||
else:
|
||||
try:
|
||||
familyid = int(args.family, 0)
|
||||
except ValueError:
|
||||
error("Family ID needs to be a number or one of: " + ", ".join(families.keys()))
|
||||
|
||||
if args.list:
|
||||
list_drives()
|
||||
else:
|
||||
if not args.input:
|
||||
error("Need input file")
|
||||
with open(args.input, mode='rb') as f:
|
||||
inpbuf = f.read()
|
||||
from_uf2 = is_uf2(inpbuf)
|
||||
ext = "uf2"
|
||||
if args.deploy:
|
||||
outbuf = inpbuf
|
||||
elif from_uf2 and not args.info:
|
||||
outbuf = convert_from_uf2(inpbuf)
|
||||
ext = "bin"
|
||||
elif from_uf2 and args.info:
|
||||
outbuf = ""
|
||||
convert_from_uf2(inpbuf)
|
||||
elif is_hex(inpbuf):
|
||||
outbuf = convert_from_hex_to_uf2(inpbuf.decode("utf-8"))
|
||||
elif args.carray:
|
||||
outbuf = convert_to_carray(inpbuf)
|
||||
ext = "h"
|
||||
else:
|
||||
outbuf = convert_to_uf2(inpbuf)
|
||||
if not args.deploy and not args.info:
|
||||
print("Converted to %s, output size: %d, start address: 0x%x" %
|
||||
(ext, len(outbuf), appstartaddr))
|
||||
if args.convert or ext != "uf2":
|
||||
if args.output == None:
|
||||
args.output = "flash." + ext
|
||||
if args.output:
|
||||
write_file(args.output, outbuf)
|
||||
if ext == "uf2" and not args.convert and not args.info:
|
||||
drives = get_drives()
|
||||
if len(drives) == 0:
|
||||
if args.wait:
|
||||
print("Waiting for drive to deploy...")
|
||||
while len(drives) == 0:
|
||||
sleep(0.1)
|
||||
drives = get_drives()
|
||||
elif not args.output:
|
||||
error("No drive to deploy.")
|
||||
for d in drives:
|
||||
print("Flashing %s (%s)" % (d, board_id(d)))
|
||||
write_file(d + "/NEW.UF2", outbuf)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
35
hackpads/woagpad/firmware/src/keymap.rs
Normal file
35
hackpads/woagpad/firmware/src/keymap.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
use rmk::action::KeyAction;
|
||||
use rmk::{a, k, layer, mo};
|
||||
pub(crate) const COL: usize = 3;
|
||||
pub(crate) const ROW: usize = 3;
|
||||
pub(crate) const NUM_LAYER: usize = 2;
|
||||
pub(crate) const NUM_ENCODER: usize = 2;
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub fn get_default_keymap() -> [[[KeyAction; COL]; ROW]; NUM_LAYER] {
|
||||
[
|
||||
layer!([
|
||||
[k!(MediaPrevTrack), k!(MediaPlayPause), k!(MediaNextTrack)],
|
||||
[k!(Kp4), k!(LShift), k!(Kp6)],
|
||||
[mo!(1), k!(Kp2), k!(Kp3)]
|
||||
]),
|
||||
layer!([
|
||||
[k!(Kp7), k!(Kp8), k!(Kp9)],
|
||||
[k!(Kp4), k!(Kp5), k!(Kp6)],
|
||||
[mo!(0), k!(SecureUnlock), k!(Bootloader)]
|
||||
]),
|
||||
]
|
||||
}
|
||||
|
||||
pub fn get_default_encoder_map() -> [[(KeyAction, KeyAction); NUM_ENCODER]; NUM_LAYER] {
|
||||
[
|
||||
[
|
||||
(k!(KbVolumeUp), k!(KbVolumeDown)),
|
||||
(k!(KbVolumeUp), k!(KbVolumeDown)),
|
||||
],
|
||||
[
|
||||
(k!(KbVolumeUp), k!(KbVolumeDown)),
|
||||
(k!(KbVolumeUp), k!(KbVolumeDown)),
|
||||
],
|
||||
]
|
||||
}
|
||||
12
hackpads/woagpad/firmware/src/macros.rs
Normal file
12
hackpads/woagpad/firmware/src/macros.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
macro_rules! config_matrix_pins_rp {
|
||||
(peripherals: $p:ident, input: [$($in_pin:ident), *], output: [$($out_pin:ident), +]) => {
|
||||
{
|
||||
let mut output_pins = [$(Output::new(AnyPin::from($p.$out_pin), embassy_rp::gpio::Level::Low)), +];
|
||||
let input_pins = [$(Input::new(AnyPin::from($p.$in_pin), embassy_rp::gpio::Pull::Down)), +];
|
||||
output_pins.iter_mut().for_each(|p| {
|
||||
p.set_low();
|
||||
});
|
||||
(input_pins, output_pins)
|
||||
}
|
||||
};
|
||||
}
|
||||
94
hackpads/woagpad/firmware/src/main.rs
Normal file
94
hackpads/woagpad/firmware/src/main.rs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
#[macro_use]
|
||||
mod keymap;
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
mod vial;
|
||||
|
||||
use defmt::*;
|
||||
use defmt_rtt as _;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_rp::{
|
||||
bind_interrupts,
|
||||
flash::{Async, Flash},
|
||||
gpio::{AnyPin, Input, Output},
|
||||
peripherals::USB,
|
||||
usb::{Driver, InterruptHandler},
|
||||
Peripheral,
|
||||
};
|
||||
// use embassy_rp::flash::Blocking;
|
||||
use panic_probe as _;
|
||||
use rmk::{
|
||||
config::{KeyboardUsbConfig, RmkConfig, VialConfig},
|
||||
input_device::{rotary_encoder::RotaryEncoder, InputDevice},
|
||||
run_devices, run_rmk, run_rmk_with_async_flash,
|
||||
};
|
||||
use vial::{VIAL_KEYBOARD_DEF, VIAL_KEYBOARD_ID};
|
||||
|
||||
bind_interrupts!(struct Irqs {
|
||||
USBCTRL_IRQ => InterruptHandler<USB>;
|
||||
});
|
||||
|
||||
const FLASH_SIZE: usize = 2 * 1024 * 1024;
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(spawner: Spawner) {
|
||||
info!("RMK start!");
|
||||
// Initialize peripherals
|
||||
let p = embassy_rp::init(Default::default());
|
||||
|
||||
// Create the usb driver, from the HAL
|
||||
let driver = Driver::new(p.USB, Irqs);
|
||||
|
||||
// Pin config
|
||||
let (input_pins, output_pins) = config_matrix_pins_rp!(peripherals: p, input: [PIN_2, PIN_29, PIN_27], output: [PIN_28, PIN_0, PIN_1]);
|
||||
|
||||
// Use internal flash to emulate eeprom
|
||||
// Both blocking and async flash are support, use different API
|
||||
// let flash = Flash::<_, Blocking, FLASH_SIZE>::new_blocking(p.FLASH);
|
||||
let flash = Flash::<_, Async, FLASH_SIZE>::new(p.FLASH, p.DMA_CH0);
|
||||
|
||||
let keyboard_usb_config = KeyboardUsbConfig {
|
||||
vid: 0x4c4b,
|
||||
pid: 0x4643,
|
||||
manufacturer: "woagpad",
|
||||
product_name: "woagpad",
|
||||
serial_number: "vial:f64c2b3c:000001",
|
||||
};
|
||||
|
||||
let vial_config = VialConfig::new(VIAL_KEYBOARD_ID, VIAL_KEYBOARD_DEF);
|
||||
|
||||
let keyboard_config = RmkConfig {
|
||||
usb_config: keyboard_usb_config,
|
||||
vial_config,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut pin_4 = AnyPin::from(p.PIN_4).into_ref();
|
||||
let pin_shared = Input::new(&mut pin_4, embassy_rp::gpio::Pull::Up);
|
||||
let pin_left_b = Input::new(AnyPin::from(p.PIN_3), embassy_rp::gpio::Pull::Up);
|
||||
let pin_right_b = Input::new(AnyPin::from(p.PIN_26), embassy_rp::gpio::Pull::Up);
|
||||
let mut left_encoder = RotaryEncoder::new(pin_shared, pin_left_b, 0);
|
||||
// TODO: Implement right encoder (currently, the pin cannot be shared like this)
|
||||
// let mut right_encoder = RotaryEncoder::new(pin_shared, pin_right_b, 1);
|
||||
|
||||
// Start serving
|
||||
// Use `run_rmk` for blocking flash
|
||||
embassy_futures::join::join(
|
||||
run_rmk_with_async_flash(
|
||||
input_pins,
|
||||
output_pins,
|
||||
driver,
|
||||
flash,
|
||||
&mut keymap::get_default_keymap(),
|
||||
keyboard_config,
|
||||
spawner,
|
||||
),
|
||||
// note: encoders aren't implemented yet, so this does basically nothing for now /shrug
|
||||
run_devices!(left_encoder),
|
||||
// run_devices!(left_encoder, right_encoder),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
28
hackpads/woagpad/firmware/src/vial.rs
Normal file
28
hackpads/woagpad/firmware/src/vial.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// Vial config is automatically generated by `build.rs`, according to `vial.json`
|
||||
// Please put `vial.json` at your project's root
|
||||
include!(concat!(env!("OUT_DIR"), "/config_generated.rs"));
|
||||
|
||||
// Or you can manually generate vial config then put here
|
||||
// pub const VIAL_KEYBOARD_ID: &[u8; 8] = &[0xB9, 0xBC, 0x09, 0xB2, 0x9D, 0x37, 0x4C, 0xEA];
|
||||
// pub const VIAL_KEYBOARD_DEF: &[u8; 308] = &[
|
||||
// 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x04, 0xE6, 0xD6, 0xB4, 0x46, 0x02, 0x00, 0x21, 0x01,
|
||||
// 0x16, 0x00, 0x00, 0x00, 0x74, 0x2F, 0xE5, 0xA3, 0xE0, 0x01, 0x58, 0x00, 0xF1, 0x5D, 0x00, 0x3D,
|
||||
// 0x88, 0x89, 0xC6, 0x54, 0x36, 0xC3, 0x17, 0x4F, 0xE4, 0xE2, 0x11, 0x2F, 0x22, 0xB0, 0xBC, 0xC8,
|
||||
// 0x21, 0x18, 0x12, 0x8B, 0x06, 0x39, 0x42, 0xED, 0x2D, 0x7A, 0x5C, 0xC0, 0x20, 0x95, 0xFA, 0x59,
|
||||
// 0xBD, 0x04, 0x61, 0xF7, 0xDE, 0x2F, 0xD2, 0xFB, 0x8E, 0xAD, 0x8E, 0xE5, 0x16, 0x4E, 0xEA, 0x09,
|
||||
// 0xC7, 0x59, 0xDC, 0x04, 0x50, 0xB5, 0x7A, 0x56, 0x03, 0xA4, 0x7C, 0xE2, 0xFE, 0x87, 0x69, 0xA2,
|
||||
// 0xA1, 0xF1, 0xFC, 0xBB, 0xF8, 0x7D, 0xD8, 0x5F, 0x6A, 0x39, 0xB4, 0xC9, 0x00, 0xE8, 0x52, 0xD3,
|
||||
// 0xEE, 0x5C, 0x59, 0x88, 0x1E, 0x19, 0x66, 0x17, 0x5D, 0xF6, 0xD2, 0x28, 0x0B, 0xC9, 0xB8, 0x38,
|
||||
// 0x43, 0x9A, 0x38, 0x26, 0x8C, 0x45, 0xB1, 0x9C, 0xE5, 0x1B, 0x50, 0xF5, 0x71, 0x7F, 0x3A, 0xB4,
|
||||
// 0xE9, 0xB5, 0x2F, 0xA9, 0xEA, 0xE3, 0xC8, 0xAC, 0x3F, 0x77, 0x37, 0x28, 0xA3, 0x4E, 0xC7, 0x14,
|
||||
// 0xE4, 0xCF, 0x31, 0xCB, 0x33, 0x11, 0x3F, 0x27, 0x9D, 0xFB, 0x5C, 0x61, 0x96, 0xFE, 0x27, 0x7B,
|
||||
// 0x04, 0x13, 0x1F, 0xEC, 0xD6, 0x57, 0xD2, 0x32, 0xB8, 0x00, 0x4E, 0x21, 0x32, 0x79, 0xA9, 0x09,
|
||||
// 0x45, 0xCD, 0x11, 0x6F, 0xF9, 0x37, 0xFB, 0x57, 0xF7, 0x28, 0xC3, 0xAF, 0x00, 0x0F, 0xF3, 0xB2,
|
||||
// 0x1F, 0xC3, 0x7C, 0x84, 0xA0, 0xF0, 0x09, 0xEE, 0x49, 0x99, 0x39, 0xC2, 0x69, 0x4A, 0xFE, 0x38,
|
||||
// 0xFE, 0xE7, 0x80, 0xCA, 0x37, 0x46, 0x7B, 0xC9, 0xF4, 0x39, 0x7B, 0x30, 0x0E, 0x22, 0xA6, 0xD3,
|
||||
// 0x18, 0x1B, 0xA7, 0x70, 0xB9, 0x14, 0x91, 0x13, 0xC2, 0x5F, 0x02, 0xD1, 0x1A, 0x62, 0x6B, 0xC6,
|
||||
// 0xFC, 0xD3, 0x18, 0xC0, 0x62, 0xA5, 0xEA, 0xD0, 0xDF, 0x18, 0xDD, 0xD3, 0x53, 0x63, 0x11, 0x08,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0xF5, 0x5B, 0x73, 0xB4, 0xF2, 0x19, 0x3D, 0xF2, 0x00, 0x01, 0x8D, 0x02,
|
||||
// 0xD9, 0x02, 0x00, 0x00, 0xC6, 0xA2, 0x63, 0x43, 0xB1, 0xC4, 0x67, 0xFB, 0x02, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x04, 0x59, 0x5A,
|
||||
// ];
|
||||
38
hackpads/woagpad/firmware/vial.json
Normal file
38
hackpads/woagpad/firmware/vial.json
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"name": "firmware",
|
||||
"vendorId": "0x4C4B",
|
||||
"productId": "0x4643",
|
||||
"lighting": "none",
|
||||
"matrix": {
|
||||
"rows": 3,
|
||||
"cols": 3
|
||||
},
|
||||
"layouts": {
|
||||
"keymap": [
|
||||
[
|
||||
"0,0\n\n\n\n\n\n\n\n\ne",
|
||||
{
|
||||
"x": 1
|
||||
},
|
||||
"1,0\n\n\n\n\n\n\n\n\ne"
|
||||
],
|
||||
[
|
||||
"0,1\n\n\n\n\n\n\n\n\ne",
|
||||
{
|
||||
"x": 1
|
||||
},
|
||||
"1,1\n\n\n\n\n\n\n\n\ne"
|
||||
],
|
||||
[
|
||||
{
|
||||
"y": 0.25
|
||||
},
|
||||
"0,0",
|
||||
"0,1",
|
||||
"0,2"
|
||||
],
|
||||
["1,0", "1,1", "1,2"],
|
||||
["2,0", "2,1", "2,2"]
|
||||
]
|
||||
}
|
||||
}
|
||||
82
hackpads/woagpad/flake.lock
generated
Normal file
82
hackpads/woagpad/flake.lock
generated
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1739834344,
|
||||
"narHash": "sha256-PUAcU3YlKNFYrBBHkqshO4wRfMunzhMTEIH1dyhjTtk=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "f0295845e58ada369322524631821b01c0db13a7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"rust-overlay": "rust-overlay"
|
||||
}
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1739845646,
|
||||
"narHash": "sha256-UGQVBU/yDn6u0kAE4z1PYrOaaf3wl+gAAv5rui2TkFQ=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "ab2cd2b8b25ab3f65b8ce4aa701a6d69fbb0210f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
34
hackpads/woagpad/flake.nix
Normal file
34
hackpads/woagpad/flake.nix
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
description = "Cross compiling a rust program using rust-overlay";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
|
||||
rust-overlay = {
|
||||
url = "github:oxalica/rust-overlay";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { nixpkgs, flake-utils, rust-overlay, ... }:
|
||||
flake-utils.lib.eachDefaultSystem (localSystem:
|
||||
let
|
||||
|
||||
pkgs = import nixpkgs {
|
||||
inherit localSystem;
|
||||
overlays = [ (import rust-overlay) ];
|
||||
};
|
||||
|
||||
toolchain = pkgs.rust-bin.stable.latest.default.override {
|
||||
extensions = ["rust-analyzer" "rust-src" "rustfmt" "llvm-tools"];
|
||||
targets = ["thumbv6m-none-eabi"];
|
||||
};
|
||||
in
|
||||
{
|
||||
devShells.default = pkgs.mkShell {
|
||||
buildInputs = [ toolchain pkgs.cargo-binstall pkgs.alejandra pkgs.flip-link pkgs.cargo-make pkgs.probe-rs pkgs.nixd pkgs.pkg-config pkgs.openssl ];
|
||||
};
|
||||
});
|
||||
}
|
||||
1649
hackpads/woagpad/production/Bottom.step
Normal file
1649
hackpads/woagpad/production/Bottom.step
Normal file
File diff suppressed because it is too large
Load diff
1
hackpads/woagpad/production/README.md
Normal file
1
hackpads/woagpad/production/README.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Production files for [hackpad](https://hackpad.hackclub.com)!
|
||||
14055
hackpads/woagpad/production/Top.step
Normal file
14055
hackpads/woagpad/production/Top.step
Normal file
File diff suppressed because it is too large
Load diff
BIN
hackpads/woagpad/production/firmware.uf2
Normal file
BIN
hackpads/woagpad/production/firmware.uf2
Normal file
Binary file not shown.
BIN
hackpads/woagpad/production/gerber.zip
Normal file
BIN
hackpads/woagpad/production/gerber.zip
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue