From d43c7976ad9eae3f2ef7986d2816b3522523ecd2 Mon Sep 17 00:00:00 2001 From: Florian Berthold Date: Fri, 23 Jan 2026 08:15:25 +0100 Subject: [PATCH] Add panel-to-PCB mounting system with M3 standoffs Panel alignment: - PCB offset 10mm from panel top - Component holes aligned: OLED@25mm, jacks@45mm, button@58mm - 4x M3 standoff holes at corners (5,5), (35,5), (5,75), (35,75) Updates: - Panel SVG and spec aligned with PCB layout - Mounting holes added to PCB (Edge.Cuts layer) - Regenerated Gerbers with mounting holes - Updated autoroute.py to add mounting holes automatically DRC: 0 unconnected, 7 cosmetic errors (courtyard overlaps) --- .gitignore | 6 + hardware/kicad/SN-L00-gerbers.zip | Bin 30221 -> 30533 bytes hardware/kicad/SN-L00.kicad_pcb | 1286 +++++++++-------- hardware/kicad/gerbers/SN-L00-B_Cu.gbl | 75 +- hardware/kicad/gerbers/SN-L00-B_Mask.gbs | 4 +- hardware/kicad/gerbers/SN-L00-B_Paste.gbp | 4 +- .../kicad/gerbers/SN-L00-B_Silkscreen.gbo | 4 +- hardware/kicad/gerbers/SN-L00-Edge_Cuts.gm1 | 44 +- hardware/kicad/gerbers/SN-L00-F_Cu.gtl | 298 ++-- hardware/kicad/gerbers/SN-L00-F_Mask.gts | 4 +- hardware/kicad/gerbers/SN-L00-F_Paste.gtp | 4 +- .../kicad/gerbers/SN-L00-F_Silkscreen.gto | 4 +- hardware/kicad/gerbers/SN-L00-drl_map.gbr | 120 +- hardware/kicad/gerbers/SN-L00-job.gbrjob | 2 +- hardware/kicad/gerbers/SN-L00.drl | 19 +- hardware/kicad/scripts/autoroute.py | 32 + hardware/kicad/scripts/autoroute_cli.py | 116 ++ hardware/kicad/scripts/autoroute_headless.py | 293 ++++ hardware/kicad/scripts/place_6hp.py | 86 ++ hardware/panel/PANEL_SPEC.md | 136 +- hardware/panel/SN-L00_panel.svg | 59 +- 21 files changed, 1654 insertions(+), 942 deletions(-) create mode 100644 hardware/kicad/scripts/autoroute_cli.py create mode 100755 hardware/kicad/scripts/autoroute_headless.py create mode 100644 hardware/kicad/scripts/place_6hp.py diff --git a/.gitignore b/.gitignore index d16c312..1003117 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,9 @@ firmware/.pio/ # OS .DS_Store Thumbs.db + +# Build artifacts +*.dsn +*.ses +*.mgc +DRC.rpt diff --git a/hardware/kicad/SN-L00-gerbers.zip b/hardware/kicad/SN-L00-gerbers.zip index ff8252662eb838c86316805fd3053c7227bc450f..db5f888c2c78a99bfbb65303afdef69bdb6abf8c 100644 GIT binary patch literal 30533 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 literal 30221 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 diff --git a/hardware/kicad/SN-L00.kicad_pcb b/hardware/kicad/SN-L00.kicad_pcb index fa70e48..8554870 100644 --- a/hardware/kicad/SN-L00.kicad_pcb +++ b/hardware/kicad/SN-L00.kicad_pcb @@ -6447,6 +6447,39 @@ ) ) ) + (gr_circle + (center 35 5) + (end 36.6 5) + (stroke + (width 0.15) + (type default) + ) + (fill no) + (layer "Edge.Cuts") + (uuid "2034131c-3b39-4c79-bc68-6a9d17ea2f44") + ) + (gr_circle + (center 5 75) + (end 6.6 75) + (stroke + (width 0.15) + (type default) + ) + (fill no) + (layer "Edge.Cuts") + (uuid "40411225-c33e-415c-9c61-59b6f31f4607") + ) + (gr_circle + (center 35 75) + (end 36.6 75) + (stroke + (width 0.15) + (type default) + ) + (fill no) + (layer "Edge.Cuts") + (uuid "561a78cd-1d63-4c3d-af72-d958e1a02d03") + ) (gr_rect (start 0 0) (end 40 100) @@ -6458,6 +6491,17 @@ (layer "Edge.Cuts") (uuid "a1b2c3d4-e5f6-7890-abcd-ef1234567890") ) + (gr_circle + (center 5 5) + (end 6.6 5) + (stroke + (width 0.15) + (type default) + ) + (fill no) + (layer "Edge.Cuts") + (uuid "d8fbc827-56b6-43e5-9f17-8b2454811e88") + ) (gr_text "SN-L00 v0.1" (at 14.075 98.075 0) (layer "F.SilkS") @@ -6508,7 +6552,7 @@ (width 0.2) (layer "F.Cu") (net 1) - (uuid "19bb80c1-a10d-4593-aa02-d50182de5f6d") + (uuid "24390f90-2e90-473b-a17d-fad8800c6296") ) (segment (start 26 95.9624) @@ -6516,7 +6560,7 @@ (width 0.2) (layer "F.Cu") (net 1) - (uuid "3c7e8a5e-e958-4581-8ec6-2adf852045f9") + (uuid "26526db0-2e90-4f2a-a8c9-ac045b3a2a7c") ) (segment (start 6 92) @@ -6524,7 +6568,7 @@ (width 0.2) (layer "F.Cu") (net 1) - (uuid "8863b0ca-2b23-46b0-a339-94a3f23950a2") + (uuid "8663f88a-aa96-430f-baa9-37f596389e98") ) (segment (start 35.15 91.7) @@ -6532,15 +6576,7 @@ (width 0.2) (layer "F.Cu") (net 1) - (uuid "b765e2cd-2899-4fbd-aa78-fec76b86e8cd") - ) - (via - (at 7.5258 94.2317) - (size 0.6) - (drill 0.3) - (layers "F.Cu" "B.Cu") - (net 1) - (uuid "8fdcb52c-d83a-4b40-ace6-b70c8d835937") + (uuid "f76aa72d-3a14-43c1-868e-5823f668ae0c") ) (via (at 35.15 90.4362) @@ -6548,7 +6584,15 @@ (drill 0.3) (layers "F.Cu" "B.Cu") (net 1) - (uuid "a7b24b71-11dc-4206-acc9-123807814918") + (uuid "2e7ad4e2-95fb-43c8-a9a6-36ae999bcf0e") + ) + (via + (at 7.5258 94.2317) + (size 0.6) + (drill 0.3) + (layers "F.Cu" "B.Cu") + (net 1) + (uuid "60a0d2b0-7075-4059-9cfa-89ec788c59df") ) (via (at 26 95.9624) @@ -6556,31 +6600,7 @@ (drill 0.3) (layers "F.Cu" "B.Cu") (net 1) - (uuid "d4c2b999-03e1-4495-8cae-2310841150ad") - ) - (segment - (start 31.3545 94.2317) - (end 35.15 90.4362) - (width 0.2) - (layer "B.Cu") - (net 1) - (uuid "8dd0cd79-cbaa-46e2-800b-4a811a1c1600") - ) - (segment - (start 26 94.2317) - (end 31.3545 94.2317) - (width 0.2) - (layer "B.Cu") - (net 1) - (uuid "adbfd673-e963-4b46-bad5-a63b296b89c4") - ) - (segment - (start 26 95.9624) - (end 26 94.2317) - (width 0.2) - (layer "B.Cu") - (net 1) - (uuid "b631f7c4-1430-4b77-833d-05fb29ce88ff") + (uuid "d01fbd32-393c-40eb-ac30-58049b1f2eaf") ) (segment (start 7.5258 94.2317) @@ -6588,127 +6608,55 @@ (width 0.2) (layer "B.Cu") (net 1) - (uuid "b889f335-c1fe-43dd-81aa-b569de54c579") + (uuid "10898230-7f13-4527-9bf3-97dfe06ef047") ) (segment - (start 30 83.225) - (end 30 85.175) + (start 26 94.2317) + (end 31.3545 94.2317) + (width 0.2) + (layer "B.Cu") + (net 1) + (uuid "21ae4386-d7f4-4a61-88a2-dd195889ac12") + ) + (segment + (start 31.3545 94.2317) + (end 35.15 90.4362) + (width 0.2) + (layer "B.Cu") + (net 1) + (uuid "96b13834-db0a-467a-834d-3eaf0c0d0dcc") + ) + (segment + (start 26 95.9624) + (end 26 94.2317) + (width 0.2) + (layer "B.Cu") + (net 1) + (uuid "cd623290-7ca8-49cf-8412-5175349d244d") + ) + (segment + (start 28 81.225) + (end 28.9519 82.1768) (width 0.2) (layer "F.Cu") (net 2) - (uuid "052a691a-b265-4a83-9bd5-ba6aa1a81917") + (uuid "020c4253-6d42-493a-bf4e-72dca24da5a9") ) (segment - (start 34.95 50.1625) - (end 34.95 77.0397) + (start 8.5262 91.7512) + (end 8.5262 80.6137) (width 0.2) (layer "F.Cu") (net 2) - (uuid "071568ac-4346-465a-a1be-7166b46644f0") + (uuid "02a2ed39-0951-4b85-a6af-d01e00eac942") ) (segment - (start 20 95.62) - (end 20 93.08) + (start 28.7761 89.3665) + (end 28.7761 86.3989) (width 0.2) (layer "F.Cu") (net 2) - (uuid "0afca2a8-31d6-40e2-84ce-1fd7262e0308") - ) - (segment - (start 30.076 36.2167) - (end 32.7875 38.9282) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "0e8c645c-58aa-4b67-b0bc-0b88014cd555") - ) - (segment - (start 7.8782 78.3377) - (end 7.8782 76.995) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "378cad8f-c976-4f23-898d-02fd23d795ff") - ) - (segment - (start 29.051 89.0916) - (end 29.051 86.124) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "3e5f326c-608b-47f0-be71-a61e933bbc07") - ) - (segment - (start 10 93.225) - (end 10 92.3575) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "40cecb70-8bed-47af-8bc1-5e1b7b09d9dd") - ) - (segment - (start 30 35) - (end 30 36.2167) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "4143dc03-121a-4624-9848-067a6fee5508") - ) - (segment - (start 38.0547 93.3953) - (end 38.0547 89.6787) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "4a3eaacc-5daf-4b02-9e47-7149feef4ccf") - ) - (segment - (start 29.051 86.124) - (end 30 85.175) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "55ac1b50-c983-4698-af81-baf4d1b7c9e9") - ) - (segment - (start 20 93.08) - (end 20 90.54) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "5cce58d3-092f-407c-aba7-3901c5cc14f6") - ) - (segment - (start 10 92.3575) - (end 10.6569 92.3575) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "6b9dc8df-12e8-465f-94a2-ba4aa0005f06") - ) - (segment - (start 6.8625 88.0375) - (end 6.8625 78.95) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "7628ebb3-9380-4a12-854e-1545d37403e4") - ) - (segment - (start 10 92.3575) - (end 10 91.175) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "79c9825c-7d4d-4b76-9efe-e6c7ef2fd356") - ) - (segment - (start 13.3972 76.4472) - (end 14 77.05) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "7ee24e1a-1050-4a0f-8873-f060764414d8") + (uuid "0a5161f9-9c64-43db-abf0-381a4f342119") ) (segment (start 25.97 93.08) @@ -6716,119 +6664,55 @@ (width 0.2) (layer "F.Cu") (net 2) - (uuid "83959b1f-199d-4aff-8b5d-69da0f0d538d") + (uuid "1c1461c7-a3ab-42fe-89bb-6fbdb02f0353") ) (segment - (start 32.7875 48) - (end 34.95 50.1625) + (start 10 93.225) + (end 8.5262 91.7512) (width 0.2) (layer "F.Cu") (net 2) - (uuid "8897b30c-31f9-47e3-94aa-6272a2142f15") + (uuid "1cee40b9-482e-4d80-8c54-b356f8d4b7c2") ) (segment - (start 10 91.175) - (end 6.8625 88.0375) + (start 20 93.08) + (end 20 90.54) (width 0.2) (layer "F.Cu") (net 2) - (uuid "8c26bb4a-482a-4326-8546-4e8e2586a7c5") + (uuid "3a53a29a-bbc3-42e7-b778-5dbb8c59b3cd") ) (segment - (start 38.0547 89.6787) - (end 38.0547 77.51) + (start 20 95.62) + (end 20 93.08) (width 0.2) (layer "F.Cu") (net 2) - (uuid "a472cdc5-ebe4-4c64-873d-c7d06e1b4421") + (uuid "460996ff-8fad-4f72-ae15-d2a030e1c9b6") ) (segment - (start 7.2659 78.95) - (end 7.8782 78.3377) + (start 30.076 36.2167) + (end 32.7875 38.9282) (width 0.2) (layer "F.Cu") (net 2) - (uuid "a5926a4d-ccba-41b5-a1ac-ca56900bf3ff") + (uuid "4be0cabe-07fc-4627-b055-ed77d4066368") ) (segment - (start 7.8782 76.995) - (end 8.426 76.4472) + (start 32.0364 79.0923) + (end 32.0364 77.272) (width 0.2) (layer "F.Cu") (net 2) - (uuid "a61e0b10-143a-4937-9c09-8e01653a9481") + (uuid "4c591ad5-08e5-460c-902e-4e0e12b0cae0") ) (segment - (start 38.0547 77.51) - (end 37.5844 77.0397) + (start 18.8473 81.8973) + (end 18.8473 89.3873) (width 0.2) (layer "F.Cu") (net 2) - (uuid "a805a02e-902f-40cb-921b-973aa635d4ae") - ) - (segment - (start 35.15 96.3) - (end 38.0547 93.3953) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "b1eaa792-829c-4d8b-b2c8-c69378bcf67e") - ) - (segment - (start 22.54 93.08) - (end 25.97 93.08) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "c6363ab2-77e5-4405-ad1e-ba533893c550") - ) - (segment - (start 37.5844 77.0397) - (end 34.95 77.0397) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "c6a2d386-e8f2-410b-92f5-fb2d86618072") - ) - (segment - (start 34.95 77.0397) - (end 34.95 78) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "c70dc5cb-42b6-4e8a-ab25-c935404b604d") - ) - (segment - (start 30 36.2167) - (end 30.076 36.2167) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "c9ba4127-8e33-45eb-b6fd-69dedbc72f2f") - ) - (segment - (start 22.54 98.16) - (end 22.54 95.62) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "d3464df3-197b-4d1d-a43e-8423da4439fd") - ) - (segment - (start 28 81.225) - (end 30 83.225) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "db0681ac-42be-4864-9ee1-49082387c8e7") - ) - (segment - (start 6.8625 78.95) - (end 7.2659 78.95) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "e2097a83-7a57-4544-a0d5-494f9ded1854") + (uuid "5bc9fed3-17ed-48dd-94c3-cf754dcab3e5") ) (segment (start 20 98.16) @@ -6836,23 +6720,15 @@ (width 0.2) (layer "F.Cu") (net 2) - (uuid "e554b743-f65f-43fe-b71e-8933ef263ed0") + (uuid "60fa89ea-7118-4166-be29-33ec88f717df") ) (segment - (start 32.7875 38.9282) - (end 32.7875 48) + (start 22.54 93.08) + (end 25.97 93.08) (width 0.2) (layer "F.Cu") (net 2) - (uuid "e6b92c46-4976-4855-a4a8-5e3841b9ee97") - ) - (segment - (start 8.426 76.4472) - (end 13.3972 76.4472) - (width 0.2) - (layer "F.Cu") - (net 2) - (uuid "f43be537-2a7a-467c-a565-36d03e0296bc") + (uuid "61f245e1-ee44-46fe-b131-f4acd27e322e") ) (segment (start 22.54 95.62) @@ -6860,47 +6736,215 @@ (width 0.2) (layer "F.Cu") (net 2) - (uuid "f4e38b98-bbdf-487e-b9af-e201872e386d") - ) - (via - (at 29.051 89.0916) - (size 0.6) - (drill 0.3) - (layers "F.Cu" "B.Cu") - (net 2) - (uuid "636fb108-3490-44b9-8066-9b6935c5b189") - ) - (via - (at 38.0547 89.6787) - (size 0.6) - (drill 0.3) - (layers "F.Cu" "B.Cu") - (net 2) - (uuid "aac087f9-7f12-4136-990e-b28fe629bc80") - ) - (via - (at 10.6569 92.3575) - (size 0.6) - (drill 0.3) - (layers "F.Cu" "B.Cu") - (net 2) - (uuid "f2d63803-c0bf-497e-b727-53fdc96a85c4") + (uuid "6fa92ba7-ae4b-48b7-a627-7f0cf93b8060") ) (segment - (start 37.4676 89.0916) - (end 38.0547 89.6787) + (start 32.7644 78) + (end 34.95 78) (width 0.2) - (layer "B.Cu") + (layer "F.Cu") (net 2) - (uuid "4dccac4f-6ae8-418b-8966-cb8335e94d69") + (uuid "72e1343a-7406-42ef-ab3c-c1bea8362f74") ) (segment - (start 20 93.08) - (end 19.2775 92.3575) + (start 32.0364 54.6276) + (end 32.0364 77.272) (width 0.2) - (layer "B.Cu") + (layer "F.Cu") (net 2) - (uuid "9d5ac7bf-0a74-4ae3-83e1-be45a2394170") + (uuid "81a0896a-e83c-472b-9f1d-3b1bc8646b52") + ) + (segment + (start 32.0364 77.272) + (end 32.7644 78) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "83c05dbb-d85c-4ec3-b15c-401d656d76f3") + ) + (segment + (start 30 35.6083) + (end 30 36.2167) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "849abfca-e73d-4d5c-8c62-47e0d4246d5d") + ) + (segment + (start 30 35.6083) + (end 28.1882 37.4201) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "8dea0c93-8f20-4c40-a227-4eaee5d1e0b6") + ) + (segment + (start 35.15 96.3) + (end 33.6283 97.8217) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "8e46b0ab-442c-4bd5-9bab-f21e077fa13e") + ) + (segment + (start 30 36.2167) + (end 30.076 36.2167) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "98378e76-d066-4ad2-9102-ce87288271e3") + ) + (segment + (start 28.7761 86.3989) + (end 30 85.175) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "9f25f8ee-2367-4918-a7e6-fb260ed2f781") + ) + (segment + (start 30 35) + (end 30 35.6083) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "a27e7d7e-5b7d-49c8-ab14-5beb76528690") + ) + (segment + (start 32.7875 38.9282) + (end 32.7875 48) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "a629ffd6-53a3-427c-84d4-ddb8435d8273") + ) + (segment + (start 30 83.7427) + (end 30 85.175) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "b10e87f1-0f86-4c8f-b566-0eae27e2ef0c") + ) + (segment + (start 29.211 82.9537) + (end 30 83.7427) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "b2a9cfb4-b89d-454f-9bab-e84ac2638de9") + ) + (segment + (start 33.6283 97.8217) + (end 33.6283 98.16) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "bb307058-8ede-4a33-91b2-fb6caad0019b") + ) + (segment + (start 28.9519 82.1768) + (end 29.211 82.436) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "c4d43ef7-23bb-4293-8bdf-ca2ccd568971") + ) + (segment + (start 10 93.225) + (end 10 90.54) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "c683b638-ed29-4ffa-a8d3-121918df22ba") + ) + (segment + (start 8.5262 80.6137) + (end 6.8625 78.95) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "c743063a-3033-4d51-870d-e3c534a9be42") + ) + (segment + (start 28.1882 37.4201) + (end 28.1882 50.7794) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "c8e48230-7988-4ac7-9b04-62b70ece4766") + ) + (segment + (start 18.8473 89.3873) + (end 20 90.54) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "db96996f-babe-4722-9bb3-d468fdd1e1b7") + ) + (segment + (start 22.54 98.16) + (end 22.54 95.62) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "dec6aa9c-0dc6-4adc-8a15-9d8437bb1d47") + ) + (segment + (start 29.211 82.436) + (end 29.211 82.9537) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "e44ed929-277a-4b05-92fa-0303955fb908") + ) + (segment + (start 28.1882 50.7794) + (end 32.0364 54.6276) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "f4fb98f8-44b6-4ce4-96ba-5313035bce25") + ) + (segment + (start 14 77.05) + (end 18.8473 81.8973) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "f5f6467b-f7bc-4627-bb33-3b595667fbc6") + ) + (segment + (start 28.9519 82.1768) + (end 32.0364 79.0923) + (width 0.2) + (layer "F.Cu") + (net 2) + (uuid "f638745e-4059-4f5c-a793-df6236fb0786") + ) + (via + (at 33.6283 98.16) + (size 0.6) + (drill 0.3) + (layers "F.Cu" "B.Cu") + (net 2) + (uuid "2117ed12-4ac2-4ab5-a9d1-575209f4009f") + ) + (via + (at 28.7761 89.3665) + (size 0.6) + (drill 0.3) + (layers "F.Cu" "B.Cu") + (net 2) + (uuid "8bf05ace-b0f3-432b-8e7f-a2fdef56507b") + ) + (via + (at 10 90.54) + (size 0.6) + (drill 0.3) + (layers "F.Cu" "B.Cu") + (net 2) + (uuid "ddee7a53-35f0-4ee5-a50d-10b9ad01d5bb") ) (segment (start 20 95.62) @@ -6908,199 +6952,55 @@ (width 0.2) (layer "B.Cu") (net 2) - (uuid "cf219c58-28ec-4e97-bd08-67ceb99fb66f") - ) - (segment - (start 26.5284 89.0916) - (end 29.051 89.0916) - (width 0.2) - (layer "B.Cu") - (net 2) - (uuid "eada6a92-6a62-4028-836a-268e0a00caff") - ) - (segment - (start 29.051 89.0916) - (end 37.4676 89.0916) - (width 0.2) - (layer "B.Cu") - (net 2) - (uuid "f2b31cef-5e3a-4681-b66e-fbc864d392a6") - ) - (segment - (start 19.2775 92.3575) - (end 10.6569 92.3575) - (width 0.2) - (layer "B.Cu") - (net 2) - (uuid "f5c5272d-9ae1-463a-8a6d-5d67e353e66b") + (uuid "6f3d3b06-6d40-41c7-bcff-cee2ef248c15") ) (segment (start 22.54 93.08) - (end 26.5284 89.0916) + (end 26.2535 89.3665) (width 0.2) (layer "B.Cu") (net 2) - (uuid "fc9f0ce6-4b88-4756-8ceb-54bf9427cf29") + (uuid "9b7b3683-c3c0-49eb-8aaf-a593bc46c5d1") ) (segment - (start 36.4767 92.6733) - (end 35.15 94) + (start 26.2535 89.3665) + (end 28.7761 89.3665) + (width 0.2) + (layer "B.Cu") + (net 2) + (uuid "a8a86e5f-d05e-42b0-9128-ae4c7f7013c9") + ) + (segment + (start 20 90.54) + (end 10 90.54) + (width 0.2) + (layer "B.Cu") + (net 2) + (uuid "d68cffd1-3ce9-4d26-ad31-27f80b6c7004") + ) + (segment + (start 22.54 98.16) + (end 33.6283 98.16) + (width 0.2) + (layer "B.Cu") + (net 2) + (uuid "db01a3ef-e49f-46fd-9b9c-30a2c8767c55") + ) + (segment + (start 10.8206 82.3335) + (end 10.8206 86.838) (width 0.2) (layer "F.Cu") (net 3) - (uuid "060c079e-04d7-4aa1-a9a0-1eba32ec947d") + (uuid "04f1708a-8811-4abe-96d8-8fdb84dff8e5") ) (segment - (start 8.126 92.901) - (end 10 94.775) + (start 10.8206 86.838) + (end 10.8206 93.9544) (width 0.2) (layer "F.Cu") (net 3) - (uuid "172c8479-b955-4c59-94fc-cd7269a5a40c") - ) - (segment - (start 17.2323 82.1823) - (end 17.2323 86.825) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "2fb4c715-8ac0-4447-8f08-19407bb893dc") - ) - (segment - (start 17.2323 87.5427) - (end 10 94.775) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "31ab7757-1144-40cf-a2c5-705ad8d3b8db") - ) - (segment - (start 17.2323 86.825) - (end 17.2323 87.5427) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "387bd48b-f04b-430e-aac8-c85bbb6064df") - ) - (segment - (start 28 82.8) - (end 28 93.15) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "3a60412c-9c63-4265-9861-292d36eabeee") - ) - (segment - (start 5.05 82) - (end 5.05 86.825) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "3cad39e8-efd0-408d-96b1-d48fe8f22457") - ) - (segment - (start 28 93.15) - (end 28.85 94) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "67df6ea1-efaa-45b5-b93d-3cfc05a2f35e") - ) - (segment - (start 14 78.95) - (end 11.0375 78.95) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "68217817-3efa-4d40-b810-cb173eedb54e") - ) - (segment - (start 28 82.8) - (end 28 82.775) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "69f7265c-8d49-4e68-b941-a56f34d94795") - ) - (segment - (start 14 78.95) - (end 17.2323 82.1823) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "6ea49e1a-7839-447f-b707-a7d131699324") - ) - (segment - (start 24 86.825) - (end 17.2323 86.825) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "7b762ebb-e6d2-4e40-97ec-c07d694eaa9e") - ) - (segment - (start 5.05 86.825) - (end 8.126 89.901) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "820908fb-4cb0-4aff-9996-5af090158ef9") - ) - (segment - (start 36.4767 87.3017) - (end 36.4767 92.6733) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "82e8df19-392c-4db8-8f42-571d0caed1e4") - ) - (segment - (start 5.05 86.825) - (end 4 86.825) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "8537b379-c77f-43ae-b97e-ebbe1a0e56f8") - ) - (segment - (start 24 86.825) - (end 28 82.825) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "8912c1c9-5e47-4455-9fec-d240f02f40ad") - ) - (segment - (start 8.126 89.901) - (end 8.126 92.901) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "bd53a2a7-0c7e-483a-a403-0cab001c3624") - ) - (segment - (start 28 82.825) - (end 28 82.8) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "c4f5855c-0078-4b66-b4e4-889559d3a6c2") - ) - (segment - (start 36 86.825) - (end 36.4767 87.3017) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "cd673913-80d2-483a-8348-ce9542111001") - ) - (segment - (start 11.0375 78.95) - (end 9.1375 77.05) - (width 0.2) - (layer "F.Cu") - (net 3) - (uuid "d6066af6-bb0f-498f-9772-bdea6a662019") + (uuid "2b7a4359-8eb7-496c-b84c-bc570e24a3d3") ) (segment (start 35.15 94) @@ -7108,7 +7008,223 @@ (width 0.2) (layer "F.Cu") (net 3) - (uuid "fec113f7-c821-4f58-8fd0-678b5ff0a027") + (uuid "3185a161-9f06-4629-86f4-fda366820ec9") + ) + (segment + (start 5.05 82) + (end 5.05 86.825) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "34e94e85-d9ed-4776-927d-64ccf4c6cf42") + ) + (segment + (start 5.05 86.825) + (end 4 86.825) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "3a8c769f-46e0-48c8-8141-7e88dbe50c07") + ) + (segment + (start 28 82.8) + (end 28 93.15) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "437c7846-b065-4def-b2ef-194100c7bcdc") + ) + (segment + (start 35.15 94) + (end 36.4767 92.6733) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "4b26fe20-d774-4a87-b634-f7c5463fe4fc") + ) + (segment + (start 8.1671 79.68) + (end 10.8206 82.3335) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "4b4de27f-3a97-4834-8b69-2e6c33eaef40") + ) + (segment + (start 28 93.15) + (end 28.85 94) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "5af1eb47-b659-42da-b94b-3045464be535") + ) + (segment + (start 9.1986 77.1111) + (end 9.1375 77.05) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "633b4ddf-e4e9-40f3-b093-a9a3e0ed5112") + ) + (segment + (start 10.6236 78.95) + (end 9.1986 77.525) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "6de03059-d1c1-44a1-8255-a889105b7d7d") + ) + (segment + (start 8.1245 89.8995) + (end 8.1245 92.8995) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "6e2351fd-6ae9-458a-b291-617ff41056a9") + ) + (segment + (start 9.1986 77.525) + (end 9.1986 77.1111) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "78873dae-9b74-4de2-b3ba-833295cd9b3d") + ) + (segment + (start 24 86.825) + (end 28 82.825) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "85548fb7-28b5-4346-827e-25ba22aad841") + ) + (segment + (start 24 86.825) + (end 24 87.7351) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "862772dc-28b9-4cfb-b95d-5a89881f7510") + ) + (segment + (start 10.8206 86.838) + (end 11.0082 86.838) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "87c76ec6-352d-4e00-971f-5131002526e0") + ) + (segment + (start 10.8206 93.9544) + (end 10 94.775) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "9d2c67e1-a88e-44d1-848e-3781ea418212") + ) + (segment + (start 8.1245 92.8995) + (end 10 94.775) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "b9cfd178-2a38-4e5e-a16f-6515b333aeff") + ) + (segment + (start 14 78.95) + (end 10.6236 78.95) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "bf724392-ffb6-4670-a416-4256526b6f26") + ) + (segment + (start 36.4767 92.6733) + (end 36.4767 87.3017) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "bff7b230-475a-45ab-be32-ffd71944bafe") + ) + (segment + (start 28 82.825) + (end 28 82.8) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "c7cd8d76-5369-40cf-9a30-a10721f80c34") + ) + (segment + (start 28 82.8) + (end 28 82.775) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "d50ccb67-35b5-4264-8e25-0c93e011b0cb") + ) + (segment + (start 9.1986 77.525) + (end 8.1671 78.5565) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "d9f7b454-642e-49be-9b53-37d3ddfc7f5b") + ) + (segment + (start 5.05 86.825) + (end 8.1245 89.8995) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "e0fbbe8a-bdf2-4e80-b8c2-f72b31d8a34f") + ) + (segment + (start 36.4767 87.3017) + (end 36 86.825) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "f60a3e61-d618-4121-af37-f0556ec2cd76") + ) + (segment + (start 8.1671 78.5565) + (end 8.1671 79.68) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "f7270fa5-9b41-48e9-ac13-8d94cb337d5b") + ) + (via + (at 11.0082 86.838) + (size 0.6) + (drill 0.3) + (layers "F.Cu" "B.Cu") + (net 3) + (uuid "2463e142-3b07-4e91-8f36-b7a7dfac3968") + ) + (via + (at 24 87.7351) + (size 0.6) + (drill 0.3) + (layers "F.Cu" "B.Cu") + (net 3) + (uuid "2733a988-f24d-4a61-b608-e41e32734bc2") + ) + (segment + (start 24 87.7351) + (end 23.1029 86.838) + (width 0.2) + (layer "B.Cu") + (net 3) + (uuid "4384d180-648c-4ad4-b55d-6faeb8279dd8") + ) + (segment + (start 23.1029 86.838) + (end 11.0082 86.838) + (width 0.2) + (layer "B.Cu") + (net 3) + (uuid "d2fcfa2e-257e-43d3-a5e8-fe61e488adf2") ) (segment (start 2 90.5779) @@ -7116,7 +7232,7 @@ (width 0.2) (layer "F.Cu") (net 6) - (uuid "4dec7264-b16b-45a2-b4c6-5dd837e7aae3") + (uuid "95186ddd-9792-467f-b2fe-bee627bd8292") ) (via (at 2 90.5779) @@ -7124,7 +7240,7 @@ (drill 0.3) (layers "F.Cu" "B.Cu") (net 6) - (uuid "92bb0797-48e7-4038-beab-5745a8aa22cc") + (uuid "410a98b4-4fd3-4863-a9a5-ceca91077168") ) (segment (start 21.3494 91.7306) @@ -7132,15 +7248,7 @@ (width 0.2) (layer "B.Cu") (net 6) - (uuid "342fa68d-5882-4505-85e4-5e386edbd220") - ) - (segment - (start 22.54 90.54) - (end 21.3494 91.7306) - (width 0.2) - (layer "B.Cu") - (net 6) - (uuid "70f0bcd0-d8a4-4d62-a028-6259904c1482") + (uuid "70b28c49-fa5f-45ab-9e99-86261b03f6d1") ) (segment (start 3.1527 91.7306) @@ -7148,223 +7256,191 @@ (width 0.2) (layer "B.Cu") (net 6) - (uuid "fed0f8ed-61be-4c49-89fc-03f319979939") + (uuid "7541f414-fcbc-4613-8c84-8195f281796f") ) (segment - (start 2.95 82) - (end 2.95 83.5559) + (start 22.54 90.54) + (end 21.3494 91.7306) (width 0.2) - (layer "F.Cu") - (net 7) - (uuid "0dd6d8dc-9f06-4336-979d-caebe57b92b6") + (layer "B.Cu") + (net 6) + (uuid "bc5abde0-c5c0-4fe3-9ef0-2d5b54f74c26") ) (segment - (start 36.1 78.95) - (end 37.05 78) - (width 0.2) - (layer "F.Cu") - (net 7) - (uuid "2ddc9cf2-8d72-41a0-925a-9778832134f2") - ) - (segment - (start 32.1433 79.9442) + (start 33.1375 83.6875) (end 33.1375 78.95) (width 0.2) (layer "F.Cu") (net 7) - (uuid "400dfc57-3723-474a-9773-64d82f8061a5") + (uuid "0d50fb85-c6c9-401d-b69d-982cdb54797b") ) (segment - (start 31.8567 79.9442) - (end 30.8625 78.95) + (start 36.1 78.95) + (end 33.1375 78.95) (width 0.2) (layer "F.Cu") (net 7) - (uuid "73240b5c-2f31-4447-a1de-79f04e0ff7f6") - ) - (segment - (start 24 83.9981) - (end 29.0481 78.95) - (width 0.2) - (layer "F.Cu") - (net 7) - (uuid "8751f5e9-f19e-48d8-8885-d4415e8a7819") - ) - (segment - (start 10 85.175) - (end 10 83.5559) - (width 0.2) - (layer "F.Cu") - (net 7) - (uuid "9e19d887-0132-4ac5-ac4c-a97d2fad1a91") - ) - (segment - (start 29.0481 78.95) - (end 30.8625 78.95) - (width 0.2) - (layer "F.Cu") - (net 7) - (uuid "ad2f7e8d-5aba-41d4-bd03-77056b01dba5") + (uuid "13e2e1d4-dcf7-437f-9eac-02fefa3f5b0e") ) (segment (start 24 85.175) - (end 24 83.9981) + (end 24 83.9036) (width 0.2) (layer "F.Cu") (net 7) - (uuid "b81561e6-9b59-4192-bc6d-2c363a2b2db6") + (uuid "1ec9024f-0bc7-4ed5-9f2f-47a14bb423f1") ) (segment - (start 33.1375 78.95) + (start 37.05 78) (end 36.1 78.95) (width 0.2) (layer "F.Cu") (net 7) - (uuid "c9738c6c-5599-4bf2-9c61-28cca01bda14") + (uuid "379a76be-ff2c-4353-accc-9ca408ed7670") + ) + (segment + (start 10 85.175) + (end 10 83.5958) + (width 0.2) + (layer "F.Cu") + (net 7) + (uuid "5a675a31-3d66-4046-80d7-b4310b8f6c0f") + ) + (segment + (start 24.3078 83.5958) + (end 28.9536 78.95) + (width 0.2) + (layer "F.Cu") + (net 7) + (uuid "aa3c759e-3242-4aad-a276-ecc2517b21e3") + ) + (segment + (start 24 83.9036) + (end 24.3078 83.5958) + (width 0.2) + (layer "F.Cu") + (net 7) + (uuid "afb2ed87-78a2-456e-8168-51eabb4a74b3") + ) + (segment + (start 2.95 82) + (end 2.95 83.5958) + (width 0.2) + (layer "F.Cu") + (net 7) + (uuid "b6b84416-332d-4fc1-9db6-4fdcb97b6d53") ) (segment (start 30 86.825) - (end 31.8567 84.9683) + (end 32.083 84.742) (width 0.2) (layer "F.Cu") (net 7) - (uuid "dc5bab26-48db-4053-a2b8-1ac29daed0b9") + (uuid "eba56329-f946-47e4-9fba-4f32317c4bf7") ) (segment - (start 31.8567 79.9442) - (end 32.1433 79.9442) + (start 32.083 84.742) + (end 33.1375 83.6875) (width 0.2) (layer "F.Cu") (net 7) - (uuid "e434640d-1d8c-4539-ab67-63cfd65976e8") + (uuid "f37dd2a9-9576-486e-b9fb-ef9ee193833e") ) (segment - (start 31.8567 84.9683) - (end 31.8567 79.9442) + (start 28.9536 78.95) + (end 30.8625 78.95) (width 0.2) (layer "F.Cu") (net 7) - (uuid "f938bfea-7195-449a-a5ac-b0dae4be5679") + (uuid "f821098e-2e32-492f-a7c5-1650cbd235cc") ) (via - (at 24 83.9981) + (at 32.083 84.742) (size 0.6) (drill 0.3) (layers "F.Cu" "B.Cu") (net 7) - (uuid "883c579a-3f65-4173-b3a9-6f190cecb6b6") + (uuid "16ba1b62-71a8-42cb-abda-bce9159da6f5") ) (via - (at 10 83.5559) + (at 24.3078 83.5958) (size 0.6) (drill 0.3) (layers "F.Cu" "B.Cu") (net 7) - (uuid "ef4d5bc8-cc11-40d9-bb21-6121c93cf4af") + (uuid "1c56ee14-a292-41d0-b980-cedc425a8262") ) (via - (at 2.95 83.5559) + (at 10 83.5958) (size 0.6) (drill 0.3) (layers "F.Cu" "B.Cu") (net 7) - (uuid "fc7e9c7d-9983-4c0b-98b3-090595bfea37") + (uuid "84e763ec-16d2-478b-b703-97ce819a97eb") + ) + (via + (at 2.95 83.5958) + (size 0.6) + (drill 0.3) + (layers "F.Cu" "B.Cu") + (net 7) + (uuid "904ca2ad-fd28-43e4-ad82-e6b70bd7efdd") ) (segment - (start 10 83.5559) - (end 23.5578 83.5559) + (start 24.3078 83.5958) + (end 10 83.5958) (width 0.2) (layer "B.Cu") (net 7) - (uuid "4aaa64d4-2dcd-41e8-bcef-6f6f7428753e") + (uuid "3ee93d9c-307d-4fcc-a4f3-15ff1025538e") ) (segment - (start 10 83.5559) - (end 2.95 83.5559) + (start 24.3078 83.5958) + (end 30.9368 83.5958) (width 0.2) (layer "B.Cu") (net 7) - (uuid "b3a9797b-be7c-45ba-a332-27eee54ec89e") + (uuid "7a25eb03-89b4-4975-8111-1b4ff0378dbd") ) (segment - (start 23.5578 83.5559) - (end 24 83.9981) + (start 30.9368 83.5958) + (end 32.083 84.742) (width 0.2) (layer "B.Cu") (net 7) - (uuid "ebd36b53-4b24-4036-acfc-63709c71b50e") + (uuid "923abf92-c220-4b07-8d7f-0297c38a423d") + ) + (segment + (start 10 83.5958) + (end 2.95 83.5958) + (width 0.2) + (layer "B.Cu") + (net 7) + (uuid "c341b0df-d413-4e7e-9b27-8bc9712f36f3") ) (segment (start 31.2125 48) - (end 34.241 51.0285) + (end 37.6919 54.4794) (width 0.2) (layer "F.Cu") (net 8) - (uuid "0e7b4c82-d135-4d93-83e8-a1d0959e92d2") + (uuid "018f5948-0fd5-4115-989b-70f34a234218") ) (segment - (start 37.4181 77.4414) - (end 37.653 77.6763) - (width 0.2) - (layer "F.Cu") - (net 8) - (uuid "16fd3e4f-9481-41b8-8d3a-e7894e3e623a") - ) - (segment - (start 34.241 78.249) - (end 34.5191 78.5271) - (width 0.2) - (layer "F.Cu") - (net 8) - (uuid "48106692-6097-49dc-ada7-4ab60cd979da") - ) - (segment - (start 36.4345 77.4414) - (end 37.4181 77.4414) - (width 0.2) - (layer "F.Cu") - (net 8) - (uuid "7361f689-e1c1-4630-bc3a-4428d68ea7a9") - ) - (segment - (start 37.653 77.6763) - (end 37.653 83.522) - (width 0.2) - (layer "F.Cu") - (net 8) - (uuid "983c9c56-6829-40ac-989a-47341ea9e8f1") - ) - (segment - (start 35.3488 78.5271) - (end 36.4345 77.4414) - (width 0.2) - (layer "F.Cu") - (net 8) - (uuid "9c393b49-3ede-4165-a967-81cc851d90b6") - ) - (segment - (start 34.5191 78.5271) - (end 35.3488 78.5271) - (width 0.2) - (layer "F.Cu") - (net 8) - (uuid "b853baf5-86f7-448e-b61a-dbea3297ef47") - ) - (segment - (start 37.653 83.522) + (start 37.6919 83.4831) (end 36 85.175) (width 0.2) (layer "F.Cu") (net 8) - (uuid "d34261de-1aec-48d3-bdda-10e6d5b7abf2") + (uuid "84711289-141e-44f6-9d51-c619902d5ec9") ) (segment - (start 34.241 51.0285) - (end 34.241 78.249) + (start 37.6919 54.4794) + (end 37.6919 83.4831) (width 0.2) (layer "F.Cu") (net 8) - (uuid "f6936bc5-fc24-4c2a-9d21-98a971618b58") + (uuid "9e05e7b2-7014-48bc-be66-d33e3aa4e2c0") ) (segment (start 18.73 32) @@ -7372,7 +7448,7 @@ (width 0.2) (layer "F.Cu") (net 17) - (uuid "1279d7e2-3c3f-44b7-8b3c-106c73579324") + (uuid "456c2a2f-940c-4382-9af9-e2effad77116") ) (segment (start 18.73 48.03) @@ -7380,15 +7456,7 @@ (width 0.2) (layer "F.Cu") (net 17) - (uuid "c882f2fd-9b34-40a8-afdb-7b8a0ed2f1a8") - ) - (segment - (start 27.62 64.54) - (end 30.8625 67.7825) - (width 0.2) - (layer "F.Cu") - (net 20) - (uuid "0974a60d-d842-4411-b9fb-eb4e05c15b53") + (uuid "83d49645-fa94-4a84-996e-2d0e1ade38f6") ) (segment (start 30.8625 67.7825) @@ -7396,7 +7464,15 @@ (width 0.2) (layer "F.Cu") (net 20) - (uuid "41a004ae-c9e5-4d08-8243-4dcc2a70182c") + (uuid "86188837-3731-4779-9a12-d60bd05e3ecd") + ) + (segment + (start 27.62 64.54) + (end 30.8625 67.7825) + (width 0.2) + (layer "F.Cu") + (net 20) + (uuid "8e52fc89-4af2-4c40-88d4-fcd651d84ec0") ) (segment (start 4 81.8241) @@ -7404,7 +7480,7 @@ (width 0.2) (layer "F.Cu") (net 21) - (uuid "68832f9e-7de5-4816-85ae-7cdbaa2a28d8") + (uuid "66d4962d-ae61-40a7-bb28-f20ca8d2ab96") ) (via (at 4 81.8241) @@ -7412,7 +7488,7 @@ (drill 0.3) (layers "F.Cu" "B.Cu") (net 21) - (uuid "e4d187cd-7599-4abf-b965-a4876327fcdf") + (uuid "19018fc7-b065-4232-8629-a4ad5a5f13ce") ) (segment (start 12.8759 81.8241) @@ -7420,7 +7496,7 @@ (width 0.2) (layer "B.Cu") (net 21) - (uuid "2cef4206-b262-4493-bf50-584002b4fc9d") + (uuid "19ee01a3-f619-49da-a032-c9d06da1541a") ) (segment (start 27.62 67.08) @@ -7428,7 +7504,7 @@ (width 0.2) (layer "B.Cu") (net 21) - (uuid "8e1990b7-1a0e-4b4d-9a19-435b1e4b540d") + (uuid "b7cec840-a46e-4ced-8de7-f740290355aa") ) (segment (start 16.19 48.03) @@ -7436,7 +7512,7 @@ (width 0.2) (layer "F.Cu") (net 28) - (uuid "10a13f77-92c8-482c-b264-a7a5ddf36a24") + (uuid "c42e4625-bc7d-44d4-9b06-963df61377c5") ) (segment (start 16.19 32) @@ -7444,7 +7520,7 @@ (width 0.2) (layer "F.Cu") (net 28) - (uuid "7c8b9742-4935-4410-ab81-d74d9da525cd") + (uuid "cab4388b-84a5-47b6-9e90-44fb844a33ee") ) (segment (start 9.1375 79.9625) @@ -7452,7 +7528,7 @@ (width 0.2) (layer "F.Cu") (net 35) - (uuid "178bf5b5-839e-4c89-9977-d48976c6aebb") + (uuid "104007bb-edda-4e09-9d7c-a7d90bb2de14") ) (segment (start 16 86.825) @@ -7460,7 +7536,7 @@ (width 0.2) (layer "F.Cu") (net 35) - (uuid "f7f0b6e0-f82c-496c-a299-d64676cccb28") + (uuid "91e21be1-18dd-402f-ba7e-5487a3f9ec79") ) (embedded_fonts no) ) diff --git a/hardware/kicad/gerbers/SN-L00-B_Cu.gbl b/hardware/kicad/gerbers/SN-L00-B_Cu.gbl index 58af238..3be60f6 100644 --- a/hardware/kicad/gerbers/SN-L00-B_Cu.gbl +++ b/hardware/kicad/gerbers/SN-L00-B_Cu.gbl @@ -1,12 +1,12 @@ %TF.GenerationSoftware,KiCad,Pcbnew,9.0.2+dfsg-1*% -%TF.CreationDate,2026-01-23T08:01:42+01:00*% +%TF.CreationDate,2026-01-23T08:14:38+01:00*% %TF.ProjectId,SN-L00,534e2d4c-3030-42e6-9b69-6361645f7063,0.1*% %TF.SameCoordinates,Original*% %TF.FileFunction,Copper,L2,Bot*% %TF.FilePolarity,Positive*% %FSLAX46Y46*% G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* -G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:01:42* +G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:14:38* %MOMM*% %LPD*% G01* @@ -177,61 +177,68 @@ X22540000Y-98160000D03* %TD*% D15* %TO.N,Net-(D2-A)*% -X7525800Y-94231700D03* X35150000Y-90436200D03* +X7525800Y-94231700D03* X26000000Y-95962400D03* %TO.N,+12V*% -X29051000Y-89091600D03* -X38054700Y-89678700D03* -X10656900Y-92357500D03* +X33628300Y-98160000D03* +X28776100Y-89366500D03* +X10000000Y-90540000D03* +%TO.N,+3.3V*% +X11008200Y-86838000D03* +X24000000Y-87735100D03* %TO.N,Net-(D2-K)*% X2000000Y-90577900D03* %TO.N,Net-(D3-K)*% -X24000000Y-83998100D03* -X10000000Y-83555900D03* -X2950000Y-83555900D03* +X32083000Y-84742000D03* +X24307800Y-83595800D03* +X10000000Y-83595800D03* +X2950000Y-83595800D03* %TO.N,/BTN*% X4000000Y-81824100D03* %TD*% D16* %TO.N,Net-(D2-A)*% -X31354500Y-94231700D02* -X35150000Y-90436200D01* -X26000000Y-94231700D02* -X31354500Y-94231700D01* -X26000000Y-95962400D02* -X26000000Y-94231700D01* X7525800Y-94231700D02* X26000000Y-94231700D01* +X26000000Y-94231700D02* +X31354500Y-94231700D01* +X31354500Y-94231700D02* +X35150000Y-90436200D01* +X26000000Y-95962400D02* +X26000000Y-94231700D01* %TO.N,+12V*% -X37467600Y-89091600D02* -X38054700Y-89678700D01* -X20000000Y-93080000D02* -X19277500Y-92357500D01* X20000000Y-95620000D02* X22540000Y-95620000D01* -X26528400Y-89091600D02* -X29051000Y-89091600D01* -X29051000Y-89091600D02* -X37467600Y-89091600D01* -X19277500Y-92357500D02* -X10656900Y-92357500D01* X22540000Y-93080000D02* -X26528400Y-89091600D01* +X26253500Y-89366500D01* +X26253500Y-89366500D02* +X28776100Y-89366500D01* +X20000000Y-90540000D02* +X10000000Y-90540000D01* +X22540000Y-98160000D02* +X33628300Y-98160000D01* +%TO.N,+3.3V*% +X24000000Y-87735100D02* +X23102900Y-86838000D01* +X23102900Y-86838000D02* +X11008200Y-86838000D01* %TO.N,Net-(D2-K)*% X21349400Y-91730600D02* X3152700Y-91730600D01* -X22540000Y-90540000D02* -X21349400Y-91730600D01* X3152700Y-91730600D02* X2000000Y-90577900D01* +X22540000Y-90540000D02* +X21349400Y-91730600D01* %TO.N,Net-(D3-K)*% -X10000000Y-83555900D02* -X23557800Y-83555900D01* -X10000000Y-83555900D02* -X2950000Y-83555900D01* -X23557800Y-83555900D02* -X24000000Y-83998100D01* +X24307800Y-83595800D02* +X10000000Y-83595800D01* +X24307800Y-83595800D02* +X30936800Y-83595800D01* +X30936800Y-83595800D02* +X32083000Y-84742000D01* +X10000000Y-83595800D02* +X2950000Y-83595800D01* %TO.N,/BTN*% X12875900Y-81824100D02* X4000000Y-81824100D01* diff --git a/hardware/kicad/gerbers/SN-L00-B_Mask.gbs b/hardware/kicad/gerbers/SN-L00-B_Mask.gbs index d56aa5e..2159acd 100644 --- a/hardware/kicad/gerbers/SN-L00-B_Mask.gbs +++ b/hardware/kicad/gerbers/SN-L00-B_Mask.gbs @@ -1,12 +1,12 @@ %TF.GenerationSoftware,KiCad,Pcbnew,9.0.2+dfsg-1*% -%TF.CreationDate,2026-01-23T08:01:42+01:00*% +%TF.CreationDate,2026-01-23T08:14:38+01:00*% %TF.ProjectId,SN-L00,534e2d4c-3030-42e6-9b69-6361645f7063,0.1*% %TF.SameCoordinates,Original*% %TF.FileFunction,Soldermask,Bot*% %TF.FilePolarity,Negative*% %FSLAX46Y46*% G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* -G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:01:42* +G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:14:38* %MOMM*% %LPD*% G01* diff --git a/hardware/kicad/gerbers/SN-L00-B_Paste.gbp b/hardware/kicad/gerbers/SN-L00-B_Paste.gbp index e60176f..ed6c511 100644 --- a/hardware/kicad/gerbers/SN-L00-B_Paste.gbp +++ b/hardware/kicad/gerbers/SN-L00-B_Paste.gbp @@ -1,12 +1,12 @@ %TF.GenerationSoftware,KiCad,Pcbnew,9.0.2+dfsg-1*% -%TF.CreationDate,2026-01-23T08:01:42+01:00*% +%TF.CreationDate,2026-01-23T08:14:38+01:00*% %TF.ProjectId,SN-L00,534e2d4c-3030-42e6-9b69-6361645f7063,0.1*% %TF.SameCoordinates,Original*% %TF.FileFunction,Paste,Bot*% %TF.FilePolarity,Positive*% %FSLAX46Y46*% G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* -G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:01:42* +G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:14:38* %MOMM*% %LPD*% G01* diff --git a/hardware/kicad/gerbers/SN-L00-B_Silkscreen.gbo b/hardware/kicad/gerbers/SN-L00-B_Silkscreen.gbo index b5b039f..203dcb3 100644 --- a/hardware/kicad/gerbers/SN-L00-B_Silkscreen.gbo +++ b/hardware/kicad/gerbers/SN-L00-B_Silkscreen.gbo @@ -1,12 +1,12 @@ %TF.GenerationSoftware,KiCad,Pcbnew,9.0.2+dfsg-1*% -%TF.CreationDate,2026-01-23T08:01:42+01:00*% +%TF.CreationDate,2026-01-23T08:14:38+01:00*% %TF.ProjectId,SN-L00,534e2d4c-3030-42e6-9b69-6361645f7063,0.1*% %TF.SameCoordinates,Original*% %TF.FileFunction,Legend,Bot*% %TF.FilePolarity,Positive*% %FSLAX46Y46*% G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* -G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:01:42* +G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:14:38* %MOMM*% %LPD*% G01* diff --git a/hardware/kicad/gerbers/SN-L00-Edge_Cuts.gm1 b/hardware/kicad/gerbers/SN-L00-Edge_Cuts.gm1 index 2d998c3..e67297b 100644 --- a/hardware/kicad/gerbers/SN-L00-Edge_Cuts.gm1 +++ b/hardware/kicad/gerbers/SN-L00-Edge_Cuts.gm1 @@ -1,11 +1,11 @@ %TF.GenerationSoftware,KiCad,Pcbnew,9.0.2+dfsg-1*% -%TF.CreationDate,2026-01-23T08:01:42+01:00*% +%TF.CreationDate,2026-01-23T08:14:38+01:00*% %TF.ProjectId,SN-L00,534e2d4c-3030-42e6-9b69-6361645f7063,0.1*% %TF.SameCoordinates,Original*% %TF.FileFunction,Profile,NP*% %FSLAX46Y46*% G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* -G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:01:42* +G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:14:38* %MOMM*% %LPD*% G01* @@ -15,9 +15,49 @@ G04 APERTURE LIST* %TD*% G04 APERTURE END LIST* D10* +X36600000Y-5000000D02* +G75* +G02* +X33400000Y-5000000I-1600000J0D01* +G01* +X33400000Y-5000000D02* +G75* +G02* +X36600000Y-5000000I1600000J0D01* +G01* +X6600000Y-75000000D02* +G75* +G02* +X3400000Y-75000000I-1600000J0D01* +G01* +X3400000Y-75000000D02* +G75* +G02* +X6600000Y-75000000I1600000J0D01* +G01* +X36600000Y-75000000D02* +G75* +G02* +X33400000Y-75000000I-1600000J0D01* +G01* +X33400000Y-75000000D02* +G75* +G02* +X36600000Y-75000000I1600000J0D01* +G01* X0Y0D02* X40000000Y0D01* X40000000Y-100000000D01* X0Y-100000000D01* X0Y0D01* +X6600000Y-5000000D02* +G75* +G02* +X3400000Y-5000000I-1600000J0D01* +G01* +X3400000Y-5000000D02* +G75* +G02* +X6600000Y-5000000I1600000J0D01* +G01* M02* diff --git a/hardware/kicad/gerbers/SN-L00-F_Cu.gtl b/hardware/kicad/gerbers/SN-L00-F_Cu.gtl index 68b9eb1..c45b3b3 100644 --- a/hardware/kicad/gerbers/SN-L00-F_Cu.gtl +++ b/hardware/kicad/gerbers/SN-L00-F_Cu.gtl @@ -1,12 +1,12 @@ %TF.GenerationSoftware,KiCad,Pcbnew,9.0.2+dfsg-1*% -%TF.CreationDate,2026-01-23T08:01:42+01:00*% +%TF.CreationDate,2026-01-23T08:14:38+01:00*% %TF.ProjectId,SN-L00,534e2d4c-3030-42e6-9b69-6361645f7063,0.1*% %TF.SameCoordinates,Original*% %TF.FileFunction,Copper,L1,Top*% %TF.FilePolarity,Positive*% %FSLAX46Y46*% G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* -G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:01:42* +G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:14:38* %MOMM*% %LPD*% G01* @@ -371,19 +371,23 @@ X22540000Y-98160000D03* %TD*% D24* %TO.N,Net-(D2-A)*% -X7525800Y-94231700D03* X35150000Y-90436200D03* +X7525800Y-94231700D03* X26000000Y-95962400D03* %TO.N,+12V*% -X29051000Y-89091600D03* -X38054700Y-89678700D03* -X10656900Y-92357500D03* +X33628300Y-98160000D03* +X28776100Y-89366500D03* +X10000000Y-90540000D03* +%TO.N,+3.3V*% +X11008200Y-86838000D03* +X24000000Y-87735100D03* %TO.N,Net-(D2-K)*% X2000000Y-90577900D03* %TO.N,Net-(D3-K)*% -X24000000Y-83998100D03* -X10000000Y-83555900D03* -X2950000Y-83555900D03* +X32083000Y-84742000D03* +X24307800Y-83595800D03* +X10000000Y-83595800D03* +X2950000Y-83595800D03* %TO.N,/BTN*% X4000000Y-81824100D03* %TD*% @@ -398,174 +402,174 @@ X7525800Y-93525800D01* X35150000Y-91700000D02* X35150000Y-90436200D01* %TO.N,+12V*% -X30000000Y-83225000D02* -X30000000Y-85175000D01* -X34950000Y-50162500D02* -X34950000Y-77039700D01* +X28000000Y-81225000D02* +X28951900Y-82176800D01* +X8526200Y-91751200D02* +X8526200Y-80613700D01* +X28776100Y-89366500D02* +X28776100Y-86398900D01* +X25970000Y-93080000D02* +X26000000Y-93050000D01* +X10000000Y-93225000D02* +X8526200Y-91751200D01* +X20000000Y-93080000D02* +X20000000Y-90540000D01* X20000000Y-95620000D02* X20000000Y-93080000D01* X30076000Y-36216700D02* X32787500Y-38928200D01* -X7878200Y-78337700D02* -X7878200Y-76995000D01* -X29051000Y-89091600D02* -X29051000Y-86124000D01* -X10000000Y-93225000D02* -X10000000Y-92357500D01* -X30000000Y-35000000D02* -X30000000Y-36216700D01* -X38054700Y-93395300D02* -X38054700Y-89678700D01* -X29051000Y-86124000D02* -X30000000Y-85175000D01* -X20000000Y-93080000D02* -X20000000Y-90540000D01* -X10000000Y-92357500D02* -X10656900Y-92357500D01* -X6862500Y-88037500D02* -X6862500Y-78950000D01* -X10000000Y-92357500D02* -X10000000Y-91175000D01* -X13397200Y-76447200D02* -X14000000Y-77050000D01* -X25970000Y-93080000D02* -X26000000Y-93050000D01* -X32787500Y-48000000D02* -X34950000Y-50162500D01* -X10000000Y-91175000D02* -X6862500Y-88037500D01* -X38054700Y-89678700D02* -X38054700Y-77510000D01* -X7265900Y-78950000D02* -X7878200Y-78337700D01* -X7878200Y-76995000D02* -X8426000Y-76447200D01* -X38054700Y-77510000D02* -X37584400Y-77039700D01* -X35150000Y-96300000D02* -X38054700Y-93395300D01* -X22540000Y-93080000D02* -X25970000Y-93080000D01* -X37584400Y-77039700D02* -X34950000Y-77039700D01* -X34950000Y-77039700D02* -X34950000Y-78000000D01* -X30000000Y-36216700D02* -X30076000Y-36216700D01* -X22540000Y-98160000D02* -X22540000Y-95620000D01* -X28000000Y-81225000D02* -X30000000Y-83225000D01* -X6862500Y-78950000D02* -X7265900Y-78950000D01* +X32036400Y-79092300D02* +X32036400Y-77272000D01* +X18847300Y-81897300D02* +X18847300Y-89387300D01* X20000000Y-98160000D02* X20000000Y-95620000D01* -X32787500Y-38928200D02* -X32787500Y-48000000D01* -X8426000Y-76447200D02* -X13397200Y-76447200D01* +X22540000Y-93080000D02* +X25970000Y-93080000D01* X22540000Y-95620000D02* X22540000Y-93080000D01* +X32764400Y-78000000D02* +X34950000Y-78000000D01* +X32036400Y-54627600D02* +X32036400Y-77272000D01* +X32036400Y-77272000D02* +X32764400Y-78000000D01* +X30000000Y-35608300D02* +X30000000Y-36216700D01* +X30000000Y-35608300D02* +X28188200Y-37420100D01* +X35150000Y-96300000D02* +X33628300Y-97821700D01* +X30000000Y-36216700D02* +X30076000Y-36216700D01* +X28776100Y-86398900D02* +X30000000Y-85175000D01* +X30000000Y-35000000D02* +X30000000Y-35608300D01* +X32787500Y-38928200D02* +X32787500Y-48000000D01* +X30000000Y-83742700D02* +X30000000Y-85175000D01* +X29211000Y-82953700D02* +X30000000Y-83742700D01* +X33628300Y-97821700D02* +X33628300Y-98160000D01* +X28951900Y-82176800D02* +X29211000Y-82436000D01* +X10000000Y-93225000D02* +X10000000Y-90540000D01* +X8526200Y-80613700D02* +X6862500Y-78950000D01* +X28188200Y-37420100D02* +X28188200Y-50779400D01* +X18847300Y-89387300D02* +X20000000Y-90540000D01* +X22540000Y-98160000D02* +X22540000Y-95620000D01* +X29211000Y-82436000D02* +X29211000Y-82953700D01* +X28188200Y-50779400D02* +X32036400Y-54627600D01* +X14000000Y-77050000D02* +X18847300Y-81897300D01* +X28951900Y-82176800D02* +X32036400Y-79092300D01* %TO.N,+3.3V*% -X36476700Y-92673300D02* -X35150000Y-94000000D01* -X8126000Y-92901000D02* -X10000000Y-94775000D01* -X17232300Y-82182300D02* -X17232300Y-86825000D01* -X17232300Y-87542700D02* -X10000000Y-94775000D01* -X17232300Y-86825000D02* -X17232300Y-87542700D01* -X28000000Y-82800000D02* -X28000000Y-93150000D01* -X5050000Y-82000000D02* -X5050000Y-86825000D01* -X28000000Y-93150000D02* -X28850000Y-94000000D01* -X14000000Y-78950000D02* -X11037500Y-78950000D01* -X28000000Y-82800000D02* -X28000000Y-82775000D01* -X14000000Y-78950000D02* -X17232300Y-82182300D01* -X24000000Y-86825000D02* -X17232300Y-86825000D01* -X5050000Y-86825000D02* -X8126000Y-89901000D01* -X36476700Y-87301700D02* -X36476700Y-92673300D01* -X5050000Y-86825000D02* -X4000000Y-86825000D01* -X24000000Y-86825000D02* -X28000000Y-82825000D01* -X8126000Y-89901000D02* -X8126000Y-92901000D01* -X28000000Y-82825000D02* -X28000000Y-82800000D01* -X36000000Y-86825000D02* -X36476700Y-87301700D01* -X11037500Y-78950000D02* -X9137500Y-77050000D01* +X10820600Y-82333500D02* +X10820600Y-86838000D01* +X10820600Y-86838000D02* +X10820600Y-93954400D01* X35150000Y-94000000D02* X28850000Y-94000000D01* +X5050000Y-82000000D02* +X5050000Y-86825000D01* +X5050000Y-86825000D02* +X4000000Y-86825000D01* +X28000000Y-82800000D02* +X28000000Y-93150000D01* +X35150000Y-94000000D02* +X36476700Y-92673300D01* +X8167100Y-79680000D02* +X10820600Y-82333500D01* +X28000000Y-93150000D02* +X28850000Y-94000000D01* +X9198600Y-77111100D02* +X9137500Y-77050000D01* +X10623600Y-78950000D02* +X9198600Y-77525000D01* +X8124500Y-89899500D02* +X8124500Y-92899500D01* +X9198600Y-77525000D02* +X9198600Y-77111100D01* +X24000000Y-86825000D02* +X28000000Y-82825000D01* +X24000000Y-86825000D02* +X24000000Y-87735100D01* +X10820600Y-86838000D02* +X11008200Y-86838000D01* +X10820600Y-93954400D02* +X10000000Y-94775000D01* +X8124500Y-92899500D02* +X10000000Y-94775000D01* +X14000000Y-78950000D02* +X10623600Y-78950000D01* +X36476700Y-92673300D02* +X36476700Y-87301700D01* +X28000000Y-82825000D02* +X28000000Y-82800000D01* +X28000000Y-82800000D02* +X28000000Y-82775000D01* +X9198600Y-77525000D02* +X8167100Y-78556500D01* +X5050000Y-86825000D02* +X8124500Y-89899500D01* +X36476700Y-87301700D02* +X36000000Y-86825000D01* +X8167100Y-78556500D02* +X8167100Y-79680000D01* %TO.N,Net-(D2-K)*% X2000000Y-90577900D02* X2000000Y-92000000D01* %TO.N,Net-(D3-K)*% -X2950000Y-82000000D02* -X2950000Y-83555900D01* -X36100000Y-78950000D02* -X37050000Y-78000000D01* -X32143300Y-79944200D02* +X33137500Y-83687500D02* +X33137500Y-78950000D01* +X36100000Y-78950000D02* X33137500Y-78950000D01* -X31856700Y-79944200D02* -X30862500Y-78950000D01* -X24000000Y-83998100D02* -X29048100Y-78950000D01* -X10000000Y-85175000D02* -X10000000Y-83555900D01* -X29048100Y-78950000D02* -X30862500Y-78950000D01* X24000000Y-85175000D02* -X24000000Y-83998100D01* -X33137500Y-78950000D02* +X24000000Y-83903600D01* +X37050000Y-78000000D02* X36100000Y-78950000D01* +X10000000Y-85175000D02* +X10000000Y-83595800D01* +X24307800Y-83595800D02* +X28953600Y-78950000D01* +X24000000Y-83903600D02* +X24307800Y-83595800D01* +X2950000Y-82000000D02* +X2950000Y-83595800D01* X30000000Y-86825000D02* -X31856700Y-84968300D01* -X31856700Y-79944200D02* -X32143300Y-79944200D01* -X31856700Y-84968300D02* -X31856700Y-79944200D01* +X32083000Y-84742000D01* +X32083000Y-84742000D02* +X33137500Y-83687500D01* +X28953600Y-78950000D02* +X30862500Y-78950000D01* %TO.N,Net-(D5-K)*% X31212500Y-48000000D02* -X34241000Y-51028500D01* -X37418100Y-77441400D02* -X37653000Y-77676300D01* -X34241000Y-78249000D02* -X34519100Y-78527100D01* -X36434500Y-77441400D02* -X37418100Y-77441400D01* -X37653000Y-77676300D02* -X37653000Y-83522000D01* -X35348800Y-78527100D02* -X36434500Y-77441400D01* -X34519100Y-78527100D02* -X35348800Y-78527100D01* -X37653000Y-83522000D02* +X37691900Y-54479400D01* +X37691900Y-83483100D02* X36000000Y-85175000D01* -X34241000Y-51028500D02* -X34241000Y-78249000D01* +X37691900Y-54479400D02* +X37691900Y-83483100D01* %TO.N,/SDA*% X18730000Y-32000000D02* X18730000Y-48030000D01* X18730000Y-48030000D02* X27620000Y-56920000D01* %TO.N,/RETURN_IN*% -X27620000Y-64540000D02* -X30862500Y-67782500D01* X30862500Y-67782500D02* X30862500Y-77050000D01* +X27620000Y-64540000D02* +X30862500Y-67782500D01* %TO.N,/BTN*% X4000000Y-81824100D02* X4000000Y-85175000D01* diff --git a/hardware/kicad/gerbers/SN-L00-F_Mask.gts b/hardware/kicad/gerbers/SN-L00-F_Mask.gts index 98fb96b..f5cb826 100644 --- a/hardware/kicad/gerbers/SN-L00-F_Mask.gts +++ b/hardware/kicad/gerbers/SN-L00-F_Mask.gts @@ -1,12 +1,12 @@ %TF.GenerationSoftware,KiCad,Pcbnew,9.0.2+dfsg-1*% -%TF.CreationDate,2026-01-23T08:01:42+01:00*% +%TF.CreationDate,2026-01-23T08:14:38+01:00*% %TF.ProjectId,SN-L00,534e2d4c-3030-42e6-9b69-6361645f7063,0.1*% %TF.SameCoordinates,Original*% %TF.FileFunction,Soldermask,Top*% %TF.FilePolarity,Negative*% %FSLAX46Y46*% G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* -G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:01:42* +G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:14:38* %MOMM*% %LPD*% G01* diff --git a/hardware/kicad/gerbers/SN-L00-F_Paste.gtp b/hardware/kicad/gerbers/SN-L00-F_Paste.gtp index 7ce7b38..cf41163 100644 --- a/hardware/kicad/gerbers/SN-L00-F_Paste.gtp +++ b/hardware/kicad/gerbers/SN-L00-F_Paste.gtp @@ -1,12 +1,12 @@ %TF.GenerationSoftware,KiCad,Pcbnew,9.0.2+dfsg-1*% -%TF.CreationDate,2026-01-23T08:01:42+01:00*% +%TF.CreationDate,2026-01-23T08:14:38+01:00*% %TF.ProjectId,SN-L00,534e2d4c-3030-42e6-9b69-6361645f7063,0.1*% %TF.SameCoordinates,Original*% %TF.FileFunction,Paste,Top*% %TF.FilePolarity,Positive*% %FSLAX46Y46*% G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* -G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:01:42* +G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:14:38* %MOMM*% %LPD*% G01* diff --git a/hardware/kicad/gerbers/SN-L00-F_Silkscreen.gto b/hardware/kicad/gerbers/SN-L00-F_Silkscreen.gto index 9a1cc2f..e6adb40 100644 --- a/hardware/kicad/gerbers/SN-L00-F_Silkscreen.gto +++ b/hardware/kicad/gerbers/SN-L00-F_Silkscreen.gto @@ -1,12 +1,12 @@ %TF.GenerationSoftware,KiCad,Pcbnew,9.0.2+dfsg-1*% -%TF.CreationDate,2026-01-23T08:01:42+01:00*% +%TF.CreationDate,2026-01-23T08:14:38+01:00*% %TF.ProjectId,SN-L00,534e2d4c-3030-42e6-9b69-6361645f7063,0.1*% %TF.SameCoordinates,Original*% %TF.FileFunction,Legend,Top*% %TF.FilePolarity,Positive*% %FSLAX46Y46*% G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* -G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:01:42* +G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:14:38* %MOMM*% %LPD*% G01* diff --git a/hardware/kicad/gerbers/SN-L00-drl_map.gbr b/hardware/kicad/gerbers/SN-L00-drl_map.gbr index 32ffb6a..1b7f708 100644 --- a/hardware/kicad/gerbers/SN-L00-drl_map.gbr +++ b/hardware/kicad/gerbers/SN-L00-drl_map.gbr @@ -1,12 +1,12 @@ %TF.GenerationSoftware,KiCad,Pcbnew,9.0.2+dfsg-1*% -%TF.CreationDate,2026-01-23T08:01:45+01:00*% +%TF.CreationDate,2026-01-23T08:14:39+01:00*% %TF.ProjectId,SN-L00,534e2d4c-3030-42e6-9b69-6361645f7063,0.1*% %TF.SameCoordinates,Original*% %TF.FileFunction,Drillmap*% %TF.FilePolarity,Positive*% %FSLAX45Y45*% G04 Gerber Fmt 4.5, Leading zero omitted, Abs format (unit mm)* -G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:01:45* +G04 Created by KiCad (PCBNEW 9.0.2+dfsg-1) date 2026-01-23 08:14:39* %MOMM*% %LPD*% G01* @@ -19,21 +19,61 @@ G04 APERTURE LIST* %ADD15C,0.143000*% G04 APERTURE END LIST* D10* +X3660000Y-500000D02* +G75* +G02* +X3340000Y-500000I-160000J0D01* +G01* +X3340000Y-500000D02* +G75* +G02* +X3660000Y-500000I160000J0D01* +G01* +X660000Y-7500000D02* +G75* +G02* +X340000Y-7500000I-160000J0D01* +G01* +X340000Y-7500000D02* +G75* +G02* +X660000Y-7500000I160000J0D01* +G01* +X3660000Y-7500000D02* +G75* +G02* +X3340000Y-7500000I-160000J0D01* +G01* +X3340000Y-7500000D02* +G75* +G02* +X3660000Y-7500000I160000J0D01* +G01* X0Y0D02* X4000000Y0D01* X4000000Y-10000000D01* X0Y-10000000D01* X0Y0D01* +X660000Y-500000D02* +G75* +G02* +X340000Y-500000I-160000J0D01* +G01* +X340000Y-500000D02* +G75* +G02* +X660000Y-500000I160000J0D01* +G01* D11* D12* X185000Y-9042790D02* X215000Y-9072790D01* X215000Y-9042790D02* X185000Y-9072790D01* -X280000Y-8340590D02* -X310000Y-8370590D01* -X310000Y-8340590D02* -X280000Y-8370590D01* +X280000Y-8344580D02* +X310000Y-8374580D01* +X310000Y-8344580D02* +X280000Y-8374580D01* X385000Y-8167410D02* X415000Y-8197410D01* X415000Y-8167410D02* @@ -42,34 +82,46 @@ X737580Y-9408170D02* X767580Y-9438170D01* X767580Y-9408170D02* X737580Y-9438170D01* -X985000Y-8340590D02* -X1015000Y-8370590D01* -X1015000Y-8340590D02* -X985000Y-8370590D01* -X1050690Y-9220750D02* -X1080690Y-9250750D01* -X1080690Y-9220750D02* -X1050690Y-9250750D01* -X2385000Y-8384810D02* -X2415000Y-8414810D01* -X2415000Y-8384810D02* -X2385000Y-8414810D01* +X985000Y-8344580D02* +X1015000Y-8374580D01* +X1015000Y-8344580D02* +X985000Y-8374580D01* +X985000Y-9039000D02* +X1015000Y-9069000D01* +X1015000Y-9039000D02* +X985000Y-9069000D01* +X1085820Y-8668800D02* +X1115820Y-8698800D01* +X1115820Y-8668800D02* +X1085820Y-8698800D01* +X2385000Y-8758510D02* +X2415000Y-8788510D01* +X2415000Y-8758510D02* +X2385000Y-8788510D01* +X2415780Y-8344580D02* +X2445780Y-8374580D01* +X2445780Y-8344580D02* +X2415780Y-8374580D01* X2585000Y-9581240D02* X2615000Y-9611240D01* X2615000Y-9581240D02* X2585000Y-9611240D01* -X2890100Y-8894160D02* -X2920100Y-8924160D01* -X2920100Y-8894160D02* -X2890100Y-8924160D01* +X2862610Y-8921650D02* +X2892610Y-8951650D01* +X2892610Y-8921650D02* +X2862610Y-8951650D01* +X3193300Y-8459200D02* +X3223300Y-8489200D01* +X3223300Y-8459200D02* +X3193300Y-8489200D01* +X3347830Y-9801000D02* +X3377830Y-9831000D01* +X3377830Y-9801000D02* +X3347830Y-9831000D01* X3500000Y-9028620D02* X3530000Y-9058620D01* X3530000Y-9028620D02* X3500000Y-9058620D01* -X3790470Y-8952870D02* -X3820470Y-8982870D01* -X3820470Y-8952870D02* -X3790470Y-8982870D01* X1288000Y-5184000D02* G75* G02* @@ -984,16 +1036,12 @@ X3672325Y-10567555D02* X3653277Y-10586603D01* X3653277Y-10586603D02* X3634229Y-10596127D01* -X3938991Y-10738984D02* -X3824706Y-10738984D01* -X3881848Y-10738984D02* -X3881848Y-10538984D01* -X3881848Y-10538984D02* -X3862801Y-10567555D01* -X3862801Y-10567555D02* -X3843753Y-10586603D01* -X3843753Y-10586603D02* -X3824706Y-10596127D01* +X3919944Y-10605650D02* +X3919944Y-10738984D01* +X3872325Y-10529460D02* +X3824706Y-10672317D01* +X3824706Y-10672317D02* +X3948515Y-10672317D01* X4177087Y-10738984D02* X4177087Y-10538984D01* X4262801Y-10738984D02* diff --git a/hardware/kicad/gerbers/SN-L00-job.gbrjob b/hardware/kicad/gerbers/SN-L00-job.gbrjob index 19c7c97..861bb54 100644 --- a/hardware/kicad/gerbers/SN-L00-job.gbrjob +++ b/hardware/kicad/gerbers/SN-L00-job.gbrjob @@ -5,7 +5,7 @@ "Application": "Pcbnew", "Version": "9.0.2+dfsg-1" }, - "CreationDate": "2026-01-23T08:01:42+01:00" + "CreationDate": "2026-01-23T08:14:38+01:00" }, "GeneralSpecs": { "ProjectId": { diff --git a/hardware/kicad/gerbers/SN-L00.drl b/hardware/kicad/gerbers/SN-L00.drl index 4166ef2..02f34b8 100644 --- a/hardware/kicad/gerbers/SN-L00.drl +++ b/hardware/kicad/gerbers/SN-L00.drl @@ -1,7 +1,7 @@ M48 -; DRILL file {KiCad 9.0.2+dfsg-1} date 2026-01-23T08:01:45+0100 +; DRILL file {KiCad 9.0.2+dfsg-1} date 2026-01-23T08:14:39+0100 ; FORMAT={-:-/ absolute / metric / decimal} -; #@! TF.CreationDate,2026-01-23T08:01:45+01:00 +; #@! TF.CreationDate,2026-01-23T08:14:39+01:00 ; #@! TF.GenerationSoftware,Kicad,Pcbnew,9.0.2+dfsg-1 ; #@! TF.FileFunction,MixedPlating,1,2 FMAT,2 @@ -21,16 +21,19 @@ G90 G05 T1 X2.0Y-90.578 -X2.95Y-83.556 +X2.95Y-83.596 X4.0Y-81.824 X7.526Y-94.232 -X10.0Y-83.556 -X10.657Y-92.358 -X24.0Y-83.998 +X10.0Y-83.596 +X10.0Y-90.54 +X11.008Y-86.838 +X24.0Y-87.735 +X24.308Y-83.596 X26.0Y-95.962 -X29.051Y-89.092 +X28.776Y-89.367 +X32.083Y-84.742 +X33.628Y-98.16 X35.15Y-90.436 -X38.055Y-89.679 T2 X12.38Y-51.84 X12.38Y-54.38 diff --git a/hardware/kicad/scripts/autoroute.py b/hardware/kicad/scripts/autoroute.py index 6e50539..463d46c 100755 --- a/hardware/kicad/scripts/autoroute.py +++ b/hardware/kicad/scripts/autoroute.py @@ -33,6 +33,15 @@ DRC_FILE = "DRC.rpt" FREEROUTING_JAR = "/tmp/freerouting.jar" FREEROUTING_URL = "https://github.com/freerouting/freerouting/releases/download/v2.0.1/freerouting-2.0.1.jar" +# Mounting hole positions (M3, 3.2mm diameter) +# Bottom holes moved up to avoid power section +MOUNTING_HOLES = [ + (5, 5), # Top left + (35, 5), # Top right + (5, 75), # Bottom left (above power section) + (35, 75), # Bottom right (above power section) +] + # Component positions for 8HP (40mm x 100mm) layout v2 PLACEMENTS = { # Top - OLED display @@ -124,6 +133,29 @@ def main(): placed += 1 print(f" Placed {placed} components") + # Step 4b: Add mounting holes + print("\n[4b/9] Adding mounting holes...") + # Remove existing mounting holes first + for drawing in list(board.GetDrawings()): + if drawing.GetClass() == "PCB_SHAPE": + if drawing.GetShape() == pcbnew.SHAPE_T_CIRCLE: + # Check if it's a mounting hole (on Edge.Cuts, 3.2mm diameter) + if drawing.GetLayer() == pcbnew.Edge_Cuts: + radius = pcbnew.ToMM(drawing.GetRadius()) + if 1.5 < radius < 1.7: # ~3.2mm diameter + board.Delete(drawing) + + # Add new mounting holes + for x, y in MOUNTING_HOLES: + hole = pcbnew.PCB_SHAPE(board) + hole.SetShape(pcbnew.SHAPE_T_CIRCLE) + hole.SetCenter(place(x, y)) + hole.SetEnd(place(x + 1.6, y)) # Radius = 1.6mm (3.2mm diameter) + hole.SetLayer(pcbnew.Edge_Cuts) + hole.SetWidth(mm(0.15)) + board.Add(hole) + print(f" Added {len(MOUNTING_HOLES)} mounting holes (M3, 3.2mm)") + # Step 5: Export DSN print("\n[5/9] Exporting Specctra DSN...") board.Save(PCB_FILE) # Save first diff --git a/hardware/kicad/scripts/autoroute_cli.py b/hardware/kicad/scripts/autoroute_cli.py new file mode 100644 index 0000000..f95ca93 --- /dev/null +++ b/hardware/kicad/scripts/autoroute_cli.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 +""" +SN-L00 Command-Line Autoroute Pipeline +Run from terminal: python3 scripts/autoroute_cli.py + +Requires: kicad-cli or pcbnew Python module available +""" + +import subprocess +import os +import sys + +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +KICAD_DIR = os.path.dirname(SCRIPT_DIR) +PCB_FILE = os.path.join(KICAD_DIR, "SN-L00.kicad_pcb") +DSN_FILE = os.path.join(KICAD_DIR, "SN-L00.dsn") +SES_FILE = os.path.join(KICAD_DIR, "SN-L00.ses") +FREEROUTING_JAR = "/tmp/freerouting.jar" +FREEROUTING_URL = "https://github.com/freerouting/freerouting/releases/download/v2.0.1/freerouting-2.0.1.jar" + +def run(cmd, desc, cwd=None): + """Run command with description""" + print(f" {desc}...") + result = subprocess.run(cmd, capture_output=True, text=True, cwd=cwd) + if result.returncode != 0: + print(f" ERROR: {result.stderr}") + return False + return True + +def main(): + print("=" * 50) + print("SN-L00 Command-Line Autoroute Pipeline") + print("=" * 50) + + # Check for kicad-cli + kicad_cli = None + for path in ["/usr/bin/kicad-cli", "/usr/local/bin/kicad-cli", + "/Applications/KiCad/KiCad.app/Contents/MacOS/kicad-cli"]: + if os.path.exists(path): + kicad_cli = path + break + + if not kicad_cli: + # Try to find in PATH + result = subprocess.run(["which", "kicad-cli"], capture_output=True, text=True) + if result.returncode == 0: + kicad_cli = result.stdout.strip() + + if not kicad_cli: + print("ERROR: kicad-cli not found. Please run in KiCad scripting console instead:") + print(" exec(open('scripts/autoroute_full.py').read())") + sys.exit(1) + + print(f"Using: {kicad_cli}") + + # Step 1: Run placement script in KiCad + print("\n[1/4] Placing components...") + # kicad-cli pcb export dsn also runs any embedded scripts, but we need + # to place first. For now, assume placement was done or use Python API + print(" (Run place_8hp.py in KiCad first, or components should already be placed)") + + # Step 2: Export DSN + print("\n[2/4] Exporting DSN...") + if not run([kicad_cli, "pcb", "export", "dsn", "-o", DSN_FILE, PCB_FILE], + "Exporting Specctra DSN"): + sys.exit(1) + print(f" Created: {DSN_FILE}") + + # Step 3: Download Freerouting if needed + print("\n[3/4] Running Freerouting...") + if not os.path.exists(FREEROUTING_JAR): + print(" Downloading Freerouting...") + if not run(["curl", "-L", "-o", FREEROUTING_JAR, FREEROUTING_URL], + "Downloading"): + sys.exit(1) + + # Run Freerouting + result = subprocess.run( + ["java", "-jar", FREEROUTING_JAR, + "-de", DSN_FILE, + "-do", SES_FILE, + "-mp", "200", + "-mt", "1", + "-oit"], + capture_output=True, + text=True, + cwd=KICAD_DIR + ) + + if result.returncode != 0: + print(f" Freerouting error: {result.stderr}") + sys.exit(1) + + # Parse output for timing + for line in result.stdout.split('\n') + result.stderr.split('\n'): + if 'completed' in line.lower(): + print(f" {line.split(']')[-1].strip()}") + + print(f" Created: {SES_FILE}") + + # Step 4: Import SES + print("\n[4/4] Importing routed session...") + if not run([kicad_cli, "pcb", "import", "ses", "-i", SES_FILE, PCB_FILE], + "Importing Specctra session"): + # kicad-cli might not support import, manual step needed + print(" NOTE: Import via kicad-cli may not be supported.") + print(" In KiCad: File → Import → Specctra Session") + else: + print(f" Imported routes into: {PCB_FILE}") + + print("\n" + "=" * 50) + print("DONE! Open PCB in KiCad and run DRC to verify.") + print("=" * 50) + +if __name__ == "__main__": + main() diff --git a/hardware/kicad/scripts/autoroute_headless.py b/hardware/kicad/scripts/autoroute_headless.py new file mode 100755 index 0000000..769a426 --- /dev/null +++ b/hardware/kicad/scripts/autoroute_headless.py @@ -0,0 +1,293 @@ +#!/usr/bin/env python3 +""" +SN-L00 Headless Autoroute Pipeline +Fully automated: place → export DSN → freeroute → import SES → DRC + +Usage: + # Install dependencies first: + sudo apt install xvfb + pip install kigadgets + + # Run: + python3 scripts/autoroute_headless.py + +Based on: https://github.com/atait/kicad-python +""" + +import os +import sys +import subprocess +import tempfile + +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +KICAD_DIR = os.path.dirname(SCRIPT_DIR) +PCB_FILE = os.path.join(KICAD_DIR, "SN-L00.kicad_pcb") +DSN_FILE = os.path.join(KICAD_DIR, "SN-L00.dsn") +SES_FILE = os.path.join(KICAD_DIR, "SN-L00.ses") +DRC_FILE = os.path.join(KICAD_DIR, "DRC.rpt") +FREEROUTING_JAR = "/tmp/freerouting.jar" + +# Component positions for 8HP (40mm x 100mm) layout v2 +PLACEMENTS = { + "MOD3": (20, 15, 90), + "J3": (10, 35, 0), + "J4": (30, 35, 0), + "SW1": (20, 48, 0), + "D5": (32, 48, 0), + "MOD2": (20, 62, 0), + "U2": (8, 78, 0), + "U4": (32, 78, 0), + "C4": (4, 78, 90), + "C5": (14, 78, 90), + "C6": (28, 82, 90), + "D3": (4, 82, 0), + "D4": (36, 78, 0), + "R2": (4, 86, 90), + "R3": (10, 86, 90), + "R4": (16, 86, 90), + "R5": (24, 86, 90), + "R6": (30, 86, 90), + "R7": (36, 86, 90), + "J2": (20, 88, 0), + "D2": (4, 92, 0), + "U3": (32, 94, 180), + "C2": (10, 94, 90), + "C3": (26, 94, 90), +} + + +def check_dependencies(): + """Check if required tools are available.""" + missing = [] + + # Check xvfb + if subprocess.run(["which", "xvfb-run"], capture_output=True).returncode != 0: + missing.append("xvfb (sudo apt install xvfb)") + + # Check java + if subprocess.run(["which", "java"], capture_output=True).returncode != 0: + missing.append("java (sudo apt install default-jre)") + + # Check kicad-cli + if subprocess.run(["which", "kicad-cli"], capture_output=True).returncode != 0: + missing.append("kicad-cli (install KiCad)") + + if missing: + print("Missing dependencies:") + for dep in missing: + print(f" - {dep}") + sys.exit(1) + + +def download_freerouting(): + """Download Freerouting if not present.""" + if not os.path.exists(FREEROUTING_JAR): + print("Downloading Freerouting...") + url = "https://github.com/freerouting/freerouting/releases/download/v2.0.1/freerouting-2.0.1.jar" + subprocess.run(["curl", "-L", "-o", FREEROUTING_JAR, url], check=True) + + +def run_pcbnew_script(script_content): + """Run a Python script inside pcbnew using xvfb.""" + with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f: + f.write(script_content) + script_path = f.name + + try: + # Run pcbnew with xvfb, execute script, then exit + # This is a workaround since pcbnew doesn't have a direct script execution mode + result = subprocess.run( + ["xvfb-run", "-a", "python3", "-c", f""" +import sys +sys.path.insert(0, '/usr/lib/python3/dist-packages') +try: + import pcbnew + exec(open('{script_path}').read()) +except Exception as e: + print(f"Error: {{e}}") + sys.exit(1) +"""], + capture_output=True, + text=True, + timeout=120 + ) + print(result.stdout) + if result.stderr: + print(result.stderr) + return result.returncode == 0 + finally: + os.unlink(script_path) + + +def place_and_export(): + """Place components and export DSN using pcbnew API.""" + script = f''' +import pcbnew + +board = pcbnew.LoadBoard("{PCB_FILE}") + +def mm(val): + return pcbnew.FromMM(val) + +def place(x, y): + return pcbnew.VECTOR2I(mm(x), mm(y)) + +# Update board outline +for drawing in board.GetDrawings(): + if drawing.GetClass() == "PCB_SHAPE": + if drawing.GetShape() == pcbnew.SHAPE_T_RECT: + drawing.SetStart(pcbnew.VECTOR2I(mm(0), mm(0))) + drawing.SetEnd(pcbnew.VECTOR2I(mm(40), mm(100))) + print("Updated board outline") + break + +# Delete tracks +tracks = list(board.GetTracks()) +for track in tracks: + board.Delete(track) +print(f"Deleted {{len(tracks)}} tracks") + +# Place components +placements = {repr(PLACEMENTS)} + +placed = 0 +for ref, (x, y, rot) in placements.items(): + fp = board.FindFootprintByReference(ref) + if fp: + fp.SetPosition(place(x, y)) + fp.SetOrientationDegrees(rot) + placed += 1 + +print(f"Placed {{placed}} components") + +# Save board +board.Save("{PCB_FILE}") +print("Saved board") + +# Export DSN +try: + result = pcbnew.ExportSpecctraDSN("{DSN_FILE}") + if result: + print("Exported DSN") + else: + print("DSN export returned False - trying alternate method") + # Try with board parameter + result = pcbnew.ExportSpecctraDSN(board, "{DSN_FILE}") + print(f"Alternate export result: {{result}}") +except Exception as e: + print(f"DSN export error: {{e}}") +''' + return run_pcbnew_script(script) + + +def run_freerouting(): + """Run Freerouting autorouter.""" + print("Running Freerouting...") + result = subprocess.run( + ["java", "-jar", FREEROUTING_JAR, + "-de", DSN_FILE, + "-do", SES_FILE, + "-mp", "200", + "-mt", "1", + "-oit"], + capture_output=True, + text=True, + cwd=KICAD_DIR + ) + + for line in (result.stdout + result.stderr).split('\n'): + if 'completed' in line.lower() or 'error' in line.lower(): + print(f" {line.split(']')[-1].strip()}") + + return os.path.exists(SES_FILE) + + +def import_ses(): + """Import SES file using pcbnew API.""" + script = f''' +import pcbnew + +board = pcbnew.LoadBoard("{PCB_FILE}") + +try: + result = pcbnew.ImportSpecctraSES("{SES_FILE}") + if result: + print("Imported SES") + board.Save("{PCB_FILE}") + print("Saved board") + else: + print("SES import returned False - trying alternate method") + result = pcbnew.ImportSpecctraSES(board, "{SES_FILE}") + if result: + board.Save("{PCB_FILE}") + print("Saved board") +except Exception as e: + print(f"SES import error: {{e}}") +''' + return run_pcbnew_script(script) + + +def run_drc(): + """Run DRC using kicad-cli.""" + print("Running DRC...") + result = subprocess.run( + ["kicad-cli", "pcb", "drc", + "--severity-all", + "--units", "mm", + "-o", DRC_FILE, + PCB_FILE], + capture_output=True, + text=True + ) + print(result.stdout) + + # Count errors + if os.path.exists(DRC_FILE): + with open(DRC_FILE) as f: + content = f.read() + errors = content.count('; error') + warnings = content.count('; warning') + print(f"DRC: {errors} errors, {warnings} warnings") + return errors == 0 + return False + + +def main(): + print("=" * 50) + print("SN-L00 Headless Autoroute Pipeline") + print("=" * 50) + + check_dependencies() + download_freerouting() + + print("\n[1/4] Placing components and exporting DSN...") + if not place_and_export(): + print("Failed to place/export") + # Fall back to manual DSN check + if not os.path.exists(DSN_FILE): + print(f"ERROR: {DSN_FILE} not found") + print("Export manually: File → Export → Specctra DSN") + sys.exit(1) + + print("\n[2/4] Running Freerouting...") + if not run_freerouting(): + print("Freerouting failed") + sys.exit(1) + + print("\n[3/4] Importing routed session...") + if not import_ses(): + print("SES import failed - import manually in KiCad") + + print("\n[4/4] Running DRC...") + success = run_drc() + + print("\n" + "=" * 50) + if success: + print("SUCCESS! Board routed with no DRC errors.") + else: + print("Done. Check DRC.rpt for remaining issues.") + print("=" * 50) + + +if __name__ == "__main__": + main() diff --git a/hardware/kicad/scripts/place_6hp.py b/hardware/kicad/scripts/place_6hp.py new file mode 100644 index 0000000..14d7f31 --- /dev/null +++ b/hardware/kicad/scripts/place_6hp.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +""" +SN-L00 Component Placement Script for 6HP Eurorack +Board at origin (0,0) to (28,100) +Run in KiCad PCB Editor: Tools → Scripting Console +Then: exec(open('scripts/place_6hp.py').read()) +""" + +import pcbnew + +board = pcbnew.GetBoard() + +def mm(val): + return pcbnew.FromMM(val) + +def place(x, y): + return pcbnew.VECTOR2I(mm(x), mm(y)) + +# Component positions for 6HP (28mm x 100mm) layout +# Board origin at (0,0), components placed relative to that +placements = { + # Top - OLED display (rotated 90°, 13mm wide when rotated) + "MOD3": (14, 18, 90), + + # Audio jacks + "J3": (7, 40, 0), # RETURN_IN + "J4": (21, 40, 0), # TRIG_OUT + + # Button + "SW1": (14, 54, 0), + + # RP2040-Zero module + "MOD2": (14, 70, 0), + + # Signal conditioning ICs + "U2": (6, 85, 0), # 74LVC1G17 + "U4": (22, 85, 0), # MCP6001 + + # Resistors + "R2": (3, 90, 0), + "R3": (7, 90, 0), + "R4": (11, 90, 0), + "R5": (15, 90, 0), + "R6": (19, 90, 0), + "R7": (23, 90, 0), + + # Decoupling caps + "C4": (3, 85, 90), + "C5": (11, 85, 90), + "C6": (25, 85, 90), + + # LED + "D5": (25, 90, 0), + + # Protection diodes + "D3": (6, 94, 0), + "D4": (22, 94, 0), + + # Power section + "J2": (14, 94, 0), # Eurorack power header + "D2": (3, 94, 90), # Protection diode + "U3": (25, 94, 180), # LDO - moved right + "C2": (3, 90, 90), # Input cap + "C3": (25, 90, 90), # Output cap - moved right +} + +print("Placing components for 6HP Eurorack layout...") +placed = 0 +not_found = [] + +for ref, (x, y, rot) in placements.items(): + fp = board.FindFootprintByReference(ref) + if fp: + fp.SetPosition(place(x, y)) + fp.SetOrientationDegrees(rot) + placed += 1 + print(f" {ref} -> ({x}, {y}) rot={rot}°") + else: + not_found.append(ref) + +print(f"\nPlaced {placed} components") +if not_found: + print(f"Not found: {', '.join(not_found)}") + +pcbnew.Refresh() +print("\nDone! Save (Ctrl+S), then export DSN for routing.") diff --git a/hardware/panel/PANEL_SPEC.md b/hardware/panel/PANEL_SPEC.md index eb61a32..62e0e09 100644 --- a/hardware/panel/PANEL_SPEC.md +++ b/hardware/panel/PANEL_SPEC.md @@ -9,9 +9,7 @@ | Thickness | 1.5-2.0mm | Aluminum or PCB | | Corner radius | 0mm | Square corners | -## Mounting Holes - -Eurorack standard mounting rail positions: +## Mounting Holes (Eurorack Rails) | Hole | X | Y | Diameter | Notes | |------|---|---|----------|-------| @@ -22,51 +20,78 @@ Eurorack standard mounting rail positions: **Note**: Slots (elongated holes) of 3.2mm × 4mm allow for rail tolerance. +## PCB Mounting + +The PCB (40×100mm) mounts horizontally behind the panel. + +| Parameter | Value | Notes | +|-----------|-------|-------| +| PCB offset from panel top | 10mm | PCB top edge at panel Y=10mm | +| PCB offset from panel bottom | 18.5mm | Clearance for power header | +| Standoff length | 10mm | M3 hex standoffs | +| Standoff holes | 3.2mm | M3 clearance | + +### Standoff Mounting Holes + +| Hole | Panel X | Panel Y | PCB X | PCB Y | +|------|---------|---------|-------|-------| +| Top Left | 5mm | 15mm | 5mm | 5mm | +| Top Right | 35mm | 15mm | 35mm | 5mm | +| Bottom Left | 5mm | 85mm | 5mm | 75mm | +| Bottom Right | 35mm | 85mm | 35mm | 75mm | + +Note: Bottom holes positioned above power section for routing clearance. + ## Component Holes -| Component | X | Y | Diameter | Notes | -|-----------|---|---|----------|-------| -| OLED cutout | 20.15mm | 25.0mm | 28×12mm rect | Rectangular window | -| Button | 20.15mm | 50.0mm | 7.0mm | For 6mm tactile + cap | -| LED (status) | 32.0mm | 50.0mm | 3.0mm | For 3mm LED or light pipe | -| Jack RETURN | 10.0mm | 95.0mm | 6.0mm | Thonkiconn PJ398SM | -| Jack TRIG | 30.0mm | 95.0mm | 6.0mm | Thonkiconn PJ398SM | +All positions aligned with PCB layout (PCB offset = 10mm). + +| Component | Panel X | Panel Y | Diameter | Notes | +|-----------|---------|---------|----------|-------| +| OLED cutout | 20mm | 25mm | 28×12mm rect | Rectangular window | +| Jack RETURN | 10mm | 45mm | 6.0mm | Thonkiconn PJ398SM | +| Jack TRIG | 30mm | 45mm | 6.0mm | Thonkiconn PJ398SM | +| Button | 20mm | 58mm | 7.0mm | For 6mm tactile + cap | +| LED (status) | 32mm | 58mm | 3.0mm | For 3mm LED or light pipe | ## Panel Layout Drawing ``` ←─────── 40.30mm ───────→ - ┌───────────────────────────┐ ─┬─ 0.00mm - │ ○ ○ │ │ 3.00mm (mounting holes) - │ │ │ - │ SubModular │ │ 12.00mm + ┌───────────────────────────┐ ─┬─ 0mm + │ ○ ○ │ │ 3mm (rail mounting holes) │ │ │ + │ SubModular │ │ 12mm + │ · · │ │ 15mm (standoff holes) │ ┌─────────────────┐ │ │ │ │ │ │ │ - │ │ OLED │ │ │ 19-31mm (display window) + │ │ OLED │ │ │ 19-31mm (display window @ 25mm) │ │ DISPLAY │ │ │ │ │ │ │ │ │ └─────────────────┘ │ │ │ │ │ - │ SN-L00 │ │ 42.00mm - │ │ │ - │ ◯ • │ │ 50.00mm (button + LED) - │ BTN PWR │ │ - │ │ │ - │ │ │ - │ │ │ │ ┌───┐ ┌───┐ │ │ │ │ │ │ │ │ │ - │ │ ○ │ │ ○ │ │ │ 95.00mm (jacks) + │ │ ○ │ │ ○ │ │ │ 45mm (jacks) │ │ │ │ │ │ │ │ └───┘ └───┘ │ │ - │ RETURN TRIG │ │ 105.00mm (labels) + │ RETURN TRIG │ │ 52mm (labels) │ │ │ - │ LATENCY TESTER │ │ 115.00mm + │ ◯ • │ │ 58mm (button + LED) + │ BTN PWR │ │ │ │ │ - │ ○ ○ │ │ 125.50mm (mounting holes) - └───────────────────────────┘ ─┴─ 128.50mm + │ SN-L00 │ │ 72mm + │ │ │ + │ │ │ + │ │ │ + │ LATENCY TESTER │ │ 95mm + │ │ │ + │ · · │ │ 85mm (standoff holes) + │ │ │ + │ │ │ + │ ○ ○ │ │ 125.5mm (rail mounting holes) + └───────────────────────────┘ ─┴─ 128.5mm ``` ## OLED Display Window @@ -79,9 +104,7 @@ The 0.91" 128×32 OLED module dimensions: | Active area | ~22 × 6mm | | Mounting | Pin header on edge | -**Panel cutout**: 28mm × 10mm rectangle, centered at (20.15, 25.0) - -Alternatively, a slightly larger window (30 × 12mm) gives tolerance for module alignment. +**Panel cutout**: 28mm × 12mm rectangle, centered at (20mm, 25mm) ## Material Options @@ -106,47 +129,20 @@ Alternatively, a slightly larger window (30 × 12mm) gives tolerance for module - Printing: Engraved or adhesive labels - Cost: ~€3-5/panel -## PCB Panel Design +## Hardware Required -If using a PCB as the panel: - -``` -Front copper: None (for clean look) or decorative pattern -Back copper: Optional ground plane -Silkscreen: All text and graphics -Soldermask: Black (or custom color) -``` - -## Graphics & Text - -### Suggested Layout - -| Element | Position | Size | Font | -|---------|----------|------|------| -| "SubModular" | Top center, Y=12mm | 2.5mm | Bold sans-serif | -| "SN-L00" | Above button, Y=42mm | 3.0mm | Bold | -| "RETURN" | Below left jack, Y=105mm | 2.0mm | Regular | -| "TRIG" | Below right jack, Y=105mm | 2.0mm | Regular | -| "LATENCY TESTER" | Bottom, Y=115mm | 1.5mm | Light | - -## Hole Tolerances - -| Hole Type | Nominal | Tolerance | -|-----------|---------|-----------| -| Mounting | 3.2mm | +0.1/-0.0 | -| Jack | 6.0mm | +0.1/-0.0 | -| Button | 7.0mm | +0.2/-0.0 | -| LED | 3.0mm | +0.1/-0.0 | - -## Files - -- **PANEL_SPEC.md** - This file -- **SN-L00_panel.svg** - Vector graphic for manufacturing -- **SN-L00_panel.kicad_pcb** - PCB panel (if using FR4) +| Item | Qty | Notes | +|------|-----|-------| +| M3×10mm standoff | 4 | Hex, male-female | +| M3×6mm screw | 4 | Pan head, for PCB side | +| M3 nut | 4 | Or use female-female standoffs | +| Thonkiconn nut | 2 | Included with jacks | ## Assembly -1. Mount OLED module with M2 standoffs or double-sided tape -2. Jacks mount through panel, secured with nut -3. Button may need extension shaft or cap -4. LED can use light pipe for front visibility +1. Insert standoffs through panel holes, secure with nuts on front +2. Mount jacks through panel, finger-tighten nuts +3. Align PCB with standoffs and jack pins +4. Secure PCB to standoffs with M3 screws +5. Fully tighten jack nuts +6. Attach OLED module to PCB header diff --git a/hardware/panel/SN-L00_panel.svg b/hardware/panel/SN-L00_panel.svg index c5dbfd5..5cfbe7a 100644 --- a/hardware/panel/SN-L00_panel.svg +++ b/hardware/panel/SN-L00_panel.svg @@ -4,13 +4,14 @@ viewBox="0 0 40.30 128.5"> SN-L00 Eurorack Panel - 8HP Eurorack panel for SN-L00 Latency Tester + 8HP Eurorack panel for SN-L00 Latency Tester - aligned with PCB