├── .gitignore ├── sch ├── .gitignore ├── bytesync │ ├── fp-info-cache │ ├── gerber │ │ ├── bytesync-Edge_Cuts.gbr │ │ ├── millproject │ │ └── bytesync.drl │ ├── bytesync.kicad_prl │ └── bytesync.kicad_pro ├── transmitter │ ├── fp-info-cache │ ├── gerber │ │ ├── transmitter-Edge_Cuts.gbr │ │ ├── millproject │ │ ├── transmitter.drl │ │ └── transmitter-B_Cu.gbr │ ├── transmitter.kicad_prl │ └── transmitter.kicad_pro ├── shield │ ├── ERRATA.md │ ├── fp-lib-table │ ├── sym-lib-table │ ├── gerber │ │ ├── shield-B_Paste.gbr │ │ ├── shield-Edge_Cuts.gbr │ │ ├── shield-B_Mask.gbr │ │ ├── shield.drl │ │ ├── shield-F_Paste.gbr │ │ ├── shield-B_Silkscreen.gbr │ │ └── shield-F_Mask.gbr │ ├── shield.kicad_prl │ ├── schield.pretty │ │ ├── ARJM11D7-009.kicad_mod │ │ └── partial-nucleo64.kicad_mod │ ├── shield.kicad_sym │ └── shield.kicad_pro ├── ethernet-to-spi │ ├── fp-lib-table │ ├── sym-lib-table │ ├── gerber │ │ ├── ethernet-to-spi-Edge_Cuts.gbr │ │ ├── millproject │ │ └── ethernet-to-spi.drl │ ├── ethernet-to-spi.kicad_prl │ ├── eth.pretty │ │ └── G8X-188S7-BP.kicad_mod │ ├── ethernet-to-spi.kicad_pro │ └── eth.kicad_sym └── nlpgen │ ├── gerber │ ├── nlpgen-Edge_Cuts.gbr │ ├── millproject │ └── nlpgen.drl │ ├── nlpgen.kicad_prl │ └── nlpgen.kicad_pro ├── stm32eth-f401 ├── .gitignore ├── .cargo │ └── config ├── memory.x ├── src │ ├── event.rs │ ├── tx_frame_buf.rs │ ├── tg.rs │ ├── device.rs │ ├── transmitter.rs │ ├── unescape.rs │ ├── bot_task.rs │ ├── tg_bot.rs │ ├── adapter.rs │ └── receiver.rs └── Cargo.toml ├── model ├── .gitignore ├── test │ ├── verilog-verify.sh │ ├── Makefile │ └── test_eth2spi.v └── eth2spi.v ├── images ├── spi1.jpeg ├── spi2.jpeg ├── edgedetect.jpeg ├── firstfilter.jpeg └── framedetect.jpeg ├── waveforms ├── eth.png ├── encoder.json └── eth.json ├── .gitmodules ├── LICENSE.txt ├── spitest └── spitest.py └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.gc 3 | -------------------------------------------------------------------------------- /sch/.gitignore: -------------------------------------------------------------------------------- 1 | *-backups/ 2 | -------------------------------------------------------------------------------- /sch/bytesync/fp-info-cache: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /sch/transmitter/fp-info-cache: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /stm32eth-f401/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | Cargo.lock 3 | src/bot_token.rs 4 | -------------------------------------------------------------------------------- /model/.gitignore: -------------------------------------------------------------------------------- 1 | test/* 2 | !test/*.v 3 | !test/Makefile 4 | !test/*.sh 5 | -------------------------------------------------------------------------------- /sch/shield/ERRATA.md: -------------------------------------------------------------------------------- 1 | # Revision 1 2 | 3 | Pin 1 of U8 should be connected to GND. 4 | -------------------------------------------------------------------------------- /images/spi1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imihajlow/ethernet-to-spi/HEAD/images/spi1.jpeg -------------------------------------------------------------------------------- /images/spi2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imihajlow/ethernet-to-spi/HEAD/images/spi2.jpeg -------------------------------------------------------------------------------- /waveforms/eth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imihajlow/ethernet-to-spi/HEAD/waveforms/eth.png -------------------------------------------------------------------------------- /images/edgedetect.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imihajlow/ethernet-to-spi/HEAD/images/edgedetect.jpeg -------------------------------------------------------------------------------- /images/firstfilter.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imihajlow/ethernet-to-spi/HEAD/images/firstfilter.jpeg -------------------------------------------------------------------------------- /images/framedetect.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imihajlow/ethernet-to-spi/HEAD/images/framedetect.jpeg -------------------------------------------------------------------------------- /model/test/verilog-verify.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if $1 | rg --passthru FATAL 4 | then 5 | exit 1 6 | else 7 | exit 0 8 | fi 9 | -------------------------------------------------------------------------------- /sch/ethernet-to-spi/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name "eth")(type "KiCad")(uri "${KIPRJMOD}/eth.pretty")(options "")(descr "")) 3 | ) 4 | -------------------------------------------------------------------------------- /sch/shield/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name "schield")(type "KiCad")(uri "${KIPRJMOD}/schield.pretty")(options "")(descr "")) 3 | ) 4 | -------------------------------------------------------------------------------- /sch/ethernet-to-spi/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (lib (name "eth")(type "KiCad")(uri "${KIPRJMOD}/eth.kicad_sym")(options "")(descr "")) 3 | ) 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "model/74xx"] 2 | path = model/74xx 3 | url = https://github.com/imihajlow/74xx-verilog.git 4 | [submodule "stm32f4xx-hal"] 5 | path = stm32f4xx-hal 6 | url = https://github.com/imihajlow/stm32f4xx-hal.git 7 | -------------------------------------------------------------------------------- /sch/shield/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (lib (name "shield")(type "KiCad")(uri "${KIPRJMOD}/shield.kicad_sym")(options "")(descr "")) 3 | (lib (name "eth")(type "KiCad")(uri "${KIPRJMOD}/../ethernet-to-spi/eth.kicad_sym")(options "")(descr "")) 4 | ) 5 | -------------------------------------------------------------------------------- /model/test/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all clean 2 | 3 | 4 | all: test_eth2spi 5 | 6 | clean: 7 | rm -f ./test_eth2spi 8 | rm -f *.vcd 9 | 10 | test_eth2spi: test_eth2spi.v ../eth2spi.v 11 | iverilog -o $@ $^ 12 | ./verilog-verify.sh ./test_eth2spi 13 | 14 | -------------------------------------------------------------------------------- /stm32eth-f401/.cargo/config: -------------------------------------------------------------------------------- 1 | [target.thumbv7em-none-eabihf] 2 | runner = 'probe-run --chip STM32F401RETx' 3 | rustflags = [ 4 | "-C", "link-arg=-Tlink.x", 5 | "-C", "link-arg=-Tdefmt.x", 6 | ] 7 | 8 | [build] 9 | target = "thumbv7em-none-eabihf" 10 | 11 | [env] 12 | DEFMT_LOG = "trace" 13 | -------------------------------------------------------------------------------- /stm32eth-f401/memory.x: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | /* NOTE K = KiBi = 1024 bytes */ 4 | FLASH : ORIGIN = 0x08000000, LENGTH = 512K 5 | RAM : ORIGIN = 0x20000000, LENGTH = 96K 6 | } 7 | 8 | /* This is where the call stack will be allocated. */ 9 | /* The stack is of the full descending type. */ 10 | /* NOTE Do NOT modify `_stack_start` unless you know what you are doing */ 11 | _stack_start = ORIGIN(RAM) + LENGTH(RAM); 12 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2020-2022 Ivan Mikhailov 2 | 3 | Unless otherwise stated: 4 | 5 | Hardware design, documentation, and products are licensed under the TAPR Open 6 | Hardware License, version 1.0. See LICENSE.TAPR. 7 | https://www.tapr.org/OHL 8 | 9 | Software, firmware, or code loaded into programmable devices is 10 | licensed under the GNU General Public License, version 3. See LICENSE.GPL. 11 | http://www.gnu.org/licenses/gpl-3.0.html 12 | -------------------------------------------------------------------------------- /spitest/spitest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import pyftdi.spi 3 | import time 4 | 5 | if __name__ == '__main__': 6 | spi = pyftdi.spi.SpiController() 7 | spi.configure("ftdi://::/1") 8 | port = spi.get_port(cs=0, mode=0, freq=10e6) 9 | gpio = spi.get_gpio() 10 | gpio.set_direction(0x20, 0x20) 11 | gpio.write(0x20) 12 | while True: 13 | port.write(bytes([1,2,3,4])) 14 | time.sleep(1) 15 | # gpio.write(0x00) 16 | -------------------------------------------------------------------------------- /sch/shield/gerber/shield-B_Paste.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,(6.0.9-0)*% 2 | %TF.CreationDate,2022-11-17T19:03:50+01:00*% 3 | %TF.ProjectId,shield,73686965-6c64-42e6-9b69-6361645f7063,1*% 4 | %TF.SameCoordinates,PX3a2c940PY82a7440*% 5 | %TF.FileFunction,Paste,Bot*% 6 | %TF.FilePolarity,Positive*% 7 | %FSLAX46Y46*% 8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 9 | G04 Created by KiCad (PCBNEW (6.0.9-0)) date 2022-11-17 19:03:50* 10 | %MOMM*% 11 | %LPD*% 12 | G01* 13 | G04 APERTURE LIST* 14 | G04 APERTURE END LIST* 15 | M02* 16 | -------------------------------------------------------------------------------- /waveforms/encoder.json: -------------------------------------------------------------------------------- 1 | /* https://wavedrom.com/editor.html */ 2 | {signal: [ 3 | {name: "SCK", wave: "0..101010101010.|..", node: "..............a"}, 4 | {name: "MOSI", wave: "x..2.2.2.2.2.2.x|..", data: "1 0 1 0 1 1"}, 5 | {name: "xor", wave: "x..01.0.1.0.101x|.."}, 6 | {name: "driver input", wave: "x..01.0.1.0.101x|1x"}, 7 | {name: "driver ena", wave: "0..1...........0|10", node: "...............b"}, 8 | {name: "output", wave: "z..01.0.1.0.101z|1z"}, 9 | ], 10 | config: {hscale: 1}, 11 | edge: ["a~b 100nS"], 12 | head: {text: "Ethernet encoder"} 13 | } 14 | 15 | -------------------------------------------------------------------------------- /sch/nlpgen/gerber/nlpgen-Edge_Cuts.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,(6.0.7-1)-1*% 2 | %TF.CreationDate,2022-09-19T13:49:17+02:00*% 3 | %TF.ProjectId,nlpgen,6e6c7067-656e-42e6-9b69-6361645f7063,rev?*% 4 | %TF.SameCoordinates,PX81b3200PY53ec600*% 5 | %TF.FileFunction,Profile,NP*% 6 | %FSLAX46Y46*% 7 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 8 | G04 Created by KiCad (PCBNEW (6.0.7-1)-1) date 2022-09-19 13:49:17* 9 | %MOMM*% 10 | %LPD*% 11 | G01* 12 | G04 APERTURE LIST* 13 | %TA.AperFunction,Profile*% 14 | %ADD10C,0.100000*% 15 | %TD*% 16 | G04 APERTURE END LIST* 17 | D10* 18 | X0Y0D02* 19 | X70000000Y0D01* 20 | X70000000Y0D02* 21 | X70000000Y25000000D01* 22 | X70000000Y25000000D02* 23 | X0Y25000000D01* 24 | X0Y25000000D02* 25 | X0Y0D01* 26 | M02* 27 | -------------------------------------------------------------------------------- /sch/bytesync/gerber/bytesync-Edge_Cuts.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,(6.0.7-1)-1*% 2 | %TF.CreationDate,2022-11-06T10:24:33+01:00*% 3 | %TF.ProjectId,bytesync,62797465-7379-46e6-932e-6b696361645f,rev?*% 4 | %TF.SameCoordinates,PX6052340PY68e7780*% 5 | %TF.FileFunction,Profile,NP*% 6 | %FSLAX46Y46*% 7 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 8 | G04 Created by KiCad (PCBNEW (6.0.7-1)-1) date 2022-11-06 10:24:33* 9 | %MOMM*% 10 | %LPD*% 11 | G01* 12 | G04 APERTURE LIST* 13 | %TA.AperFunction,Profile*% 14 | %ADD10C,0.100000*% 15 | %TD*% 16 | G04 APERTURE END LIST* 17 | D10* 18 | X0Y28000000D02* 19 | X64000000Y28000000D01* 20 | X64000000Y28000000D02* 21 | X64000000Y0D01* 22 | X64000000Y0D02* 23 | X0Y0D01* 24 | X0Y0D02* 25 | X0Y28000000D01* 26 | M02* 27 | -------------------------------------------------------------------------------- /sch/transmitter/gerber/transmitter-Edge_Cuts.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,(6.0.7-1)-1*% 2 | %TF.CreationDate,2022-11-12T09:43:50+01:00*% 3 | %TF.ProjectId,transmitter,7472616e-736d-4697-9474-65722e6b6963,rev?*% 4 | %TF.SameCoordinates,PX4b571c0PY82e44d0*% 5 | %TF.FileFunction,Profile,NP*% 6 | %FSLAX46Y46*% 7 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 8 | G04 Created by KiCad (PCBNEW (6.0.7-1)-1) date 2022-11-12 09:43:50* 9 | %MOMM*% 10 | %LPD*% 11 | G01* 12 | G04 APERTURE LIST* 13 | %TA.AperFunction,Profile*% 14 | %ADD10C,0.100000*% 15 | %TD*% 16 | G04 APERTURE END LIST* 17 | D10* 18 | X51000000Y0D02* 19 | X0Y0D01* 20 | X0Y0D02* 21 | X0Y45450000D01* 22 | X0Y45450000D02* 23 | X51000000Y45450000D01* 24 | X51000000Y45450000D02* 25 | X51000000Y0D01* 26 | M02* 27 | -------------------------------------------------------------------------------- /sch/ethernet-to-spi/gerber/ethernet-to-spi-Edge_Cuts.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,(6.0.7-1)-1*% 2 | %TF.CreationDate,2022-09-09T18:16:01+02:00*% 3 | %TF.ProjectId,ethernet-to-spi,65746865-726e-4657-942d-746f2d737069,rev?*% 4 | %TF.SameCoordinates,PX3dcc500PY7f69300*% 5 | %TF.FileFunction,Profile,NP*% 6 | %FSLAX46Y46*% 7 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 8 | G04 Created by KiCad (PCBNEW (6.0.7-1)-1) date 2022-09-09 18:16:01* 9 | %MOMM*% 10 | %LPD*% 11 | G01* 12 | G04 APERTURE LIST* 13 | %TA.AperFunction,Profile*% 14 | %ADD10C,0.100000*% 15 | %TD*% 16 | G04 APERTURE END LIST* 17 | D10* 18 | X0Y0D02* 19 | X113000000Y0D01* 20 | X113000000Y0D02* 21 | X113000000Y32000000D01* 22 | X113000000Y32000000D02* 23 | X0Y32000000D01* 24 | X0Y32000000D02* 25 | X0Y0D01* 26 | M02* 27 | -------------------------------------------------------------------------------- /sch/nlpgen/gerber/millproject: -------------------------------------------------------------------------------- 1 | metric=true 2 | metricoutput=true 3 | nog64=true 4 | 5 | front=nlpgen-F_Cu.gbr 6 | outline=nlpgen-Edge_Cuts.gbr 7 | drill=nlpgen.drl 8 | 9 | front-output=front.gc 10 | outline-output=outline.gc 11 | drill-output=drill.gc 12 | milldrill-output=milldrill.gc 13 | 14 | # engraving 15 | zwork=-0.2 16 | mill-infeed=0.1 17 | zsafe=2 18 | mill-feed=250 19 | mill-speed=10000 20 | offset=0.15 21 | extra-passes=1 22 | 23 | # outline 24 | cutter-diameter=2 25 | zcut=-0.8 26 | cut-feed=300 27 | cut-speed=10000 28 | cut-infeed=0.2 29 | fill-outline=true 30 | 31 | # drill 32 | zdrill=-1 33 | zchange=8 34 | drill-feed=50 35 | drill-speed=10000 36 | min-milldrill-hole-diameter=2.0mm 37 | nog81=true 38 | drills-available=0.3mm,0.4mm,0.5mm,0.6mm,0.7mm,0.8mm,0.9mm,1.0mm,1.1mm,1.2mm,1.7mm:0.1mm 39 | -------------------------------------------------------------------------------- /sch/transmitter/gerber/millproject: -------------------------------------------------------------------------------- 1 | metric=true 2 | metricoutput=true 3 | nog64=true 4 | 5 | front=transmitter-F_Cu.gbr 6 | outline=transmitter-Edge_Cuts.gbr 7 | drill=transmitter.drl 8 | 9 | front-output=front.gc 10 | outline-output=outline.gc 11 | drill-output=drill.gc 12 | milldrill-output=milldrill.gc 13 | 14 | # engraving 15 | zwork=-0.2 16 | mill-infeed=0.2 17 | zsafe=2 18 | mill-feed=250 19 | mill-speed=10000 20 | offset=0.15 21 | extra-passes=1 22 | 23 | # outline 24 | cutter-diameter=2 25 | zcut=-0.8 26 | cut-feed=300 27 | cut-speed=10000 28 | cut-infeed=0.2 29 | fill-outline=true 30 | 31 | # drill 32 | zdrill=-1 33 | zchange=8 34 | drill-feed=50 35 | drill-speed=10000 36 | min-milldrill-hole-diameter=2.0mm 37 | nog81=true 38 | drills-available=0.3mm,0.4mm,0.5mm,0.6mm,0.7mm,0.8mm,0.9mm,1.0mm,1.1mm,1.2mm,1.7mm:0.1mm 39 | -------------------------------------------------------------------------------- /sch/bytesync/gerber/millproject: -------------------------------------------------------------------------------- 1 | metric=true 2 | metricoutput=true 3 | nog64=true 4 | nom6=true 5 | 6 | front=bytesync-F_Cu.gbr 7 | outline=bytesync-Edge_Cuts.gbr 8 | drill=bytesync.drl 9 | 10 | front-output=front.gc 11 | outline-output=outline.gc 12 | drill-output=drill.gc 13 | milldrill-output=milldrill.gc 14 | 15 | # engraving 16 | zwork=-0.2 17 | mill-infeed=0.1 18 | zsafe=2 19 | mill-feed=250 20 | mill-speed=10000 21 | offset=0.15 22 | extra-passes=0 23 | 24 | # outline 25 | cutter-diameter=2 26 | zcut=-0.8 27 | cut-feed=300 28 | cut-speed=10000 29 | cut-infeed=0.2 30 | fill-outline=true 31 | 32 | # drill 33 | zdrill=-1 34 | zchange=8 35 | drill-feed=50 36 | drill-speed=10000 37 | min-milldrill-hole-diameter=2.0mm 38 | nog81=true 39 | drills-available=0.3mm,0.4mm,0.5mm,0.6mm,0.7mm,0.8mm,0.9mm,1.0mm,1.1mm,1.2mm,1.4mm,1.6mm,1.7mm:0.1mm 40 | -------------------------------------------------------------------------------- /sch/ethernet-to-spi/gerber/millproject: -------------------------------------------------------------------------------- 1 | metric=true 2 | metricoutput=true 3 | nog64=true 4 | 5 | front=ethernet-to-spi-F_Cu.gbr 6 | outline=ethernet-to-spi-Edge_Cuts.gbr 7 | drill=ethernet-to-spi.drl 8 | 9 | front-output=front.gc 10 | outline-output=outline.gc 11 | drill-output=drill.gc 12 | milldrill-output=milldrill.gc 13 | 14 | # engraving 15 | zwork=-0.2 16 | mill-infeed=0.1 17 | zsafe=2 18 | mill-feed=250 19 | mill-speed=10000 20 | offset=0.15 21 | extra-passes=1 22 | 23 | # outline 24 | cutter-diameter=2 25 | zcut=-0.8 26 | cut-feed=300 27 | cut-speed=10000 28 | cut-infeed=0.2 29 | fill-outline=true 30 | 31 | # drill 32 | zdrill=-1 33 | zchange=8 34 | drill-feed=50 35 | drill-speed=10000 36 | min-milldrill-hole-diameter=2.0mm 37 | nog81=true 38 | drills-available=0.3mm,0.4mm,0.5mm,0.6mm,0.7mm,0.8mm,0.9mm,1.0mm,1.1mm,1.2mm,1.7mm:0.1mm 39 | -------------------------------------------------------------------------------- /stm32eth-f401/src/event.rs: -------------------------------------------------------------------------------- 1 | use core::task::Poll; 2 | use core::future::Future; 3 | 4 | pub type BtnPressConsumer = heapless::spsc::Consumer<'static, (), 4>; 5 | 6 | pub enum ExternalEvent { 7 | ButtonPressed 8 | } 9 | 10 | pub struct ButtonPressFuture<'a>(&'a mut BtnPressConsumer); 11 | 12 | pub /* async */ fn wait_btn_press<'a>(consumer: &'a mut BtnPressConsumer) -> ButtonPressFuture<'a> { 13 | ButtonPressFuture(consumer) 14 | } 15 | 16 | impl<'a> Future for ButtonPressFuture<'a> { 17 | type Output = ExternalEvent; 18 | fn poll(mut self: core::pin::Pin<&mut Self>, ctx: &mut core::task::Context<'_>) -> Poll { 19 | match self.0.dequeue() { 20 | Some(_) => Poll::Ready(ExternalEvent::ButtonPressed), 21 | None => { 22 | ctx.waker().wake_by_ref(); 23 | Poll::Pending 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /sch/bytesync/gerber/bytesync.drl: -------------------------------------------------------------------------------- 1 | M48 2 | ; DRILL file {KiCad (6.0.7-1)-1} date 2022 November 06, Sunday 10:25:01 3 | ; FORMAT={-:-/ absolute / metric / decimal} 4 | ; #@! TF.CreationDate,2022-11-06T10:25:01+01:00 5 | ; #@! TF.GenerationSoftware,Kicad,Pcbnew,(6.0.7-1)-1 6 | ; #@! TF.FileFunction,MixedPlating,1,2 7 | FMAT,2 8 | METRIC 9 | ; #@! TA.AperFunction,Plated,PTH,ViaDrill 10 | T1C0.600 11 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 12 | T2C1.550 13 | ; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill 14 | T3C2.800 15 | % 16 | G90 17 | G05 18 | T1 19 | X17.5Y16.7 20 | X27.0Y19.8 21 | X28.0Y18.5 22 | X28.3Y10.5 23 | X30.7Y21.1 24 | X30.7Y15.9 25 | X33.5Y11.1 26 | X34.9Y12.2 27 | X39.8Y3.1 28 | T2 29 | X7.0Y21.16 30 | X11.2Y21.16 31 | X15.3Y21.06 32 | X16.76Y25.2 33 | X22.5Y11.7 34 | X43.5Y7.44 35 | X48.5Y21.46 36 | X52.7Y7.44 37 | X56.9Y21.36 38 | X61.0Y7.44 39 | T3 40 | X2.96Y25.2 41 | X7.0Y7.36 42 | X11.2Y7.36 43 | X15.3Y7.26 44 | X22.5Y25.5 45 | X43.5Y21.24 46 | X48.5Y7.66 47 | X52.7Y21.24 48 | X56.9Y7.56 49 | X61.0Y21.24 50 | T0 51 | M30 52 | -------------------------------------------------------------------------------- /sch/shield/gerber/shield-Edge_Cuts.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,(6.0.9-0)*% 2 | %TF.CreationDate,2022-11-17T19:03:50+01:00*% 3 | %TF.ProjectId,shield,73686965-6c64-42e6-9b69-6361645f7063,1*% 4 | %TF.SameCoordinates,PX3a2c940PY82a7440*% 5 | %TF.FileFunction,Profile,NP*% 6 | %FSLAX46Y46*% 7 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 8 | G04 Created by KiCad (PCBNEW (6.0.9-0)) date 2022-11-17 19:03:50* 9 | %MOMM*% 10 | %LPD*% 11 | G01* 12 | G04 APERTURE LIST* 13 | %TA.AperFunction,Profile*% 14 | %ADD10C,0.100000*% 15 | %TD*% 16 | G04 APERTURE END LIST* 17 | D10* 18 | X69000000Y74000000D02* 19 | X53500000Y74000000D01* 20 | X0Y0D02* 21 | X69000000Y0D01* 22 | X49000000Y69500000D02* 23 | G75* 24 | G03* 25 | X53500000Y74000000I0J4500000D01* 26 | G01* 27 | X0Y74000000D02* 28 | X15000000Y74000000D01* 29 | X20000000Y69500000D02* 30 | X49000000Y69500000D01* 31 | X69000000Y0D02* 32 | X69000000Y74000000D01* 33 | X14999980Y73999998D02* 34 | G75* 35 | G03* 36 | X20000000Y69500000I5000020J527802D01* 37 | G01* 38 | X0Y0D02* 39 | X0Y74000000D01* 40 | M02* 41 | -------------------------------------------------------------------------------- /waveforms/eth.json: -------------------------------------------------------------------------------- 1 | /* https://wavedrom.com/editor.html */ 2 | {signal: [ 3 | {name: "data", wave: "z222222z|222222z", data: ["1", "0", "1", "0", "1", "1", "1", "0", "1", "0", "1", "1"], period: 2, phase: 0.2}, 4 | {node: ".ab", period: 2, phase: 0.2}, 5 | {name: "line", wave: "0..1.0.1.0.10..x|101.0.1.0.101..", phase: 0.2}, 6 | {name: "n_line", wave: "1..0.1.0.1.01..x|010.1.0.1.010..", phase: 0.2}, 7 | {name: "edge_in", wave: "0..0.0.0.0.000.x|000.0.0.0.000..", node: "...g........."}, 8 | {}, 9 | {name: "sck", wave: "0.....1..01..01..01..01..01..0.x|0....1..01..01..01..01..01..0..", period: 0.5, node: "......c..d", phase: -0.2}, 10 | {name: "n_idle", wave: "0..1...........0|.1............0", node: "...h...........f", phase: -0.2}, 11 | {name: "edge_ena", wave: "1...............|01............0", node: "...............", phase: -0.2}, 12 | {name: "edge", wave: "0..0.0.0.0.000..|..0.0.0.0.000..", node: ".............e"}, 13 | {node: "x..............y.z..............w",}, 14 | ], 15 | edge: ['a~>b 100ns', 'c->d 75ns', 'e~>f 150ns', 'g->h', 'x<->y line low when idle', 'z<->w line high when idle'], 16 | config: {hscale: 1}, 17 | head: {text: "Ethernet decoder"} 18 | } 19 | 20 | -------------------------------------------------------------------------------- /sch/nlpgen/gerber/nlpgen.drl: -------------------------------------------------------------------------------- 1 | M48 2 | ; DRILL file {KiCad (6.0.7-1)-1} date 2022 September 19, Monday 13:49:21 3 | ; FORMAT={-:-/ absolute / metric / decimal} 4 | ; #@! TF.CreationDate,2022-09-19T13:49:21+02:00 5 | ; #@! TF.GenerationSoftware,Kicad,Pcbnew,(6.0.7-1)-1 6 | ; #@! TF.FileFunction,MixedPlating,1,2 7 | FMAT,2 8 | METRIC 9 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 10 | T1C0.700 11 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 12 | T2C0.800 13 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 14 | T3C1.100 15 | ; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill 16 | T4C2.800 17 | % 18 | G90 19 | G05 20 | T1 21 | X34.8Y19.11 22 | X34.8Y11.49 23 | T2 24 | X23.38Y18.925 25 | X23.38Y16.385 26 | X23.38Y13.845 27 | X23.38Y11.305 28 | X23.38Y8.765 29 | X23.38Y6.225 30 | X23.38Y3.685 31 | X31.0Y18.925 32 | X31.0Y16.385 33 | X31.0Y13.845 34 | X31.0Y11.305 35 | X31.0Y8.765 36 | X31.0Y6.225 37 | X31.0Y3.685 38 | T3 39 | X2.9Y4.175 40 | X7.5Y18.125 41 | X12.2Y18.125 42 | X17.2Y18.125 43 | X52.2Y18.225 44 | X56.5Y18.225 45 | X61.7Y4.175 46 | X66.0Y4.175 47 | T4 48 | X2.9Y17.975 49 | X7.5Y4.325 50 | X12.2Y4.325 51 | X17.2Y4.325 52 | X52.2Y4.425 53 | X56.5Y4.425 54 | X61.7Y17.975 55 | X66.0Y17.975 56 | T0 57 | M30 58 | -------------------------------------------------------------------------------- /model/eth2spi.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ns 2 | module eth2spi(eth_line, sck, mosi, cs); 3 | input eth_line; 4 | output sck, mosi, cs; 5 | 6 | assign mosi = eth_line; 7 | wire #11 n_eth_line = ~eth_line; // 74hc86 8 | wire #11 eth_line_delayed = ~n_eth_line; // 74hc86 XOR 9 | wire #11 edge_in = eth_line ^ eth_line_delayed; // 74hc86 10 | 11 | 12 | // mosfet + RC + 74hc14 contraption 13 | reg n_idle; 14 | integer last_edge_time; 15 | initial begin 16 | last_edge_time = 0; 17 | n_idle = 1'b0; 18 | end 19 | always @(posedge edge_in) begin 20 | last_edge_time <= $time; 21 | #10 n_idle <= 1'b1; 22 | end 23 | always @(posedge edge_in) begin 24 | #130 25 | if ($time - last_edge_time > 120) begin 26 | n_idle = 1'b0; 27 | end 28 | end 29 | 30 | wire #30 edge_ena = n_idle | n_eth_line; // 74hc32 + additional RC delay 31 | 32 | wire #10 edge_ = edge_in & edge_ena; // 74hc08 33 | 34 | // mosfet + RC + 74hc14 + 74hc08 35 | reg inhibit; 36 | initial begin 37 | inhibit = 1'b0; 38 | end 39 | always @(posedge edge_) begin 40 | if (~inhibit) begin 41 | inhibit = 1'b1; 42 | #75 inhibit = 1'b0; 43 | end 44 | end 45 | 46 | assign sck = inhibit; 47 | assign cs = n_idle; 48 | 49 | endmodule 50 | -------------------------------------------------------------------------------- /sch/transmitter/gerber/transmitter.drl: -------------------------------------------------------------------------------- 1 | M48 2 | ; DRILL file {KiCad (6.0.7-1)-1} date 2022 November 12, Saturday 09:43:56 3 | ; FORMAT={-:-/ absolute / metric / decimal} 4 | ; #@! TF.CreationDate,2022-11-12T09:43:56+01:00 5 | ; #@! TF.GenerationSoftware,Kicad,Pcbnew,(6.0.7-1)-1 6 | ; #@! TF.FileFunction,MixedPlating,1,2 7 | FMAT,2 8 | METRIC 9 | ; #@! TA.AperFunction,Plated,PTH,ViaDrill 10 | T1C0.600 11 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 12 | T2C0.800 13 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 14 | T3C1.100 15 | ; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill 16 | T4C2.800 17 | % 18 | G90 19 | G05 20 | T1 21 | X19.0Y16.95 22 | X19.2Y11.35 23 | X29.5Y11.45 24 | X29.6Y17.05 25 | X31.0Y25.25 26 | X36.5Y25.25 27 | X36.7Y8.75 28 | X41.6Y8.75 29 | T2 30 | X20.58Y35.375 31 | X20.58Y32.835 32 | X20.58Y30.295 33 | X20.58Y27.755 34 | X20.58Y25.215 35 | X20.58Y22.675 36 | X20.58Y20.135 37 | X27.69Y39.25 38 | X28.2Y35.375 39 | X28.2Y32.835 40 | X28.2Y30.295 41 | X28.2Y27.755 42 | X28.2Y25.215 43 | X28.2Y22.675 44 | X28.2Y20.135 45 | X35.31Y39.25 46 | X38.5Y43.05 47 | X38.5Y38.05 48 | T3 49 | X3.0Y19.725 50 | X7.0Y19.725 51 | X11.5Y33.775 52 | X15.5Y33.775 53 | X35.0Y18.775 54 | X39.0Y4.725 55 | X44.0Y18.775 56 | X48.0Y4.725 57 | T4 58 | X3.0Y33.525 59 | X7.0Y33.525 60 | X11.5Y19.975 61 | X15.5Y19.975 62 | X35.0Y4.975 63 | X39.0Y18.525 64 | X44.0Y4.975 65 | X48.0Y18.525 66 | T0 67 | M30 68 | -------------------------------------------------------------------------------- /sch/shield/shield.kicad_prl: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "active_layer": 31, 4 | "active_layer_preset": "", 5 | "auto_track_width": true, 6 | "hidden_nets": [], 7 | "high_contrast_mode": 0, 8 | "net_color_mode": 1, 9 | "opacity": { 10 | "pads": 1.0, 11 | "tracks": 1.0, 12 | "vias": 1.0, 13 | "zones": 0.6 14 | }, 15 | "ratsnest_display_mode": 0, 16 | "selection_filter": { 17 | "dimensions": true, 18 | "footprints": true, 19 | "graphics": true, 20 | "keepouts": true, 21 | "lockedItems": true, 22 | "otherItems": true, 23 | "pads": true, 24 | "text": true, 25 | "tracks": true, 26 | "vias": true, 27 | "zones": true 28 | }, 29 | "visible_items": [ 30 | 0, 31 | 1, 32 | 2, 33 | 3, 34 | 4, 35 | 5, 36 | 8, 37 | 9, 38 | 10, 39 | 11, 40 | 12, 41 | 13, 42 | 14, 43 | 15, 44 | 16, 45 | 17, 46 | 18, 47 | 19, 48 | 20, 49 | 21, 50 | 22, 51 | 23, 52 | 24, 53 | 25, 54 | 26, 55 | 27, 56 | 28, 57 | 29, 58 | 30, 59 | 32, 60 | 33, 61 | 34, 62 | 35, 63 | 36 64 | ], 65 | "visible_layers": "fffffff_fffffff9", 66 | "zone_display_mode": 0 67 | }, 68 | "meta": { 69 | "filename": "shield.kicad_prl", 70 | "version": 3 71 | }, 72 | "project": { 73 | "files": [] 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /sch/nlpgen/nlpgen.kicad_prl: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "active_layer": 0, 4 | "active_layer_preset": "All Layers", 5 | "auto_track_width": true, 6 | "hidden_nets": [], 7 | "high_contrast_mode": 0, 8 | "net_color_mode": 1, 9 | "opacity": { 10 | "pads": 1.0, 11 | "tracks": 1.0, 12 | "vias": 1.0, 13 | "zones": 0.6 14 | }, 15 | "ratsnest_display_mode": 0, 16 | "selection_filter": { 17 | "dimensions": true, 18 | "footprints": true, 19 | "graphics": true, 20 | "keepouts": true, 21 | "lockedItems": true, 22 | "otherItems": true, 23 | "pads": true, 24 | "text": true, 25 | "tracks": true, 26 | "vias": true, 27 | "zones": true 28 | }, 29 | "visible_items": [ 30 | 0, 31 | 1, 32 | 2, 33 | 3, 34 | 4, 35 | 5, 36 | 8, 37 | 9, 38 | 10, 39 | 11, 40 | 12, 41 | 13, 42 | 14, 43 | 15, 44 | 16, 45 | 17, 46 | 18, 47 | 19, 48 | 20, 49 | 21, 50 | 22, 51 | 23, 52 | 24, 53 | 25, 54 | 26, 55 | 27, 56 | 28, 57 | 29, 58 | 30, 59 | 32, 60 | 33, 61 | 34, 62 | 35, 63 | 36 64 | ], 65 | "visible_layers": "fffffff_ffffffff", 66 | "zone_display_mode": 0 67 | }, 68 | "meta": { 69 | "filename": "nlpgen.kicad_prl", 70 | "version": 3 71 | }, 72 | "project": { 73 | "files": [] 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /sch/bytesync/bytesync.kicad_prl: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "active_layer": 0, 4 | "active_layer_preset": "All Layers", 5 | "auto_track_width": false, 6 | "hidden_nets": [], 7 | "high_contrast_mode": 0, 8 | "net_color_mode": 1, 9 | "opacity": { 10 | "pads": 1.0, 11 | "tracks": 1.0, 12 | "vias": 1.0, 13 | "zones": 0.6 14 | }, 15 | "ratsnest_display_mode": 0, 16 | "selection_filter": { 17 | "dimensions": true, 18 | "footprints": true, 19 | "graphics": true, 20 | "keepouts": true, 21 | "lockedItems": true, 22 | "otherItems": true, 23 | "pads": true, 24 | "text": true, 25 | "tracks": true, 26 | "vias": true, 27 | "zones": true 28 | }, 29 | "visible_items": [ 30 | 0, 31 | 1, 32 | 2, 33 | 3, 34 | 4, 35 | 5, 36 | 8, 37 | 9, 38 | 10, 39 | 11, 40 | 12, 41 | 13, 42 | 14, 43 | 15, 44 | 16, 45 | 17, 46 | 18, 47 | 19, 48 | 20, 49 | 21, 50 | 22, 51 | 23, 52 | 24, 53 | 25, 54 | 26, 55 | 27, 56 | 28, 57 | 29, 58 | 30, 59 | 32, 60 | 33, 61 | 34, 62 | 35, 63 | 36 64 | ], 65 | "visible_layers": "fffffff_ffffffff", 66 | "zone_display_mode": 0 67 | }, 68 | "meta": { 69 | "filename": "bytesync.kicad_prl", 70 | "version": 3 71 | }, 72 | "project": { 73 | "files": [] 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /sch/transmitter/transmitter.kicad_prl: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "active_layer": 31, 4 | "active_layer_preset": "All Layers", 5 | "auto_track_width": false, 6 | "hidden_nets": [], 7 | "high_contrast_mode": 0, 8 | "net_color_mode": 1, 9 | "opacity": { 10 | "pads": 1.0, 11 | "tracks": 1.0, 12 | "vias": 1.0, 13 | "zones": 0.6 14 | }, 15 | "ratsnest_display_mode": 0, 16 | "selection_filter": { 17 | "dimensions": true, 18 | "footprints": true, 19 | "graphics": true, 20 | "keepouts": true, 21 | "lockedItems": true, 22 | "otherItems": true, 23 | "pads": true, 24 | "text": true, 25 | "tracks": true, 26 | "vias": true, 27 | "zones": true 28 | }, 29 | "visible_items": [ 30 | 0, 31 | 1, 32 | 2, 33 | 3, 34 | 4, 35 | 5, 36 | 8, 37 | 9, 38 | 10, 39 | 11, 40 | 12, 41 | 13, 42 | 14, 43 | 15, 44 | 16, 45 | 17, 46 | 18, 47 | 19, 48 | 20, 49 | 21, 50 | 22, 51 | 23, 52 | 24, 53 | 25, 54 | 26, 55 | 27, 56 | 28, 57 | 29, 58 | 30, 59 | 32, 60 | 33, 61 | 34, 62 | 35, 63 | 36 64 | ], 65 | "visible_layers": "fffffff_ffffffff", 66 | "zone_display_mode": 0 67 | }, 68 | "meta": { 69 | "filename": "transmitter.kicad_prl", 70 | "version": 3 71 | }, 72 | "project": { 73 | "files": [] 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /sch/ethernet-to-spi/ethernet-to-spi.kicad_prl: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "active_layer": 0, 4 | "active_layer_preset": "All Layers", 5 | "auto_track_width": true, 6 | "hidden_nets": [], 7 | "high_contrast_mode": 0, 8 | "net_color_mode": 1, 9 | "opacity": { 10 | "pads": 1.0, 11 | "tracks": 1.0, 12 | "vias": 1.0, 13 | "zones": 0.3100000023841858 14 | }, 15 | "ratsnest_display_mode": 0, 16 | "selection_filter": { 17 | "dimensions": true, 18 | "footprints": true, 19 | "graphics": true, 20 | "keepouts": true, 21 | "lockedItems": true, 22 | "otherItems": true, 23 | "pads": true, 24 | "text": true, 25 | "tracks": true, 26 | "vias": true, 27 | "zones": true 28 | }, 29 | "visible_items": [ 30 | 0, 31 | 1, 32 | 2, 33 | 3, 34 | 4, 35 | 5, 36 | 8, 37 | 9, 38 | 10, 39 | 11, 40 | 12, 41 | 13, 42 | 14, 43 | 15, 44 | 16, 45 | 17, 46 | 18, 47 | 19, 48 | 20, 49 | 21, 50 | 22, 51 | 23, 52 | 24, 53 | 25, 54 | 26, 55 | 27, 56 | 28, 57 | 29, 58 | 30, 59 | 32, 60 | 33, 61 | 34, 62 | 35, 63 | 36 64 | ], 65 | "visible_layers": "fffffff_ffffffff", 66 | "zone_display_mode": 0 67 | }, 68 | "meta": { 69 | "filename": "ethernet-to-spi.kicad_prl", 70 | "version": 3 71 | }, 72 | "project": { 73 | "files": [] 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /model/test/test_eth2spi.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ns 2 | module test_eth2spi(); 3 | 4 | task assert; 5 | input v; 6 | if (v !== 1'b1) 7 | $fatal; 8 | endtask 9 | 10 | reg clk; 11 | initial begin 12 | clk = 1'b0; 13 | end 14 | always begin 15 | #50 clk = ~clk; 16 | end 17 | 18 | reg tx_ena; 19 | reg tx_idle; 20 | initial begin 21 | tx_ena = 1'b0; 22 | tx_idle = 1'b1; 23 | end 24 | 25 | reg [63:0] src = 64'h2f9a77c388e50055; 26 | reg [5:0] i; 27 | initial begin 28 | i = 0; 29 | end 30 | 31 | wire data = src[i]; 32 | 33 | wire manchester = tx_ena ? (data ^ clk) : tx_idle; 34 | 35 | always @(posedge clk) begin 36 | if (tx_ena) begin 37 | i <= i + 1; 38 | end 39 | end 40 | 41 | wire sck, mosi, cs; 42 | eth2spi eth2spi_inst( 43 | .eth_line(manchester), 44 | .sck(sck), 45 | .mosi(mosi), 46 | .cs(cs)); 47 | 48 | reg [63:0] dst; 49 | always @(posedge sck) begin 50 | dst <= {mosi, dst[63:1]}; 51 | end 52 | 53 | initial begin 54 | #1000 55 | 56 | // transmit with idle 1 57 | @(posedge clk); 58 | #1 59 | tx_ena = 1'b1; 60 | #6400 61 | tx_ena = 1'b0; 62 | #1000 63 | assert(dst === src); 64 | 65 | // transmit with idle 0 66 | tx_idle = 1'b0; 67 | dst = 64'd0; 68 | #1000 69 | @(posedge clk); 70 | #1 71 | tx_ena = 1'b1; 72 | #6400 73 | tx_ena = 1'b0; 74 | #1000 75 | assert(dst === src); 76 | $finish; 77 | end 78 | 79 | initial begin 80 | $dumpfile("test_eth2spi.vcd"); 81 | $dumpvars; 82 | end 83 | 84 | 85 | endmodule 86 | -------------------------------------------------------------------------------- /sch/shield/gerber/shield-B_Mask.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,(6.0.9-0)*% 2 | %TF.CreationDate,2022-11-17T19:03:50+01:00*% 3 | %TF.ProjectId,shield,73686965-6c64-42e6-9b69-6361645f7063,1*% 4 | %TF.SameCoordinates,PX3a2c940PY82a7440*% 5 | %TF.FileFunction,Soldermask,Bot*% 6 | %TF.FilePolarity,Negative*% 7 | %FSLAX46Y46*% 8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 9 | G04 Created by KiCad (PCBNEW (6.0.9-0)) date 2022-11-17 19:03:50* 10 | %MOMM*% 11 | %LPD*% 12 | G01* 13 | G04 APERTURE LIST* 14 | %ADD10C,1.600000*% 15 | %ADD11O,1.500000X2.500000*% 16 | %ADD12R,1.500000X2.500000*% 17 | %ADD13O,2.200000X3.500000*% 18 | %ADD14C,2.400000*% 19 | %ADD15C,1.400000*% 20 | %ADD16C,1.300000*% 21 | %ADD17C,1.524000*% 22 | G04 APERTURE END LIST* 23 | D10* 24 | %TO.C,J2*% 25 | X5490000Y50370000D03* 26 | X2950000Y47830000D03* 27 | X63910000Y60530000D03* 28 | X5490000Y47830000D03* 29 | X66450000Y47830000D03* 30 | X5490000Y63070000D03* 31 | X5490000Y45290000D03* 32 | X66450000Y35130000D03* 33 | X66450000Y40210000D03* 34 | X66450000Y68150000D03* 35 | X2950000Y70690000D03* 36 | X2950000Y68150000D03* 37 | %TD*% 38 | D11* 39 | %TO.C,SW1*% 40 | X9000000Y3702500D03* 41 | X7000000Y3702500D03* 42 | D12* 43 | X5000000Y3702500D03* 44 | D13* 45 | X11100000Y3702500D03* 46 | X2900000Y3702500D03* 47 | %TD*% 48 | D14* 49 | %TO.C,J1*% 50 | X42550000Y14050000D03* 51 | X26850000Y14050000D03* 52 | D15* 53 | X41485000Y8460000D03* 54 | X41485000Y6430000D03* 55 | X27915000Y8460000D03* 56 | X27915000Y6430000D03* 57 | D16* 58 | X30300000Y17350000D03* 59 | X31570000Y19890000D03* 60 | X32840000Y17350000D03* 61 | X34110000Y19890000D03* 62 | X35380000Y17350000D03* 63 | X36650000Y19890000D03* 64 | X37920000Y17350000D03* 65 | X39190000Y19890000D03* 66 | D17* 67 | X40415000Y11000000D03* 68 | X28985000Y11000000D03* 69 | %TD*% 70 | M02* 71 | -------------------------------------------------------------------------------- /stm32eth-f401/src/tx_frame_buf.rs: -------------------------------------------------------------------------------- 1 | use core::cmp::max; 2 | use crc::{Crc, CRC_32_ISO_HDLC}; 3 | use embedded_dma::ReadBuffer; 4 | 5 | pub struct TxFrameBuf { 6 | buf: &'static mut [u8; L], 7 | len: usize, 8 | } 9 | 10 | const PREAMBLE: [u8; 9] = [0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5]; 11 | 12 | const CRC: Crc = Crc::::new(&CRC_32_ISO_HDLC); 13 | 14 | impl TxFrameBuf { 15 | pub fn new_with_fn(buf: &'static mut [u8; L], len: usize, f: F, invert: bool) -> (Self, R) 16 | where 17 | F: FnOnce(&mut [u8]) -> R, 18 | { 19 | buf[0..PREAMBLE.len()].copy_from_slice(&PREAMBLE); 20 | let slice = &mut buf[PREAMBLE.len()..PREAMBLE.len() + len]; 21 | let result = f(slice); 22 | let padded_len = max(len, 60); 23 | buf[PREAMBLE.len() + len..PREAMBLE.len() + padded_len].fill(0); 24 | let mut digest = CRC.digest(); 25 | digest.update(&buf[PREAMBLE.len()..PREAMBLE.len() + padded_len]); 26 | let crc = digest.finalize().to_le_bytes(); 27 | buf[padded_len + PREAMBLE.len()..padded_len + PREAMBLE.len() + crc.len()] 28 | .copy_from_slice(&crc); 29 | if invert { 30 | buf[0..PREAMBLE.len() + padded_len + crc.len()] 31 | .iter_mut() 32 | .for_each(|x| *x = !*x); 33 | } 34 | ( 35 | Self { 36 | buf: buf, 37 | len: padded_len + PREAMBLE.len() + crc.len(), 38 | }, 39 | result, 40 | ) 41 | } 42 | 43 | pub fn release(self) -> &'static mut [u8; L] { 44 | self.buf 45 | } 46 | } 47 | 48 | unsafe impl ReadBuffer for TxFrameBuf { 49 | type Word = u8; 50 | 51 | unsafe fn read_buffer(&self) -> (*const Self::Word, usize) { 52 | (self.buf.as_ptr(), self.len) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # An experiment project to receive and decode a 10BASE-T Ethernet signal 2 | 3 | The Nucleo64 shield schematic files are located in sch/shield/. 4 | 5 | The firmware for stm32f401 is located in stm32eth-f401/. 6 | 7 | ## Receiver operation 8 | 9 | The idea is to convert the Manchester-encoded 10BASE-T signal to SPI and use an STM32 MCU to parse it. 10 | 11 | A 75C1168 chip is used to convert differential signals to 5V logic levels. 12 | 13 | Then, edges are detected using a 74HC86 XOR. 14 | 15 | ![edge detect](/images/edgedetect.jpeg) 16 | 17 | *Blue is the input signal, yellow - detected edges.* 18 | 19 | Then, an `~idle` signal is formed using a delay circuit. It goes from 0 to 1 with the first edge and goes back to 0 after approximately 2 µS after the last transition. This signal is used by the MCU to detect the end of an Ethernet frame. 20 | 21 | ![frame detect](/images/framedetect.jpeg) 22 | 23 | When the line is idle, the output of an 75C1168 is undefined. In my case it was always high. Since the Ethernet frame always starts with a pattern of 101010..., this leads to the first transition always being from 1 to 0, which generates the first edge. This edge must be ignored for SPI clock generation. However, the case with a low idle state needs to be handled as well. In that case the line remains low on the frame begin and the first edge should not be ignored. 24 | 25 | The filtering of the first edge is done using the already generated `~idle` signal. 26 | 27 | 28 | ![first edge filtering](/images/firstfilter.jpeg) 29 | 30 | *First edge is filtered* 31 | 32 | The resulting filtered edge signal is fed onto a non-retriggerable monostable circuit which generates a pulse of approximately 75 nS, which is finally used as an SPI clock. 33 | 34 | ![SPI signal](/images/spi1.jpeg) 35 | 36 | ![SPI signal](/images/spi2.jpeg) 37 | 38 | *Blue - generated SPI SCK signal, yellow - SPI MOSI which is just the input 10BASE-T signal.* 39 | -------------------------------------------------------------------------------- /stm32eth-f401/src/tg.rs: -------------------------------------------------------------------------------- 1 | use heapless::Vec; 2 | use serde::Deserialize; 3 | use serde::Serialize; 4 | 5 | #[derive(Deserialize)] 6 | pub struct User<'a> { 7 | pub id: u64, 8 | pub is_bot: bool, 9 | pub first_name: &'a str, 10 | pub last_name: Option<&'a str>, 11 | pub username: Option<&'a str>, 12 | } 13 | 14 | #[derive(Deserialize)] 15 | pub struct Chat<'a> { 16 | pub id: u64, 17 | #[serde(rename = "type")] 18 | pub chat_type: &'a str, 19 | pub first_name: Option<&'a str>, 20 | pub last_name: Option<&'a str>, 21 | pub username: Option<&'a str>, 22 | } 23 | 24 | #[derive(Deserialize)] 25 | pub struct Message<'a> { 26 | pub message_id: u64, 27 | #[serde(borrow)] 28 | pub from: Option>, 29 | pub date: u64, 30 | #[serde(borrow)] 31 | pub chat: Chat<'a>, 32 | pub text: Option<&'a str>, 33 | } 34 | 35 | #[derive(Deserialize)] 36 | pub struct Update<'a> { 37 | pub update_id: u64, 38 | #[serde(borrow)] 39 | pub message: Option>, 40 | } 41 | 42 | #[derive(Deserialize)] 43 | pub struct GetUpdatesResponse<'a, const N: usize> { 44 | pub ok: bool, 45 | #[serde(borrow)] 46 | pub result: Vec, N>, 47 | } 48 | 49 | #[derive(Deserialize)] 50 | pub struct SendMessageResponse<'a> { 51 | pub ok: bool, 52 | #[serde(borrow)] 53 | pub result: Message<'a>, 54 | } 55 | 56 | 57 | #[derive(Serialize)] 58 | pub struct GetUpdatesParams<'a> { 59 | #[serde(skip_serializing_if = "Option::is_none")] 60 | pub offset: Option, 61 | #[serde(skip_serializing_if = "Option::is_none")] 62 | pub limit: Option, 63 | #[serde(skip_serializing_if = "Option::is_none")] 64 | pub timeout: Option, 65 | #[serde(skip_serializing_if = "Option::is_none")] 66 | pub allowed_updates: Option<&'a [&'a str]>, 67 | } 68 | 69 | 70 | #[derive(Serialize)] 71 | pub struct SendMessageParams<'a> { 72 | pub chat_id: u64, 73 | pub text: &'a str, 74 | } 75 | -------------------------------------------------------------------------------- /stm32eth-f401/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "stm32eth-f401" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | embedded-hal = "0.2" 8 | nb = "1" 9 | cortex-m = { version = "0.7", features = ["critical-section-single-core"] } 10 | cortex-m-rt = "0.7" 11 | # Panic behaviour, see https://crates.io/keywords/panic-impl for alternatives 12 | # panic-halt = "0.2" 13 | defmt-rtt = "0.4" 14 | systick-monotonic = "1" 15 | cortex-m-rtic = ">=1.1" 16 | crc = "2" 17 | embedded-dma = ">=0.2" 18 | 19 | [dependencies.panic-probe] 20 | version = "0.3" 21 | features = ["print-defmt"] 22 | 23 | [dependencies.defmt] 24 | version = "0.3" 25 | features = ["encoding-raw"] 26 | 27 | [dependencies.stm32f4xx-hal] 28 | path = "../stm32f4xx-hal" 29 | features = ["stm32f401"] 30 | 31 | [dependencies.replace_with] 32 | version = "0.1.7" 33 | default-features = false 34 | 35 | [dependencies.smoltcp] 36 | version = "0.8" 37 | default-features = false 38 | features = ["proto-ipv4", "socket-udp", "socket-icmp", "socket-tcp", "socket-dhcpv4", "medium-ethernet", "defmt"] 39 | 40 | [dependencies.httparse] 41 | version = "1.8" 42 | default-features = false 43 | 44 | [dependencies.heapless] 45 | version = "0.7" 46 | features = ["serde"] 47 | 48 | [dependencies.embedded-tls] 49 | version = "0.10" 50 | default-features = false 51 | features = ["async", "defmt"] 52 | 53 | [dependencies.rand] 54 | version = "0.8" 55 | default-features = false 56 | features = ["std_rng"] 57 | 58 | [dependencies.embedded-io] 59 | version = "0.4" 60 | default-features = false 61 | features = ["defmt", "async"] 62 | 63 | [dependencies.futures] 64 | version = "0.3" 65 | default-features = false 66 | 67 | [dependencies.futures-executor] 68 | version = "0.3" 69 | default-features = false 70 | 71 | [dependencies.serde] 72 | version = "1.0" 73 | default-features = false 74 | features = ["derive"] 75 | 76 | [dependencies.serde_derive] 77 | version = "1.0.147" 78 | default-features = false 79 | 80 | [dependencies.serde-json-core] 81 | version = "0.5" 82 | default-features = false 83 | features = ["heapless"] 84 | -------------------------------------------------------------------------------- /sch/ethernet-to-spi/gerber/ethernet-to-spi.drl: -------------------------------------------------------------------------------- 1 | M48 2 | ; DRILL file {KiCad (6.0.7-1)-1} date 2022 September 09, Friday 18:07:52 3 | ; FORMAT={-:-/ absolute / metric / decimal} 4 | ; #@! TF.CreationDate,2022-09-09T18:07:52+02:00 5 | ; #@! TF.GenerationSoftware,Kicad,Pcbnew,(6.0.7-1)-1 6 | ; #@! TF.FileFunction,MixedPlating,1,2 7 | FMAT,2 8 | METRIC 9 | ; #@! TA.AperFunction,Plated,PTH,ViaDrill 10 | T1C0.600 11 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 12 | T2C0.800 13 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 14 | T3C0.850 15 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 16 | T4C0.900 17 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 18 | T5C1.700 19 | ; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill 20 | T6C2.500 21 | ; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill 22 | T7C3.200 23 | % 24 | G90 25 | G05 26 | T1 27 | X45.0Y20.4 28 | X45.0Y13.8 29 | X50.4Y22.2 30 | X52.2Y19.8 31 | X52.2Y7.8 32 | X53.4Y5.8 33 | X54.6Y8.8 34 | X56.8Y20.4 35 | X57.0Y24.2 36 | X58.8Y10.6 37 | X61.0Y17.2 38 | X61.0Y13.8 39 | X68.8Y22.8 40 | X73.6Y19.6 41 | X73.8Y7.6 42 | X77.2Y18.8 43 | X81.0Y17.4 44 | X81.0Y13.6 45 | X85.4Y21.4 46 | X88.4Y20.4 47 | X92.156Y19.45 48 | X94.375Y21.499 49 | X96.6Y17.4 50 | X96.61Y13.59 51 | X103.715Y22.95 52 | X104.915Y20.55 53 | T2 54 | X29.48Y23.675 55 | X29.48Y21.135 56 | X29.48Y18.595 57 | X29.48Y16.055 58 | X29.48Y13.515 59 | X29.48Y10.975 60 | X29.48Y8.435 61 | X29.48Y5.895 62 | X37.1Y23.675 63 | X37.1Y21.135 64 | X37.1Y18.595 65 | X37.1Y16.055 66 | X37.1Y13.515 67 | X37.1Y10.975 68 | X37.1Y8.435 69 | X37.1Y5.895 70 | X85.38Y25.8 71 | X100.62Y25.8 72 | T3 73 | X48.675Y7.8 74 | X48.675Y3.6 75 | X68.075Y7.8 76 | X68.075Y3.4 77 | X98.675Y3.0 78 | X98.875Y29.2 79 | X107.6Y20.725 80 | T4 81 | X17.25Y20.815 82 | X17.25Y18.275 83 | X17.25Y15.735 84 | X17.25Y13.195 85 | X17.25Y10.655 86 | X19.79Y19.545 87 | X19.79Y17.005 88 | X19.79Y14.465 89 | X19.79Y11.925 90 | X19.79Y9.385 91 | T5 92 | X13.95Y22.975 93 | X13.95Y7.225 94 | T6 95 | X60.675Y7.8 96 | X60.675Y3.6 97 | X80.075Y7.8 98 | X80.075Y3.4 99 | X107.6Y8.725 100 | X110.675Y3.0 101 | X110.875Y29.2 102 | T7 103 | X10.9Y20.815 104 | X10.9Y9.385 105 | T0 106 | M30 107 | -------------------------------------------------------------------------------- /sch/ethernet-to-spi/eth.pretty/G8X-188S7-BP.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "G8X-188S7-BP" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 0) 4 | (attr through_hole) 5 | (fp_text reference "REF**" (at 0 6.985 unlocked) (layer "F.SilkS") 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp fcb259bb-694a-406a-95bc-8b91e8ab3228) 8 | ) 9 | (fp_text value "G8X-188S7-BP" (at 0 12.065 unlocked) (layer "F.Fab") 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp 08e95daf-2fe7-48df-b20d-e534514189ed) 12 | ) 13 | (fp_rect (start 8 19.64) (end -8 -1.46) (layer "F.SilkS") (width 0.12) (fill none) (tstamp e9f8d4db-eae8-487b-b462-c2a00c85e307)) 14 | (pad "" np_thru_hole circle (at 5.715 8.89) (size 1.524 1.524) (drill 3.2) (layers *.Mask) (tstamp 229e2e5c-99ae-45fb-998f-b36cff2c903a)) 15 | (pad "" np_thru_hole circle (at -5.715 8.89) (size 1.524 1.524) (drill 3.2) (layers *.Mask) (tstamp daf1330a-6acc-45a7-8b0a-b94a8d218128)) 16 | (pad "1" thru_hole circle (at -5.715 0) (size 1.524 1.524) (drill 0.9) (layers *.Cu *.Mask) (tstamp 960aea08-0d94-47a2-9ecc-b0a98a5dbfef)) 17 | (pad "2" thru_hole circle (at -4.445 2.54) (size 1.524 1.524) (drill 0.9) (layers *.Cu *.Mask) (tstamp 53b6daef-8b80-423a-89ec-bb77168953e2)) 18 | (pad "3" thru_hole circle (at -3.175 0) (size 1.524 1.524) (drill 0.9) (layers *.Cu *.Mask) (tstamp dc3d70ef-6e9b-42ba-b792-8ba86a2d2026)) 19 | (pad "4" thru_hole circle (at -1.905 2.54) (size 1.524 1.524) (drill 0.9) (layers *.Cu *.Mask) (tstamp f2c1583e-aeae-49b0-a44b-0accfe2fa608)) 20 | (pad "5" thru_hole circle (at -0.635 0) (size 1.524 1.524) (drill 0.9) (layers *.Cu *.Mask) (tstamp 69655aba-ac7f-4664-9b11-9abe82600a9d)) 21 | (pad "6" thru_hole circle (at 0.635 2.54) (size 1.524 1.524) (drill 0.9) (layers *.Cu *.Mask) (tstamp 6f8a25db-80a0-4017-8f64-7ef6e88a92c6)) 22 | (pad "7" thru_hole circle (at 1.905 0) (size 1.524 1.524) (drill 0.9) (layers *.Cu *.Mask) (tstamp 5ab080f4-3837-4d80-b830-3474935420de)) 23 | (pad "8" thru_hole circle (at 3.175 2.54) (size 1.524 1.524) (drill 0.9) (layers *.Cu *.Mask) (tstamp 9684c46c-289f-4285-9912-647b0f1a1573)) 24 | (pad "9" thru_hole circle (at 4.445 0) (size 1.524 1.524) (drill 0.9) (layers *.Cu *.Mask) (tstamp 959f3d6e-b052-4487-bbcb-1431892a02a3)) 25 | (pad "10" thru_hole circle (at 5.715 2.54) (size 1.524 1.524) (drill 0.9) (layers *.Cu *.Mask) (tstamp 2ac74225-8ff6-461b-acfd-4f7ea6f21915)) 26 | (pad "11" thru_hole circle (at 7.875 5.84) (size 2.7 2.7) (drill 1.7) (layers *.Cu *.Mask) (tstamp ea6531f5-0328-45f1-8561-c48304495e38)) 27 | (pad "11" thru_hole circle (at -7.875 5.84) (size 2.7 2.7) (drill 1.7) (layers *.Cu *.Mask) (tstamp f2d758b1-0cd3-48fa-a485-3c6da91c8340)) 28 | ) 29 | -------------------------------------------------------------------------------- /sch/shield/schield.pretty/ARJM11D7-009.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "ARJM11D7-009" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 0) 4 | (attr through_hole) 5 | (fp_text reference "REF**" (at 0 -0.5 unlocked) (layer "F.SilkS") 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp e907bea5-1369-46e0-b1f9-8a4d4300c955) 8 | ) 9 | (fp_text value "ARJM11D7-009" (at 0 1 unlocked) (layer "F.Fab") 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp 34fef3e1-36f4-4620-ba8f-2c0b5b44d394) 12 | ) 13 | (fp_rect (start 7.85 10.85) (end -7.85 -10.85) (layer "F.CrtYd") (width 0.05) (fill none) (tstamp 55ac8136-fbc7-4849-a054-b31679ff51b2)) 14 | (pad "" np_thru_hole circle (at -5.715 0) (size 1.524 1.524) (drill 3.25) (layers *.Mask) (tstamp 0b808d2b-adb4-4e31-902b-2a99881175ea)) 15 | (pad "" np_thru_hole circle (at 5.715 0) (size 1.524 1.524) (drill 3.25) (layers *.Mask) (tstamp 10775d35-7290-4f6d-b961-1abee2870c6a)) 16 | (pad "1" thru_hole circle (at 4.49 -8.89) (size 1.3 1.3) (drill 0.9) (layers *.Cu *.Mask) (tstamp c305a54a-76e6-447b-bca2-126f1627e3d5)) 17 | (pad "2" thru_hole circle (at 3.22 -6.35) (size 1.3 1.3) (drill 0.9) (layers *.Cu *.Mask) (tstamp abbe0f67-158c-4503-b131-5489964d94ea)) 18 | (pad "3" thru_hole circle (at 1.95 -8.89) (size 1.3 1.3) (drill 0.9) (layers *.Cu *.Mask) (tstamp b3014b8e-9b27-4d5b-9a2c-a6a74a159f55)) 19 | (pad "4" thru_hole circle (at 0.68 -6.35) (size 1.3 1.3) (drill 0.9) (layers *.Cu *.Mask) (tstamp 17a493ad-784d-4e15-8f09-9b3362297866)) 20 | (pad "5" thru_hole circle (at -0.59 -8.89) (size 1.3 1.3) (drill 0.9) (layers *.Cu *.Mask) (tstamp 26447768-4d12-4e30-97e0-d4ab33c28b5b)) 21 | (pad "6" thru_hole circle (at -1.86 -6.35) (size 1.3 1.3) (drill 0.9) (layers *.Cu *.Mask) (tstamp 78919df1-2ae8-424d-9cd8-cc376d8ccef4)) 22 | (pad "7" thru_hole circle (at -3.13 -8.89) (size 1.3 1.3) (drill 0.9) (layers *.Cu *.Mask) (tstamp 40f9fe93-1df0-4734-a133-a8cab959666b)) 23 | (pad "8" thru_hole circle (at -4.4 -6.35) (size 1.3 1.3) (drill 0.9) (layers *.Cu *.Mask) (tstamp 1b7ef6af-717e-41c0-9091-051d0a2bd08f)) 24 | (pad "9" thru_hole circle (at -6.785 4.57) (size 1.4 1.4) (drill 1) (layers *.Cu *.Mask) (tstamp 024a693d-5221-40f1-8fdb-561926357e5d)) 25 | (pad "10" thru_hole circle (at -6.785 2.54) (size 1.4 1.4) (drill 1) (layers *.Cu *.Mask) (tstamp c2caa856-77da-4349-a1c1-f62feeea58a0)) 26 | (pad "11" thru_hole circle (at 6.785 4.57) (size 1.4 1.4) (drill 1) (layers *.Cu *.Mask) (tstamp f7ca60e5-a780-4895-b37c-6fa4d17d5d92)) 27 | (pad "12" thru_hole circle (at 6.785 2.54) (size 1.4 1.4) (drill 1) (layers *.Cu *.Mask) (tstamp 48107152-5993-457d-a00b-d8995eab92a4)) 28 | (pad "SH" thru_hole circle (at -7.85 -3.05) (size 2.4 2.4) (drill 1.6) (layers *.Cu *.Mask) (tstamp be202b0b-3ede-4bd2-9fe2-b06d431599f1)) 29 | (pad "SH" thru_hole circle (at 7.85 -3.05) (size 2.4 2.4) (drill 1.6) (layers *.Cu *.Mask) (tstamp d1a411c8-e1fa-47f6-990d-72a0bdba5f8f)) 30 | ) 31 | -------------------------------------------------------------------------------- /stm32eth-f401/src/device.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | receiver::{Receiver, RxBuf}, 3 | transmitter::Transmitter, 4 | }; 5 | 6 | use core::cell::RefCell; 7 | use cortex_m::interrupt; 8 | use smoltcp::phy::{Device, DeviceCapabilities, Medium}; 9 | 10 | pub type ReceiverMutex = &'static cortex_m::interrupt::Mutex>>; 11 | pub struct SpiDevice { 12 | receiver: ReceiverMutex, 13 | transmitter: Transmitter, 14 | } 15 | 16 | impl SpiDevice { 17 | pub fn new(receiver: ReceiverMutex, transmitter: Transmitter) -> Self { 18 | Self { 19 | receiver, 20 | transmitter, 21 | } 22 | } 23 | } 24 | 25 | impl<'a> Device<'a> for SpiDevice { 26 | type RxToken = RxToken; 27 | 28 | type TxToken = TxToken<'a>; 29 | 30 | fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> { 31 | let b = interrupt::free(|cs| { 32 | self.receiver 33 | .borrow(cs) 34 | .borrow_mut() 35 | .as_mut() 36 | .unwrap() 37 | .try_get_data() 38 | }); 39 | match b { 40 | Some((buf, len)) => Some(( 41 | RxToken { 42 | buf, 43 | len, 44 | receiver: self.receiver, 45 | }, 46 | TxToken(&mut self.transmitter), 47 | )), 48 | None => None, 49 | } 50 | } 51 | 52 | fn transmit(&'a mut self) -> Option { 53 | Some(TxToken(&mut self.transmitter)) 54 | } 55 | 56 | fn capabilities(&self) -> smoltcp::phy::DeviceCapabilities { 57 | let mut caps = DeviceCapabilities::default(); 58 | caps.medium = Medium::Ethernet; 59 | caps.max_transmission_unit = crate::transmitter::MTU; 60 | caps.max_burst_size = Some(1); 61 | caps 62 | } 63 | } 64 | 65 | pub struct RxToken { 66 | buf: RxBuf, 67 | len: usize, 68 | receiver: ReceiverMutex, 69 | } 70 | 71 | pub struct TxToken<'a>(&'a mut Transmitter); 72 | 73 | impl smoltcp::phy::RxToken for RxToken { 74 | fn consume(self, _timestamp: smoltcp::time::Instant, f: F) -> smoltcp::Result 75 | where 76 | F: FnOnce(&mut [u8]) -> smoltcp::Result, 77 | { 78 | let result = f(&mut self.buf[0..self.len - 4]); 79 | interrupt::free(|cs| { 80 | self.receiver 81 | .borrow(cs) 82 | .borrow_mut() 83 | .as_mut() 84 | .unwrap() 85 | .return_buffer(self.buf) 86 | }); 87 | result 88 | } 89 | } 90 | 91 | impl<'a> smoltcp::phy::TxToken for TxToken<'a> { 92 | fn consume( 93 | self, 94 | _timestamp: smoltcp::time::Instant, 95 | len: usize, 96 | f: F, 97 | ) -> smoltcp::Result 98 | where 99 | F: FnOnce(&mut [u8]) -> smoltcp::Result, 100 | { 101 | self.0.transmit(len, f).unwrap() 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /stm32eth-f401/src/transmitter.rs: -------------------------------------------------------------------------------- 1 | 2 | use replace_with::replace_with_and_return; 3 | use stm32f4xx_hal::{ 4 | dma::{config, Stream7, Transfer}, 5 | gpio::{Output, PC10, PC12}, 6 | pac::{DMA1, SPI3}, 7 | prelude::*, 8 | rcc::Clocks, 9 | spi::{BitFormat, Mode, NoMiso, Phase, Polarity, Spi}, 10 | }; 11 | 12 | use crate::tx_frame_buf::TxFrameBuf; 13 | 14 | pub const BUFFER_LEN: usize = 1600; 15 | pub const MTU: usize = BUFFER_LEN - 8 - 4; 16 | 17 | pub type TxBuf = &'static mut [u8; BUFFER_LEN]; 18 | 19 | type PinSck = PC10; 20 | type PinMosi = PC12; 21 | type DmaStream = Stream7; 22 | 23 | pub struct Transmitter { 24 | spi: Spi, 25 | dma_stream: DmaStream, 26 | buf: TxBuf, 27 | invert_idle: bool, 28 | invert_data: bool, 29 | invert_sck_pol: bool, 30 | } 31 | 32 | impl Transmitter { 33 | pub fn new( 34 | invert_idle: bool, 35 | invert_data: bool, 36 | invert_sck_pol: bool, 37 | spi: SPI3, 38 | mut sck: PinSck, 39 | mut mosi: PinMosi, 40 | dma_stream: DmaStream, 41 | clocks: &Clocks, 42 | buf: TxBuf, 43 | ) -> Self { 44 | if invert_idle { 45 | sck.set_high(); 46 | } else { 47 | sck.set_low(); 48 | } 49 | mosi.set_low(); 50 | let mode = Mode { 51 | polarity: Polarity::IdleLow, 52 | phase: Phase::CaptureOnSecondTransition, 53 | }; 54 | let mut spi = Spi::new(spi, (sck, NoMiso {}, mosi), mode, 10.MHz(), clocks); 55 | spi.bit_format(BitFormat::LsbFirst); 56 | Self { 57 | spi, 58 | dma_stream, 59 | buf, 60 | invert_idle, 61 | invert_data, 62 | invert_sck_pol, 63 | } 64 | } 65 | 66 | pub fn transmit(&mut self, len: usize, f: F) -> Option 67 | where 68 | F: FnOnce(&mut [u8]) -> R, 69 | { 70 | replace_with_and_return( 71 | self, 72 | || panic!(), 73 | |s| { 74 | let Self { 75 | spi, 76 | dma_stream, 77 | buf, 78 | invert_idle, 79 | invert_data, 80 | invert_sck_pol, 81 | } = s; 82 | let (frame_buf, result) = TxFrameBuf::new_with_fn(buf, len, f, invert_data); 83 | 84 | let dma_tx = spi.use_dma().tx(); 85 | let mut transfer = Transfer::init_memory_to_peripheral( 86 | dma_stream, 87 | dma_tx, 88 | frame_buf, 89 | None, 90 | config::DmaConfig::default().memory_increment(true), 91 | ); 92 | 93 | transfer.start(|_tx| {}); 94 | 95 | transfer.wait(); 96 | 97 | let (dma_stream, tx, buf, _) = transfer.release(); 98 | let spi = tx.release(); 99 | 100 | while spi.is_busy() {} 101 | 102 | ( 103 | Some(result), 104 | Self { 105 | spi, 106 | dma_stream, 107 | buf: buf.release(), 108 | invert_idle, 109 | invert_data, 110 | invert_sck_pol, 111 | }, 112 | ) 113 | }, 114 | ) 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /sch/shield/gerber/shield.drl: -------------------------------------------------------------------------------- 1 | M48 2 | ; DRILL file {KiCad (6.0.9-0)} date 2022 November 17, Thursday 19:03:58 3 | ; FORMAT={-:-/ absolute / metric / decimal} 4 | ; #@! TF.CreationDate,2022-11-17T19:03:58+01:00 5 | ; #@! TF.GenerationSoftware,Kicad,Pcbnew,(6.0.9-0) 6 | ; #@! TF.FileFunction,MixedPlating,1,4 7 | FMAT,2 8 | METRIC 9 | ; #@! TA.AperFunction,Plated,PTH,ViaDrill 10 | T1C0.250 11 | ; #@! TA.AperFunction,Plated,PTH,ViaDrill 12 | T2C0.350 13 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 14 | T3C0.800 15 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 16 | T4C0.900 17 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 18 | T5C1.000 19 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 20 | T6C1.500 21 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 22 | T7C1.600 23 | ; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill 24 | T8C3.250 25 | % 26 | G90 27 | G05 28 | T1 29 | X5.2Y41.9 30 | X5.2Y26.3 31 | X7.1Y57.7 32 | X7.1Y49.1 33 | X7.1Y47.7 34 | X10.0Y61.6 35 | X10.0Y37.3 36 | X11.6Y49.1 37 | X11.6Y23.7 38 | X11.7Y70.8 39 | X11.7Y63.5 40 | X13.2Y59.0 41 | X13.2Y39.7 42 | X14.0Y32.7 43 | X14.0Y21.2 44 | X14.3Y68.2 45 | X14.3Y60.3 46 | X14.3Y54.0 47 | X14.4Y62.9 48 | X15.3Y60.3 49 | X15.3Y41.9 50 | X18.2Y56.5 51 | X18.2Y27.5 52 | X18.3Y21.2 53 | X21.1Y57.8 54 | X21.1Y32.7 55 | X23.0Y34.9 56 | X23.05Y37.85 57 | X25.3Y63.8 58 | X25.3Y45.6 59 | X26.0Y63.1 60 | X26.0Y61.8 61 | X26.4Y35.9 62 | X26.4Y22.3 63 | X26.7Y54.0 64 | X26.7Y37.2 65 | X26.8Y63.8 66 | X28.0Y37.9 67 | X28.0Y25.0 68 | X28.0Y19.6 69 | X29.2Y24.0 70 | X29.3Y34.0 71 | X30.7Y26.2 72 | X30.8Y48.6 73 | X31.8Y57.0 74 | X31.8Y36.5 75 | X31.9Y62.6 76 | X31.9Y30.3 77 | X32.7Y68.3 78 | X32.7Y63.8 79 | X32.7Y61.2 80 | X32.8Y25.9 81 | X34.2Y43.8 82 | X34.2Y38.6 83 | X34.4Y33.1 84 | X34.4Y29.7 85 | X35.0Y55.2 86 | X35.0Y37.2 87 | X35.5Y35.0 88 | X35.5Y31.1 89 | X36.4Y32.4 90 | X36.4Y29.8 91 | X36.6Y52.7 92 | X36.6Y34.0 93 | X36.6Y25.9 94 | X39.2Y22.9 95 | X40.4Y25.5 96 | X41.5Y44.6 97 | X41.5Y39.8 98 | X42.8Y37.0 99 | X42.8Y31.8 100 | X45.4Y66.5 101 | X45.4Y60.4 102 | X46.9Y60.2 103 | X46.9Y57.0 104 | X47.8Y63.4 105 | X47.8Y58.9 106 | X48.7Y48.2 107 | X48.7Y37.0 108 | X49.1Y15.6 109 | X49.1Y12.2 110 | X49.3Y68.4 111 | X49.3Y62.0 112 | X49.5Y47.5 113 | X49.5Y45.0 114 | X50.1Y54.5 115 | X50.1Y41.5 116 | X52.2Y61.4 117 | X52.2Y52.7 118 | X52.8Y53.9 119 | X52.9Y59.4 120 | X53.6Y60.7 121 | X54.2Y54.7 122 | X54.4Y62.0 123 | X54.6Y9.6 124 | X55.2Y59.4 125 | X55.4Y22.3 126 | X55.4Y8.4 127 | X55.7Y35.7 128 | X68.0Y54.0 129 | T2 130 | X3.0Y16.0 131 | X3.8Y53.7 132 | X11.7Y55.6 133 | X13.1Y35.4 134 | X15.6Y66.2 135 | X16.8Y19.1 136 | X17.1Y38.5 137 | X18.2Y59.0 138 | X19.4Y66.2 139 | X20.0Y42.6 140 | X20.0Y33.7 141 | X20.7Y29.5 142 | X20.9Y62.5 143 | X22.4Y59.7 144 | X24.5Y29.5 145 | X24.7Y34.6 146 | X27.2Y66.5 147 | X29.4Y61.9 148 | X29.5Y41.1 149 | X31.2Y66.6 150 | X33.5Y41.1 151 | X34.1Y62.5 152 | X35.5Y59.8 153 | X37.4Y47.4 154 | X38.6Y41.9 155 | X40.3Y27.8 156 | X40.4Y66.5 157 | X42.7Y63.2 158 | X42.7Y61.9 159 | X43.0Y41.9 160 | X44.3Y66.5 161 | X44.4Y54.5 162 | X45.2Y34.8 163 | X45.9Y13.4 164 | X45.9Y10.9 165 | X45.9Y8.4 166 | X46.1Y27.9 167 | X47.0Y40.9 168 | X47.5Y30.5 169 | X48.1Y53.5 170 | X49.3Y34.8 171 | X50.7Y58.1 172 | X50.7Y18.4 173 | X50.7Y3.7 174 | X51.2Y51.5 175 | X52.8Y18.4 176 | X53.6Y48.1 177 | X53.6Y43.1 178 | X55.1Y51.5 179 | X55.5Y64.6 180 | X56.3Y15.7 181 | X59.4Y64.6 182 | X60.0Y72.0 183 | X60.3Y15.7 184 | X60.8Y12.2 185 | X60.8Y9.6 186 | X60.8Y7.1 187 | X64.0Y3.0 188 | X65.2Y11.0 189 | X65.4Y13.1 190 | T3 191 | X5.0Y3.702 192 | X7.0Y3.702 193 | X9.0Y3.702 194 | T4 195 | X2.95Y70.69 196 | X2.95Y68.15 197 | X2.95Y47.83 198 | X5.49Y63.07 199 | X5.49Y50.37 200 | X5.49Y47.83 201 | X5.49Y45.29 202 | X30.3Y17.35 203 | X31.57Y19.89 204 | X32.84Y17.35 205 | X34.11Y19.89 206 | X35.38Y17.35 207 | X36.65Y19.89 208 | X37.92Y17.35 209 | X39.19Y19.89 210 | X63.91Y60.53 211 | X66.45Y68.15 212 | X66.45Y47.83 213 | X66.45Y40.21 214 | X66.45Y35.13 215 | T5 216 | X27.915Y8.46 217 | X27.915Y6.43 218 | X41.485Y8.46 219 | X41.485Y6.43 220 | T6 221 | X2.9Y3.702 222 | X11.1Y3.702 223 | T7 224 | X26.85Y14.05 225 | X42.55Y14.05 226 | T8 227 | X28.985Y11.0 228 | X40.415Y11.0 229 | T0 230 | M30 231 | -------------------------------------------------------------------------------- /sch/transmitter/gerber/transmitter-B_Cu.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,(6.0.7-1)-1*% 2 | %TF.CreationDate,2022-11-12T09:43:49+01:00*% 3 | %TF.ProjectId,transmitter,7472616e-736d-4697-9474-65722e6b6963,rev?*% 4 | %TF.SameCoordinates,PX4b571c0PY82e44d0*% 5 | %TF.FileFunction,Copper,L2,Bot*% 6 | %TF.FilePolarity,Positive*% 7 | %FSLAX46Y46*% 8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 9 | G04 Created by KiCad (PCBNEW (6.0.7-1)-1) date 2022-11-12 09:43:49* 10 | %MOMM*% 11 | %LPD*% 12 | G01* 13 | G04 APERTURE LIST* 14 | G04 Aperture macros list* 15 | %AMRoundRect* 16 | 0 Rectangle with rounded corners* 17 | 0 $1 Rounding radius* 18 | 0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners* 19 | 0 Add a 4 corners polygon primitive as box body* 20 | 4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0* 21 | 0 Add four circle primitives for the rounded corners* 22 | 1,1,$1+$1,$2,$3* 23 | 1,1,$1+$1,$4,$5* 24 | 1,1,$1+$1,$6,$7* 25 | 1,1,$1+$1,$8,$9* 26 | 0 Add four rect primitives between the rounded corners* 27 | 20,1,$1+$1,$2,$3,$4,$5,0* 28 | 20,1,$1+$1,$4,$5,$6,$7,0* 29 | 20,1,$1+$1,$6,$7,$8,$9,0* 30 | 20,1,$1+$1,$8,$9,$2,$3,0*% 31 | G04 Aperture macros list end* 32 | %TA.AperFunction,ComponentPad*% 33 | %ADD10C,1.600000*% 34 | %TD*% 35 | %TA.AperFunction,ComponentPad*% 36 | %ADD11O,1.600000X1.600000*% 37 | %TD*% 38 | %TA.AperFunction,ComponentPad*% 39 | %ADD12R,1.600000X1.600000*% 40 | %TD*% 41 | %TA.AperFunction,ComponentPad*% 42 | %ADD13RoundRect,0.250001X-0.899999X-0.899999X0.899999X-0.899999X0.899999X0.899999X-0.899999X0.899999X0*% 43 | %TD*% 44 | %TA.AperFunction,ComponentPad*% 45 | %ADD14RoundRect,0.250001X0.899999X0.899999X-0.899999X0.899999X-0.899999X-0.899999X0.899999X-0.899999X0*% 46 | %TD*% 47 | %TA.AperFunction,ViaPad*% 48 | %ADD15C,1.000000*% 49 | %TD*% 50 | %TA.AperFunction,Conductor*% 51 | %ADD16C,0.400000*% 52 | %TD*% 53 | %TA.AperFunction,Conductor*% 54 | %ADD17C,0.600000*% 55 | %TD*% 56 | G04 APERTURE END LIST* 57 | D10* 58 | %TO.P,C2,1*% 59 | %TO.N,Net-(C2-Pad1)*% 60 | X38500000Y38050000D03* 61 | %TO.P,C2,2*% 62 | %TO.N,GND*% 63 | X38500000Y43050000D03* 64 | %TD*% 65 | %TO.P,R2,1*% 66 | %TO.N,Net-(C2-Pad1)*% 67 | X35310000Y39250000D03* 68 | D11* 69 | %TO.P,R2,2*% 70 | %TO.N,Net-(R2-Pad2)*% 71 | X27690000Y39250000D03* 72 | %TD*% 73 | D12* 74 | %TO.P,U1,1*% 75 | %TO.N,Net-(R2-Pad2)*% 76 | X28200000Y35375000D03* 77 | D11* 78 | %TO.P,U1,2*% 79 | %TO.N,Net-(U1-Pad2)*% 80 | X28200000Y32835000D03* 81 | %TO.P,U1,3*% 82 | %TO.N,/nlp*% 83 | X28200000Y30295000D03* 84 | %TO.P,U1,4*% 85 | X28200000Y27755000D03* 86 | %TO.P,U1,5*% 87 | %TO.N,VCC*% 88 | X28200000Y25215000D03* 89 | %TO.P,U1,6*% 90 | %TO.N,/~{nlp}*% 91 | X28200000Y22675000D03* 92 | %TO.P,U1,7,GND*% 93 | %TO.N,GND*% 94 | X28200000Y20135000D03* 95 | %TO.P,U1,8*% 96 | %TO.N,Net-(U1-Pad8)*% 97 | X20580000Y20135000D03* 98 | %TO.P,U1,9*% 99 | %TO.N,Net-(U1-Pad9)*% 100 | X20580000Y22675000D03* 101 | %TO.P,U1,10*% 102 | %TO.N,VCC*% 103 | X20580000Y25215000D03* 104 | %TO.P,U1,11*% 105 | %TO.N,/xor_tx*% 106 | X20580000Y27755000D03* 107 | %TO.P,U1,12*% 108 | %TO.N,/sck_tx*% 109 | X20580000Y30295000D03* 110 | %TO.P,U1,13*% 111 | %TO.N,/mosi_tx*% 112 | X20580000Y32835000D03* 113 | %TO.P,U1,14,VCC*% 114 | %TO.N,VCC*% 115 | X20580000Y35375000D03* 116 | %TD*% 117 | D13* 118 | %TO.P,J8,1,Pin_1*% 119 | %TO.N,/driver_ena*% 120 | X7000000Y19725000D03* 121 | %TD*% 122 | %TO.P,J7,1,Pin_1*% 123 | %TO.N,/driver_in*% 124 | X3000000Y19725000D03* 125 | %TD*% 126 | D14* 127 | %TO.P,J6,1,Pin_1*% 128 | %TO.N,/mosi_tx*% 129 | X11500000Y33775000D03* 130 | %TD*% 131 | %TO.P,J5,1,Pin_1*% 132 | %TO.N,/sck_tx*% 133 | X15500000Y33775000D03* 134 | %TD*% 135 | %TO.P,J4,1,Pin_1*% 136 | %TO.N,GND*% 137 | X44000000Y18775000D03* 138 | %TD*% 139 | D13* 140 | %TO.P,J3,1,Pin_1*% 141 | %TO.N,GND*% 142 | X48000000Y4725000D03* 143 | %TD*% 144 | %TO.P,J2,1,Pin_1*% 145 | %TO.N,VCC*% 146 | X39000000Y4725000D03* 147 | %TD*% 148 | D14* 149 | %TO.P,J1,1,Pin_1*% 150 | %TO.N,VCC*% 151 | X35000000Y18775000D03* 152 | %TD*% 153 | D15* 154 | %TO.N,GND*% 155 | X41600000Y8750000D03* 156 | X36700000Y8750000D03* 157 | X36500000Y25250000D03* 158 | X31000000Y25250000D03* 159 | %TO.N,Net-(U1-Pad9)*% 160 | X19000000Y16950000D03* 161 | X29600000Y17050000D03* 162 | %TO.N,/tx_ena*% 163 | X29500000Y11450000D03* 164 | X19200000Y11350000D03* 165 | %TD*% 166 | D16* 167 | %TO.N,GND*% 168 | X41600000Y8750000D02* 169 | X36700000Y8750000D01* 170 | D17* 171 | %TO.N,VCC*% 172 | X35000000Y18775000D02* 173 | X34640000Y18775000D01* 174 | X34640000Y18775000D02* 175 | X28200000Y25215000D01* 176 | X20580000Y25215000D02* 177 | X28200000Y25215000D01* 178 | D16* 179 | %TO.N,GND*% 180 | X36500000Y25250000D02* 181 | X31000000Y25250000D01* 182 | %TO.N,/tx_ena*% 183 | X19300000Y11450000D02* 184 | X19200000Y11350000D01* 185 | X29500000Y11450000D02* 186 | X19300000Y11450000D01* 187 | %TO.N,Net-(U1-Pad9)*% 188 | X29500000Y16950000D02* 189 | X29600000Y17050000D01* 190 | X19000000Y16950000D02* 191 | X29500000Y16950000D01* 192 | %TD*% 193 | M02* 194 | -------------------------------------------------------------------------------- /stm32eth-f401/src/unescape.rs: -------------------------------------------------------------------------------- 1 | use defmt::Format; 2 | use heapless::String; 3 | 4 | #[derive(Debug, PartialEq, Format)] 5 | pub enum UnescapeError { 6 | Overflow(String), 7 | UnexpectedEnd(String), 8 | BadEscape(char), 9 | BadHexUnicode, 10 | } 11 | 12 | pub fn unescape(s: &str) -> Result, UnescapeError> { 13 | let mut result = String::new(); 14 | let mut state = State::Text; 15 | for c in s.chars() { 16 | let r = match state { 17 | State::Text => { 18 | if c == '\\' { 19 | Ok(State::Escape) 20 | } else { 21 | result.push(c).map(|_| State::Text) 22 | } 23 | } 24 | State::Escape => match c { 25 | '"' => result.push('"').map(|_| State::Text), 26 | '\\' => result.push('\\').map(|_| State::Text), 27 | '/' => result.push('/').map(|_| State::Text), 28 | 'b' => result.push('\x08').map(|_| State::Text), 29 | 'f' => result.push('\x0c').map(|_| State::Text), 30 | 'n' => result.push('\n').map(|_| State::Text), 31 | 'r' => result.push('\r').map(|_| State::Text), 32 | 't' => result.push('\t').map(|_| State::Text), 33 | 'u' => Ok(State::HexDigit(0, 0)), 34 | _ => { 35 | return Err(UnescapeError::BadEscape(c)); 36 | } 37 | }, 38 | State::HexDigit(n, v) => { 39 | let new_state = if c.is_digit(16) { 40 | State::HexDigit(n + 1, v * 16 + c.to_digit(16).unwrap()) 41 | } else { 42 | return Err(UnescapeError::BadHexUnicode); 43 | }; 44 | match new_state { 45 | State::HexDigit(4, v) if v >= 0xd800 && v <= 0xdbff => { 46 | Ok(State::SurrogateEscape(v)) 47 | } 48 | State::HexDigit(4, v) => { 49 | if let Some(uc) = char::from_u32(v) { 50 | result.push(uc).map(|_| State::Text) 51 | } else { 52 | return Err(UnescapeError::BadHexUnicode); 53 | } 54 | } 55 | State::HexDigit(_, _) => Ok(new_state), 56 | _ => unreachable!(), 57 | } 58 | } 59 | State::SurrogateEscape(v) => { 60 | if c == '\\' { 61 | Ok(State::SurrogateU(v)) 62 | } else { 63 | return Err(UnescapeError::BadHexUnicode); 64 | } 65 | } 66 | State::SurrogateU(v) => { 67 | if c == 'u' { 68 | Ok(State::SurrogateHexDigit(v, 0, 0)) 69 | } else { 70 | return Err(UnescapeError::BadHexUnicode); 71 | } 72 | } 73 | State::SurrogateHexDigit(hi, n, v) => { 74 | let new_state = if c.is_digit(16) { 75 | State::SurrogateHexDigit(hi, n + 1, v * 16 + c.to_digit(16).unwrap()) 76 | } else { 77 | return Err(UnescapeError::BadHexUnicode); 78 | }; 79 | match new_state { 80 | State::SurrogateHexDigit(hi, 4, lo) if lo >= 0xdc00 && lo <= 0xdfff => { 81 | let codepoint = ((hi - 0xd800) << 10) + (lo - 0xdc00) + 0x10000; 82 | if let Some(uc) = char::from_u32(codepoint) { 83 | result.push(uc).map(|_| State::Text) 84 | } else { 85 | return Err(UnescapeError::BadHexUnicode); 86 | } 87 | } 88 | State::SurrogateHexDigit(_, 4, _) => return Err(UnescapeError::BadHexUnicode), 89 | State::SurrogateHexDigit(_, _, _) => Ok(new_state), 90 | _ => unreachable!(), 91 | } 92 | } 93 | }; 94 | state = match r { 95 | Ok(s) => s, 96 | Err(()) => return Err(UnescapeError::Overflow(result)), 97 | }; 98 | } 99 | 100 | if let State::Text = state { 101 | Ok(result) 102 | } else { 103 | return Err(UnescapeError::UnexpectedEnd(result)); 104 | } 105 | } 106 | 107 | #[derive(Copy, Clone)] 108 | enum State { 109 | Text, 110 | Escape, 111 | HexDigit(u16, u32), 112 | SurrogateEscape(u32), // expecting backslash after first utf-16 value 113 | SurrogateU(u32), // expecting u 114 | SurrogateHexDigit(u32, u16, u32), 115 | } 116 | 117 | #[cfg(test)] 118 | mod tests { 119 | use crate::unescape::UnescapeError; 120 | 121 | use super::unescape; 122 | 123 | #[test] 124 | fn test_unescape() { 125 | assert!(matches!(unescape::<16>("hello"), Ok(s) if s == "hello")); 126 | assert!(matches!(unescape::<16>("hel\\nlo"), Ok(s) if s == "hel\nlo")); 127 | assert!(matches!(unescape::<16>("hel\\\"lo"), Ok(s) if s == "hel\"lo")); 128 | assert!(matches!(unescape::<16>("hel\\u1234lo"), Ok(s) if s == "hel\u{1234}lo")); 129 | assert_eq!( 130 | unescape::<16>("hell\\o w"), 131 | Err(UnescapeError::BadEscape('o')) 132 | ); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /stm32eth-f401/src/bot_task.rs: -------------------------------------------------------------------------------- 1 | use crate::adapter::TcpSocketAdapter; 2 | use crate::tg_bot::{get_updates, send_message, TgBotError}; 3 | use crate::unescape::unescape; 4 | use crate::{event, unescape}; 5 | use core::cell::RefCell; 6 | use core::ops::DerefMut; 7 | use core::pin::Pin; 8 | use cortex_m::singleton; 9 | use futures::{future::select, future::Either, pin_mut}; 10 | use heapless::{FnvIndexSet, String}; 11 | use rand::{CryptoRng, RngCore, SeedableRng, rngs::StdRng}; 12 | 13 | pub async fn bot_task( 14 | seed: u64, 15 | adapter1: TcpSocketAdapter<'_>, 16 | mut adapter2: TcpSocketAdapter<'_>, 17 | bt_press_consumer: &mut crate::event::BtnPressConsumer, 18 | ) -> ! { 19 | let mut rng1 = StdRng::seed_from_u64(seed); 20 | let mut rng2 = StdRng::seed_from_u64(rng1.next_u64()); 21 | let send_msg_rx_buf = singleton!(: [u8; 2048] = [0; 2048]).unwrap(); 22 | let bot = RefCell::new(Bot { 23 | adapter_poll: adapter1, 24 | rng: &mut rng1, 25 | last_update: None, 26 | }); 27 | let mut get_msg_future_opt = None; 28 | let mut button_listeners = FnvIndexSet::<_, 16>::new(); 29 | loop { 30 | let btn_press_future = event::wait_btn_press(bt_press_consumer); 31 | pin_mut!(btn_press_future); 32 | 33 | if get_msg_future_opt.is_none() { 34 | get_msg_future_opt = Some(Bot::get_message::<256>(&bot)); 35 | } 36 | 37 | let get_msg_future_pin = unsafe { 38 | let r = get_msg_future_opt.as_mut().unwrap(); 39 | Pin::new_unchecked(r) 40 | }; 41 | 42 | match select(get_msg_future_pin, btn_press_future).await { 43 | Either::Left((msg_r, _btn_press_future)) => { 44 | match msg_r { 45 | Ok(Some((chat_id, text))) => { 46 | button_listeners.insert(chat_id).ok(); 47 | let r = send_message(chat_id, &text, send_msg_rx_buf, &mut adapter2, &mut rng2) 48 | .await; 49 | if let Err(e) = r { 50 | defmt::error!("send_message error: {}", e); 51 | } 52 | } 53 | Ok(None) => (), 54 | Err(e) => { 55 | defmt::error!("get_message error: {}", e); 56 | } 57 | }; 58 | get_msg_future_opt = None; 59 | } 60 | Either::Right((_ev, _r_get_msg_future)) => { 61 | defmt::warn!("Button is pressed"); 62 | for chat_id in button_listeners.iter() { 63 | let r = send_message( 64 | *chat_id, 65 | "Button is pressed!", 66 | send_msg_rx_buf, 67 | &mut adapter2, 68 | &mut rng2, 69 | ) 70 | .await; 71 | if let Err(e) = r { 72 | defmt::error!("send_message error: {}", e); 73 | } 74 | } 75 | } 76 | }; 77 | } 78 | } 79 | 80 | struct Bot<'iface, 'a, Rng: CryptoRng + RngCore> { 81 | adapter_poll: TcpSocketAdapter<'iface>, 82 | rng: &'a mut Rng, 83 | last_update: Option, 84 | } 85 | 86 | impl Bot<'_, '_, Rng> { 87 | async fn get_message( 88 | self_: &RefCell, 89 | ) -> Result)>, TgBotError> { 90 | let mut self_ref = self_.borrow_mut(); 91 | let this = self_ref.deref_mut(); 92 | defmt::info!("now = {}", (this.adapter_poll.get_ticks)()); 93 | let mut rx_buf = [0; 2048]; 94 | 95 | let offset = this.last_update.map(|x| x as i64 + 1); 96 | 97 | let owned_msg = { 98 | let rsp = { 99 | get_updates( 100 | offset, 101 | Some(20), 102 | &mut rx_buf, 103 | &mut this.adapter_poll, 104 | &mut this.rng, 105 | ) 106 | .await? 107 | }; 108 | 109 | if rsp.result.len() > 0 { 110 | let update = &rsp.result[0]; 111 | this.last_update = Some(update.update_id); 112 | if let Some(message) = &update.message { 113 | if let Some(text) = message.text { 114 | let ue = unescape(text); 115 | if let Err(e) = &ue { 116 | defmt::error!("unescape error: {:?}", e); 117 | } 118 | match ue { 119 | Ok(s) 120 | | Err(unescape::UnescapeError::Overflow(s)) 121 | | Err(unescape::UnescapeError::UnexpectedEnd(s)) => { 122 | Some((message.chat.id, s)) 123 | } 124 | Err(_) => { 125 | let mut s = String::new(); 126 | s.push_str("error").unwrap(); 127 | Some((message.chat.id, s)) 128 | } 129 | } 130 | } else { 131 | Some((message.chat.id, String::new())) 132 | } 133 | } else { 134 | None 135 | } 136 | } else { 137 | None 138 | } 139 | }; 140 | Ok(owned_msg) 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /stm32eth-f401/src/tg_bot.rs: -------------------------------------------------------------------------------- 1 | use crate::adapter::{TcpSocketAdapter, TcpSocketAdapterError}; 2 | use crate::bot_token; 3 | use crate::tg::{self, GetUpdatesResponse, SendMessageResponse}; 4 | use core::fmt::Write; 5 | use core::str::FromStr; 6 | use embedded_tls::*; 7 | use heapless::String; 8 | use heapless::Vec; 9 | use httparse; 10 | use rand::{CryptoRng, RngCore}; 11 | use smoltcp::wire::IpAddress; 12 | 13 | #[derive(defmt::Format)] 14 | pub enum TgBotError { 15 | Socket(TcpSocketAdapterError), 16 | Tls(embedded_tls::TlsError), 17 | HttpParseError, 18 | ResponseOverflow, 19 | HttpCodeNotOk, 20 | DeserializeError, 21 | TgNotOk, 22 | } 23 | 24 | pub async fn get_updates<'a, Rng: CryptoRng + RngCore>( 25 | offset: Option, 26 | timeout: Option, 27 | rx_buf: &'a mut [u8], 28 | adapter: &mut TcpSocketAdapter<'_>, 29 | rng: &mut Rng, 30 | ) -> Result, TgBotError> { 31 | let params = tg::GetUpdatesParams { 32 | allowed_updates: Some(&["message"]), 33 | limit: Some(1), 34 | offset, 35 | timeout, 36 | }; 37 | 38 | let rsp: GetUpdatesResponse<1> = api_post::<_, _, _, 128>("getUpdates", params, rx_buf, adapter, rng).await?; 39 | 40 | if !rsp.ok { 41 | return Err(TgBotError::TgNotOk); 42 | } 43 | 44 | Ok(rsp) 45 | } 46 | 47 | pub async fn send_message<'a, Rng: CryptoRng + RngCore>( 48 | chat_id: u64, 49 | text: &str, 50 | rx_buf: &'a mut [u8], 51 | adapter: &mut TcpSocketAdapter<'_>, 52 | rng: &mut Rng, 53 | ) -> Result, TgBotError> { 54 | let params = tg::SendMessageParams { 55 | chat_id, 56 | text 57 | }; 58 | 59 | let rsp: SendMessageResponse = api_post::<_, _, _, 128>("sendMessage", params, rx_buf, adapter, rng).await?; 60 | 61 | if !rsp.ok { 62 | return Err(TgBotError::TgNotOk); 63 | } 64 | 65 | Ok(rsp) 66 | } 67 | 68 | async fn api_post< 69 | 'a, 70 | Rng: CryptoRng + RngCore, 71 | Req: serde::Serialize, 72 | Rsp: serde::Deserialize<'a>, 73 | const PARAMS_LEN: usize, 74 | >( 75 | method: &str, 76 | req: Req, 77 | rx_buf: &'a mut [u8], 78 | adapter: &mut TcpSocketAdapter<'_>, 79 | rng: &mut Rng, 80 | ) -> Result { 81 | defmt::info!("Connecting..."); 82 | let server_ip = IpAddress::from_str("149.154.167.220").unwrap(); // TODO DNS 83 | let local_port: u16 = 50000 + (rng.next_u32() % 15535) as u16; 84 | adapter.connect((server_ip, 443), local_port).await?; 85 | 86 | let mut record_buffer = [0 as u8; 16384]; 87 | let config = TlsConfig::new() 88 | .with_server_name("api.telegram.org") 89 | .verify_cert(false); 90 | let mut conn: TlsConnection<_, Aes128GcmSha256> = 91 | TlsConnection::new(adapter, &mut record_buffer); 92 | conn.open::(TlsContext::new(&config, rng)) 93 | .await?; 94 | 95 | let params_json: Vec<_, PARAMS_LEN> = serde_json_core::to_vec(&req).unwrap(); 96 | 97 | let task_result = api_post_tls(method, ¶ms_json, rx_buf, &mut conn).await; 98 | 99 | let (socket, tls_close_result) = match conn.close().await { 100 | Ok(s) => (s, Ok(())), 101 | Err((s, e)) => (s, Err(e)), 102 | }; 103 | 104 | let close_result: Result<_, TgBotError> = socket.close().await.map_err(Into::into); 105 | 106 | let rsp_data = task_result?; 107 | defmt::info!("rsp_data: {}", rsp_data); 108 | tls_close_result?; 109 | close_result?; 110 | 111 | let (rsp, _) = match serde_json_core::from_slice::<_>(rsp_data) { 112 | Ok(r) => r, 113 | Err(_) => { 114 | return Err(TgBotError::DeserializeError); 115 | } 116 | }; 117 | Ok(rsp) 118 | } 119 | 120 | async fn api_post_tls<'a>( 121 | method: &str, 122 | data: &[u8], 123 | rx_buf: &'a mut [u8], 124 | conn: &mut TlsConnection<'_, &mut TcpSocketAdapter<'_>, Aes128GcmSha256>, 125 | ) -> Result<&'a [u8], TgBotError> { 126 | let mut request_str: String<256> = String::new(); 127 | write!(&mut request_str, "POST /bot{}/{} HTTP/1.1\r\nHost: api.telegram.org\r\nContent-Length: {}\r\nContent-Type: application/json\r\n\r\n", 128 | bot_token::BOT_TOKEN, method, data.len()).ok(); 129 | defmt::info!("{}", request_str); 130 | conn.write(request_str.as_bytes()).await?; 131 | conn.write(&data).await?; 132 | defmt::info!("{}", data); 133 | defmt::info!("HTTP POST Written OK"); 134 | 135 | let rsp_len = conn.read(rx_buf).await?; 136 | defmt::info!("Read {} bytes", rsp_len); 137 | 138 | defmt::info!("Read: {}", rx_buf[..rsp_len]); 139 | 140 | let mut headers = [httparse::EMPTY_HEADER; 24]; 141 | let mut rsp = httparse::Response::new(&mut headers); 142 | let data_offset = match rsp.parse(&rx_buf[..rsp_len]) { 143 | Ok(httparse::Status::Complete(len)) => len, 144 | Ok(httparse::Status::Partial) => return Err(TgBotError::ResponseOverflow), 145 | Err(e) => { 146 | let mut es = String::<128>::new(); 147 | write!(es, "{:?}", e).ok(); 148 | defmt::error!("Parse error: {}", es); 149 | return Err(TgBotError::HttpParseError); 150 | } 151 | }; 152 | if rsp.code != Some(200) { 153 | return Err(TgBotError::HttpCodeNotOk); 154 | } 155 | Ok(&rx_buf[data_offset..rsp_len]) 156 | } 157 | 158 | impl From for TgBotError { 159 | fn from(e: TlsError) -> Self { 160 | Self::Tls(e) 161 | } 162 | } 163 | 164 | impl From for TgBotError { 165 | fn from(e: TcpSocketAdapterError) -> Self { 166 | Self::Socket(e) 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /sch/shield/shield.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20211014) (generator kicad_symbol_editor) 2 | (symbol "74HC4538" (in_bom yes) (on_board yes) 3 | (property "Reference" "U" (id 0) (at 6.35 10.16 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "74HC4538" (id 1) (at 10.16 7.62 0) 7 | (effects (font (size 1.27 1.27))) 8 | ) 9 | (property "Footprint" "" (id 2) (at 0 0 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "" (id 3) (at 0 0 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (symbol "74HC4538_1_1" 16 | (rectangle (start -6.35 6.35) (end 7.62 -6.35) 17 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 18 | (fill (type background)) 19 | ) 20 | (pin passive line (at -1.905 8.89 270) (length 2.54) 21 | (name "CEXT" (effects (font (size 1.27 1.27)))) 22 | (number "1" (effects (font (size 1.27 1.27)))) 23 | ) 24 | (pin passive line (at 2.54 8.89 270) (length 2.54) 25 | (name "REXT/CEXT" (effects (font (size 1.27 1.27)))) 26 | (number "2" (effects (font (size 1.27 1.27)))) 27 | ) 28 | (pin input line (at 0 -8.89 90) (length 2.54) 29 | (name "~{CD}" (effects (font (size 1.27 1.27)))) 30 | (number "3" (effects (font (size 1.27 1.27)))) 31 | ) 32 | (pin input line (at -8.89 -3.81 0) (length 2.54) 33 | (name "B" (effects (font (size 1.27 1.27)))) 34 | (number "4" (effects (font (size 1.27 1.27)))) 35 | ) 36 | (pin input line (at -8.89 -1.27 0) (length 2.54) 37 | (name "~{A}" (effects (font (size 1.27 1.27)))) 38 | (number "5" (effects (font (size 1.27 1.27)))) 39 | ) 40 | (pin output line (at 10.16 -1.27 180) (length 2.54) 41 | (name "Q" (effects (font (size 1.27 1.27)))) 42 | (number "6" (effects (font (size 1.27 1.27)))) 43 | ) 44 | (pin output line (at 10.16 -3.81 180) (length 2.54) 45 | (name "~{Q}" (effects (font (size 1.27 1.27)))) 46 | (number "7" (effects (font (size 1.27 1.27)))) 47 | ) 48 | ) 49 | (symbol "74HC4538_2_1" 50 | (rectangle (start -6.35 6.35) (end 7.62 -6.35) 51 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 52 | (fill (type background)) 53 | ) 54 | (pin output line (at 10.16 -1.27 180) (length 2.54) 55 | (name "Q" (effects (font (size 1.27 1.27)))) 56 | (number "10" (effects (font (size 1.27 1.27)))) 57 | ) 58 | (pin input line (at -8.89 -1.27 0) (length 2.54) 59 | (name "~{A}" (effects (font (size 1.27 1.27)))) 60 | (number "11" (effects (font (size 1.27 1.27)))) 61 | ) 62 | (pin input line (at -8.89 -3.81 0) (length 2.54) 63 | (name "B" (effects (font (size 1.27 1.27)))) 64 | (number "12" (effects (font (size 1.27 1.27)))) 65 | ) 66 | (pin input line (at 0 -8.89 90) (length 2.54) 67 | (name "~{CD}" (effects (font (size 1.27 1.27)))) 68 | (number "13" (effects (font (size 1.27 1.27)))) 69 | ) 70 | (pin passive line (at 2.54 8.89 270) (length 2.54) 71 | (name "REXT/CEXT" (effects (font (size 1.27 1.27)))) 72 | (number "14" (effects (font (size 1.27 1.27)))) 73 | ) 74 | (pin passive line (at -1.905 8.89 270) (length 2.54) 75 | (name "CEXT" (effects (font (size 1.27 1.27)))) 76 | (number "15" (effects (font (size 1.27 1.27)))) 77 | ) 78 | (pin output line (at 10.16 -3.81 180) (length 2.54) 79 | (name "~{Q}" (effects (font (size 1.27 1.27)))) 80 | (number "9" (effects (font (size 1.27 1.27)))) 81 | ) 82 | ) 83 | (symbol "74HC4538_3_1" 84 | (rectangle (start -3.81 3.81) (end 3.81 -8.89) 85 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 86 | (fill (type background)) 87 | ) 88 | (pin power_in line (at 0 6.35 270) (length 2.54) 89 | (name "VCC" (effects (font (size 1.27 1.27)))) 90 | (number "16" (effects (font (size 1.27 1.27)))) 91 | ) 92 | (pin power_in line (at 0 -11.43 90) (length 2.54) 93 | (name "GND" (effects (font (size 1.27 1.27)))) 94 | (number "8" (effects (font (size 1.27 1.27)))) 95 | ) 96 | ) 97 | ) 98 | (symbol "partial-nucleo64" (pin_numbers hide) (in_bom yes) (on_board yes) 99 | (property "Reference" "J" (id 0) (at 0 10.16 0) 100 | (effects (font (size 1.27 1.27))) 101 | ) 102 | (property "Value" "partial-nucleo64" (id 1) (at 0 7.62 0) 103 | (effects (font (size 1.27 1.27))) 104 | ) 105 | (property "Footprint" "schield:partial-nucleo64" (id 2) (at 0 0 0) 106 | (effects (font (size 1.27 1.27)) hide) 107 | ) 108 | (property "Datasheet" "" (id 3) (at 0 0 0) 109 | (effects (font (size 1.27 1.27)) hide) 110 | ) 111 | (symbol "partial-nucleo64_0_1" 112 | (rectangle (start -7.62 -7.62) (end 7.62 5.08) 113 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 114 | (fill (type background)) 115 | ) 116 | ) 117 | (symbol "partial-nucleo64_1_1" 118 | (pin power_out line (at -10.16 -3.81 0) (length 2.54) 119 | (name "+5V" (effects (font (size 1.27 1.27)))) 120 | (number "+5V" (effects (font (size 1.27 1.27)))) 121 | ) 122 | (pin power_out line (at -10.16 -6.35 0) (length 2.54) 123 | (name "GND" (effects (font (size 1.27 1.27)))) 124 | (number "GND" (effects (font (size 1.27 1.27)))) 125 | ) 126 | (pin input line (at 10.16 -3.81 180) (length 2.54) 127 | (name "PB13" (effects (font (size 1.27 1.27)))) 128 | (number "PB13" (effects (font (size 1.27 1.27)))) 129 | ) 130 | (pin input line (at 10.16 -1.27 180) (length 2.54) 131 | (name "PB15" (effects (font (size 1.27 1.27)))) 132 | (number "PB15" (effects (font (size 1.27 1.27)))) 133 | ) 134 | (pin output line (at -10.16 0 0) (length 2.54) 135 | (name "PC10" (effects (font (size 1.27 1.27)))) 136 | (number "PC10" (effects (font (size 1.27 1.27)))) 137 | ) 138 | (pin output line (at -10.16 2.54 0) (length 2.54) 139 | (name "PC12" (effects (font (size 1.27 1.27)))) 140 | (number "PC12" (effects (font (size 1.27 1.27)))) 141 | ) 142 | (pin input line (at 10.16 1.27 180) (length 2.54) 143 | (name "PC6" (effects (font (size 1.27 1.27)))) 144 | (number "PC6" (effects (font (size 1.27 1.27)))) 145 | ) 146 | ) 147 | ) 148 | ) 149 | -------------------------------------------------------------------------------- /stm32eth-f401/src/adapter.rs: -------------------------------------------------------------------------------- 1 | use core::cell::RefCell; 2 | use core::future::Future; 3 | use core::task::Poll; 4 | use smoltcp::time::{Duration, Instant}; 5 | 6 | use embedded_io::asynch::{Read, Write}; 7 | use embedded_io::Io; 8 | use smoltcp::iface::{Interface, SocketHandle}; 9 | use smoltcp::socket::TcpSocket; 10 | use smoltcp::wire::IpEndpoint; 11 | 12 | use crate::device::SpiDevice; 13 | 14 | type GetTicks = fn() -> i64; 15 | 16 | pub struct TcpSocketAdapter<'a> { 17 | iface: &'a RefCell>, 18 | handle: SocketHandle, 19 | pub get_ticks: GetTicks, 20 | } 21 | 22 | #[derive(Debug, defmt::Format)] 23 | pub enum TcpSocketAdapterError { 24 | Smoltcp(smoltcp::Error), 25 | Timeout, 26 | } 27 | 28 | pub struct ReadFuture<'socket, 'adapter, 'buf> 29 | where 30 | 'socket: 'adapter, 31 | 'socket: 'buf, 32 | { 33 | adapter: &'adapter mut TcpSocketAdapter<'socket>, 34 | buf: &'buf mut [u8], 35 | } 36 | 37 | pub struct WriteFuture<'socket, 'adapter, 'buf> 38 | where 39 | 'socket: 'adapter, 40 | 'socket: 'buf, 41 | { 42 | adapter: &'adapter mut TcpSocketAdapter<'socket>, 43 | buf: &'buf [u8], 44 | } 45 | 46 | pub struct ConnectFuture<'a, 'b> 47 | where 48 | 'a: 'b, 49 | { 50 | adapter: &'b mut TcpSocketAdapter<'a>, 51 | remote_endpoint: IpEndpoint, 52 | local_endpoint: IpEndpoint, 53 | connecting: bool, 54 | } 55 | 56 | pub struct CloseFuture<'a, 'b> 57 | where 58 | 'a: 'b, 59 | { 60 | adapter: &'b mut TcpSocketAdapter<'a>, 61 | } 62 | 63 | pub struct FlushFuture(); 64 | 65 | impl<'a> TcpSocketAdapter<'a> { 66 | pub fn new( 67 | iface: &'a RefCell>, 68 | handle: SocketHandle, 69 | get_ticks: GetTicks, 70 | ) -> Self { 71 | Self { 72 | iface, 73 | handle, 74 | get_ticks, 75 | } 76 | } 77 | 78 | pub fn connect<'b, T: Into, U: Into>( 79 | &'b mut self, 80 | remote_endpoint: T, 81 | local_endpoint: U, 82 | ) -> ConnectFuture<'a, 'b> { 83 | ConnectFuture { 84 | adapter: self, 85 | remote_endpoint: remote_endpoint.into(), 86 | local_endpoint: local_endpoint.into(), 87 | connecting: false, 88 | } 89 | } 90 | 91 | pub fn close<'b>(&'b mut self) -> CloseFuture<'a, 'b> { 92 | { 93 | let mut iface = self.iface.borrow_mut(); 94 | let sock = iface.get_socket::(self.handle); 95 | sock.close(); 96 | } 97 | CloseFuture { adapter: self } 98 | } 99 | 100 | fn poll(&mut self) -> Result<(), TcpSocketAdapterError> { 101 | let now = Instant::from_millis((self.get_ticks)()); 102 | self.iface.borrow_mut().poll(now)?; 103 | Ok(()) 104 | } 105 | 106 | fn is_active(&mut self) -> bool { 107 | let mut iface = self.iface.borrow_mut(); 108 | let sock = iface.get_socket::(self.handle); 109 | sock.is_active() 110 | } 111 | 112 | fn can_send(&mut self) -> bool { 113 | let mut iface = self.iface.borrow_mut(); 114 | let sock = iface.get_socket::(self.handle); 115 | sock.can_send() 116 | } 117 | 118 | fn can_recv(&mut self) -> bool { 119 | let mut iface = self.iface.borrow_mut(); 120 | let sock = iface.get_socket::(self.handle); 121 | sock.can_recv() 122 | } 123 | } 124 | 125 | impl From for TcpSocketAdapterError { 126 | fn from(e: smoltcp::Error) -> Self { 127 | Self::Smoltcp(e) 128 | } 129 | } 130 | 131 | impl embedded_io::Error for TcpSocketAdapterError { 132 | fn kind(&self) -> embedded_io::ErrorKind { 133 | embedded_io::ErrorKind::Other 134 | } 135 | } 136 | 137 | impl<'a> Io for TcpSocketAdapter<'a> { 138 | type Error = TcpSocketAdapterError; 139 | } 140 | 141 | impl<'socket> Read for TcpSocketAdapter<'socket> { 142 | fn read<'adapter, 'buf>( 143 | &'adapter mut self, 144 | buf: &'buf mut [u8], 145 | ) -> ReadFuture<'socket, 'adapter, 'buf> { 146 | ReadFuture { adapter: self, buf } 147 | } 148 | } 149 | 150 | impl<'socket> Write for TcpSocketAdapter<'socket> { 151 | fn write<'adapter, 'buf>( 152 | &'adapter mut self, 153 | buf: &'buf [u8], 154 | ) -> WriteFuture<'socket, 'adapter, 'buf> { 155 | WriteFuture { adapter: self, buf } 156 | } 157 | 158 | fn flush<'adapter>(&'adapter mut self) -> FlushFuture { 159 | FlushFuture() 160 | } 161 | } 162 | 163 | impl<'socket, 'adapter, 'buf> ReadFuture<'socket, 'adapter, 'buf> { 164 | fn recv(&mut self) -> Result { 165 | let mut iface = self.adapter.iface.borrow_mut(); 166 | let sock = iface.get_socket::(self.adapter.handle); 167 | sock.recv_slice(self.buf).map_err(Into::into) 168 | } 169 | } 170 | 171 | impl<'socket, 'adapter, 'buf> Future for ReadFuture<'socket, 'adapter, 'buf> { 172 | type Output = Result; 173 | fn poll( 174 | mut self: core::pin::Pin<&mut Self>, 175 | ctx: &mut core::task::Context<'_>, 176 | ) -> Poll<::Output> { 177 | if let Err(e) = self.adapter.poll() { 178 | return Poll::Ready(Err(e)); 179 | } 180 | if !self.adapter.is_active() { 181 | return Poll::Ready(Err(TcpSocketAdapterError::Smoltcp(smoltcp::Error::Dropped))); 182 | } 183 | if self.adapter.can_recv() { 184 | Poll::Ready((*self).recv()) 185 | } else { 186 | ctx.waker().wake_by_ref(); 187 | Poll::Pending 188 | } 189 | } 190 | } 191 | 192 | impl<'socket, 'adapter, 'buf> WriteFuture<'socket, 'adapter, 'buf> { 193 | fn send(&mut self) -> Result { 194 | let mut iface = self.adapter.iface.borrow_mut(); 195 | let sock = iface 196 | .get_socket::(self.adapter.handle); 197 | sock.send_slice(self.buf).map_err(Into::into) 198 | } 199 | } 200 | 201 | impl<'socket, 'adapter, 'buf> Future for WriteFuture<'socket, 'adapter, 'buf> { 202 | type Output = Result; 203 | fn poll( 204 | mut self: core::pin::Pin<&mut Self>, 205 | ctx: &mut core::task::Context<'_>, 206 | ) -> Poll<::Output> { 207 | if let Err(e) = self.adapter.poll() { 208 | return Poll::Ready(Err(e)); 209 | } 210 | if !self.adapter.is_active() { 211 | return Poll::Ready(Err(TcpSocketAdapterError::Smoltcp(smoltcp::Error::Dropped))); 212 | } 213 | if self.adapter.can_send() { 214 | Poll::Ready((*self).send()) 215 | } else { 216 | ctx.waker().wake_by_ref(); 217 | Poll::Pending 218 | } 219 | } 220 | } 221 | 222 | impl Future for FlushFuture { 223 | type Output = Result<(), TcpSocketAdapterError>; 224 | fn poll( 225 | self: core::pin::Pin<&mut Self>, 226 | _: &mut core::task::Context<'_>, 227 | ) -> Poll<::Output> { 228 | Poll::Ready(Ok(())) 229 | } 230 | } 231 | 232 | impl<'a, 'b> ConnectFuture<'a, 'b> { 233 | fn connect(&mut self) -> Result<(), TcpSocketAdapterError> { 234 | let mut iface = self.adapter.iface.borrow_mut(); 235 | let (sock, cx) = iface 236 | .get_socket_and_context::(self.adapter.handle); 237 | sock.set_timeout(Some(Duration::from_secs(20))); 238 | sock.set_keep_alive(Some(Duration::from_secs(5))); 239 | sock.connect(cx, self.remote_endpoint, self.local_endpoint) 240 | .map_err(Into::into) 241 | } 242 | } 243 | 244 | impl<'a, 'b> Future for ConnectFuture<'a, 'b> { 245 | type Output = Result<(), TcpSocketAdapterError>; 246 | fn poll( 247 | mut self: core::pin::Pin<&mut Self>, 248 | ctx: &mut core::task::Context<'_>, 249 | ) -> Poll<::Output> { 250 | if !self.connecting { 251 | self.connecting = true; 252 | match self.connect() { 253 | Ok(()) => { 254 | ctx.waker().wake_by_ref(); 255 | Poll::Pending 256 | } 257 | Err(e) => Poll::Ready(Err(e)), 258 | } 259 | } else { 260 | if let Err(e) = self.adapter.poll() { 261 | return Poll::Ready(Err(e)); 262 | } 263 | if self.adapter.is_active() { 264 | Poll::Ready(Ok(())) 265 | } else { 266 | ctx.waker().wake_by_ref(); 267 | Poll::Pending 268 | } 269 | } 270 | } 271 | } 272 | 273 | impl<'a, 'b> Future for CloseFuture<'a, 'b> { 274 | type Output = Result<(), TcpSocketAdapterError>; 275 | fn poll( 276 | mut self: core::pin::Pin<&mut Self>, 277 | ctx: &mut core::task::Context<'_>, 278 | ) -> Poll<::Output> { 279 | if !self.adapter.is_active() { 280 | Poll::Ready(Ok(())) 281 | } else { 282 | if let Err(e) = self.adapter.poll() { 283 | return Poll::Ready(Err(e)); 284 | } 285 | ctx.waker().wake_by_ref(); 286 | Poll::Pending 287 | } 288 | } 289 | } 290 | -------------------------------------------------------------------------------- /sch/shield/gerber/shield-F_Paste.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,(6.0.9-0)*% 2 | %TF.CreationDate,2022-11-17T19:03:50+01:00*% 3 | %TF.ProjectId,shield,73686965-6c64-42e6-9b69-6361645f7063,1*% 4 | %TF.SameCoordinates,PX3a2c940PY82a7440*% 5 | %TF.FileFunction,Paste,Top*% 6 | %TF.FilePolarity,Positive*% 7 | %FSLAX46Y46*% 8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 9 | G04 Created by KiCad (PCBNEW (6.0.9-0)) date 2022-11-17 19:03:50* 10 | %MOMM*% 11 | %LPD*% 12 | G01* 13 | G04 APERTURE LIST* 14 | G04 Aperture macros list* 15 | %AMRoundRect* 16 | 0 Rectangle with rounded corners* 17 | 0 $1 Rounding radius* 18 | 0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners* 19 | 0 Add a 4 corners polygon primitive as box body* 20 | 4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0* 21 | 0 Add four circle primitives for the rounded corners* 22 | 1,1,$1+$1,$2,$3* 23 | 1,1,$1+$1,$4,$5* 24 | 1,1,$1+$1,$6,$7* 25 | 1,1,$1+$1,$8,$9* 26 | 0 Add four rect primitives between the rounded corners* 27 | 20,1,$1+$1,$2,$3,$4,$5,0* 28 | 20,1,$1+$1,$4,$5,$6,$7,0* 29 | 20,1,$1+$1,$6,$7,$8,$9,0* 30 | 20,1,$1+$1,$8,$9,$2,$3,0*% 31 | G04 Aperture macros list end* 32 | %ADD10RoundRect,0.250000X0.450000X-0.262500X0.450000X0.262500X-0.450000X0.262500X-0.450000X-0.262500X0*% 33 | %ADD11RoundRect,0.100000X-0.637500X-0.100000X0.637500X-0.100000X0.637500X0.100000X-0.637500X0.100000X0*% 34 | %ADD12RoundRect,0.250000X-0.250000X-0.475000X0.250000X-0.475000X0.250000X0.475000X-0.250000X0.475000X0*% 35 | %ADD13RoundRect,0.250000X-0.475000X0.250000X-0.475000X-0.250000X0.475000X-0.250000X0.475000X0.250000X0*% 36 | %ADD14RoundRect,0.150000X-0.825000X-0.150000X0.825000X-0.150000X0.825000X0.150000X-0.825000X0.150000X0*% 37 | %ADD15RoundRect,0.250000X0.475000X-0.250000X0.475000X0.250000X-0.475000X0.250000X-0.475000X-0.250000X0*% 38 | %ADD16RoundRect,0.150000X-0.587500X-0.150000X0.587500X-0.150000X0.587500X0.150000X-0.587500X0.150000X0*% 39 | %ADD17RoundRect,0.137500X-0.662500X-0.137500X0.662500X-0.137500X0.662500X0.137500X-0.662500X0.137500X0*% 40 | %ADD18RoundRect,0.250000X0.262500X0.450000X-0.262500X0.450000X-0.262500X-0.450000X0.262500X-0.450000X0*% 41 | %ADD19RoundRect,0.250000X0.250000X0.475000X-0.250000X0.475000X-0.250000X-0.475000X0.250000X-0.475000X0*% 42 | %ADD20RoundRect,0.250000X-0.262500X-0.450000X0.262500X-0.450000X0.262500X0.450000X-0.262500X0.450000X0*% 43 | %ADD21RoundRect,0.250000X0.325000X1.100000X-0.325000X1.100000X-0.325000X-1.100000X0.325000X-1.100000X0*% 44 | G04 APERTURE END LIST* 45 | D10* 46 | %TO.C,R3*% 47 | X16050000Y36687500D03* 48 | X16050000Y38512500D03* 49 | %TD*% 50 | D11* 51 | %TO.C,U4*% 52 | X50687500Y62650000D03* 53 | X50687500Y62000000D03* 54 | X50687500Y61350000D03* 55 | X50687500Y60700000D03* 56 | X50687500Y60050000D03* 57 | X50687500Y59400000D03* 58 | X50687500Y58750000D03* 59 | X56412500Y58750000D03* 60 | X56412500Y59400000D03* 61 | X56412500Y60050000D03* 62 | X56412500Y60700000D03* 63 | X56412500Y61350000D03* 64 | X56412500Y62000000D03* 65 | X56412500Y62650000D03* 66 | %TD*% 67 | D10* 68 | %TO.C,R10*% 69 | X24900000Y6487500D03* 70 | X24900000Y8312500D03* 71 | %TD*% 72 | D12* 73 | %TO.C,C18*% 74 | X16550000Y66200000D03* 75 | X18450000Y66200000D03* 76 | %TD*% 77 | D13* 78 | %TO.C,C14*% 79 | X18150000Y38550000D03* 80 | X18150000Y36650000D03* 81 | %TD*% 82 | D14* 83 | %TO.C,U8*% 84 | X11725000Y64110000D03* 85 | X11725000Y62840000D03* 86 | X11725000Y61570000D03* 87 | X11725000Y60300000D03* 88 | X11725000Y59030000D03* 89 | X11725000Y57760000D03* 90 | X11725000Y56490000D03* 91 | X16675000Y56490000D03* 92 | X16675000Y57760000D03* 93 | X16675000Y59030000D03* 94 | X16675000Y60300000D03* 95 | X16675000Y61570000D03* 96 | X16675000Y62840000D03* 97 | X16675000Y64110000D03* 98 | %TD*% 99 | D15* 100 | %TO.C,C9*% 101 | X49100000Y53400000D03* 102 | X49100000Y55300000D03* 103 | %TD*% 104 | D16* 105 | %TO.C,Q1*% 106 | X41762500Y43850000D03* 107 | X41762500Y41950000D03* 108 | X43637500Y42900000D03* 109 | %TD*% 110 | D12* 111 | %TO.C,C4*% 112 | X52150000Y51500000D03* 113 | X54050000Y51500000D03* 114 | %TD*% 115 | D17* 116 | %TO.C,U9*% 117 | X50750000Y13445000D03* 118 | X50750000Y12175000D03* 119 | X50750000Y10905000D03* 120 | X50750000Y9635000D03* 121 | X50750000Y8365000D03* 122 | X50750000Y7095000D03* 123 | X50750000Y5825000D03* 124 | X50750000Y4555000D03* 125 | X57250000Y4555000D03* 126 | X57250000Y5825000D03* 127 | X57250000Y7095000D03* 128 | X57250000Y8365000D03* 129 | X57250000Y9635000D03* 130 | X57250000Y10905000D03* 131 | X57250000Y12175000D03* 132 | X57250000Y13445000D03* 133 | %TD*% 134 | D11* 135 | %TO.C,U2*% 136 | X24737500Y39150000D03* 137 | X24737500Y38500000D03* 138 | X24737500Y37850000D03* 139 | X24737500Y37200000D03* 140 | X24737500Y36550000D03* 141 | X24737500Y35900000D03* 142 | X24737500Y35250000D03* 143 | X30462500Y35250000D03* 144 | X30462500Y35900000D03* 145 | X30462500Y36550000D03* 146 | X30462500Y37200000D03* 147 | X30462500Y37850000D03* 148 | X30462500Y38500000D03* 149 | X30462500Y39150000D03* 150 | %TD*% 151 | D15* 152 | %TO.C,C2*% 153 | X36400000Y26850000D03* 154 | X36400000Y28750000D03* 155 | %TD*% 156 | D14* 157 | %TO.C,U5*% 158 | X16825000Y27510000D03* 159 | X16825000Y26240000D03* 160 | X16825000Y24970000D03* 161 | X16825000Y23700000D03* 162 | X16825000Y22430000D03* 163 | X16825000Y21160000D03* 164 | X16825000Y19890000D03* 165 | X21775000Y19890000D03* 166 | X21775000Y21160000D03* 167 | X21775000Y22430000D03* 168 | X21775000Y23700000D03* 169 | X21775000Y24970000D03* 170 | X21775000Y26240000D03* 171 | X21775000Y27510000D03* 172 | %TD*% 173 | D10* 174 | %TO.C,R2*% 175 | X38800000Y23887500D03* 176 | X38800000Y25712500D03* 177 | %TD*% 178 | D16* 179 | %TO.C,Q2*% 180 | X43062500Y56350000D03* 181 | X43062500Y54450000D03* 182 | X44937500Y55400000D03* 183 | %TD*% 184 | D12* 185 | %TO.C,C7*% 186 | X21650000Y29500000D03* 187 | X23550000Y29500000D03* 188 | %TD*% 189 | D14* 190 | %TO.C,U1*% 191 | X47025000Y49410000D03* 192 | X47025000Y48140000D03* 193 | X47025000Y46870000D03* 194 | X47025000Y45600000D03* 195 | X47025000Y44330000D03* 196 | X47025000Y43060000D03* 197 | X47025000Y41790000D03* 198 | X51975000Y41790000D03* 199 | X51975000Y43060000D03* 200 | X51975000Y44330000D03* 201 | X51975000Y45600000D03* 202 | X51975000Y46870000D03* 203 | X51975000Y48140000D03* 204 | X51975000Y49410000D03* 205 | %TD*% 206 | D18* 207 | %TO.C,R6*% 208 | X43700000Y47400000D03* 209 | X41875000Y47400000D03* 210 | %TD*% 211 | D15* 212 | %TO.C,C8*% 213 | X37600000Y41950000D03* 214 | X37600000Y43850000D03* 215 | %TD*% 216 | D11* 217 | %TO.C,U7*% 218 | X35537500Y64450000D03* 219 | X35537500Y63800000D03* 220 | X35537500Y63150000D03* 221 | X35537500Y62500000D03* 222 | X35537500Y61850000D03* 223 | X35537500Y61200000D03* 224 | X35537500Y60550000D03* 225 | X41262500Y60550000D03* 226 | X41262500Y61200000D03* 227 | X41262500Y61850000D03* 228 | X41262500Y62500000D03* 229 | X41262500Y63150000D03* 230 | X41262500Y63800000D03* 231 | X41262500Y64450000D03* 232 | %TD*% 233 | D18* 234 | %TO.C,R1*% 235 | X36312500Y24800000D03* 236 | X34487500Y24800000D03* 237 | %TD*% 238 | D12* 239 | %TO.C,C1*% 240 | X46250000Y34800000D03* 241 | X48150000Y34800000D03* 242 | %TD*% 243 | %TO.C,C6*% 244 | X30550000Y41100000D03* 245 | X32450000Y41100000D03* 246 | %TD*% 247 | %TO.C,C16*% 248 | X41350000Y66500000D03* 249 | X43250000Y66500000D03* 250 | %TD*% 251 | D19* 252 | %TO.C,C13*% 253 | X21950000Y41350000D03* 254 | X20050000Y41350000D03* 255 | %TD*% 256 | D18* 257 | %TO.C,R7*% 258 | X21912500Y39300000D03* 259 | X20087500Y39300000D03* 260 | %TD*% 261 | D19* 262 | %TO.C,C10*% 263 | X40250000Y47400000D03* 264 | X38350000Y47400000D03* 265 | %TD*% 266 | D20* 267 | %TO.C,R12*% 268 | X62337500Y11000000D03* 269 | X64162500Y11000000D03* 270 | %TD*% 271 | D10* 272 | %TO.C,R5*% 273 | X47050000Y53437500D03* 274 | X47050000Y55262500D03* 275 | %TD*% 276 | D11* 277 | %TO.C,U3*% 278 | X40337500Y33075000D03* 279 | X40337500Y32425000D03* 280 | X40337500Y31775000D03* 281 | X40337500Y31125000D03* 282 | X40337500Y30475000D03* 283 | X40337500Y29825000D03* 284 | X40337500Y29175000D03* 285 | X40337500Y28525000D03* 286 | X46062500Y28525000D03* 287 | X46062500Y29175000D03* 288 | X46062500Y29825000D03* 289 | X46062500Y30475000D03* 290 | X46062500Y31125000D03* 291 | X46062500Y31775000D03* 292 | X46062500Y32425000D03* 293 | X46062500Y33075000D03* 294 | %TD*% 295 | D20* 296 | %TO.C,R8*% 297 | X20087500Y37250000D03* 298 | X21912500Y37250000D03* 299 | %TD*% 300 | D15* 301 | %TO.C,C3*% 302 | X34400000Y26850000D03* 303 | X34400000Y28750000D03* 304 | %TD*% 305 | D12* 306 | %TO.C,C5*% 307 | X57300000Y15700000D03* 308 | X59200000Y15700000D03* 309 | %TD*% 310 | %TO.C,C11*% 311 | X56500000Y64600000D03* 312 | X58400000Y64600000D03* 313 | %TD*% 314 | D21* 315 | %TO.C,C17*% 316 | X5675000Y53700000D03* 317 | X2725000Y53700000D03* 318 | %TD*% 319 | D13* 320 | %TO.C,C19*% 321 | X52800000Y17450000D03* 322 | X52800000Y15550000D03* 323 | %TD*% 324 | D10* 325 | %TO.C,R11*% 326 | X50650000Y17412500D03* 327 | X50650000Y15587500D03* 328 | %TD*% 329 | D12* 330 | %TO.C,C12*% 331 | X28150000Y66500000D03* 332 | X30050000Y66500000D03* 333 | %TD*% 334 | D19* 335 | %TO.C,C15*% 336 | X21950000Y34950000D03* 337 | X20050000Y34950000D03* 338 | %TD*% 339 | %TO.C,C20*% 340 | X64200000Y13050000D03* 341 | X62300000Y13050000D03* 342 | %TD*% 343 | D16* 344 | %TO.C,Q3*% 345 | X11812500Y37350000D03* 346 | X11812500Y35450000D03* 347 | X13687500Y36400000D03* 348 | %TD*% 349 | D11* 350 | %TO.C,U6*% 351 | X22337500Y64450000D03* 352 | X22337500Y63800000D03* 353 | X22337500Y63150000D03* 354 | X22337500Y62500000D03* 355 | X22337500Y61850000D03* 356 | X22337500Y61200000D03* 357 | X22337500Y60550000D03* 358 | X28062500Y60550000D03* 359 | X28062500Y61200000D03* 360 | X28062500Y61850000D03* 361 | X28062500Y62500000D03* 362 | X28062500Y63150000D03* 363 | X28062500Y63800000D03* 364 | X28062500Y64450000D03* 365 | %TD*% 366 | D10* 367 | %TO.C,R9*% 368 | X44000000Y6487500D03* 369 | X44000000Y8312500D03* 370 | %TD*% 371 | %TO.C,R4*% 372 | X39700000Y41987500D03* 373 | X39700000Y43812500D03* 374 | %TD*% 375 | M02* 376 | -------------------------------------------------------------------------------- /stm32eth-f401/src/receiver.rs: -------------------------------------------------------------------------------- 1 | use crc::{Crc, CRC_32_ISO_HDLC}; 2 | use defmt::Format; 3 | use heapless::spsc::Queue; 4 | use cortex_m::asm; 5 | use stm32f4xx_hal::{ 6 | dma::{self, config::DmaConfig, traits::Stream}, 7 | gpio::{ExtiPin, NoPin, PB13, PB15, PC6}, 8 | pac::{DMA1, SPI2}, 9 | prelude::*, 10 | rcc::Clocks, 11 | spi::{self, BitFormat, Mode, NoMiso, Phase, Polarity, Slave, Spi}, 12 | }; 13 | 14 | use replace_with::{replace_with, replace_with_and_return}; 15 | 16 | pub const BUFFER_LEN: usize = 1600; 17 | pub const MAX_BUFFERS: usize = 4; 18 | const MIN_FRAME_LEN: usize = 2 * 6 + 2 + 4; 19 | const CRC: Crc = Crc::::new(&CRC_32_ISO_HDLC); 20 | 21 | type PinCs = PC6; 22 | type PinSck = PB13; 23 | type PinMosi = PB15; 24 | 25 | type DmaStream = dma::Stream3; 26 | 27 | pub struct SpiRxPeriph { 28 | spi: Spi, 29 | pin_cs: PinCs, 30 | dma_stream: DmaStream, 31 | } 32 | 33 | pub type RxBuf = &'static mut [u8; BUFFER_LEN]; 34 | 35 | type Transfer = dma::Transfer< 36 | dma::Stream3, 37 | 0, 38 | spi::Rx, 39 | dma::PeripheralToMemory, 40 | RxBuf, 41 | >; 42 | 43 | pub struct Receiver { 44 | vacant_buffers: Queue, 45 | received_frames: Queue<(RxBuf, usize), MAX_BUFFERS>, 46 | state: ReceiverState, 47 | stats: Stats, 48 | } 49 | 50 | enum ReceiverState { 51 | Idle(SpiRxPeriph), 52 | Listen(Transfer, PinCs), 53 | } 54 | 55 | #[derive(Default)] 56 | pub struct Stats { 57 | flipped: usize, 58 | missed: usize, 59 | received: usize, 60 | bad_fcs: usize, 61 | iteration: usize, 62 | } 63 | 64 | #[derive(Format)] 65 | pub enum FrameError { 66 | InvalidLength(usize), 67 | InvalidFcs, 68 | InvalidPreamble, 69 | Missed, 70 | } 71 | 72 | impl Receiver { 73 | pub fn new( 74 | spi: SPI2, 75 | pin_sck: PinSck, 76 | pin_mosi: PinMosi, 77 | pin_cs: PinCs, 78 | dma_stream: dma::Stream3, 79 | buffers: [RxBuf; MAX_BUFFERS], 80 | clocks: &Clocks, 81 | ) -> Self { 82 | let mut spi = Spi::new_slave( 83 | spi, 84 | (pin_sck, NoMiso {}, pin_mosi), 85 | Mode { 86 | polarity: Polarity::IdleLow, 87 | phase: Phase::CaptureOnFirstTransition, 88 | }, 89 | 10_000_000.Hz(), 90 | &clocks, 91 | ); 92 | spi.bit_format(BitFormat::LsbFirst); 93 | spi.set_internal_nss(true); 94 | let mut vacant_buffers = Queue::new(); 95 | for buf in buffers.into_iter() { 96 | vacant_buffers.enqueue(buf).ok(); 97 | } 98 | Self { 99 | vacant_buffers, 100 | received_frames: Queue::new(), 101 | state: ReceiverState::Idle(SpiRxPeriph { 102 | spi, 103 | pin_cs, 104 | dma_stream, 105 | }), 106 | stats: Default::default(), 107 | } 108 | } 109 | 110 | pub fn try_get_data(&mut self) -> Option<(RxBuf, usize)> { 111 | self.received_frames.dequeue() 112 | } 113 | 114 | pub fn return_buffer(&mut self, buf: RxBuf) { 115 | self.vacant_buffers.enqueue(buf).ok(); 116 | self.start_listen(); 117 | } 118 | 119 | pub fn start_listen(&mut self) { 120 | replace_with( 121 | &mut self.state, 122 | || panic!(), 123 | |state| match state { 124 | ReceiverState::Idle(periph) => { 125 | if periph.pin_cs.is_low() { 126 | // a frame is already being sent, we've missed it 127 | ReceiverState::Idle(periph) 128 | } else { 129 | if let Some(buf) = self.vacant_buffers.dequeue() { 130 | let (transfer, pin_cs) = create_dma_transfer(periph, buf); 131 | ReceiverState::Listen(transfer, pin_cs) 132 | } else { 133 | ReceiverState::Idle(periph) 134 | } 135 | } 136 | } 137 | s => s, 138 | }, 139 | ); 140 | } 141 | 142 | pub fn on_edge_maybe(&mut self) -> Option> { 143 | let is_low = self.clear_cs_interrupt_and_return_true_if_still_low(); 144 | if is_low { 145 | // defmt::info!("still low"); 146 | return None; 147 | } 148 | let result = replace_with_and_return( 149 | &mut self.state, 150 | || panic!(), 151 | |state| match state { 152 | ReceiverState::Listen(transfer, pin_cs) => { 153 | let (stream, ret_rx, ret_buf, _) = transfer.release(); 154 | let mut spi = ret_rx.release(); 155 | spi.set_internal_nss(true); 156 | let stream: DmaStream = stream; // ensure type 157 | let ndtr = DmaStream::get_number_of_transfers() as usize; 158 | let len = ret_buf.len() - ndtr; 159 | // defmt::info!("got {:02X}", ret_buf[0..len]); 160 | let result = if len < MIN_FRAME_LEN { 161 | Err(FrameError::InvalidLength(len)) 162 | } else { 163 | let mut digest = CRC.digest(); 164 | digest.update(&ret_buf[0..len - 4]); 165 | let fcs = digest.finalize().to_le_bytes(); 166 | if ret_buf[len - 4..len] == fcs { 167 | Ok(len) 168 | } else { 169 | // try flipping the first bit 170 | // first SCK edge comes after MOSI/Manchester transition 171 | self.stats.count_flip(); 172 | ret_buf[0] = ret_buf[0] ^ 0x01; 173 | let mut digest = CRC.digest(); 174 | digest.update(&ret_buf[0..len - 4]); 175 | let fcs = digest.finalize().to_le_bytes(); 176 | if ret_buf[len - 4..len] == fcs { 177 | Ok(len) 178 | } else { 179 | Err(FrameError::InvalidFcs) 180 | } 181 | } 182 | }; 183 | 184 | // release SPI to reset it (in case there's an incomplete byte in the register) 185 | let periph = SpiRxPeriph { 186 | spi, 187 | dma_stream: stream, 188 | pin_cs, 189 | }; 190 | 191 | if result.is_ok() { 192 | self.stats.count_good(); 193 | self.received_frames.enqueue((ret_buf, len)).ok(); 194 | } else { 195 | if let Err(FrameError::InvalidFcs) = result { 196 | self.stats.count_bad_fcs(); 197 | } 198 | self.vacant_buffers.enqueue(ret_buf).ok(); 199 | } 200 | (Some(result), ReceiverState::Idle(periph)) 201 | } 202 | ReceiverState::Idle(_) => { 203 | self.stats.count_miss(); 204 | (Some(Err(FrameError::Missed)), state) 205 | } 206 | }, 207 | ); 208 | if let ReceiverState::Idle(_) = self.state { 209 | self.start_listen(); 210 | } 211 | self.stats.dump(); 212 | result 213 | } 214 | 215 | pub fn get_stats(&self) -> &Stats { 216 | &self.stats 217 | } 218 | 219 | fn clear_cs_interrupt_and_return_true_if_still_low(&mut self) -> bool { 220 | asm::delay(150); 221 | match &mut self.state { 222 | ReceiverState::Idle(periph) => { 223 | periph.pin_cs.clear_interrupt_pending_bit(); 224 | periph.pin_cs.is_low() 225 | } 226 | ReceiverState::Listen(_, pin_cs) => { 227 | pin_cs.clear_interrupt_pending_bit(); 228 | pin_cs.is_low() 229 | } 230 | } 231 | } 232 | } 233 | 234 | impl Stats { 235 | fn count_miss(&mut self) { 236 | self.missed += 1; 237 | } 238 | 239 | fn count_flip(&mut self) { 240 | self.flipped += 1; 241 | } 242 | 243 | fn count_good(&mut self) { 244 | self.received += 1; 245 | } 246 | 247 | fn count_bad_fcs(&mut self) { 248 | self.bad_fcs += 1; 249 | } 250 | 251 | fn dump(&mut self) { 252 | self.iteration += 1; 253 | if self.iteration == 10 { 254 | defmt::info!( 255 | "Good: {}, bad FCS: {}, missed: {}, flipped: {}", 256 | self.received, 257 | self.bad_fcs, 258 | self.missed, 259 | self.flipped 260 | ); 261 | self.iteration = 0; 262 | } 263 | } 264 | } 265 | 266 | impl core::fmt::Display for Stats { 267 | fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { 268 | write!(fmt, "Good: {}, bad FCS: {}, missed: {}, flipped: {}", self.received, self.bad_fcs, self.missed, self.flipped) 269 | } 270 | } 271 | 272 | fn create_dma_transfer(periph: SpiRxPeriph, buf: RxBuf) -> (Transfer, PinCs) { 273 | let mut spi = periph.spi; 274 | spi.set_internal_nss(false); 275 | let rx = spi.use_dma().rx(); 276 | let mut transfer = Transfer::init_peripheral_to_memory( 277 | periph.dma_stream, 278 | rx, 279 | buf, 280 | None, 281 | DmaConfig::default().memory_increment(true), 282 | ); 283 | transfer.start(|_rx| {}); 284 | 285 | (transfer, periph.pin_cs) 286 | } 287 | -------------------------------------------------------------------------------- /sch/shield/schield.pretty/partial-nucleo64.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "partial-nucleo64" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 0) 4 | (attr through_hole) 5 | (fp_text reference "REF**" (at -30.48 -52.07 unlocked) (layer "Dwgs.User") 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp e7e095d2-62ac-4491-92fa-d2163c5e9405) 8 | ) 9 | (fp_text value "partial-nucleo64" (at -26.67 -49.53 unlocked) (layer "F.Fab") 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp 7b18f187-60cc-4ca3-819b-e5cbcefe2d87) 12 | ) 13 | (fp_text user "PB13" (at 27.94 -11.43 unlocked) (layer "F.SilkS") 14 | (effects (font (size 1 1) (thickness 0.15))) 15 | (tstamp 0cbac455-6127-4e9e-a749-76c7d7b7156d) 16 | ) 17 | (fp_text user "PC6" (at 29.21 -44.45 unlocked) (layer "F.SilkS") 18 | (effects (font (size 1 1) (thickness 0.15))) 19 | (tstamp 11d949d6-ce70-40a5-ae41-646ee9cbb2ce) 20 | ) 21 | (fp_text user "+5V" (at -26.67 -26.67 unlocked) (layer "F.SilkS") 22 | (effects (font (size 1 1) (thickness 0.15))) 23 | (tstamp 4d4f3f10-4034-426f-9311-e0cd16e7e30d) 24 | ) 25 | (fp_text user "GND" (at 26.67 -36.83 unlocked) (layer "F.SilkS") 26 | (effects (font (size 1 1) (thickness 0.15))) 27 | (tstamp 767b57da-9b9e-48ce-9ea5-da2a4c0f6f8f) 28 | ) 29 | (fp_text user "PC12" (at -27.94 -44.45 unlocked) (layer "F.SilkS") 30 | (effects (font (size 1 1) (thickness 0.15))) 31 | (tstamp 8694219f-d8a5-4db4-8d6f-287820b1e6eb) 32 | ) 33 | (fp_text user "GND" (at -26.67 -24.13 unlocked) (layer "F.SilkS") 34 | (effects (font (size 1 1) (thickness 0.15))) 35 | (tstamp 97d37197-8f68-411b-81f3-35e4d9033e45) 36 | ) 37 | (fp_text user "PC10" (at -27.94 -46.99 unlocked) (layer "F.SilkS") 38 | (effects (font (size 1 1) (thickness 0.15))) 39 | (tstamp 9f7df9a1-20d9-439e-90b3-3ce073f50713) 40 | ) 41 | (fp_text user "GND" (at -26.67 -21.59 unlocked) (layer "F.SilkS") 42 | (effects (font (size 1 1) (thickness 0.15))) 43 | (tstamp a95414df-191e-470d-a263-4c74844cac57) 44 | ) 45 | (fp_text user "GND" (at 29.21 -24.13 unlocked) (layer "F.SilkS") 46 | (effects (font (size 1 1) (thickness 0.15))) 47 | (tstamp c8e4ab3d-ebce-4392-9530-95b5ada6c3ff) 48 | ) 49 | (fp_text user "GND" (at -26.67 -39.37 unlocked) (layer "F.SilkS") 50 | (effects (font (size 1 1) (thickness 0.15))) 51 | (tstamp dee7c241-a51d-4b36-8868-1a4fd1bd9f6a) 52 | ) 53 | (fp_text user "PB15" (at 27.94 -16.51 unlocked) (layer "F.SilkS") 54 | (effects (font (size 1 1) (thickness 0.15))) 55 | (tstamp e48945fd-f6d4-456d-86cf-ac5b286c7611) 56 | ) 57 | (fp_line (start -33.02 -10.16) (end -27.94 -10.16) (layer "Dwgs.User") (width 0.12) (tstamp 051f24a5-c53c-4ef4-a678-652efb196b50)) 58 | (fp_line (start -33.02 -33.02) (end -27.94 -33.02) (layer "Dwgs.User") (width 0.12) (tstamp 11479b4f-57cc-4409-876a-f1302fb16396)) 59 | (fp_line (start 27.94 -45.72) (end 33.02 -45.72) (layer "Dwgs.User") (width 0.12) (tstamp 12796c14-2173-465a-aad9-ef38ab66e716)) 60 | (fp_line (start 27.94 -2.54) (end 33.02 -2.54) (layer "Dwgs.User") (width 0.12) (tstamp 16b62826-cc5b-4b62-9196-0008e00dcf2e)) 61 | (fp_line (start 27.94 -38.1) (end 33.02 -38.1) (layer "Dwgs.User") (width 0.12) (tstamp 1e9ad659-2732-4c27-83f7-60f3a1e4e01e)) 62 | (fp_line (start -33.02 -12.7) (end -27.94 -12.7) (layer "Dwgs.User") (width 0.12) (tstamp 2c6752fa-599c-4b3f-b895-636582cae2c4)) 63 | (fp_line (start 27.94 -35.56) (end 33.02 -35.56) (layer "Dwgs.User") (width 0.12) (tstamp 32cca001-3618-42af-a212-e34a2b489cad)) 64 | (fp_line (start -33.02 -20.32) (end -27.94 -20.32) (layer "Dwgs.User") (width 0.12) (tstamp 33fe1ef9-5995-4a38-ae7b-7cf4606a19eb)) 65 | (fp_line (start -33.02 -17.78) (end -27.94 -17.78) (layer "Dwgs.User") (width 0.12) (tstamp 36886512-64ac-4523-8f9a-13b3335ee73b)) 66 | (fp_line (start -33.02 -22.86) (end -27.94 -22.86) (layer "Dwgs.User") (width 0.12) (tstamp 3724226a-a250-4d4b-853a-aa690a21bc32)) 67 | (fp_line (start -33.02 -38.1) (end -27.94 -38.1) (layer "Dwgs.User") (width 0.12) (tstamp 3a44d876-e545-4035-8bb6-3512525f9953)) 68 | (fp_line (start 27.94 -40.64) (end 33.02 -40.64) (layer "Dwgs.User") (width 0.12) (tstamp 404767a7-56f5-4e35-8db7-0333ae8baf9e)) 69 | (fp_line (start 27.94 -7.62) (end 33.02 -7.62) (layer "Dwgs.User") (width 0.12) (tstamp 42580842-0189-4634-b809-caa678026f94)) 70 | (fp_line (start -33.02 -27.94) (end -27.94 -27.94) (layer "Dwgs.User") (width 0.12) (tstamp 4650e0b7-81a9-4098-b95b-0a0024dedff2)) 71 | (fp_line (start 27.94 -33.02) (end 33.02 -33.02) (layer "Dwgs.User") (width 0.12) (tstamp 4900db03-b9cb-4023-bbd0-615768bbe970)) 72 | (fp_line (start -33.02 -45.72) (end -27.94 -45.72) (layer "Dwgs.User") (width 0.12) (tstamp 58d2b1e7-c0ab-4a3c-a15f-95522aacfddd)) 73 | (fp_line (start -33.02 -25.4) (end -27.94 -25.4) (layer "Dwgs.User") (width 0.12) (tstamp 59005b82-e9a5-41e5-aa96-fa40bef11713)) 74 | (fp_line (start 27.94 -5.08) (end 33.02 -5.08) (layer "Dwgs.User") (width 0.12) (tstamp 63e44563-bbd7-44b5-a513-13cc1a611a98)) 75 | (fp_line (start 27.94 -43.18) (end 33.02 -43.18) (layer "Dwgs.User") (width 0.12) (tstamp 73ab9e40-9c39-46de-9806-b2d2751ff76e)) 76 | (fp_line (start 27.94 -22.86) (end 33.02 -22.86) (layer "Dwgs.User") (width 0.12) (tstamp 79d9a27a-2b13-4953-a9b4-824a87bc853c)) 77 | (fp_line (start 27.94 -30.48) (end 33.02 -30.48) (layer "Dwgs.User") (width 0.12) (tstamp 7dae6ce7-e8c1-4832-8360-b6f5549c1ff2)) 78 | (fp_line (start -33.02 -2.54) (end -27.94 -2.54) (layer "Dwgs.User") (width 0.12) (tstamp 7f28b80c-32f7-40dc-889b-f974bfa26807)) 79 | (fp_line (start 30.48 0) (end 30.48 -48.26) (layer "Dwgs.User") (width 0.12) (tstamp 8021540d-2056-4991-9869-d6446aa84c47)) 80 | (fp_line (start 27.94 -27.94) (end 33.02 -27.94) (layer "Dwgs.User") (width 0.12) (tstamp 80491601-4777-4e43-9e0a-928e8432c828)) 81 | (fp_line (start -30.48 0) (end -30.48 -48.26) (layer "Dwgs.User") (width 0.12) (tstamp 8519111a-cf3c-4231-8086-e66b42015904)) 82 | (fp_line (start -33.02 -5.08) (end -27.94 -5.08) (layer "Dwgs.User") (width 0.12) (tstamp 9c8342be-23da-4655-813e-05989c339b5f)) 83 | (fp_line (start -33.02 -15.24) (end -27.94 -15.24) (layer "Dwgs.User") (width 0.12) (tstamp a16b89ec-22ce-4429-896e-bb7b92b91ed4)) 84 | (fp_line (start -33.02 -35.56) (end -27.94 -35.56) (layer "Dwgs.User") (width 0.12) (tstamp bcf4f1dc-7e39-4d8f-9b03-0b9c3b126d1a)) 85 | (fp_line (start -33.02 -43.18) (end -27.94 -43.18) (layer "Dwgs.User") (width 0.12) (tstamp c0b05e65-b250-4fb5-b1a1-2d8ab3bdf45b)) 86 | (fp_line (start 27.94 -15.24) (end 33.02 -15.24) (layer "Dwgs.User") (width 0.12) (tstamp c681fb47-10e0-4ebf-ad0f-05f1367c642a)) 87 | (fp_line (start -33.02 -40.64) (end -27.94 -40.64) (layer "Dwgs.User") (width 0.12) (tstamp cbeffaf7-0a2e-4f9a-a952-23eed2ce9bdb)) 88 | (fp_line (start 27.94 -10.16) (end 33.02 -10.16) (layer "Dwgs.User") (width 0.12) (tstamp cf1d7a5f-49d4-4d41-b6e9-e689b6d99462)) 89 | (fp_line (start -33.02 -7.62) (end -27.94 -7.62) (layer "Dwgs.User") (width 0.12) (tstamp d9270c8a-061f-46e8-87ca-cb577e3aa4b4)) 90 | (fp_line (start 27.94 -25.4) (end 33.02 -25.4) (layer "Dwgs.User") (width 0.12) (tstamp e10d1cf8-67b9-48f1-a183-f620bdc44987)) 91 | (fp_line (start 27.94 -12.7) (end 33.02 -12.7) (layer "Dwgs.User") (width 0.12) (tstamp e4a812fd-9669-42bb-8e48-20261a7dd052)) 92 | (fp_line (start 27.94 -17.78) (end 33.02 -17.78) (layer "Dwgs.User") (width 0.12) (tstamp e6a9b462-696a-4d17-aab5-95ff735af8a7)) 93 | (fp_line (start 27.94 -20.32) (end 33.02 -20.32) (layer "Dwgs.User") (width 0.12) (tstamp ed541cee-1936-4b53-99bc-146c52f01918)) 94 | (fp_line (start -33.02 -30.48) (end -27.94 -30.48) (layer "Dwgs.User") (width 0.12) (tstamp f8532766-5769-4503-a6ae-bbdc8418ecc1)) 95 | (fp_rect (start -27.94 -48.26) (end -33.02 0) (layer "Dwgs.User") (width 0.12) (fill none) (tstamp 3424859a-5efe-46ab-a963-7660b373b7c6)) 96 | (fp_rect (start 33.02 -48.26) (end 27.94 0) (layer "Dwgs.User") (width 0.12) (fill none) (tstamp a6344469-5bb3-4544-a8e5-daeb08490d09)) 97 | (pad "+5V" thru_hole circle (at -29.21 -26.67 90) (size 1.6 1.6) (drill 0.9) (layers *.Cu *.Mask) (tstamp 31422438-9732-407b-beee-813f8795a65a)) 98 | (pad "GND" thru_hole circle (at -29.21 -21.59 90) (size 1.6 1.6) (drill 0.9) (layers *.Cu *.Mask) (tstamp 1f827e88-1d89-4726-8b90-00ccfd0e9831)) 99 | (pad "GND" thru_hole circle (at 31.75 -24.13 90) (size 1.6 1.6) (drill 0.9) (layers *.Cu *.Mask) (tstamp 2a90ed99-1485-474b-9aaa-5a0579c1f1d1)) 100 | (pad "GND" thru_hole circle (at -31.75 -24.13 90) (size 1.6 1.6) (drill 0.9) (layers *.Cu *.Mask) (tstamp 98727a28-ce63-4abc-902a-6c4d0ac0624e)) 101 | (pad "GND" thru_hole circle (at 29.21 -36.83 90) (size 1.6 1.6) (drill 0.9) (layers *.Cu *.Mask) (tstamp a18749d2-5361-40e7-905a-5b06ee5fe7bb)) 102 | (pad "GND" thru_hole circle (at -29.21 -39.37 90) (size 1.6 1.6) (drill 0.9) (layers *.Cu *.Mask) (tstamp b0c756ea-401b-4d9b-bfeb-84d765fbe675)) 103 | (pad "GND" thru_hole circle (at -29.21 -24.13 90) (size 1.6 1.6) (drill 0.9) (layers *.Cu *.Mask) (tstamp c1ab32af-439e-4bbe-aef5-41db110dd8b9)) 104 | (pad "PB13" thru_hole circle (at 31.75 -11.43 90) (size 1.6 1.6) (drill 0.9) (layers *.Cu *.Mask) (tstamp 02949456-a3a1-4eec-9f44-36bd04dfebb8)) 105 | (pad "PB15" thru_hole circle (at 31.75 -16.51 90) (size 1.6 1.6) (drill 0.9) (layers *.Cu *.Mask) (tstamp 27fa799c-8f8e-4f05-9ac3-84395c997bc2)) 106 | (pad "PC6" thru_hole circle (at 31.75 -44.45 90) (size 1.6 1.6) (drill 0.9) (layers *.Cu *.Mask) (tstamp 299d8af1-d830-4400-b469-7a07890bbe5a)) 107 | (pad "PC10" thru_hole circle (at -31.75 -46.99 90) (size 1.6 1.6) (drill 0.9) (layers *.Cu *.Mask) (tstamp ca8fc540-604f-4be7-81ce-4b86694d5033)) 108 | (pad "PC12" thru_hole circle (at -31.75 -44.45 90) (size 1.6 1.6) (drill 0.9) (layers *.Cu *.Mask) (tstamp ac1f14bc-e9b9-4965-8527-e35e4cb12e02)) 109 | (zone (net 0) (net_name "") (layers "B.Cu" "B.CrtYd") (tstamp 41c61f40-d6be-425f-aa1d-fc3d54e4e9a0) (hatch edge 0.508) 110 | (connect_pads (clearance 0)) 111 | (min_thickness 0.254) 112 | (keepout (tracks allowed) (vias allowed) (pads allowed) (copperpour allowed) (footprints not_allowed)) 113 | (fill (thermal_gap 0.508) (thermal_bridge_width 0.508)) 114 | (polygon 115 | (pts 116 | (xy 33.02 1.27) 117 | (xy -33.02 1.27) 118 | (xy -33.02 -52.07) 119 | (xy 33.02 -52.07) 120 | ) 121 | ) 122 | ) 123 | ) 124 | -------------------------------------------------------------------------------- /sch/nlpgen/nlpgen.kicad_pro: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "design_settings": { 4 | "defaults": { 5 | "board_outline_line_width": 0.09999999999999999, 6 | "copper_line_width": 0.19999999999999998, 7 | "copper_text_italic": false, 8 | "copper_text_size_h": 1.5, 9 | "copper_text_size_v": 1.5, 10 | "copper_text_thickness": 0.3, 11 | "copper_text_upright": false, 12 | "courtyard_line_width": 0.049999999999999996, 13 | "dimension_precision": 4, 14 | "dimension_units": 3, 15 | "dimensions": { 16 | "arrow_length": 1270000, 17 | "extension_offset": 500000, 18 | "keep_text_aligned": true, 19 | "suppress_zeroes": false, 20 | "text_position": 0, 21 | "units_format": 1 22 | }, 23 | "fab_line_width": 0.09999999999999999, 24 | "fab_text_italic": false, 25 | "fab_text_size_h": 1.0, 26 | "fab_text_size_v": 1.0, 27 | "fab_text_thickness": 0.15, 28 | "fab_text_upright": false, 29 | "other_line_width": 0.15, 30 | "other_text_italic": false, 31 | "other_text_size_h": 1.0, 32 | "other_text_size_v": 1.0, 33 | "other_text_thickness": 0.15, 34 | "other_text_upright": false, 35 | "pads": { 36 | "drill": 0.762, 37 | "height": 1.524, 38 | "width": 1.524 39 | }, 40 | "silk_line_width": 0.15, 41 | "silk_text_italic": false, 42 | "silk_text_size_h": 1.0, 43 | "silk_text_size_v": 1.0, 44 | "silk_text_thickness": 0.15, 45 | "silk_text_upright": false, 46 | "zones": { 47 | "45_degree_only": false, 48 | "min_clearance": 0.508 49 | } 50 | }, 51 | "diff_pair_dimensions": [ 52 | { 53 | "gap": 0.0, 54 | "via_gap": 0.0, 55 | "width": 0.0 56 | } 57 | ], 58 | "drc_exclusions": [], 59 | "meta": { 60 | "version": 2 61 | }, 62 | "rule_severities": { 63 | "annular_width": "error", 64 | "clearance": "error", 65 | "copper_edge_clearance": "error", 66 | "courtyards_overlap": "error", 67 | "diff_pair_gap_out_of_range": "error", 68 | "diff_pair_uncoupled_length_too_long": "error", 69 | "drill_out_of_range": "error", 70 | "duplicate_footprints": "warning", 71 | "extra_footprint": "warning", 72 | "footprint_type_mismatch": "error", 73 | "hole_clearance": "error", 74 | "hole_near_hole": "error", 75 | "invalid_outline": "error", 76 | "item_on_disabled_layer": "error", 77 | "items_not_allowed": "error", 78 | "length_out_of_range": "error", 79 | "malformed_courtyard": "error", 80 | "microvia_drill_out_of_range": "error", 81 | "missing_courtyard": "ignore", 82 | "missing_footprint": "warning", 83 | "net_conflict": "warning", 84 | "npth_inside_courtyard": "ignore", 85 | "padstack": "error", 86 | "pth_inside_courtyard": "ignore", 87 | "shorting_items": "error", 88 | "silk_over_copper": "warning", 89 | "silk_overlap": "warning", 90 | "skew_out_of_range": "error", 91 | "through_hole_pad_without_hole": "error", 92 | "too_many_vias": "error", 93 | "track_dangling": "warning", 94 | "track_width": "error", 95 | "tracks_crossing": "error", 96 | "unconnected_items": "error", 97 | "unresolved_variable": "error", 98 | "via_dangling": "warning", 99 | "zone_has_empty_net": "error", 100 | "zones_intersect": "error" 101 | }, 102 | "rules": { 103 | "allow_blind_buried_vias": false, 104 | "allow_microvias": false, 105 | "max_error": 0.005, 106 | "min_clearance": 0.0, 107 | "min_copper_edge_clearance": 0.0, 108 | "min_hole_clearance": 0.25, 109 | "min_hole_to_hole": 0.25, 110 | "min_microvia_diameter": 0.19999999999999998, 111 | "min_microvia_drill": 0.09999999999999999, 112 | "min_silk_clearance": 0.0, 113 | "min_through_hole_diameter": 0.5, 114 | "min_track_width": 0.39999999999999997, 115 | "min_via_annular_width": 0.049999999999999996, 116 | "min_via_diameter": 0.5, 117 | "solder_mask_clearance": 0.0, 118 | "solder_mask_min_width": 0.0, 119 | "use_height_for_length_calcs": true 120 | }, 121 | "track_widths": [ 122 | 0.0 123 | ], 124 | "via_dimensions": [ 125 | { 126 | "diameter": 0.0, 127 | "drill": 0.0 128 | } 129 | ], 130 | "zones_allow_external_fillets": false, 131 | "zones_use_no_outline": true 132 | }, 133 | "layer_presets": [] 134 | }, 135 | "boards": [], 136 | "cvpcb": { 137 | "equivalence_files": [] 138 | }, 139 | "erc": { 140 | "erc_exclusions": [], 141 | "meta": { 142 | "version": 0 143 | }, 144 | "pin_map": [ 145 | [ 146 | 0, 147 | 0, 148 | 0, 149 | 0, 150 | 0, 151 | 0, 152 | 1, 153 | 0, 154 | 0, 155 | 0, 156 | 0, 157 | 2 158 | ], 159 | [ 160 | 0, 161 | 2, 162 | 0, 163 | 1, 164 | 0, 165 | 0, 166 | 1, 167 | 0, 168 | 2, 169 | 2, 170 | 2, 171 | 2 172 | ], 173 | [ 174 | 0, 175 | 0, 176 | 0, 177 | 0, 178 | 0, 179 | 0, 180 | 1, 181 | 0, 182 | 1, 183 | 0, 184 | 1, 185 | 2 186 | ], 187 | [ 188 | 0, 189 | 1, 190 | 0, 191 | 0, 192 | 0, 193 | 0, 194 | 1, 195 | 1, 196 | 2, 197 | 1, 198 | 1, 199 | 2 200 | ], 201 | [ 202 | 0, 203 | 0, 204 | 0, 205 | 0, 206 | 0, 207 | 0, 208 | 1, 209 | 0, 210 | 0, 211 | 0, 212 | 0, 213 | 2 214 | ], 215 | [ 216 | 0, 217 | 0, 218 | 0, 219 | 0, 220 | 0, 221 | 0, 222 | 0, 223 | 0, 224 | 0, 225 | 0, 226 | 0, 227 | 2 228 | ], 229 | [ 230 | 1, 231 | 1, 232 | 1, 233 | 1, 234 | 1, 235 | 0, 236 | 1, 237 | 1, 238 | 1, 239 | 1, 240 | 1, 241 | 2 242 | ], 243 | [ 244 | 0, 245 | 0, 246 | 0, 247 | 1, 248 | 0, 249 | 0, 250 | 1, 251 | 0, 252 | 0, 253 | 0, 254 | 0, 255 | 2 256 | ], 257 | [ 258 | 0, 259 | 2, 260 | 1, 261 | 2, 262 | 0, 263 | 0, 264 | 1, 265 | 0, 266 | 2, 267 | 2, 268 | 2, 269 | 2 270 | ], 271 | [ 272 | 0, 273 | 2, 274 | 0, 275 | 1, 276 | 0, 277 | 0, 278 | 1, 279 | 0, 280 | 2, 281 | 0, 282 | 0, 283 | 2 284 | ], 285 | [ 286 | 0, 287 | 2, 288 | 1, 289 | 1, 290 | 0, 291 | 0, 292 | 1, 293 | 0, 294 | 2, 295 | 0, 296 | 0, 297 | 2 298 | ], 299 | [ 300 | 2, 301 | 2, 302 | 2, 303 | 2, 304 | 2, 305 | 2, 306 | 2, 307 | 2, 308 | 2, 309 | 2, 310 | 2, 311 | 2 312 | ] 313 | ], 314 | "rule_severities": { 315 | "bus_definition_conflict": "error", 316 | "bus_entry_needed": "error", 317 | "bus_label_syntax": "error", 318 | "bus_to_bus_conflict": "error", 319 | "bus_to_net_conflict": "error", 320 | "different_unit_footprint": "error", 321 | "different_unit_net": "error", 322 | "duplicate_reference": "error", 323 | "duplicate_sheet_names": "error", 324 | "extra_units": "error", 325 | "global_label_dangling": "warning", 326 | "hier_label_mismatch": "error", 327 | "label_dangling": "error", 328 | "lib_symbol_issues": "warning", 329 | "multiple_net_names": "warning", 330 | "net_not_bus_member": "warning", 331 | "no_connect_connected": "warning", 332 | "no_connect_dangling": "warning", 333 | "pin_not_connected": "error", 334 | "pin_not_driven": "error", 335 | "pin_to_pin": "warning", 336 | "power_pin_not_driven": "error", 337 | "similar_labels": "warning", 338 | "unannotated": "error", 339 | "unit_value_mismatch": "error", 340 | "unresolved_variable": "error", 341 | "wire_dangling": "error" 342 | } 343 | }, 344 | "libraries": { 345 | "pinned_footprint_libs": [], 346 | "pinned_symbol_libs": [] 347 | }, 348 | "meta": { 349 | "filename": "nlpgen.kicad_pro", 350 | "version": 1 351 | }, 352 | "net_settings": { 353 | "classes": [ 354 | { 355 | "bus_width": 12.0, 356 | "clearance": 0.25, 357 | "diff_pair_gap": 0.25, 358 | "diff_pair_via_gap": 0.25, 359 | "diff_pair_width": 0.2, 360 | "line_style": 0, 361 | "microvia_diameter": 0.3, 362 | "microvia_drill": 0.1, 363 | "name": "Default", 364 | "pcb_color": "rgba(0, 0, 0, 0.000)", 365 | "schematic_color": "rgba(0, 0, 0, 0.000)", 366 | "track_width": 0.4, 367 | "via_diameter": 1.0, 368 | "via_drill": 0.6, 369 | "wire_width": 6.0 370 | } 371 | ], 372 | "meta": { 373 | "version": 2 374 | }, 375 | "net_colors": null 376 | }, 377 | "pcbnew": { 378 | "last_paths": { 379 | "gencad": "", 380 | "idf": "", 381 | "netlist": "", 382 | "specctra_dsn": "", 383 | "step": "", 384 | "vrml": "" 385 | }, 386 | "page_layout_descr_file": "" 387 | }, 388 | "schematic": { 389 | "annotate_start_num": 0, 390 | "drawing": { 391 | "default_line_thickness": 6.0, 392 | "default_text_size": 50.0, 393 | "field_names": [], 394 | "intersheets_ref_own_page": false, 395 | "intersheets_ref_prefix": "", 396 | "intersheets_ref_short": false, 397 | "intersheets_ref_show": false, 398 | "intersheets_ref_suffix": "", 399 | "junction_size_choice": 3, 400 | "label_size_ratio": 0.375, 401 | "pin_symbol_size": 25.0, 402 | "text_offset_ratio": 0.15 403 | }, 404 | "legacy_lib_dir": "", 405 | "legacy_lib_list": [], 406 | "meta": { 407 | "version": 1 408 | }, 409 | "net_format_name": "", 410 | "ngspice": { 411 | "fix_include_paths": true, 412 | "fix_passive_vals": false, 413 | "meta": { 414 | "version": 0 415 | }, 416 | "model_mode": 0, 417 | "workbook_filename": "" 418 | }, 419 | "page_layout_descr_file": "", 420 | "plot_directory": "", 421 | "spice_adjust_passive_values": false, 422 | "spice_external_command": "spice \"%I\"", 423 | "subpart_first_id": 65, 424 | "subpart_id_separator": 0 425 | }, 426 | "sheets": [ 427 | [ 428 | "03f25abc-ef84-4cea-99c0-e37831abc964", 429 | "" 430 | ] 431 | ], 432 | "text_variables": {} 433 | } 434 | -------------------------------------------------------------------------------- /sch/bytesync/bytesync.kicad_pro: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "design_settings": { 4 | "defaults": { 5 | "board_outline_line_width": 0.09999999999999999, 6 | "copper_line_width": 0.19999999999999998, 7 | "copper_text_italic": false, 8 | "copper_text_size_h": 1.5, 9 | "copper_text_size_v": 1.5, 10 | "copper_text_thickness": 0.3, 11 | "copper_text_upright": false, 12 | "courtyard_line_width": 0.049999999999999996, 13 | "dimension_precision": 4, 14 | "dimension_units": 3, 15 | "dimensions": { 16 | "arrow_length": 1270000, 17 | "extension_offset": 500000, 18 | "keep_text_aligned": true, 19 | "suppress_zeroes": false, 20 | "text_position": 0, 21 | "units_format": 1 22 | }, 23 | "fab_line_width": 0.09999999999999999, 24 | "fab_text_italic": false, 25 | "fab_text_size_h": 1.0, 26 | "fab_text_size_v": 1.0, 27 | "fab_text_thickness": 0.15, 28 | "fab_text_upright": false, 29 | "other_line_width": 0.15, 30 | "other_text_italic": false, 31 | "other_text_size_h": 1.0, 32 | "other_text_size_v": 1.0, 33 | "other_text_thickness": 0.15, 34 | "other_text_upright": false, 35 | "pads": { 36 | "drill": 0.762, 37 | "height": 1.524, 38 | "width": 1.524 39 | }, 40 | "silk_line_width": 0.15, 41 | "silk_text_italic": false, 42 | "silk_text_size_h": 1.0, 43 | "silk_text_size_v": 1.0, 44 | "silk_text_thickness": 0.15, 45 | "silk_text_upright": false, 46 | "zones": { 47 | "45_degree_only": false, 48 | "min_clearance": 0.508 49 | } 50 | }, 51 | "diff_pair_dimensions": [ 52 | { 53 | "gap": 0.0, 54 | "via_gap": 0.0, 55 | "width": 0.0 56 | } 57 | ], 58 | "drc_exclusions": [], 59 | "meta": { 60 | "version": 2 61 | }, 62 | "rule_severities": { 63 | "annular_width": "error", 64 | "clearance": "error", 65 | "copper_edge_clearance": "error", 66 | "courtyards_overlap": "error", 67 | "diff_pair_gap_out_of_range": "error", 68 | "diff_pair_uncoupled_length_too_long": "error", 69 | "drill_out_of_range": "error", 70 | "duplicate_footprints": "warning", 71 | "extra_footprint": "warning", 72 | "footprint_type_mismatch": "error", 73 | "hole_clearance": "error", 74 | "hole_near_hole": "error", 75 | "invalid_outline": "error", 76 | "item_on_disabled_layer": "error", 77 | "items_not_allowed": "error", 78 | "length_out_of_range": "error", 79 | "malformed_courtyard": "error", 80 | "microvia_drill_out_of_range": "error", 81 | "missing_courtyard": "ignore", 82 | "missing_footprint": "warning", 83 | "net_conflict": "warning", 84 | "npth_inside_courtyard": "ignore", 85 | "padstack": "error", 86 | "pth_inside_courtyard": "ignore", 87 | "shorting_items": "error", 88 | "silk_over_copper": "warning", 89 | "silk_overlap": "warning", 90 | "skew_out_of_range": "error", 91 | "through_hole_pad_without_hole": "error", 92 | "too_many_vias": "error", 93 | "track_dangling": "warning", 94 | "track_width": "error", 95 | "tracks_crossing": "error", 96 | "unconnected_items": "error", 97 | "unresolved_variable": "error", 98 | "via_dangling": "warning", 99 | "zone_has_empty_net": "error", 100 | "zones_intersect": "error" 101 | }, 102 | "rules": { 103 | "allow_blind_buried_vias": false, 104 | "allow_microvias": false, 105 | "max_error": 0.005, 106 | "min_clearance": 0.0, 107 | "min_copper_edge_clearance": 0.0, 108 | "min_hole_clearance": 0.25, 109 | "min_hole_to_hole": 0.25, 110 | "min_microvia_diameter": 0.19999999999999998, 111 | "min_microvia_drill": 0.09999999999999999, 112 | "min_silk_clearance": 0.0, 113 | "min_through_hole_diameter": 0.5, 114 | "min_track_width": 0.39999999999999997, 115 | "min_via_annular_width": 0.049999999999999996, 116 | "min_via_diameter": 0.5, 117 | "solder_mask_clearance": 0.0, 118 | "solder_mask_min_width": 0.0, 119 | "use_height_for_length_calcs": true 120 | }, 121 | "track_widths": [ 122 | 0.0 123 | ], 124 | "via_dimensions": [ 125 | { 126 | "diameter": 0.0, 127 | "drill": 0.0 128 | } 129 | ], 130 | "zones_allow_external_fillets": false, 131 | "zones_use_no_outline": true 132 | }, 133 | "layer_presets": [] 134 | }, 135 | "boards": [], 136 | "cvpcb": { 137 | "equivalence_files": [] 138 | }, 139 | "erc": { 140 | "erc_exclusions": [], 141 | "meta": { 142 | "version": 0 143 | }, 144 | "pin_map": [ 145 | [ 146 | 0, 147 | 0, 148 | 0, 149 | 0, 150 | 0, 151 | 0, 152 | 1, 153 | 0, 154 | 0, 155 | 0, 156 | 0, 157 | 2 158 | ], 159 | [ 160 | 0, 161 | 2, 162 | 0, 163 | 1, 164 | 0, 165 | 0, 166 | 1, 167 | 0, 168 | 2, 169 | 2, 170 | 2, 171 | 2 172 | ], 173 | [ 174 | 0, 175 | 0, 176 | 0, 177 | 0, 178 | 0, 179 | 0, 180 | 1, 181 | 0, 182 | 1, 183 | 0, 184 | 1, 185 | 2 186 | ], 187 | [ 188 | 0, 189 | 1, 190 | 0, 191 | 0, 192 | 0, 193 | 0, 194 | 1, 195 | 1, 196 | 2, 197 | 1, 198 | 1, 199 | 2 200 | ], 201 | [ 202 | 0, 203 | 0, 204 | 0, 205 | 0, 206 | 0, 207 | 0, 208 | 1, 209 | 0, 210 | 0, 211 | 0, 212 | 0, 213 | 2 214 | ], 215 | [ 216 | 0, 217 | 0, 218 | 0, 219 | 0, 220 | 0, 221 | 0, 222 | 0, 223 | 0, 224 | 0, 225 | 0, 226 | 0, 227 | 2 228 | ], 229 | [ 230 | 1, 231 | 1, 232 | 1, 233 | 1, 234 | 1, 235 | 0, 236 | 1, 237 | 1, 238 | 1, 239 | 1, 240 | 1, 241 | 2 242 | ], 243 | [ 244 | 0, 245 | 0, 246 | 0, 247 | 1, 248 | 0, 249 | 0, 250 | 1, 251 | 0, 252 | 0, 253 | 0, 254 | 0, 255 | 2 256 | ], 257 | [ 258 | 0, 259 | 2, 260 | 1, 261 | 2, 262 | 0, 263 | 0, 264 | 1, 265 | 0, 266 | 2, 267 | 2, 268 | 2, 269 | 2 270 | ], 271 | [ 272 | 0, 273 | 2, 274 | 0, 275 | 1, 276 | 0, 277 | 0, 278 | 1, 279 | 0, 280 | 2, 281 | 0, 282 | 0, 283 | 2 284 | ], 285 | [ 286 | 0, 287 | 2, 288 | 1, 289 | 1, 290 | 0, 291 | 0, 292 | 1, 293 | 0, 294 | 2, 295 | 0, 296 | 0, 297 | 2 298 | ], 299 | [ 300 | 2, 301 | 2, 302 | 2, 303 | 2, 304 | 2, 305 | 2, 306 | 2, 307 | 2, 308 | 2, 309 | 2, 310 | 2, 311 | 2 312 | ] 313 | ], 314 | "rule_severities": { 315 | "bus_definition_conflict": "error", 316 | "bus_entry_needed": "error", 317 | "bus_label_syntax": "error", 318 | "bus_to_bus_conflict": "error", 319 | "bus_to_net_conflict": "error", 320 | "different_unit_footprint": "error", 321 | "different_unit_net": "error", 322 | "duplicate_reference": "error", 323 | "duplicate_sheet_names": "error", 324 | "extra_units": "error", 325 | "global_label_dangling": "warning", 326 | "hier_label_mismatch": "error", 327 | "label_dangling": "error", 328 | "lib_symbol_issues": "warning", 329 | "multiple_net_names": "warning", 330 | "net_not_bus_member": "warning", 331 | "no_connect_connected": "warning", 332 | "no_connect_dangling": "warning", 333 | "pin_not_connected": "error", 334 | "pin_not_driven": "error", 335 | "pin_to_pin": "warning", 336 | "power_pin_not_driven": "error", 337 | "similar_labels": "warning", 338 | "unannotated": "error", 339 | "unit_value_mismatch": "error", 340 | "unresolved_variable": "error", 341 | "wire_dangling": "error" 342 | } 343 | }, 344 | "libraries": { 345 | "pinned_footprint_libs": [], 346 | "pinned_symbol_libs": [] 347 | }, 348 | "meta": { 349 | "filename": "bytesync.kicad_pro", 350 | "version": 1 351 | }, 352 | "net_settings": { 353 | "classes": [ 354 | { 355 | "bus_width": 12.0, 356 | "clearance": 0.25, 357 | "diff_pair_gap": 0.25, 358 | "diff_pair_via_gap": 0.25, 359 | "diff_pair_width": 0.2, 360 | "line_style": 0, 361 | "microvia_diameter": 0.3, 362 | "microvia_drill": 0.1, 363 | "name": "Default", 364 | "pcb_color": "rgba(0, 0, 0, 0.000)", 365 | "schematic_color": "rgba(0, 0, 0, 0.000)", 366 | "track_width": 0.4, 367 | "via_diameter": 1.0, 368 | "via_drill": 0.6, 369 | "wire_width": 6.0 370 | } 371 | ], 372 | "meta": { 373 | "version": 2 374 | }, 375 | "net_colors": null 376 | }, 377 | "pcbnew": { 378 | "last_paths": { 379 | "gencad": "", 380 | "idf": "", 381 | "netlist": "", 382 | "specctra_dsn": "", 383 | "step": "", 384 | "vrml": "" 385 | }, 386 | "page_layout_descr_file": "" 387 | }, 388 | "schematic": { 389 | "annotate_start_num": 0, 390 | "drawing": { 391 | "default_line_thickness": 6.0, 392 | "default_text_size": 50.0, 393 | "field_names": [], 394 | "intersheets_ref_own_page": false, 395 | "intersheets_ref_prefix": "", 396 | "intersheets_ref_short": false, 397 | "intersheets_ref_show": false, 398 | "intersheets_ref_suffix": "", 399 | "junction_size_choice": 3, 400 | "label_size_ratio": 0.375, 401 | "pin_symbol_size": 25.0, 402 | "text_offset_ratio": 0.15 403 | }, 404 | "legacy_lib_dir": "", 405 | "legacy_lib_list": [], 406 | "meta": { 407 | "version": 1 408 | }, 409 | "net_format_name": "", 410 | "ngspice": { 411 | "fix_include_paths": true, 412 | "fix_passive_vals": false, 413 | "meta": { 414 | "version": 0 415 | }, 416 | "model_mode": 0, 417 | "workbook_filename": "" 418 | }, 419 | "page_layout_descr_file": "", 420 | "plot_directory": "", 421 | "spice_adjust_passive_values": false, 422 | "spice_external_command": "spice \"%I\"", 423 | "subpart_first_id": 65, 424 | "subpart_id_separator": 0 425 | }, 426 | "sheets": [ 427 | [ 428 | "df4bb283-6f45-43d0-a85d-a42d4da2c5f0", 429 | "" 430 | ] 431 | ], 432 | "text_variables": {} 433 | } 434 | -------------------------------------------------------------------------------- /sch/ethernet-to-spi/ethernet-to-spi.kicad_pro: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "design_settings": { 4 | "defaults": { 5 | "board_outline_line_width": 0.09999999999999999, 6 | "copper_line_width": 0.19999999999999998, 7 | "copper_text_italic": false, 8 | "copper_text_size_h": 1.5, 9 | "copper_text_size_v": 1.5, 10 | "copper_text_thickness": 0.3, 11 | "copper_text_upright": false, 12 | "courtyard_line_width": 0.049999999999999996, 13 | "dimension_precision": 4, 14 | "dimension_units": 3, 15 | "dimensions": { 16 | "arrow_length": 1270000, 17 | "extension_offset": 500000, 18 | "keep_text_aligned": true, 19 | "suppress_zeroes": false, 20 | "text_position": 0, 21 | "units_format": 1 22 | }, 23 | "fab_line_width": 0.09999999999999999, 24 | "fab_text_italic": false, 25 | "fab_text_size_h": 1.0, 26 | "fab_text_size_v": 1.0, 27 | "fab_text_thickness": 0.15, 28 | "fab_text_upright": false, 29 | "other_line_width": 0.15, 30 | "other_text_italic": false, 31 | "other_text_size_h": 1.0, 32 | "other_text_size_v": 1.0, 33 | "other_text_thickness": 0.15, 34 | "other_text_upright": false, 35 | "pads": { 36 | "drill": 0.762, 37 | "height": 1.524, 38 | "width": 1.524 39 | }, 40 | "silk_line_width": 0.15, 41 | "silk_text_italic": false, 42 | "silk_text_size_h": 1.0, 43 | "silk_text_size_v": 1.0, 44 | "silk_text_thickness": 0.15, 45 | "silk_text_upright": false, 46 | "zones": { 47 | "45_degree_only": false, 48 | "min_clearance": 0.508 49 | } 50 | }, 51 | "diff_pair_dimensions": [ 52 | { 53 | "gap": 0.0, 54 | "via_gap": 0.0, 55 | "width": 0.0 56 | } 57 | ], 58 | "drc_exclusions": [], 59 | "meta": { 60 | "version": 2 61 | }, 62 | "rule_severities": { 63 | "annular_width": "error", 64 | "clearance": "error", 65 | "copper_edge_clearance": "error", 66 | "courtyards_overlap": "error", 67 | "diff_pair_gap_out_of_range": "error", 68 | "diff_pair_uncoupled_length_too_long": "error", 69 | "drill_out_of_range": "error", 70 | "duplicate_footprints": "warning", 71 | "extra_footprint": "warning", 72 | "footprint_type_mismatch": "error", 73 | "hole_clearance": "error", 74 | "hole_near_hole": "error", 75 | "invalid_outline": "error", 76 | "item_on_disabled_layer": "error", 77 | "items_not_allowed": "error", 78 | "length_out_of_range": "error", 79 | "malformed_courtyard": "error", 80 | "microvia_drill_out_of_range": "error", 81 | "missing_courtyard": "ignore", 82 | "missing_footprint": "warning", 83 | "net_conflict": "warning", 84 | "npth_inside_courtyard": "ignore", 85 | "padstack": "error", 86 | "pth_inside_courtyard": "ignore", 87 | "shorting_items": "error", 88 | "silk_over_copper": "warning", 89 | "silk_overlap": "warning", 90 | "skew_out_of_range": "error", 91 | "through_hole_pad_without_hole": "error", 92 | "too_many_vias": "error", 93 | "track_dangling": "warning", 94 | "track_width": "error", 95 | "tracks_crossing": "error", 96 | "unconnected_items": "error", 97 | "unresolved_variable": "error", 98 | "via_dangling": "warning", 99 | "zone_has_empty_net": "error", 100 | "zones_intersect": "error" 101 | }, 102 | "rules": { 103 | "allow_blind_buried_vias": false, 104 | "allow_microvias": false, 105 | "max_error": 0.005, 106 | "min_clearance": 0.0, 107 | "min_copper_edge_clearance": 0.0, 108 | "min_hole_clearance": 0.25, 109 | "min_hole_to_hole": 0.25, 110 | "min_microvia_diameter": 0.19999999999999998, 111 | "min_microvia_drill": 0.09999999999999999, 112 | "min_silk_clearance": 0.0, 113 | "min_through_hole_diameter": 0.5, 114 | "min_track_width": 0.39999999999999997, 115 | "min_via_annular_width": 0.049999999999999996, 116 | "min_via_diameter": 0.5, 117 | "solder_mask_clearance": 0.0, 118 | "solder_mask_min_width": 0.0, 119 | "use_height_for_length_calcs": true 120 | }, 121 | "track_widths": [ 122 | 0.0 123 | ], 124 | "via_dimensions": [ 125 | { 126 | "diameter": 0.0, 127 | "drill": 0.0 128 | } 129 | ], 130 | "zones_allow_external_fillets": false, 131 | "zones_use_no_outline": true 132 | }, 133 | "layer_presets": [] 134 | }, 135 | "boards": [], 136 | "cvpcb": { 137 | "equivalence_files": [] 138 | }, 139 | "erc": { 140 | "erc_exclusions": [], 141 | "meta": { 142 | "version": 0 143 | }, 144 | "pin_map": [ 145 | [ 146 | 0, 147 | 0, 148 | 0, 149 | 0, 150 | 0, 151 | 0, 152 | 1, 153 | 0, 154 | 0, 155 | 0, 156 | 0, 157 | 2 158 | ], 159 | [ 160 | 0, 161 | 2, 162 | 0, 163 | 1, 164 | 0, 165 | 0, 166 | 1, 167 | 0, 168 | 2, 169 | 2, 170 | 2, 171 | 2 172 | ], 173 | [ 174 | 0, 175 | 0, 176 | 0, 177 | 0, 178 | 0, 179 | 0, 180 | 1, 181 | 0, 182 | 1, 183 | 0, 184 | 1, 185 | 2 186 | ], 187 | [ 188 | 0, 189 | 1, 190 | 0, 191 | 0, 192 | 0, 193 | 0, 194 | 1, 195 | 1, 196 | 2, 197 | 1, 198 | 1, 199 | 2 200 | ], 201 | [ 202 | 0, 203 | 0, 204 | 0, 205 | 0, 206 | 0, 207 | 0, 208 | 1, 209 | 0, 210 | 0, 211 | 0, 212 | 0, 213 | 2 214 | ], 215 | [ 216 | 0, 217 | 0, 218 | 0, 219 | 0, 220 | 0, 221 | 0, 222 | 0, 223 | 0, 224 | 0, 225 | 0, 226 | 0, 227 | 2 228 | ], 229 | [ 230 | 1, 231 | 1, 232 | 1, 233 | 1, 234 | 1, 235 | 0, 236 | 1, 237 | 1, 238 | 1, 239 | 1, 240 | 1, 241 | 2 242 | ], 243 | [ 244 | 0, 245 | 0, 246 | 0, 247 | 1, 248 | 0, 249 | 0, 250 | 1, 251 | 0, 252 | 0, 253 | 0, 254 | 0, 255 | 2 256 | ], 257 | [ 258 | 0, 259 | 2, 260 | 1, 261 | 2, 262 | 0, 263 | 0, 264 | 1, 265 | 0, 266 | 2, 267 | 2, 268 | 2, 269 | 2 270 | ], 271 | [ 272 | 0, 273 | 2, 274 | 0, 275 | 1, 276 | 0, 277 | 0, 278 | 1, 279 | 0, 280 | 2, 281 | 0, 282 | 0, 283 | 2 284 | ], 285 | [ 286 | 0, 287 | 2, 288 | 1, 289 | 1, 290 | 0, 291 | 0, 292 | 1, 293 | 0, 294 | 2, 295 | 0, 296 | 0, 297 | 2 298 | ], 299 | [ 300 | 2, 301 | 2, 302 | 2, 303 | 2, 304 | 2, 305 | 2, 306 | 2, 307 | 2, 308 | 2, 309 | 2, 310 | 2, 311 | 2 312 | ] 313 | ], 314 | "rule_severities": { 315 | "bus_definition_conflict": "error", 316 | "bus_entry_needed": "error", 317 | "bus_label_syntax": "error", 318 | "bus_to_bus_conflict": "error", 319 | "bus_to_net_conflict": "error", 320 | "different_unit_footprint": "error", 321 | "different_unit_net": "error", 322 | "duplicate_reference": "error", 323 | "duplicate_sheet_names": "error", 324 | "extra_units": "error", 325 | "global_label_dangling": "warning", 326 | "hier_label_mismatch": "error", 327 | "label_dangling": "error", 328 | "lib_symbol_issues": "warning", 329 | "multiple_net_names": "warning", 330 | "net_not_bus_member": "warning", 331 | "no_connect_connected": "warning", 332 | "no_connect_dangling": "warning", 333 | "pin_not_connected": "error", 334 | "pin_not_driven": "error", 335 | "pin_to_pin": "error", 336 | "power_pin_not_driven": "error", 337 | "similar_labels": "warning", 338 | "unannotated": "error", 339 | "unit_value_mismatch": "error", 340 | "unresolved_variable": "error", 341 | "wire_dangling": "error" 342 | } 343 | }, 344 | "libraries": { 345 | "pinned_footprint_libs": [], 346 | "pinned_symbol_libs": [] 347 | }, 348 | "meta": { 349 | "filename": "ethernet-to-spi.kicad_pro", 350 | "version": 1 351 | }, 352 | "net_settings": { 353 | "classes": [ 354 | { 355 | "bus_width": 12.0, 356 | "clearance": 0.25, 357 | "diff_pair_gap": 0.25, 358 | "diff_pair_via_gap": 0.25, 359 | "diff_pair_width": 0.2, 360 | "line_style": 0, 361 | "microvia_diameter": 0.3, 362 | "microvia_drill": 0.1, 363 | "name": "Default", 364 | "pcb_color": "rgba(0, 0, 0, 0.000)", 365 | "schematic_color": "rgba(0, 0, 0, 0.000)", 366 | "track_width": 0.4, 367 | "via_diameter": 1.0, 368 | "via_drill": 0.6, 369 | "wire_width": 6.0 370 | } 371 | ], 372 | "meta": { 373 | "version": 2 374 | }, 375 | "net_colors": null 376 | }, 377 | "pcbnew": { 378 | "last_paths": { 379 | "gencad": "", 380 | "idf": "", 381 | "netlist": "", 382 | "specctra_dsn": "", 383 | "step": "", 384 | "vrml": "" 385 | }, 386 | "page_layout_descr_file": "" 387 | }, 388 | "schematic": { 389 | "annotate_start_num": 0, 390 | "drawing": { 391 | "default_line_thickness": 6.0, 392 | "default_text_size": 50.0, 393 | "field_names": [], 394 | "intersheets_ref_own_page": false, 395 | "intersheets_ref_prefix": "", 396 | "intersheets_ref_short": false, 397 | "intersheets_ref_show": false, 398 | "intersheets_ref_suffix": "", 399 | "junction_size_choice": 3, 400 | "label_size_ratio": 0.375, 401 | "pin_symbol_size": 25.0, 402 | "text_offset_ratio": 0.15 403 | }, 404 | "legacy_lib_dir": "", 405 | "legacy_lib_list": [], 406 | "meta": { 407 | "version": 1 408 | }, 409 | "net_format_name": "", 410 | "ngspice": { 411 | "fix_include_paths": true, 412 | "fix_passive_vals": false, 413 | "meta": { 414 | "version": 0 415 | }, 416 | "model_mode": 0, 417 | "workbook_filename": "" 418 | }, 419 | "page_layout_descr_file": "", 420 | "plot_directory": "", 421 | "spice_adjust_passive_values": false, 422 | "spice_external_command": "spice \"%I\"", 423 | "subpart_first_id": 65, 424 | "subpart_id_separator": 0 425 | }, 426 | "sheets": [ 427 | [ 428 | "05593d22-f90c-4ccc-a506-a77fc2ada352", 429 | "" 430 | ] 431 | ], 432 | "text_variables": {} 433 | } 434 | -------------------------------------------------------------------------------- /sch/shield/gerber/shield-B_Silkscreen.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,(6.0.9-0)*% 2 | %TF.CreationDate,2022-11-17T19:03:50+01:00*% 3 | %TF.ProjectId,shield,73686965-6c64-42e6-9b69-6361645f7063,1*% 4 | %TF.SameCoordinates,PX3a2c940PY82a7440*% 5 | %TF.FileFunction,Legend,Bot*% 6 | %TF.FilePolarity,Positive*% 7 | %FSLAX46Y46*% 8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 9 | G04 Created by KiCad (PCBNEW (6.0.9-0)) date 2022-11-17 19:03:50* 10 | %MOMM*% 11 | %LPD*% 12 | G01* 13 | G04 APERTURE LIST* 14 | %ADD10C,0.150000*% 15 | G04 APERTURE END LIST* 16 | D10* 17 | X43571428Y65352620D02* 18 | X44047619Y65352620D01* 19 | X44047619Y66352620D01* 20 | X43238095Y65352620D02* 21 | X43238095Y66019286D01* 22 | X43238095Y66352620D02* 23 | X43285714Y66305000D01* 24 | X43238095Y66257381D01* 25 | X43190476Y66305000D01* 26 | X43238095Y66352620D01* 27 | X43238095Y66257381D01* 28 | X42333333Y65400239D02* 29 | X42428571Y65352620D01* 30 | X42619047Y65352620D01* 31 | X42714285Y65400239D01* 32 | X42761904Y65447858D01* 33 | X42809523Y65543096D01* 34 | X42809523Y65828810D01* 35 | X42761904Y65924048D01* 36 | X42714285Y65971667D01* 37 | X42619047Y66019286D01* 38 | X42428571Y66019286D01* 39 | X42333333Y65971667D01* 40 | X41523809Y65400239D02* 41 | X41619047Y65352620D01* 42 | X41809523Y65352620D01* 43 | X41904761Y65400239D01* 44 | X41952380Y65495477D01* 45 | X41952380Y65876429D01* 46 | X41904761Y65971667D01* 47 | X41809523Y66019286D01* 48 | X41619047Y66019286D01* 49 | X41523809Y65971667D01* 50 | X41476190Y65876429D01* 51 | X41476190Y65781191D01* 52 | X41952380Y65685953D01* 53 | X41047619Y66019286D02* 54 | X41047619Y65352620D01* 55 | X41047619Y65924048D02* 56 | X41000000Y65971667D01* 57 | X40904761Y66019286D01* 58 | X40761904Y66019286D01* 59 | X40666666Y65971667D01* 60 | X40619047Y65876429D01* 61 | X40619047Y65352620D01* 62 | X40190476Y65400239D02* 63 | X40095238Y65352620D01* 64 | X39904761Y65352620D01* 65 | X39809523Y65400239D01* 66 | X39761904Y65495477D01* 67 | X39761904Y65543096D01* 68 | X39809523Y65638334D01* 69 | X39904761Y65685953D01* 70 | X40047619Y65685953D01* 71 | X40142857Y65733572D01* 72 | X40190476Y65828810D01* 73 | X40190476Y65876429D01* 74 | X40142857Y65971667D01* 75 | X40047619Y66019286D01* 76 | X39904761Y66019286D01* 77 | X39809523Y65971667D01* 78 | X38952380Y65400239D02* 79 | X39047619Y65352620D01* 80 | X39238095Y65352620D01* 81 | X39333333Y65400239D01* 82 | X39380952Y65495477D01* 83 | X39380952Y65876429D01* 84 | X39333333Y65971667D01* 85 | X39238095Y66019286D01* 86 | X39047619Y66019286D01* 87 | X38952380Y65971667D01* 88 | X38904761Y65876429D01* 89 | X38904761Y65781191D01* 90 | X39380952Y65685953D01* 91 | X38047619Y65352620D02* 92 | X38047619Y66352620D01* 93 | X38047619Y65400239D02* 94 | X38142857Y65352620D01* 95 | X38333333Y65352620D01* 96 | X38428571Y65400239D01* 97 | X38476190Y65447858D01* 98 | X38523809Y65543096D01* 99 | X38523809Y65828810D01* 100 | X38476190Y65924048D01* 101 | X38428571Y65971667D01* 102 | X38333333Y66019286D01* 103 | X38142857Y66019286D01* 104 | X38047619Y65971667D01* 105 | X36380952Y66019286D02* 106 | X36380952Y65352620D01* 107 | X36809523Y66019286D02* 108 | X36809523Y65495477D01* 109 | X36761904Y65400239D01* 110 | X36666666Y65352620D01* 111 | X36523809Y65352620D01* 112 | X36428571Y65400239D01* 113 | X36380952Y65447858D01* 114 | X35904761Y66019286D02* 115 | X35904761Y65352620D01* 116 | X35904761Y65924048D02* 117 | X35857142Y65971667D01* 118 | X35761904Y66019286D01* 119 | X35619047Y66019286D01* 120 | X35523809Y65971667D01* 121 | X35476190Y65876429D01* 122 | X35476190Y65352620D01* 123 | X34571428Y65352620D02* 124 | X34571428Y66352620D01* 125 | X34571428Y65400239D02* 126 | X34666666Y65352620D01* 127 | X34857142Y65352620D01* 128 | X34952380Y65400239D01* 129 | X35000000Y65447858D01* 130 | X35047619Y65543096D01* 131 | X35047619Y65828810D01* 132 | X35000000Y65924048D01* 133 | X34952380Y65971667D01* 134 | X34857142Y66019286D01* 135 | X34666666Y66019286D01* 136 | X34571428Y65971667D01* 137 | X33714285Y65400239D02* 138 | X33809523Y65352620D01* 139 | X34000000Y65352620D01* 140 | X34095238Y65400239D01* 141 | X34142857Y65495477D01* 142 | X34142857Y65876429D01* 143 | X34095238Y65971667D01* 144 | X34000000Y66019286D01* 145 | X33809523Y66019286D01* 146 | X33714285Y65971667D01* 147 | X33666666Y65876429D01* 148 | X33666666Y65781191D01* 149 | X34142857Y65685953D01* 150 | X33238095Y65352620D02* 151 | X33238095Y66019286D01* 152 | X33238095Y65828810D02* 153 | X33190476Y65924048D01* 154 | X33142857Y65971667D01* 155 | X33047619Y66019286D01* 156 | X32952380Y66019286D01* 157 | X32000000Y66019286D02* 158 | X31619047Y66019286D01* 159 | X31857142Y66352620D02* 160 | X31857142Y65495477D01* 161 | X31809523Y65400239D01* 162 | X31714285Y65352620D01* 163 | X31619047Y65352620D01* 164 | X31285714Y65352620D02* 165 | X31285714Y66352620D01* 166 | X30857142Y65352620D02* 167 | X30857142Y65876429D01* 168 | X30904761Y65971667D01* 169 | X31000000Y66019286D01* 170 | X31142857Y66019286D01* 171 | X31238095Y65971667D01* 172 | X31285714Y65924048D01* 173 | X30000000Y65400239D02* 174 | X30095238Y65352620D01* 175 | X30285714Y65352620D01* 176 | X30380952Y65400239D01* 177 | X30428571Y65495477D01* 178 | X30428571Y65876429D01* 179 | X30380952Y65971667D01* 180 | X30285714Y66019286D01* 181 | X30095238Y66019286D01* 182 | X30000000Y65971667D01* 183 | X29952380Y65876429D01* 184 | X29952380Y65781191D01* 185 | X30428571Y65685953D01* 186 | X28904761Y66352620D02* 187 | X28333333Y66352620D01* 188 | X28619047Y65352620D02* 189 | X28619047Y66352620D01* 190 | X28047619Y65638334D02* 191 | X27571428Y65638334D01* 192 | X28142857Y65352620D02* 193 | X27809523Y66352620D01* 194 | X27476190Y65352620D01* 195 | X27142857Y65352620D02* 196 | X27142857Y66352620D01* 197 | X26761904Y66352620D01* 198 | X26666666Y66305000D01* 199 | X26619047Y66257381D01* 200 | X26571428Y66162143D01* 201 | X26571428Y66019286D01* 202 | X26619047Y65924048D01* 203 | X26666666Y65876429D01* 204 | X26761904Y65828810D01* 205 | X27142857Y65828810D01* 206 | X25571428Y65352620D02* 207 | X25904761Y65828810D01* 208 | X26142857Y65352620D02* 209 | X26142857Y66352620D01* 210 | X25761904Y66352620D01* 211 | X25666666Y66305000D01* 212 | X25619047Y66257381D01* 213 | X25571428Y66162143D01* 214 | X25571428Y66019286D01* 215 | X25619047Y65924048D01* 216 | X25666666Y65876429D01* 217 | X25761904Y65828810D01* 218 | X26142857Y65828810D01* 219 | X24190476Y66352620D02* 220 | X24000000Y66352620D01* 221 | X23904761Y66305000D01* 222 | X23809523Y66209762D01* 223 | X23761904Y66019286D01* 224 | X23761904Y65685953D01* 225 | X23809523Y65495477D01* 226 | X23904761Y65400239D01* 227 | X24000000Y65352620D01* 228 | X24190476Y65352620D01* 229 | X24285714Y65400239D01* 230 | X24380952Y65495477D01* 231 | X24428571Y65685953D01* 232 | X24428571Y66019286D01* 233 | X24380952Y66209762D01* 234 | X24285714Y66305000D01* 235 | X24190476Y66352620D01* 236 | X23333333Y65352620D02* 237 | X23333333Y66352620D01* 238 | X23333333Y65876429D02* 239 | X22761904Y65876429D01* 240 | X22761904Y65352620D02* 241 | X22761904Y66352620D01* 242 | X21809523Y65352620D02* 243 | X22285714Y65352620D01* 244 | X22285714Y66352620D01* 245 | X39880952Y63361667D02* 246 | X39928571Y63409286D01* 247 | X40023809Y63552143D01* 248 | X40071428Y63647381D01* 249 | X40119047Y63790239D01* 250 | X40166666Y64028334D01* 251 | X40166666Y64218810D01* 252 | X40119047Y64456905D01* 253 | X40071428Y64599762D01* 254 | X40023809Y64695000D01* 255 | X39928571Y64837858D01* 256 | X39880952Y64885477D01* 257 | X39595238Y64409286D02* 258 | X39404761Y63742620D01* 259 | X39214285Y64218810D01* 260 | X39023809Y63742620D01* 261 | X38833333Y64409286D01* 262 | X38547619Y64409286D02* 263 | X38357142Y63742620D01* 264 | X38166666Y64218810D01* 265 | X37976190Y63742620D01* 266 | X37785714Y64409286D01* 267 | X37500000Y64409286D02* 268 | X37309523Y63742620D01* 269 | X37119047Y64218810D01* 270 | X36928571Y63742620D01* 271 | X36738095Y64409286D01* 272 | X36357142Y63837858D02* 273 | X36309523Y63790239D01* 274 | X36357142Y63742620D01* 275 | X36404761Y63790239D01* 276 | X36357142Y63837858D01* 277 | X36357142Y63742620D01* 278 | X36023809Y64409286D02* 279 | X35642857Y64409286D01* 280 | X35880952Y64742620D02* 281 | X35880952Y63885477D01* 282 | X35833333Y63790239D01* 283 | X35738095Y63742620D01* 284 | X35642857Y63742620D01* 285 | X34880952Y63742620D02* 286 | X34880952Y64266429D01* 287 | X34928571Y64361667D01* 288 | X35023809Y64409286D01* 289 | X35214285Y64409286D01* 290 | X35309523Y64361667D01* 291 | X34880952Y63790239D02* 292 | X34976190Y63742620D01* 293 | X35214285Y63742620D01* 294 | X35309523Y63790239D01* 295 | X35357142Y63885477D01* 296 | X35357142Y63980715D01* 297 | X35309523Y64075953D01* 298 | X35214285Y64123572D01* 299 | X34976190Y64123572D01* 300 | X34880952Y64171191D01* 301 | X34404761Y64409286D02* 302 | X34404761Y63409286D01* 303 | X34404761Y64361667D02* 304 | X34309523Y64409286D01* 305 | X34119047Y64409286D01* 306 | X34023809Y64361667D01* 307 | X33976190Y64314048D01* 308 | X33928571Y64218810D01* 309 | X33928571Y63933096D01* 310 | X33976190Y63837858D01* 311 | X34023809Y63790239D01* 312 | X34119047Y63742620D01* 313 | X34309523Y63742620D01* 314 | X34404761Y63790239D01* 315 | X33500000Y63742620D02* 316 | X33500000Y64409286D01* 317 | X33500000Y64218810D02* 318 | X33452380Y64314048D01* 319 | X33404761Y64361667D01* 320 | X33309523Y64409286D01* 321 | X33214285Y64409286D01* 322 | X32880952Y63837858D02* 323 | X32833333Y63790239D01* 324 | X32880952Y63742620D01* 325 | X32928571Y63790239D01* 326 | X32880952Y63837858D01* 327 | X32880952Y63742620D01* 328 | X32261904Y63742620D02* 329 | X32357142Y63790239D01* 330 | X32404761Y63837858D01* 331 | X32452380Y63933096D01* 332 | X32452380Y64218810D01* 333 | X32404761Y64314048D01* 334 | X32357142Y64361667D01* 335 | X32261904Y64409286D01* 336 | X32119047Y64409286D01* 337 | X32023809Y64361667D01* 338 | X31976190Y64314048D01* 339 | X31928571Y64218810D01* 340 | X31928571Y63933096D01* 341 | X31976190Y63837858D01* 342 | X32023809Y63790239D01* 343 | X32119047Y63742620D01* 344 | X32261904Y63742620D01* 345 | X31500000Y63742620D02* 346 | X31500000Y64409286D01* 347 | X31500000Y64218810D02* 348 | X31452380Y64314048D01* 349 | X31404761Y64361667D01* 350 | X31309523Y64409286D01* 351 | X31214285Y64409286D01* 352 | X30452380Y64409286D02* 353 | X30452380Y63599762D01* 354 | X30500000Y63504524D01* 355 | X30547619Y63456905D01* 356 | X30642857Y63409286D01* 357 | X30785714Y63409286D01* 358 | X30880952Y63456905D01* 359 | X30452380Y63790239D02* 360 | X30547619Y63742620D01* 361 | X30738095Y63742620D01* 362 | X30833333Y63790239D01* 363 | X30880952Y63837858D01* 364 | X30928571Y63933096D01* 365 | X30928571Y64218810D01* 366 | X30880952Y64314048D01* 367 | X30833333Y64361667D01* 368 | X30738095Y64409286D01* 369 | X30547619Y64409286D01* 370 | X30452380Y64361667D01* 371 | X29261904Y64790239D02* 372 | X30119047Y63504524D01* 373 | X28738095Y64742620D02* 374 | X28547619Y64742620D01* 375 | X28452380Y64695000D01* 376 | X28357142Y64599762D01* 377 | X28309523Y64409286D01* 378 | X28309523Y64075953D01* 379 | X28357142Y63885477D01* 380 | X28452380Y63790239D01* 381 | X28547619Y63742620D01* 382 | X28738095Y63742620D01* 383 | X28833333Y63790239D01* 384 | X28928571Y63885477D01* 385 | X28976190Y64075953D01* 386 | X28976190Y64409286D01* 387 | X28928571Y64599762D01* 388 | X28833333Y64695000D01* 389 | X28738095Y64742620D01* 390 | X27880952Y63742620D02* 391 | X27880952Y64742620D01* 392 | X27880952Y64266429D02* 393 | X27309523Y64266429D01* 394 | X27309523Y63742620D02* 395 | X27309523Y64742620D01* 396 | X26357142Y63742620D02* 397 | X26833333Y63742620D01* 398 | X26833333Y64742620D01* 399 | X26119047Y63361667D02* 400 | X26071428Y63409286D01* 401 | X25976190Y63552143D01* 402 | X25928571Y63647381D01* 403 | X25880952Y63790239D01* 404 | X25833333Y64028334D01* 405 | X25833333Y64218810D01* 406 | X25880952Y64456905D01* 407 | X25928571Y64599762D01* 408 | X25976190Y64695000D01* 409 | X26071428Y64837858D01* 410 | X26119047Y64885477D01* 411 | M02* 412 | -------------------------------------------------------------------------------- /sch/ethernet-to-spi/eth.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20211014) (generator kicad_symbol_editor) 2 | (symbol "75C1168" (in_bom yes) (on_board yes) 3 | (property "Reference" "U" (id 0) (at 8.89 -27.94 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "75C1168" (id 1) (at 8.89 -31.75 0) 7 | (effects (font (size 1.27 1.27))) 8 | ) 9 | (property "Footprint" "" (id 2) (at 0 0 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "" (id 3) (at 0 0 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (symbol "75C1168_0_1" 16 | (rectangle (start -6.35 12.7) (end 6.35 -29.21) 17 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 18 | (fill (type background)) 19 | ) 20 | (polyline 21 | (pts 22 | (xy -2.54 -22.86) 23 | (xy -6.35 -22.86) 24 | ) 25 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 26 | (fill (type none)) 27 | ) 28 | (polyline 29 | (pts 30 | (xy -2.54 -15.24) 31 | (xy -6.35 -15.24) 32 | ) 33 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 34 | (fill (type none)) 35 | ) 36 | (polyline 37 | (pts 38 | (xy -2.54 -5.08) 39 | (xy -6.35 -5.08) 40 | ) 41 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 42 | (fill (type none)) 43 | ) 44 | (polyline 45 | (pts 46 | (xy -2.54 3.81) 47 | (xy -6.35 3.81) 48 | ) 49 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 50 | (fill (type none)) 51 | ) 52 | (polyline 53 | (pts 54 | (xy 2.54 -24.13) 55 | (xy 6.35 -24.13) 56 | ) 57 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 58 | (fill (type none)) 59 | ) 60 | (polyline 61 | (pts 62 | (xy 2.54 -21.59) 63 | (xy 6.35 -21.59) 64 | ) 65 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 66 | (fill (type none)) 67 | ) 68 | (polyline 69 | (pts 70 | (xy 2.54 -16.51) 71 | (xy 6.35 -16.51) 72 | ) 73 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 74 | (fill (type none)) 75 | ) 76 | (polyline 77 | (pts 78 | (xy 2.54 -13.97) 79 | (xy 6.35 -13.97) 80 | ) 81 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 82 | (fill (type none)) 83 | ) 84 | (polyline 85 | (pts 86 | (xy 2.54 -12.7) 87 | (xy 2.54 -17.78) 88 | ) 89 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 90 | (fill (type none)) 91 | ) 92 | (polyline 93 | (pts 94 | (xy 2.54 -6.35) 95 | (xy 6.35 -6.35) 96 | ) 97 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 98 | (fill (type none)) 99 | ) 100 | (polyline 101 | (pts 102 | (xy 2.54 -3.81) 103 | (xy 6.35 -3.81) 104 | ) 105 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 106 | (fill (type none)) 107 | ) 108 | (polyline 109 | (pts 110 | (xy 2.54 2.54) 111 | (xy 6.35 2.54) 112 | ) 113 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 114 | (fill (type none)) 115 | ) 116 | (polyline 117 | (pts 118 | (xy 2.54 5.08) 119 | (xy 6.35 5.08) 120 | ) 121 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 122 | (fill (type none)) 123 | ) 124 | (polyline 125 | (pts 126 | (xy 2.54 6.35) 127 | (xy 2.54 1.27) 128 | ) 129 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 130 | (fill (type none)) 131 | ) 132 | (polyline 133 | (pts 134 | (xy 0 -13.97) 135 | (xy 0 -10.16) 136 | (xy -6.35 -10.16) 137 | ) 138 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 139 | (fill (type none)) 140 | ) 141 | (polyline 142 | (pts 143 | (xy 0 5.08) 144 | (xy 0 8.89) 145 | (xy -6.35 8.89) 146 | ) 147 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 148 | (fill (type none)) 149 | ) 150 | (polyline 151 | (pts 152 | (xy -2.54 -22.86) 153 | (xy 2.54 -20.32) 154 | (xy 2.54 -25.4) 155 | (xy -2.54 -22.86) 156 | ) 157 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 158 | (fill (type none)) 159 | ) 160 | (polyline 161 | (pts 162 | (xy -2.54 -12.7) 163 | (xy -2.54 -17.78) 164 | (xy 2.54 -15.24) 165 | (xy -2.54 -12.7) 166 | ) 167 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 168 | (fill (type none)) 169 | ) 170 | (polyline 171 | (pts 172 | (xy -2.54 6.35) 173 | (xy -2.54 1.27) 174 | (xy 2.54 3.81) 175 | (xy -2.54 6.35) 176 | ) 177 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 178 | (fill (type none)) 179 | ) 180 | (polyline 181 | (pts 182 | (xy 2.54 -2.54) 183 | (xy 2.54 -7.62) 184 | (xy -2.54 -5.08) 185 | (xy 2.54 -2.54) 186 | ) 187 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 188 | (fill (type none)) 189 | ) 190 | ) 191 | (symbol "75C1168_1_1" 192 | (pin input inverted (at 8.89 -6.35 180) (length 2.54) 193 | (name "1B" (effects (font (size 1.27 1.27)))) 194 | (number "1" (effects (font (size 1.27 1.27)))) 195 | ) 196 | (pin output line (at 8.89 -13.97 180) (length 2.54) 197 | (name "2Y" (effects (font (size 1.27 1.27)))) 198 | (number "10" (effects (font (size 1.27 1.27)))) 199 | ) 200 | (pin output inverted (at 8.89 -16.51 180) (length 2.54) 201 | (name "2Z" (effects (font (size 1.27 1.27)))) 202 | (number "11" (effects (font (size 1.27 1.27)))) 203 | ) 204 | (pin input line (at -8.89 -10.16 0) (length 2.54) 205 | (name "2DE" (effects (font (size 1.27 1.27)))) 206 | (number "12" (effects (font (size 1.27 1.27)))) 207 | ) 208 | (pin output inverted (at 8.89 2.54 180) (length 2.54) 209 | (name "1Z" (effects (font (size 1.27 1.27)))) 210 | (number "13" (effects (font (size 1.27 1.27)))) 211 | ) 212 | (pin output line (at 8.89 5.08 180) (length 2.54) 213 | (name "1Y" (effects (font (size 1.27 1.27)))) 214 | (number "14" (effects (font (size 1.27 1.27)))) 215 | ) 216 | (pin input line (at -8.89 3.81 0) (length 2.54) 217 | (name "1D" (effects (font (size 1.27 1.27)))) 218 | (number "15" (effects (font (size 1.27 1.27)))) 219 | ) 220 | (pin power_in line (at 0 15.24 270) (length 2.54) 221 | (name "VCC" (effects (font (size 1.27 1.27)))) 222 | (number "16" (effects (font (size 1.27 1.27)))) 223 | ) 224 | (pin input line (at 8.89 -3.81 180) (length 2.54) 225 | (name "1A" (effects (font (size 1.27 1.27)))) 226 | (number "2" (effects (font (size 1.27 1.27)))) 227 | ) 228 | (pin output line (at -8.89 -5.08 0) (length 2.54) 229 | (name "1R" (effects (font (size 1.27 1.27)))) 230 | (number "3" (effects (font (size 1.27 1.27)))) 231 | ) 232 | (pin input line (at -8.89 8.89 0) (length 2.54) 233 | (name "1DE" (effects (font (size 1.27 1.27)))) 234 | (number "4" (effects (font (size 1.27 1.27)))) 235 | ) 236 | (pin output line (at -8.89 -22.86 0) (length 2.54) 237 | (name "2R" (effects (font (size 1.27 1.27)))) 238 | (number "5" (effects (font (size 1.27 1.27)))) 239 | ) 240 | (pin input line (at 8.89 -21.59 180) (length 2.54) 241 | (name "2A" (effects (font (size 1.27 1.27)))) 242 | (number "6" (effects (font (size 1.27 1.27)))) 243 | ) 244 | (pin input inverted (at 8.89 -24.13 180) (length 2.54) 245 | (name "2B" (effects (font (size 1.27 1.27)))) 246 | (number "7" (effects (font (size 1.27 1.27)))) 247 | ) 248 | (pin power_in line (at 0 -31.75 90) (length 2.54) 249 | (name "GND" (effects (font (size 1.27 1.27)))) 250 | (number "8" (effects (font (size 1.27 1.27)))) 251 | ) 252 | (pin input line (at -8.89 -15.24 0) (length 2.54) 253 | (name "2D" (effects (font (size 1.27 1.27)))) 254 | (number "9" (effects (font (size 1.27 1.27)))) 255 | ) 256 | ) 257 | ) 258 | (symbol "G8X-188S7-BP" (in_bom yes) (on_board yes) 259 | (property "Reference" "J" (id 0) (at 0 22.86 0) 260 | (effects (font (size 1.27 1.27))) 261 | ) 262 | (property "Value" "G8X-188S7-BP" (id 1) (at 0 20.32 0) 263 | (effects (font (size 1.27 1.27))) 264 | ) 265 | (property "Footprint" "eth:G8X-188S7-BP" (id 2) (at 0 0 0) 266 | (effects (font (size 1.27 1.27)) hide) 267 | ) 268 | (property "Datasheet" "https://www.kycon.com/Pub_Eng_Draw/G8X-188S7-BP.pdf" (id 3) (at 0 0 0) 269 | (effects (font (size 1.27 1.27)) hide) 270 | ) 271 | (symbol "G8X-188S7-BP_0_1" 272 | (rectangle (start 13.97 15.24) (end -13.97 -22.86) 273 | (stroke (width 0.1524) (type default) (color 0 0 0 0)) 274 | (fill (type none)) 275 | ) 276 | ) 277 | (symbol "G8X-188S7-BP_1_1" 278 | (pin input line (at 16.51 11.43 180) (length 2.54) 279 | (name "TD+" (effects (font (size 1.27 1.27)))) 280 | (number "1" (effects (font (size 1.27 1.27)))) 281 | ) 282 | (pin output line (at 16.51 -8.89 180) (length 2.54) 283 | (name "VC-" (effects (font (size 1.27 1.27)))) 284 | (number "10" (effects (font (size 1.27 1.27)))) 285 | ) 286 | (pin free line (at 0 -25.4 90) (length 2.54) 287 | (name "shield" (effects (font (size 1.27 1.27)))) 288 | (number "11" (effects (font (size 1.27 1.27)))) 289 | ) 290 | (pin input line (at 16.51 6.35 180) (length 2.54) 291 | (name "TD-" (effects (font (size 1.27 1.27)))) 292 | (number "2" (effects (font (size 1.27 1.27)))) 293 | ) 294 | (pin passive line (at 16.51 8.89 180) (length 2.54) 295 | (name "CT" (effects (font (size 1.27 1.27)))) 296 | (number "3" (effects (font (size 1.27 1.27)))) 297 | ) 298 | (pin passive line (at 16.51 -12.7 180) (length 2.54) 299 | (name "" (effects (font (size 1.27 1.27)))) 300 | (number "4" (effects (font (size 1.27 1.27)))) 301 | ) 302 | (pin passive line (at 16.51 -15.24 180) (length 2.54) 303 | (name "" (effects (font (size 1.27 1.27)))) 304 | (number "5" (effects (font (size 1.27 1.27)))) 305 | ) 306 | (pin power_in line (at 16.51 -20.32 180) (length 2.54) 307 | (name "GND" (effects (font (size 1.27 1.27)))) 308 | (number "6" (effects (font (size 1.27 1.27)))) 309 | ) 310 | (pin output line (at 16.51 1.27 180) (length 2.54) 311 | (name "RD+" (effects (font (size 1.27 1.27)))) 312 | (number "7" (effects (font (size 1.27 1.27)))) 313 | ) 314 | (pin output line (at 16.51 -1.27 180) (length 2.54) 315 | (name "RD-" (effects (font (size 1.27 1.27)))) 316 | (number "8" (effects (font (size 1.27 1.27)))) 317 | ) 318 | (pin output line (at 16.51 -6.35 180) (length 2.54) 319 | (name "VC+" (effects (font (size 1.27 1.27)))) 320 | (number "9" (effects (font (size 1.27 1.27)))) 321 | ) 322 | ) 323 | ) 324 | ) 325 | -------------------------------------------------------------------------------- /sch/transmitter/transmitter.kicad_pro: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "design_settings": { 4 | "defaults": { 5 | "board_outline_line_width": 0.09999999999999999, 6 | "copper_line_width": 0.19999999999999998, 7 | "copper_text_italic": false, 8 | "copper_text_size_h": 1.5, 9 | "copper_text_size_v": 1.5, 10 | "copper_text_thickness": 0.3, 11 | "copper_text_upright": false, 12 | "courtyard_line_width": 0.049999999999999996, 13 | "dimension_precision": 4, 14 | "dimension_units": 3, 15 | "dimensions": { 16 | "arrow_length": 1270000, 17 | "extension_offset": 500000, 18 | "keep_text_aligned": true, 19 | "suppress_zeroes": false, 20 | "text_position": 0, 21 | "units_format": 1 22 | }, 23 | "fab_line_width": 0.09999999999999999, 24 | "fab_text_italic": false, 25 | "fab_text_size_h": 1.0, 26 | "fab_text_size_v": 1.0, 27 | "fab_text_thickness": 0.15, 28 | "fab_text_upright": false, 29 | "other_line_width": 0.15, 30 | "other_text_italic": false, 31 | "other_text_size_h": 1.0, 32 | "other_text_size_v": 1.0, 33 | "other_text_thickness": 0.15, 34 | "other_text_upright": false, 35 | "pads": { 36 | "drill": 0.762, 37 | "height": 1.524, 38 | "width": 1.524 39 | }, 40 | "silk_line_width": 0.15, 41 | "silk_text_italic": false, 42 | "silk_text_size_h": 1.0, 43 | "silk_text_size_v": 1.0, 44 | "silk_text_thickness": 0.15, 45 | "silk_text_upright": false, 46 | "zones": { 47 | "45_degree_only": false, 48 | "min_clearance": 0.508 49 | } 50 | }, 51 | "diff_pair_dimensions": [ 52 | { 53 | "gap": 0.0, 54 | "via_gap": 0.0, 55 | "width": 0.0 56 | } 57 | ], 58 | "drc_exclusions": [], 59 | "meta": { 60 | "version": 2 61 | }, 62 | "rule_severities": { 63 | "annular_width": "error", 64 | "clearance": "error", 65 | "copper_edge_clearance": "error", 66 | "courtyards_overlap": "error", 67 | "diff_pair_gap_out_of_range": "error", 68 | "diff_pair_uncoupled_length_too_long": "error", 69 | "drill_out_of_range": "error", 70 | "duplicate_footprints": "warning", 71 | "extra_footprint": "warning", 72 | "footprint_type_mismatch": "error", 73 | "hole_clearance": "error", 74 | "hole_near_hole": "error", 75 | "invalid_outline": "error", 76 | "item_on_disabled_layer": "error", 77 | "items_not_allowed": "error", 78 | "length_out_of_range": "error", 79 | "malformed_courtyard": "error", 80 | "microvia_drill_out_of_range": "error", 81 | "missing_courtyard": "ignore", 82 | "missing_footprint": "warning", 83 | "net_conflict": "warning", 84 | "npth_inside_courtyard": "ignore", 85 | "padstack": "error", 86 | "pth_inside_courtyard": "ignore", 87 | "shorting_items": "error", 88 | "silk_over_copper": "warning", 89 | "silk_overlap": "warning", 90 | "skew_out_of_range": "error", 91 | "through_hole_pad_without_hole": "error", 92 | "too_many_vias": "error", 93 | "track_dangling": "warning", 94 | "track_width": "error", 95 | "tracks_crossing": "error", 96 | "unconnected_items": "error", 97 | "unresolved_variable": "error", 98 | "via_dangling": "warning", 99 | "zone_has_empty_net": "error", 100 | "zones_intersect": "error" 101 | }, 102 | "rules": { 103 | "allow_blind_buried_vias": false, 104 | "allow_microvias": false, 105 | "max_error": 0.005, 106 | "min_clearance": 0.0, 107 | "min_copper_edge_clearance": 0.0, 108 | "min_hole_clearance": 0.25, 109 | "min_hole_to_hole": 0.25, 110 | "min_microvia_diameter": 0.19999999999999998, 111 | "min_microvia_drill": 0.09999999999999999, 112 | "min_silk_clearance": 0.0, 113 | "min_through_hole_diameter": 0.5, 114 | "min_track_width": 0.35, 115 | "min_via_annular_width": 0.049999999999999996, 116 | "min_via_diameter": 0.5, 117 | "solder_mask_clearance": 0.0, 118 | "solder_mask_min_width": 0.0, 119 | "use_height_for_length_calcs": true 120 | }, 121 | "track_widths": [ 122 | 0.0, 123 | 0.35, 124 | 0.4, 125 | 0.5, 126 | 0.6 127 | ], 128 | "via_dimensions": [ 129 | { 130 | "diameter": 0.0, 131 | "drill": 0.0 132 | } 133 | ], 134 | "zones_allow_external_fillets": false, 135 | "zones_use_no_outline": true 136 | }, 137 | "layer_presets": [] 138 | }, 139 | "boards": [], 140 | "cvpcb": { 141 | "equivalence_files": [] 142 | }, 143 | "erc": { 144 | "erc_exclusions": [], 145 | "meta": { 146 | "version": 0 147 | }, 148 | "pin_map": [ 149 | [ 150 | 0, 151 | 0, 152 | 0, 153 | 0, 154 | 0, 155 | 0, 156 | 1, 157 | 0, 158 | 0, 159 | 0, 160 | 0, 161 | 2 162 | ], 163 | [ 164 | 0, 165 | 2, 166 | 0, 167 | 1, 168 | 0, 169 | 0, 170 | 1, 171 | 0, 172 | 2, 173 | 2, 174 | 2, 175 | 2 176 | ], 177 | [ 178 | 0, 179 | 0, 180 | 0, 181 | 0, 182 | 0, 183 | 0, 184 | 1, 185 | 0, 186 | 1, 187 | 0, 188 | 1, 189 | 2 190 | ], 191 | [ 192 | 0, 193 | 1, 194 | 0, 195 | 0, 196 | 0, 197 | 0, 198 | 1, 199 | 1, 200 | 2, 201 | 1, 202 | 1, 203 | 2 204 | ], 205 | [ 206 | 0, 207 | 0, 208 | 0, 209 | 0, 210 | 0, 211 | 0, 212 | 1, 213 | 0, 214 | 0, 215 | 0, 216 | 0, 217 | 2 218 | ], 219 | [ 220 | 0, 221 | 0, 222 | 0, 223 | 0, 224 | 0, 225 | 0, 226 | 0, 227 | 0, 228 | 0, 229 | 0, 230 | 0, 231 | 2 232 | ], 233 | [ 234 | 1, 235 | 1, 236 | 1, 237 | 1, 238 | 1, 239 | 0, 240 | 1, 241 | 1, 242 | 1, 243 | 1, 244 | 1, 245 | 2 246 | ], 247 | [ 248 | 0, 249 | 0, 250 | 0, 251 | 1, 252 | 0, 253 | 0, 254 | 1, 255 | 0, 256 | 0, 257 | 0, 258 | 0, 259 | 2 260 | ], 261 | [ 262 | 0, 263 | 2, 264 | 1, 265 | 2, 266 | 0, 267 | 0, 268 | 1, 269 | 0, 270 | 2, 271 | 2, 272 | 2, 273 | 2 274 | ], 275 | [ 276 | 0, 277 | 2, 278 | 0, 279 | 1, 280 | 0, 281 | 0, 282 | 1, 283 | 0, 284 | 2, 285 | 0, 286 | 0, 287 | 2 288 | ], 289 | [ 290 | 0, 291 | 2, 292 | 1, 293 | 1, 294 | 0, 295 | 0, 296 | 1, 297 | 0, 298 | 2, 299 | 0, 300 | 0, 301 | 2 302 | ], 303 | [ 304 | 2, 305 | 2, 306 | 2, 307 | 2, 308 | 2, 309 | 2, 310 | 2, 311 | 2, 312 | 2, 313 | 2, 314 | 2, 315 | 2 316 | ] 317 | ], 318 | "rule_severities": { 319 | "bus_definition_conflict": "error", 320 | "bus_entry_needed": "error", 321 | "bus_label_syntax": "error", 322 | "bus_to_bus_conflict": "error", 323 | "bus_to_net_conflict": "error", 324 | "different_unit_footprint": "error", 325 | "different_unit_net": "error", 326 | "duplicate_reference": "error", 327 | "duplicate_sheet_names": "error", 328 | "extra_units": "error", 329 | "global_label_dangling": "warning", 330 | "hier_label_mismatch": "error", 331 | "label_dangling": "error", 332 | "lib_symbol_issues": "warning", 333 | "multiple_net_names": "warning", 334 | "net_not_bus_member": "warning", 335 | "no_connect_connected": "warning", 336 | "no_connect_dangling": "warning", 337 | "pin_not_connected": "error", 338 | "pin_not_driven": "error", 339 | "pin_to_pin": "warning", 340 | "power_pin_not_driven": "error", 341 | "similar_labels": "warning", 342 | "unannotated": "error", 343 | "unit_value_mismatch": "error", 344 | "unresolved_variable": "error", 345 | "wire_dangling": "error" 346 | } 347 | }, 348 | "libraries": { 349 | "pinned_footprint_libs": [], 350 | "pinned_symbol_libs": [] 351 | }, 352 | "meta": { 353 | "filename": "transmitter.kicad_pro", 354 | "version": 1 355 | }, 356 | "net_settings": { 357 | "classes": [ 358 | { 359 | "bus_width": 12.0, 360 | "clearance": 0.2, 361 | "diff_pair_gap": 0.25, 362 | "diff_pair_via_gap": 0.25, 363 | "diff_pair_width": 0.2, 364 | "line_style": 0, 365 | "microvia_diameter": 0.3, 366 | "microvia_drill": 0.1, 367 | "name": "Default", 368 | "pcb_color": "rgba(0, 0, 0, 0.000)", 369 | "schematic_color": "rgba(0, 0, 0, 0.000)", 370 | "track_width": 0.4, 371 | "via_diameter": 1.0, 372 | "via_drill": 0.6, 373 | "wire_width": 6.0 374 | }, 375 | { 376 | "bus_width": 12.0, 377 | "clearance": 0.25, 378 | "diff_pair_gap": 0.25, 379 | "diff_pair_via_gap": 0.25, 380 | "diff_pair_width": 0.2, 381 | "line_style": 0, 382 | "microvia_diameter": 0.3, 383 | "microvia_drill": 0.1, 384 | "name": "VCC", 385 | "nets": [ 386 | "VCC" 387 | ], 388 | "pcb_color": "rgba(0, 0, 0, 0.000)", 389 | "schematic_color": "rgba(0, 0, 0, 0.000)", 390 | "track_width": 0.6, 391 | "via_diameter": 1.0, 392 | "via_drill": 0.6, 393 | "wire_width": 6.0 394 | } 395 | ], 396 | "meta": { 397 | "version": 2 398 | }, 399 | "net_colors": null 400 | }, 401 | "pcbnew": { 402 | "last_paths": { 403 | "gencad": "", 404 | "idf": "", 405 | "netlist": "", 406 | "specctra_dsn": "", 407 | "step": "", 408 | "vrml": "" 409 | }, 410 | "page_layout_descr_file": "" 411 | }, 412 | "schematic": { 413 | "annotate_start_num": 0, 414 | "drawing": { 415 | "default_line_thickness": 6.0, 416 | "default_text_size": 50.0, 417 | "field_names": [], 418 | "intersheets_ref_own_page": false, 419 | "intersheets_ref_prefix": "", 420 | "intersheets_ref_short": false, 421 | "intersheets_ref_show": false, 422 | "intersheets_ref_suffix": "", 423 | "junction_size_choice": 3, 424 | "label_size_ratio": 0.375, 425 | "pin_symbol_size": 25.0, 426 | "text_offset_ratio": 0.15 427 | }, 428 | "legacy_lib_dir": "", 429 | "legacy_lib_list": [], 430 | "meta": { 431 | "version": 1 432 | }, 433 | "net_format_name": "", 434 | "ngspice": { 435 | "fix_include_paths": true, 436 | "fix_passive_vals": false, 437 | "meta": { 438 | "version": 0 439 | }, 440 | "model_mode": 0, 441 | "workbook_filename": "" 442 | }, 443 | "page_layout_descr_file": "", 444 | "plot_directory": "", 445 | "spice_adjust_passive_values": false, 446 | "spice_external_command": "spice \"%I\"", 447 | "subpart_first_id": 65, 448 | "subpart_id_separator": 0 449 | }, 450 | "sheets": [ 451 | [ 452 | "2d881bd6-028e-436d-85d8-b75586cf7fc6", 453 | "" 454 | ] 455 | ], 456 | "text_variables": {} 457 | } 458 | -------------------------------------------------------------------------------- /sch/shield/shield.kicad_pro: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "design_settings": { 4 | "defaults": { 5 | "board_outline_line_width": 0.09999999999999999, 6 | "copper_line_width": 0.19999999999999998, 7 | "copper_text_italic": false, 8 | "copper_text_size_h": 1.5, 9 | "copper_text_size_v": 1.5, 10 | "copper_text_thickness": 0.3, 11 | "copper_text_upright": false, 12 | "courtyard_line_width": 0.049999999999999996, 13 | "dimension_precision": 4, 14 | "dimension_units": 3, 15 | "dimensions": { 16 | "arrow_length": 1270000, 17 | "extension_offset": 500000, 18 | "keep_text_aligned": true, 19 | "suppress_zeroes": false, 20 | "text_position": 0, 21 | "units_format": 1 22 | }, 23 | "fab_line_width": 0.09999999999999999, 24 | "fab_text_italic": false, 25 | "fab_text_size_h": 1.0, 26 | "fab_text_size_v": 1.0, 27 | "fab_text_thickness": 0.15, 28 | "fab_text_upright": false, 29 | "other_line_width": 0.15, 30 | "other_text_italic": false, 31 | "other_text_size_h": 1.0, 32 | "other_text_size_v": 1.0, 33 | "other_text_thickness": 0.15, 34 | "other_text_upright": false, 35 | "pads": { 36 | "drill": 0.762, 37 | "height": 1.524, 38 | "width": 1.524 39 | }, 40 | "silk_line_width": 0.15, 41 | "silk_text_italic": false, 42 | "silk_text_size_h": 1.0, 43 | "silk_text_size_v": 1.0, 44 | "silk_text_thickness": 0.15, 45 | "silk_text_upright": false, 46 | "zones": { 47 | "45_degree_only": false, 48 | "min_clearance": 0.508 49 | } 50 | }, 51 | "diff_pair_dimensions": [ 52 | { 53 | "gap": 0.0, 54 | "via_gap": 0.0, 55 | "width": 0.0 56 | } 57 | ], 58 | "drc_exclusions": [], 59 | "meta": { 60 | "version": 2 61 | }, 62 | "rule_severities": { 63 | "annular_width": "error", 64 | "clearance": "error", 65 | "copper_edge_clearance": "error", 66 | "courtyards_overlap": "error", 67 | "diff_pair_gap_out_of_range": "error", 68 | "diff_pair_uncoupled_length_too_long": "error", 69 | "drill_out_of_range": "error", 70 | "duplicate_footprints": "warning", 71 | "extra_footprint": "warning", 72 | "footprint_type_mismatch": "error", 73 | "hole_clearance": "error", 74 | "hole_near_hole": "error", 75 | "invalid_outline": "error", 76 | "item_on_disabled_layer": "error", 77 | "items_not_allowed": "error", 78 | "length_out_of_range": "error", 79 | "malformed_courtyard": "error", 80 | "microvia_drill_out_of_range": "error", 81 | "missing_courtyard": "ignore", 82 | "missing_footprint": "warning", 83 | "net_conflict": "warning", 84 | "npth_inside_courtyard": "ignore", 85 | "padstack": "error", 86 | "pth_inside_courtyard": "ignore", 87 | "shorting_items": "error", 88 | "silk_over_copper": "warning", 89 | "silk_overlap": "warning", 90 | "skew_out_of_range": "error", 91 | "through_hole_pad_without_hole": "error", 92 | "too_many_vias": "error", 93 | "track_dangling": "warning", 94 | "track_width": "error", 95 | "tracks_crossing": "error", 96 | "unconnected_items": "error", 97 | "unresolved_variable": "error", 98 | "via_dangling": "warning", 99 | "zone_has_empty_net": "error", 100 | "zones_intersect": "error" 101 | }, 102 | "rules": { 103 | "allow_blind_buried_vias": false, 104 | "allow_microvias": false, 105 | "max_error": 0.005, 106 | "min_clearance": 0.127, 107 | "min_copper_edge_clearance": 0.39999999999999997, 108 | "min_hole_clearance": 0.32999999999999996, 109 | "min_hole_to_hole": 0.5, 110 | "min_microvia_diameter": 0.19999999999999998, 111 | "min_microvia_drill": 0.09999999999999999, 112 | "min_silk_clearance": 0.0, 113 | "min_through_hole_diameter": 0.19999999999999998, 114 | "min_track_width": 0.127, 115 | "min_via_annular_width": 0.13, 116 | "min_via_diameter": 0.45999999999999996, 117 | "solder_mask_clearance": 0.0, 118 | "solder_mask_min_width": 0.0, 119 | "use_height_for_length_calcs": true 120 | }, 121 | "track_widths": [ 122 | 0.0, 123 | 0.15, 124 | 0.2, 125 | 0.25, 126 | 0.3, 127 | 0.4 128 | ], 129 | "via_dimensions": [ 130 | { 131 | "diameter": 0.0, 132 | "drill": 0.0 133 | }, 134 | { 135 | "diameter": 0.46, 136 | "drill": 0.2 137 | }, 138 | { 139 | "diameter": 0.55, 140 | "drill": 0.3 141 | } 142 | ], 143 | "zones_allow_external_fillets": false, 144 | "zones_use_no_outline": true 145 | }, 146 | "layer_presets": [] 147 | }, 148 | "boards": [], 149 | "cvpcb": { 150 | "equivalence_files": [] 151 | }, 152 | "erc": { 153 | "erc_exclusions": [], 154 | "meta": { 155 | "version": 0 156 | }, 157 | "pin_map": [ 158 | [ 159 | 0, 160 | 0, 161 | 0, 162 | 0, 163 | 0, 164 | 0, 165 | 1, 166 | 0, 167 | 0, 168 | 0, 169 | 0, 170 | 2 171 | ], 172 | [ 173 | 0, 174 | 2, 175 | 0, 176 | 1, 177 | 0, 178 | 0, 179 | 1, 180 | 0, 181 | 2, 182 | 2, 183 | 2, 184 | 2 185 | ], 186 | [ 187 | 0, 188 | 0, 189 | 0, 190 | 0, 191 | 0, 192 | 0, 193 | 1, 194 | 0, 195 | 1, 196 | 0, 197 | 1, 198 | 2 199 | ], 200 | [ 201 | 0, 202 | 1, 203 | 0, 204 | 0, 205 | 0, 206 | 0, 207 | 1, 208 | 1, 209 | 2, 210 | 1, 211 | 1, 212 | 2 213 | ], 214 | [ 215 | 0, 216 | 0, 217 | 0, 218 | 0, 219 | 0, 220 | 0, 221 | 1, 222 | 0, 223 | 0, 224 | 0, 225 | 0, 226 | 2 227 | ], 228 | [ 229 | 0, 230 | 0, 231 | 0, 232 | 0, 233 | 0, 234 | 0, 235 | 0, 236 | 0, 237 | 0, 238 | 0, 239 | 0, 240 | 2 241 | ], 242 | [ 243 | 1, 244 | 1, 245 | 1, 246 | 1, 247 | 1, 248 | 0, 249 | 1, 250 | 1, 251 | 1, 252 | 1, 253 | 1, 254 | 2 255 | ], 256 | [ 257 | 0, 258 | 0, 259 | 0, 260 | 1, 261 | 0, 262 | 0, 263 | 1, 264 | 0, 265 | 0, 266 | 0, 267 | 0, 268 | 2 269 | ], 270 | [ 271 | 0, 272 | 2, 273 | 1, 274 | 2, 275 | 0, 276 | 0, 277 | 1, 278 | 0, 279 | 2, 280 | 2, 281 | 2, 282 | 2 283 | ], 284 | [ 285 | 0, 286 | 2, 287 | 0, 288 | 1, 289 | 0, 290 | 0, 291 | 1, 292 | 0, 293 | 2, 294 | 0, 295 | 0, 296 | 2 297 | ], 298 | [ 299 | 0, 300 | 2, 301 | 1, 302 | 1, 303 | 0, 304 | 0, 305 | 1, 306 | 0, 307 | 2, 308 | 0, 309 | 0, 310 | 2 311 | ], 312 | [ 313 | 2, 314 | 2, 315 | 2, 316 | 2, 317 | 2, 318 | 2, 319 | 2, 320 | 2, 321 | 2, 322 | 2, 323 | 2, 324 | 2 325 | ] 326 | ], 327 | "rule_severities": { 328 | "bus_definition_conflict": "error", 329 | "bus_entry_needed": "error", 330 | "bus_label_syntax": "error", 331 | "bus_to_bus_conflict": "error", 332 | "bus_to_net_conflict": "error", 333 | "different_unit_footprint": "error", 334 | "different_unit_net": "error", 335 | "duplicate_reference": "error", 336 | "duplicate_sheet_names": "error", 337 | "extra_units": "error", 338 | "global_label_dangling": "warning", 339 | "hier_label_mismatch": "error", 340 | "label_dangling": "error", 341 | "lib_symbol_issues": "warning", 342 | "multiple_net_names": "warning", 343 | "net_not_bus_member": "warning", 344 | "no_connect_connected": "warning", 345 | "no_connect_dangling": "warning", 346 | "pin_not_connected": "error", 347 | "pin_not_driven": "error", 348 | "pin_to_pin": "warning", 349 | "power_pin_not_driven": "error", 350 | "similar_labels": "warning", 351 | "unannotated": "error", 352 | "unit_value_mismatch": "error", 353 | "unresolved_variable": "error", 354 | "wire_dangling": "error" 355 | } 356 | }, 357 | "libraries": { 358 | "pinned_footprint_libs": [], 359 | "pinned_symbol_libs": [] 360 | }, 361 | "meta": { 362 | "filename": "shield.kicad_pro", 363 | "version": 1 364 | }, 365 | "net_settings": { 366 | "classes": [ 367 | { 368 | "bus_width": 12.0, 369 | "clearance": 0.15, 370 | "diff_pair_gap": 0.25, 371 | "diff_pair_via_gap": 0.25, 372 | "diff_pair_width": 0.2, 373 | "line_style": 0, 374 | "microvia_diameter": 0.3, 375 | "microvia_drill": 0.1, 376 | "name": "Default", 377 | "pcb_color": "rgba(0, 0, 0, 0.000)", 378 | "schematic_color": "rgba(0, 0, 0, 0.000)", 379 | "track_width": 0.15, 380 | "via_diameter": 0.55, 381 | "via_drill": 0.25, 382 | "wire_width": 6.0 383 | }, 384 | { 385 | "bus_width": 12.0, 386 | "clearance": 0.15, 387 | "diff_pair_gap": 0.25, 388 | "diff_pair_via_gap": 0.25, 389 | "diff_pair_width": 0.2, 390 | "line_style": 0, 391 | "microvia_diameter": 0.3, 392 | "microvia_drill": 0.1, 393 | "name": "power", 394 | "nets": [ 395 | "GND", 396 | "VCC" 397 | ], 398 | "pcb_color": "rgba(0, 0, 0, 0.000)", 399 | "schematic_color": "rgba(0, 0, 0, 0.000)", 400 | "track_width": 0.3, 401 | "via_diameter": 0.64, 402 | "via_drill": 0.35, 403 | "wire_width": 6.0 404 | } 405 | ], 406 | "meta": { 407 | "version": 2 408 | }, 409 | "net_colors": null 410 | }, 411 | "pcbnew": { 412 | "last_paths": { 413 | "gencad": "", 414 | "idf": "", 415 | "netlist": "", 416 | "specctra_dsn": "", 417 | "step": "", 418 | "vrml": "" 419 | }, 420 | "page_layout_descr_file": "" 421 | }, 422 | "schematic": { 423 | "annotate_start_num": 0, 424 | "drawing": { 425 | "default_line_thickness": 6.0, 426 | "default_text_size": 50.0, 427 | "field_names": [], 428 | "intersheets_ref_own_page": false, 429 | "intersheets_ref_prefix": "", 430 | "intersheets_ref_short": false, 431 | "intersheets_ref_show": false, 432 | "intersheets_ref_suffix": "", 433 | "junction_size_choice": 3, 434 | "label_size_ratio": 0.375, 435 | "pin_symbol_size": 25.0, 436 | "text_offset_ratio": 0.15 437 | }, 438 | "legacy_lib_dir": "", 439 | "legacy_lib_list": [], 440 | "meta": { 441 | "version": 1 442 | }, 443 | "net_format_name": "", 444 | "ngspice": { 445 | "fix_include_paths": true, 446 | "fix_passive_vals": false, 447 | "meta": { 448 | "version": 0 449 | }, 450 | "model_mode": 0, 451 | "workbook_filename": "" 452 | }, 453 | "page_layout_descr_file": "", 454 | "plot_directory": "", 455 | "spice_adjust_passive_values": false, 456 | "spice_external_command": "spice \"%I\"", 457 | "subpart_first_id": 65, 458 | "subpart_id_separator": 0 459 | }, 460 | "sheets": [ 461 | [ 462 | "4f47573c-8c6b-4d6c-9737-1b69846b234f", 463 | "" 464 | ] 465 | ], 466 | "text_variables": {} 467 | } 468 | -------------------------------------------------------------------------------- /sch/shield/gerber/shield-F_Mask.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,(6.0.9-0)*% 2 | %TF.CreationDate,2022-11-17T19:03:50+01:00*% 3 | %TF.ProjectId,shield,73686965-6c64-42e6-9b69-6361645f7063,1*% 4 | %TF.SameCoordinates,PX3a2c940PY82a7440*% 5 | %TF.FileFunction,Soldermask,Top*% 6 | %TF.FilePolarity,Negative*% 7 | %FSLAX46Y46*% 8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 9 | G04 Created by KiCad (PCBNEW (6.0.9-0)) date 2022-11-17 19:03:50* 10 | %MOMM*% 11 | %LPD*% 12 | G01* 13 | G04 APERTURE LIST* 14 | G04 Aperture macros list* 15 | %AMRoundRect* 16 | 0 Rectangle with rounded corners* 17 | 0 $1 Rounding radius* 18 | 0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners* 19 | 0 Add a 4 corners polygon primitive as box body* 20 | 4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0* 21 | 0 Add four circle primitives for the rounded corners* 22 | 1,1,$1+$1,$2,$3* 23 | 1,1,$1+$1,$4,$5* 24 | 1,1,$1+$1,$6,$7* 25 | 1,1,$1+$1,$8,$9* 26 | 0 Add four rect primitives between the rounded corners* 27 | 20,1,$1+$1,$2,$3,$4,$5,0* 28 | 20,1,$1+$1,$4,$5,$6,$7,0* 29 | 20,1,$1+$1,$6,$7,$8,$9,0* 30 | 20,1,$1+$1,$8,$9,$2,$3,0*% 31 | %AMFreePoly0* 32 | 4,1,22,0.550000,-0.750000,0.000000,-0.750000,0.000000,-0.745033,-0.079941,-0.743568,-0.215256,-0.701293,-0.333266,-0.622738,-0.424486,-0.514219,-0.481581,-0.384460,-0.499164,-0.250000,-0.500000,-0.250000,-0.500000,0.250000,-0.499164,0.250000,-0.499963,0.256109,-0.478152,0.396186,-0.417904,0.524511,-0.324060,0.630769,-0.204165,0.706417,-0.067858,0.745374,0.000000,0.744959,0.000000,0.750000, 33 | 0.550000,0.750000,0.550000,-0.750000,0.550000,-0.750000,$1*% 34 | %AMFreePoly1* 35 | 4,1,20,0.000000,0.744959,0.073905,0.744508,0.209726,0.703889,0.328688,0.626782,0.421226,0.519385,0.479903,0.390333,0.500000,0.250000,0.500000,-0.250000,0.499851,-0.262216,0.476331,-0.402017,0.414519,-0.529596,0.319384,-0.634700,0.198574,-0.708877,0.061801,-0.746166,0.000000,-0.745033,0.000000,-0.750000,-0.550000,-0.750000,-0.550000,0.750000,0.000000,0.750000,0.000000,0.744959, 36 | 0.000000,0.744959,$1*% 37 | G04 Aperture macros list end* 38 | %ADD10C,1.600000*% 39 | %ADD11C,1.500000*% 40 | %ADD12RoundRect,0.250000X0.450000X-0.262500X0.450000X0.262500X-0.450000X0.262500X-0.450000X-0.262500X0*% 41 | %ADD13RoundRect,0.100000X-0.637500X-0.100000X0.637500X-0.100000X0.637500X0.100000X-0.637500X0.100000X0*% 42 | %ADD14RoundRect,0.250000X-0.250000X-0.475000X0.250000X-0.475000X0.250000X0.475000X-0.250000X0.475000X0*% 43 | %ADD15RoundRect,0.250000X-0.475000X0.250000X-0.475000X-0.250000X0.475000X-0.250000X0.475000X0.250000X0*% 44 | %ADD16RoundRect,0.150000X-0.825000X-0.150000X0.825000X-0.150000X0.825000X0.150000X-0.825000X0.150000X0*% 45 | %ADD17RoundRect,0.250000X0.475000X-0.250000X0.475000X0.250000X-0.475000X0.250000X-0.475000X-0.250000X0*% 46 | %ADD18RoundRect,0.150000X-0.587500X-0.150000X0.587500X-0.150000X0.587500X0.150000X-0.587500X0.150000X0*% 47 | %ADD19RoundRect,0.137500X-0.662500X-0.137500X0.662500X-0.137500X0.662500X0.137500X-0.662500X0.137500X0*% 48 | %ADD20O,1.500000X2.500000*% 49 | %ADD21R,1.500000X2.500000*% 50 | %ADD22O,2.200000X3.500000*% 51 | %ADD23RoundRect,0.250000X0.262500X0.450000X-0.262500X0.450000X-0.262500X-0.450000X0.262500X-0.450000X0*% 52 | %ADD24FreePoly0,270.000000*% 53 | %ADD25R,1.500000X1.000000*% 54 | %ADD26FreePoly1,270.000000*% 55 | %ADD27RoundRect,0.250000X0.250000X0.475000X-0.250000X0.475000X-0.250000X-0.475000X0.250000X-0.475000X0*% 56 | %ADD28RoundRect,0.250000X-0.262500X-0.450000X0.262500X-0.450000X0.262500X0.450000X-0.262500X0.450000X0*% 57 | %ADD29C,2.400000*% 58 | %ADD30C,1.400000*% 59 | %ADD31C,1.300000*% 60 | %ADD32C,1.524000*% 61 | %ADD33RoundRect,0.250000X0.325000X1.100000X-0.325000X1.100000X-0.325000X-1.100000X0.325000X-1.100000X0*% 62 | G04 APERTURE END LIST* 63 | D10* 64 | %TO.C,J2*% 65 | X5490000Y50370000D03* 66 | X2950000Y47830000D03* 67 | X63910000Y60530000D03* 68 | X5490000Y47830000D03* 69 | X66450000Y47830000D03* 70 | X5490000Y63070000D03* 71 | X5490000Y45290000D03* 72 | X66450000Y35130000D03* 73 | X66450000Y40210000D03* 74 | X66450000Y68150000D03* 75 | X2950000Y70690000D03* 76 | X2950000Y68150000D03* 77 | %TD*% 78 | D11* 79 | %TO.C,TP11*% 80 | X66000000Y3000000D03* 81 | %TD*% 82 | %TO.C,TP10*% 83 | X58000000Y72000000D03* 84 | %TD*% 85 | %TO.C,TP9*% 86 | X3000000Y14000000D03* 87 | %TD*% 88 | %TO.C,TP6*% 89 | X8700000Y57700000D03* 90 | %TD*% 91 | D12* 92 | %TO.C,R3*% 93 | X16050000Y36687500D03* 94 | X16050000Y38512500D03* 95 | %TD*% 96 | D13* 97 | %TO.C,U4*% 98 | X50687500Y62650000D03* 99 | X50687500Y62000000D03* 100 | X50687500Y61350000D03* 101 | X50687500Y60700000D03* 102 | X50687500Y60050000D03* 103 | X50687500Y59400000D03* 104 | X50687500Y58750000D03* 105 | X56412500Y58750000D03* 106 | X56412500Y59400000D03* 107 | X56412500Y60050000D03* 108 | X56412500Y60700000D03* 109 | X56412500Y61350000D03* 110 | X56412500Y62000000D03* 111 | X56412500Y62650000D03* 112 | %TD*% 113 | D12* 114 | %TO.C,R10*% 115 | X24900000Y6487500D03* 116 | X24900000Y8312500D03* 117 | %TD*% 118 | D14* 119 | %TO.C,C18*% 120 | X16550000Y66200000D03* 121 | X18450000Y66200000D03* 122 | %TD*% 123 | D15* 124 | %TO.C,C14*% 125 | X18150000Y38550000D03* 126 | X18150000Y36650000D03* 127 | %TD*% 128 | D16* 129 | %TO.C,U8*% 130 | X11725000Y64110000D03* 131 | X11725000Y62840000D03* 132 | X11725000Y61570000D03* 133 | X11725000Y60300000D03* 134 | X11725000Y59030000D03* 135 | X11725000Y57760000D03* 136 | X11725000Y56490000D03* 137 | X16675000Y56490000D03* 138 | X16675000Y57760000D03* 139 | X16675000Y59030000D03* 140 | X16675000Y60300000D03* 141 | X16675000Y61570000D03* 142 | X16675000Y62840000D03* 143 | X16675000Y64110000D03* 144 | %TD*% 145 | D17* 146 | %TO.C,C9*% 147 | X49100000Y53400000D03* 148 | X49100000Y55300000D03* 149 | %TD*% 150 | D18* 151 | %TO.C,Q1*% 152 | X41762500Y43850000D03* 153 | X41762500Y41950000D03* 154 | X43637500Y42900000D03* 155 | %TD*% 156 | D14* 157 | %TO.C,C4*% 158 | X52150000Y51500000D03* 159 | X54050000Y51500000D03* 160 | %TD*% 161 | D19* 162 | %TO.C,U9*% 163 | X50750000Y13445000D03* 164 | X50750000Y12175000D03* 165 | X50750000Y10905000D03* 166 | X50750000Y9635000D03* 167 | X50750000Y8365000D03* 168 | X50750000Y7095000D03* 169 | X50750000Y5825000D03* 170 | X50750000Y4555000D03* 171 | X57250000Y4555000D03* 172 | X57250000Y5825000D03* 173 | X57250000Y7095000D03* 174 | X57250000Y8365000D03* 175 | X57250000Y9635000D03* 176 | X57250000Y10905000D03* 177 | X57250000Y12175000D03* 178 | X57250000Y13445000D03* 179 | %TD*% 180 | D13* 181 | %TO.C,U2*% 182 | X24737500Y39150000D03* 183 | X24737500Y38500000D03* 184 | X24737500Y37850000D03* 185 | X24737500Y37200000D03* 186 | X24737500Y36550000D03* 187 | X24737500Y35900000D03* 188 | X24737500Y35250000D03* 189 | X30462500Y35250000D03* 190 | X30462500Y35900000D03* 191 | X30462500Y36550000D03* 192 | X30462500Y37200000D03* 193 | X30462500Y37850000D03* 194 | X30462500Y38500000D03* 195 | X30462500Y39150000D03* 196 | %TD*% 197 | D17* 198 | %TO.C,C2*% 199 | X36400000Y26850000D03* 200 | X36400000Y28750000D03* 201 | %TD*% 202 | D16* 203 | %TO.C,U5*% 204 | X16825000Y27510000D03* 205 | X16825000Y26240000D03* 206 | X16825000Y24970000D03* 207 | X16825000Y23700000D03* 208 | X16825000Y22430000D03* 209 | X16825000Y21160000D03* 210 | X16825000Y19890000D03* 211 | X21775000Y19890000D03* 212 | X21775000Y21160000D03* 213 | X21775000Y22430000D03* 214 | X21775000Y23700000D03* 215 | X21775000Y24970000D03* 216 | X21775000Y26240000D03* 217 | X21775000Y27510000D03* 218 | %TD*% 219 | D12* 220 | %TO.C,R2*% 221 | X38800000Y23887500D03* 222 | X38800000Y25712500D03* 223 | %TD*% 224 | D18* 225 | %TO.C,Q2*% 226 | X43062500Y56350000D03* 227 | X43062500Y54450000D03* 228 | X44937500Y55400000D03* 229 | %TD*% 230 | D14* 231 | %TO.C,C7*% 232 | X21650000Y29500000D03* 233 | X23550000Y29500000D03* 234 | %TD*% 235 | D20* 236 | %TO.C,SW1*% 237 | X9000000Y3702500D03* 238 | X7000000Y3702500D03* 239 | D21* 240 | X5000000Y3702500D03* 241 | D22* 242 | X11100000Y3702500D03* 243 | X2900000Y3702500D03* 244 | %TD*% 245 | D16* 246 | %TO.C,U1*% 247 | X47025000Y49410000D03* 248 | X47025000Y48140000D03* 249 | X47025000Y46870000D03* 250 | X47025000Y45600000D03* 251 | X47025000Y44330000D03* 252 | X47025000Y43060000D03* 253 | X47025000Y41790000D03* 254 | X51975000Y41790000D03* 255 | X51975000Y43060000D03* 256 | X51975000Y44330000D03* 257 | X51975000Y45600000D03* 258 | X51975000Y46870000D03* 259 | X51975000Y48140000D03* 260 | X51975000Y49410000D03* 261 | %TD*% 262 | D23* 263 | %TO.C,R6*% 264 | X43700000Y47400000D03* 265 | X41875000Y47400000D03* 266 | %TD*% 267 | D11* 268 | %TO.C,TP1*% 269 | X60100000Y56300000D03* 270 | %TD*% 271 | %TO.C,TP7*% 272 | X50300000Y32450000D03* 273 | %TD*% 274 | D17* 275 | %TO.C,C8*% 276 | X37600000Y41950000D03* 277 | X37600000Y43850000D03* 278 | %TD*% 279 | D13* 280 | %TO.C,U7*% 281 | X35537500Y64450000D03* 282 | X35537500Y63800000D03* 283 | X35537500Y63150000D03* 284 | X35537500Y62500000D03* 285 | X35537500Y61850000D03* 286 | X35537500Y61200000D03* 287 | X35537500Y60550000D03* 288 | X41262500Y60550000D03* 289 | X41262500Y61200000D03* 290 | X41262500Y61850000D03* 291 | X41262500Y62500000D03* 292 | X41262500Y63150000D03* 293 | X41262500Y63800000D03* 294 | X41262500Y64450000D03* 295 | %TD*% 296 | D11* 297 | %TO.C,TP3*% 298 | X39800000Y55600000D03* 299 | %TD*% 300 | D24* 301 | %TO.C,JP1*% 302 | X56500000Y45600000D03* 303 | D25* 304 | X56500000Y44300000D03* 305 | D26* 306 | X56500000Y43000000D03* 307 | %TD*% 308 | D23* 309 | %TO.C,R1*% 310 | X36312500Y24800000D03* 311 | X34487500Y24800000D03* 312 | %TD*% 313 | D14* 314 | %TO.C,C1*% 315 | X46250000Y34800000D03* 316 | X48150000Y34800000D03* 317 | %TD*% 318 | D11* 319 | %TO.C,TP2*% 320 | X42900000Y39800000D03* 321 | %TD*% 322 | D14* 323 | %TO.C,C6*% 324 | X30550000Y41100000D03* 325 | X32450000Y41100000D03* 326 | %TD*% 327 | D11* 328 | %TO.C,TP4*% 329 | X60100000Y60000000D03* 330 | %TD*% 331 | D14* 332 | %TO.C,C16*% 333 | X41350000Y66500000D03* 334 | X43250000Y66500000D03* 335 | %TD*% 336 | D27* 337 | %TO.C,C13*% 338 | X21950000Y41350000D03* 339 | X20050000Y41350000D03* 340 | %TD*% 341 | D23* 342 | %TO.C,R7*% 343 | X21912500Y39300000D03* 344 | X20087500Y39300000D03* 345 | %TD*% 346 | D27* 347 | %TO.C,C10*% 348 | X40250000Y47400000D03* 349 | X38350000Y47400000D03* 350 | %TD*% 351 | D28* 352 | %TO.C,R12*% 353 | X62337500Y11000000D03* 354 | X64162500Y11000000D03* 355 | %TD*% 356 | D12* 357 | %TO.C,R5*% 358 | X47050000Y53437500D03* 359 | X47050000Y55262500D03* 360 | %TD*% 361 | D13* 362 | %TO.C,U3*% 363 | X40337500Y33075000D03* 364 | X40337500Y32425000D03* 365 | X40337500Y31775000D03* 366 | X40337500Y31125000D03* 367 | X40337500Y30475000D03* 368 | X40337500Y29825000D03* 369 | X40337500Y29175000D03* 370 | X40337500Y28525000D03* 371 | X46062500Y28525000D03* 372 | X46062500Y29175000D03* 373 | X46062500Y29825000D03* 374 | X46062500Y30475000D03* 375 | X46062500Y31125000D03* 376 | X46062500Y31775000D03* 377 | X46062500Y32425000D03* 378 | X46062500Y33075000D03* 379 | %TD*% 380 | D11* 381 | %TO.C,TP8*% 382 | X24500000Y19650000D03* 383 | %TD*% 384 | D29* 385 | %TO.C,J1*% 386 | X42550000Y14050000D03* 387 | X26850000Y14050000D03* 388 | D30* 389 | X41485000Y8460000D03* 390 | X41485000Y6430000D03* 391 | X27915000Y8460000D03* 392 | X27915000Y6430000D03* 393 | D31* 394 | X30300000Y17350000D03* 395 | X31570000Y19890000D03* 396 | X32840000Y17350000D03* 397 | X34110000Y19890000D03* 398 | X35380000Y17350000D03* 399 | X36650000Y19890000D03* 400 | X37920000Y17350000D03* 401 | X39190000Y19890000D03* 402 | D32* 403 | X40415000Y11000000D03* 404 | X28985000Y11000000D03* 405 | %TD*% 406 | D28* 407 | %TO.C,R8*% 408 | X20087500Y37250000D03* 409 | X21912500Y37250000D03* 410 | %TD*% 411 | D17* 412 | %TO.C,C3*% 413 | X34400000Y26850000D03* 414 | X34400000Y28750000D03* 415 | %TD*% 416 | D14* 417 | %TO.C,C5*% 418 | X57300000Y15700000D03* 419 | X59200000Y15700000D03* 420 | %TD*% 421 | %TO.C,C11*% 422 | X56500000Y64600000D03* 423 | X58400000Y64600000D03* 424 | %TD*% 425 | D33* 426 | %TO.C,C17*% 427 | X5675000Y53700000D03* 428 | X2725000Y53700000D03* 429 | %TD*% 430 | D15* 431 | %TO.C,C19*% 432 | X52800000Y17450000D03* 433 | X52800000Y15550000D03* 434 | %TD*% 435 | D12* 436 | %TO.C,R11*% 437 | X50650000Y17412500D03* 438 | X50650000Y15587500D03* 439 | %TD*% 440 | D14* 441 | %TO.C,C12*% 442 | X28150000Y66500000D03* 443 | X30050000Y66500000D03* 444 | %TD*% 445 | D27* 446 | %TO.C,C15*% 447 | X21950000Y34950000D03* 448 | X20050000Y34950000D03* 449 | %TD*% 450 | %TO.C,C20*% 451 | X64200000Y13050000D03* 452 | X62300000Y13050000D03* 453 | %TD*% 454 | D18* 455 | %TO.C,Q3*% 456 | X11812500Y37350000D03* 457 | X11812500Y35450000D03* 458 | X13687500Y36400000D03* 459 | %TD*% 460 | D11* 461 | %TO.C,TP5*% 462 | X47000000Y61900000D03* 463 | %TD*% 464 | D13* 465 | %TO.C,U6*% 466 | X22337500Y64450000D03* 467 | X22337500Y63800000D03* 468 | X22337500Y63150000D03* 469 | X22337500Y62500000D03* 470 | X22337500Y61850000D03* 471 | X22337500Y61200000D03* 472 | X22337500Y60550000D03* 473 | X28062500Y60550000D03* 474 | X28062500Y61200000D03* 475 | X28062500Y61850000D03* 476 | X28062500Y62500000D03* 477 | X28062500Y63150000D03* 478 | X28062500Y63800000D03* 479 | X28062500Y64450000D03* 480 | %TD*% 481 | D12* 482 | %TO.C,R9*% 483 | X44000000Y6487500D03* 484 | X44000000Y8312500D03* 485 | %TD*% 486 | %TO.C,R4*% 487 | X39700000Y41987500D03* 488 | X39700000Y43812500D03* 489 | %TD*% 490 | M02* 491 | --------------------------------------------------------------------------------