mirror of
https://github.com/Djeeberjr/fw-anwesenheit.git
synced 2026-04-30 18:49:09 +00:00
Compare commits
95 Commits
59d87eb199
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 1731cff9c9 | |||
| 336249fd12 | |||
| 5ffeb969e2 | |||
| a4ab0bad48 | |||
| 02798d90c4 | |||
| 07d51264f9 | |||
| 6cc6df6298 | |||
| 7d78aa8c4c | |||
|
|
fb8d98da28 | ||
| 8100748f8a | |||
|
|
f22eb91b67 | ||
|
|
a04400a3a0 | ||
|
|
6f7561a295 | ||
|
|
279e2f7454 | ||
|
|
610840311f | ||
| 56d2dbfa7c | |||
| 35f12a4c45 | |||
| 7346fb42bd | |||
| c0bf8399a3 | |||
| 9852534dc6 | |||
| d63e9e964d | |||
| 16ea1db55f | |||
| a0ed04a560 | |||
|
|
4e988e8f01 | ||
| 009f6cbb2e | |||
|
|
967da9fc30 | ||
| 00cb7efedb | |||
| ebbec7885e | |||
| 7ecd2052d8 | |||
| 96512c8a12 | |||
| c3eaff03d9 | |||
| 4bf89626b9 | |||
| 7c0c0699b5 | |||
| 1ea70e4993 | |||
| 770dca5b0f | |||
| 2e75ba2908 | |||
| 141c1aa9cb | |||
|
|
4abbd844d2 | ||
| 7346b47816 | |||
| cd63dd3ee4 | |||
| f5d4ae1e05 | |||
| bd3f6731fd | |||
| 6fdcf7679f | |||
|
|
c4d6ed45f1 | ||
|
|
41adf7353d | ||
| 6421074931 | |||
| a34dc18381 | |||
| 252e63c607 | |||
| 99848f0e6d | |||
| f46cdc4d29 | |||
| a8d64f6af5 | |||
| 8fb6bac651 | |||
| 7eb18376e1 | |||
| b8bba28bda | |||
| 5c0ad18b94 | |||
| 75130e2d20 | |||
| 6b2c56f3e5 | |||
| 2980d34394 | |||
| 9b926f7a34 | |||
| f1b471c6d8 | |||
| 030a372949 | |||
| 211961a770 | |||
| dfe5197ab8 | |||
| 0f5ca88ae4 | |||
| 9dd2f88cbc | |||
| aa91d69f0b | |||
| b13ae76bc5 | |||
| 4a9ff47dcc | |||
| 92c7fec283 | |||
| 082f1faba9 | |||
| 8cbdf834a1 | |||
| 3eefcdd35a | |||
| 4531ef72ae | |||
|
|
2078a3bab0 | ||
|
|
7e59d836a1 | ||
|
|
09f21403ec | ||
|
|
db7e22f45d | ||
|
|
c91f290c31 | ||
| becdd43738 | |||
|
|
453b653ac5 | ||
| cc3605b75d | |||
| 57ccc0cc8b | |||
|
|
d90376121e | ||
| 2a81499f7c | |||
|
|
4ff8ff0f77 | ||
|
|
781d27ae48 | ||
|
|
671fb0cbdd | ||
|
|
99d9cf306e | ||
|
|
b551f4521f | ||
|
|
adcbe87bd7 | ||
|
|
d96b3ed11a | ||
|
|
dcb4b14854 | ||
| fe90ca9aa9 | |||
|
|
b031a47e85 | ||
|
|
bf59b6eed3 |
@@ -12,3 +12,7 @@ target = "riscv32imac-unknown-none-elf"
|
||||
|
||||
[unstable]
|
||||
build-std = ["alloc", "core"]
|
||||
|
||||
[env]
|
||||
WIFI_PASSWD = "hunter22"
|
||||
WIFI_SSID = "fwa"
|
||||
|
||||
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/pcb/bom/ibom.html linguist-vendored
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,2 +1,4 @@
|
||||
/target
|
||||
/build
|
||||
|
||||
pcb/fw-anwesenheit-backups
|
||||
BIN
3d_print/enclouseure_printfile.3mf
Normal file
BIN
3d_print/enclouseure_printfile.3mf
Normal file
Binary file not shown.
BIN
3d_print/enclousure_top_ffw.3mf
Normal file
BIN
3d_print/enclousure_top_ffw.3mf
Normal file
Binary file not shown.
BIN
3d_print/printfiles/fw-anwesenheit-enclousure-top.3mf
Normal file
BIN
3d_print/printfiles/fw-anwesenheit-enclousure-top.3mf
Normal file
Binary file not shown.
1013
Cargo.lock
generated
1013
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
78
Cargo.toml
78
Cargo.toml
@@ -12,61 +12,45 @@ bench = false
|
||||
|
||||
[dependencies]
|
||||
esp-bootloader-esp-idf = "0.1.0"
|
||||
embassy-net = { version = "0.7.0", features = [
|
||||
"dhcpv4",
|
||||
"medium-ethernet",
|
||||
"tcp",
|
||||
"udp",
|
||||
] }
|
||||
embedded-hal = "=1.0.0"
|
||||
embedded-io = "0.6.1"
|
||||
embedded-io-async = "0.6.1"
|
||||
esp-alloc = "0.8.0"
|
||||
esp-hal = { version = "1.0.0-beta.1", features = ["esp32c6", "unstable"] }
|
||||
smoltcp = { version = "0.12.0", default-features = false, features = [
|
||||
"medium-ethernet",
|
||||
"multicast",
|
||||
"proto-dhcpv4",
|
||||
"proto-dns",
|
||||
"proto-ipv4",
|
||||
"socket-dns",
|
||||
"socket-icmp",
|
||||
"socket-raw",
|
||||
"socket-tcp",
|
||||
"socket-udp",
|
||||
] }
|
||||
# for more networking protocol support see https://crates.io/crates/edge-net
|
||||
bleps = { git = "https://github.com/bjoernQ/bleps", package = "bleps", rev = "a5148d8ae679e021b78f53fd33afb8bb35d0b62e", features = [
|
||||
"async",
|
||||
"macros",
|
||||
] }
|
||||
esp-hal = { version = "1.0.0-rc.1", features = ["esp32c6", "unstable"] }
|
||||
esp-alloc = "0.9.0"
|
||||
esp-println = { version = "0.16.0", features = ["esp32c6", "log-04"] }
|
||||
esp-radio = { version = "0.16.0", features = ["esp32c6","esp-alloc", "wifi", "log-04", "smoltcp","unstable"]}
|
||||
esp-rtos = { version = "0.1.1", features = ["esp32c6", "embassy", "esp-radio", "esp-alloc"] }
|
||||
|
||||
critical-section = "1.2.0"
|
||||
embassy-executor = { version = "0.7.0", features = ["nightly"] }
|
||||
embassy-time = { version = "0.4.0", features = ["generic-queue-8"] }
|
||||
esp-hal-embassy = { version = "0.9.0", features = ["esp32c6"] }
|
||||
esp-wifi = { version = "0.15.0", features = [
|
||||
"wifi",
|
||||
"builtin-scheduler",
|
||||
"esp-alloc",
|
||||
"esp32c6",
|
||||
"log-04",
|
||||
] }
|
||||
log = { version = "0.4", features = ["release_max_level_info"]}
|
||||
static_cell = { version = "2.1.1", features = ["nightly"] }
|
||||
heapless = { version = "0.8.0", default-features = false }
|
||||
static_cell = { version = "2.1.0", features = ["nightly"] }
|
||||
esp-println = { version = "0.15.0", features = ["esp32c6", "log-04"] }
|
||||
log = { version = "0.4" }
|
||||
chrono = { version = "0.4.41", default-features = false }
|
||||
|
||||
embedded-hal = "1.0.0"
|
||||
embedded-io = "0.7.1"
|
||||
embedded-io-async = "0.7.0"
|
||||
embassy-executor = { version = "0.9.0", features = [] }
|
||||
embassy-time = { version = "0.5.0", features = [] }
|
||||
embassy-futures = { version = "0.1.2", features = ["log"] }
|
||||
embassy-sync = { version = "0.7.2", features = ["log"] }
|
||||
|
||||
embassy-net = { version = "0.7.0", features = [ "dhcpv4", "medium-ethernet", "tcp", "udp" ] }
|
||||
smoltcp = { version = "0.12.0", default-features = false, features = [ "medium-ethernet", "multicast", "proto-dhcpv4", "proto-dns", "proto-ipv4", "socket-dns", "socket-icmp", "socket-raw", "socket-tcp", "socket-udp" ] }
|
||||
bleps = { git = "https://github.com/bjoernQ/bleps", package = "bleps", rev = "a5148d8ae679e021b78f53fd33afb8bb35d0b62e", features = [ "async", "macros" ] }
|
||||
edge-dhcp = { version = "0.6.0", features = ["log"] }
|
||||
edge-nal = "0.5.0"
|
||||
edge-nal-embassy = { version = "0.6.0", features = ["log"] }
|
||||
picoserve = { version = "0.16.0", features = ["embassy", "log"] }
|
||||
embassy-sync = { version = "0.7.0", features = ["log"] }
|
||||
ds3231 = { version = "0.3.0", features = ["async", "temperature_f32"] }
|
||||
chrono = { version = "0.4.41", default-features = false }
|
||||
|
||||
picoserve = { git = "https://github.com/sammhicks/picoserve.git", rev = "400df53f61137e1bb2883ec610fc191bfe551a3a", features = ["embassy", "log", "json"] }
|
||||
dir-embed = "0.3.0"
|
||||
embedded-sdmmc-dev = "0.8.2"
|
||||
serde = { version = "1.0.219", default-features = false, features = ["derive", "alloc"] }
|
||||
serde_json = { version = "1.0.143", default-features = false, features = ["alloc"]}
|
||||
|
||||
ds3231 = { version = "0.3.0", features = ["async", "temperature_f32"] }
|
||||
esp-hal-smartled = { git = "https://github.com/esp-rs/esp-hal-community.git", package = "esp-hal-smartled", branch = "main", features = ["esp32c6"]}
|
||||
smart-leds = "0.4.0"
|
||||
serde = { version = "1.0.219", default-features = false, features = ["derive", "alloc"] }
|
||||
|
||||
embedded-sdmmc = "0.8.0"
|
||||
embedded-hal-bus = "0.3.0"
|
||||
thiserror = { version = "2.0.17", default-features = false }
|
||||
|
||||
[profile.dev]
|
||||
# Rust debug is too slow.
|
||||
|
||||
30
README.md
30
README.md
@@ -1,32 +1,6 @@
|
||||
# fw-anwesenheit
|
||||
|
||||
# Setup
|
||||

|
||||
|
||||
In order to use the LED we need to enable the SPI interface on the Rpi.
|
||||
You can enable it by running `sudo raspi-config`, or by manually adding `dtparam=spi=on` to `/boot/firmware/config.txt`.
|
||||
Enable PWM -> add dtoverlay=pwm to /boot/config.txt
|
||||
I²C fpr RTC `sudo raspi-config` -> interface -> enable I²C
|
||||

|
||||
|
||||
# Config
|
||||
|
||||
Flags:
|
||||
|
||||
`--error` or `-e`: Enters error state. The LED turns red and the hotspot is activated. This state gets called from systemd if the service is in a failure state.
|
||||
|
||||
Environment variables:
|
||||
|
||||
- `PM3_BIN`: Path to the pm3 binary. Seach in path if not set. Can also be set to the `pm3_mock.sh` for testing.
|
||||
- `LOG_LEVEL`: Can be set to either "debug","warn","error","trace" or "info". Defaults to "warn" in production.
|
||||
- `HTTP_PORT`: What port to listen on. Defaults to 80.
|
||||
- `HOTSPOT_IDS`: A semicolon seperated list of ids to activate the hotspot with e.g. `578B5DF2;c1532b57`.
|
||||
- `HOTSPOT_SSID`: Set the hotspot ssid. Defaults to "fwa".
|
||||
- `HOTSPOT_PW`: Set the hotspot password. Default to "a9LG2kUVrsRRVUo1". Recommended to change.
|
||||
|
||||
Systemd:
|
||||
|
||||
The service is run as a systemd service. There are two service `fwa.service` and `fwa-fail.service`. They read their config
|
||||
from a env file located at `/etc/fwa.env`. See example [env file](service/fwa.env).
|
||||
|
||||
# Building
|
||||
|
||||
Run `make package` to create `.deb` file. [Cross](https://github.com/cross-rs/cross) is used for building the rust code.
|
||||
|
||||
61
em4100_write.lua
Normal file
61
em4100_write.lua
Normal file
@@ -0,0 +1,61 @@
|
||||
local used_ids = {}
|
||||
local id_file_path = "used_ids.txt"
|
||||
|
||||
local function load_ids()
|
||||
local file = io.open(id_file_path, "r")
|
||||
if not file then return end
|
||||
for line in file:lines() do
|
||||
used_ids[line:lower()] = true
|
||||
end
|
||||
file:close()
|
||||
end
|
||||
|
||||
local function save_id(id)
|
||||
local file = io.open(id_file_path, "a")
|
||||
if file then
|
||||
file:write(id:lower() .. "\n")
|
||||
file:close()
|
||||
end
|
||||
end
|
||||
|
||||
local function gen_id()
|
||||
local id = ""
|
||||
for i = 1, 10 do
|
||||
id = id .. string.format("%x", math.random(0, 15))
|
||||
end
|
||||
return id
|
||||
end
|
||||
|
||||
local function get_new_id()
|
||||
local tries = 0
|
||||
while tries < 10000 do
|
||||
local id = gen_id()
|
||||
if not used_ids[id:lower()] then
|
||||
return id
|
||||
end
|
||||
tries = tries + 1
|
||||
end
|
||||
error("Could not generate a new unused ID after 10000 tries")
|
||||
end
|
||||
|
||||
local function write_new_card()
|
||||
local id = get_new_id()
|
||||
local cmd = string.format("lf em 410x clone --id %s", id)
|
||||
core.console(cmd)
|
||||
used_ids[id:lower()] = true
|
||||
save_id(id)
|
||||
print("Wrote new EM4100 card with ID:", id)
|
||||
end
|
||||
|
||||
local function write_new_card(id)
|
||||
local cmd = string.format("lf em 410x clone --id %s", id)
|
||||
core.console(cmd)
|
||||
used_ids[id:lower()] = true
|
||||
save_id(id)
|
||||
print("Wrote new EM4100 card with ID:", id)
|
||||
end
|
||||
|
||||
math.randomseed(os.time())
|
||||
load_ids()
|
||||
local id = get_new_id()
|
||||
write_new_card(id)
|
||||
4709
pcb/bom/ibom.html
vendored
Normal file
4709
pcb/bom/ibom.html
vendored
Normal file
File diff suppressed because one or more lines are too long
1
pcb/fabrication-toolkit-options.json
Normal file
1
pcb/fabrication-toolkit-options.json
Normal file
@@ -0,0 +1 @@
|
||||
{"ARCHIVE_NAME": "", "EXTRA_LAYERS": "", "ALL_ACTIVE_LAYERS": false, "EXTEND_EDGE_CUT": false, "ALTERNATIVE_EDGE_CUT": false, "AUTO TRANSLATE": true, "AUTO FILL": true, "EXCLUDE DNP": false}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +0,0 @@
|
||||
0
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
pcb/fw-anwesenheit-backups/fw-anwesenheit-2025-09-21_232810.zip
Normal file
BIN
pcb/fw-anwesenheit-backups/fw-anwesenheit-2025-09-21_232810.zip
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"board": {
|
||||
"active_layer": 5,
|
||||
"active_layer": 7,
|
||||
"active_layer_preset": "",
|
||||
"auto_track_width": true,
|
||||
"hidden_netclasses": [],
|
||||
@@ -45,15 +45,19 @@
|
||||
"pads",
|
||||
"zones",
|
||||
"drc_warnings",
|
||||
"drc_exclusions",
|
||||
"locked_item_shadows",
|
||||
"conflict_shadows",
|
||||
"shapes"
|
||||
],
|
||||
"visible_layers": "ffffffff_ffffffff_ffffffff_fdff502a",
|
||||
<<<<<<< HEAD
|
||||
"visible_layers": "00000000_00000000_0fffffff_fffff8aa",
|
||||
=======
|
||||
"visible_layers": "00000000_00000000_0fffffff_fffff8ab",
|
||||
>>>>>>> 15c64e4 (updated enclousure top 3mf)
|
||||
"zone_display_mode": 0
|
||||
},
|
||||
"git": {
|
||||
"repo_password": "",
|
||||
"repo_type": "",
|
||||
"repo_username": "",
|
||||
"ssh_key": ""
|
||||
|
||||
@@ -130,17 +130,17 @@
|
||||
"min_groove_width": 0.0,
|
||||
"min_hole_clearance": 0.25,
|
||||
"min_hole_to_hole": 0.2,
|
||||
"min_microvia_diameter": 0.2,
|
||||
"min_microvia_drill": 0.1,
|
||||
"min_microvia_diameter": 0.45,
|
||||
"min_microvia_drill": 0.3,
|
||||
"min_resolved_spokes": 2,
|
||||
"min_silk_clearance": 0.0,
|
||||
"min_text_height": 0.8,
|
||||
"min_text_thickness": 0.08,
|
||||
"min_through_hole_diameter": 0.1,
|
||||
"min_track_width": 0.1,
|
||||
"min_via_annular_width": 0.1,
|
||||
"min_via_diameter": 0.3,
|
||||
"solder_mask_to_copper_clearance": 0.0,
|
||||
"min_through_hole_diameter": 0.3,
|
||||
"min_track_width": 0.16,
|
||||
"min_via_annular_width": 0.075,
|
||||
"min_via_diameter": 0.45,
|
||||
"solder_mask_to_copper_clearance": 0.005,
|
||||
"use_height_for_length_calcs": true
|
||||
},
|
||||
"teardrop_options": [
|
||||
@@ -454,6 +454,7 @@
|
||||
"single_global_label": "ignore",
|
||||
"unannotated": "error",
|
||||
"unconnected_wire_endpoint": "warning",
|
||||
"undefined_netclass": "error",
|
||||
"unit_value_mismatch": "error",
|
||||
"unresolved_variable": "error",
|
||||
"wire_dangling": "error"
|
||||
@@ -503,7 +504,7 @@
|
||||
"plot": "production/",
|
||||
"pos_files": "",
|
||||
"specctra_dsn": "",
|
||||
"step": "",
|
||||
"step": "fw-anwesenheit.step",
|
||||
"svg": "",
|
||||
"vrml": ""
|
||||
},
|
||||
|
||||
@@ -3936,12 +3936,6 @@
|
||||
(color 0 0 0 0)
|
||||
(uuid "3e7af168-6284-4ec9-ac95-260d69fcd20f")
|
||||
)
|
||||
(junction
|
||||
(at 299.72 162.56)
|
||||
(diameter 0)
|
||||
(color 0 0 0 0)
|
||||
(uuid "492b1710-8e72-47b8-9b9e-a784f86c2608")
|
||||
)
|
||||
(junction
|
||||
(at 53.34 185.42)
|
||||
(diameter 0)
|
||||
@@ -4528,16 +4522,6 @@
|
||||
)
|
||||
(uuid "4d85d02a-9c72-4d94-a656-1d05aec86ee3")
|
||||
)
|
||||
(wire
|
||||
(pts
|
||||
(xy 299.72 162.56) (xy 303.53 162.56)
|
||||
)
|
||||
(stroke
|
||||
(width 0)
|
||||
(type default)
|
||||
)
|
||||
(uuid "4ffefdc2-a9c3-4086-abb3-ae378ab2df1f")
|
||||
)
|
||||
(wire
|
||||
(pts
|
||||
(xy 218.44 74.93) (xy 242.57 74.93)
|
||||
@@ -4548,16 +4532,6 @@
|
||||
)
|
||||
(uuid "50036f20-3754-48de-8632-88ef467de342")
|
||||
)
|
||||
(wire
|
||||
(pts
|
||||
(xy 299.72 162.56) (xy 299.72 166.37)
|
||||
)
|
||||
(stroke
|
||||
(width 0)
|
||||
(type default)
|
||||
)
|
||||
(uuid "523d0655-56d2-4f64-b966-25c99a91b7fb")
|
||||
)
|
||||
(wire
|
||||
(pts
|
||||
(xy 68.58 138.43) (xy 68.58 148.59)
|
||||
@@ -4728,16 +4702,6 @@
|
||||
)
|
||||
(uuid "6c5d018e-9b82-4c65-9b74-1d57a77cb626")
|
||||
)
|
||||
(wire
|
||||
(pts
|
||||
(xy 303.53 162.56) (xy 303.53 161.29)
|
||||
)
|
||||
(stroke
|
||||
(width 0)
|
||||
(type default)
|
||||
)
|
||||
(uuid "6c952eba-0ab6-4a45-991a-01629e0c24ca")
|
||||
)
|
||||
(wire
|
||||
(pts
|
||||
(xy 50.8 138.43) (xy 50.8 157.48)
|
||||
@@ -4768,16 +4732,6 @@
|
||||
)
|
||||
(uuid "6e480beb-bed3-4469-9c04-e88362eb5da0")
|
||||
)
|
||||
(wire
|
||||
(pts
|
||||
(xy 295.91 162.56) (xy 299.72 162.56)
|
||||
)
|
||||
(stroke
|
||||
(width 0)
|
||||
(type default)
|
||||
)
|
||||
(uuid "709c2438-a7c3-4516-bd9d-6a4e6619fc51")
|
||||
)
|
||||
(wire
|
||||
(pts
|
||||
(xy 68.58 162.56) (xy 69.85 162.56)
|
||||
@@ -5088,16 +5042,6 @@
|
||||
)
|
||||
(uuid "addcb1c7-4f32-4f77-9661-7b1f11ce33aa")
|
||||
)
|
||||
(wire
|
||||
(pts
|
||||
(xy 295.91 162.56) (xy 295.91 161.29)
|
||||
)
|
||||
(stroke
|
||||
(width 0)
|
||||
(type default)
|
||||
)
|
||||
(uuid "aee95639-1e84-4f42-89e2-efa88dff40ed")
|
||||
)
|
||||
(wire
|
||||
(pts
|
||||
(xy 201.93 101.6) (xy 201.93 105.41)
|
||||
@@ -11392,72 +11336,6 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
(symbol
|
||||
(lib_id "power:GND")
|
||||
(at 299.72 166.37 0)
|
||||
(unit 1)
|
||||
(exclude_from_sim no)
|
||||
(in_bom yes)
|
||||
(on_board yes)
|
||||
(dnp no)
|
||||
(uuid "e63902ed-6628-4dd3-87d3-341127834952")
|
||||
(property "Reference" "#PWR012"
|
||||
(at 299.72 172.72 0)
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
(hide yes)
|
||||
)
|
||||
)
|
||||
(property "Value" "GND"
|
||||
(at 299.7201 170.18 90)
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
(justify right)
|
||||
)
|
||||
)
|
||||
(property "Footprint" ""
|
||||
(at 299.72 166.37 0)
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
(hide yes)
|
||||
)
|
||||
)
|
||||
(property "Datasheet" ""
|
||||
(at 299.72 166.37 0)
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
(hide yes)
|
||||
)
|
||||
)
|
||||
(property "Description" "Power symbol creates a global label with name \"GND\" , ground"
|
||||
(at 299.72 166.37 0)
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
(hide yes)
|
||||
)
|
||||
)
|
||||
(pin "1"
|
||||
(uuid "eb27e73f-7ea7-4e8f-9547-d70e01277daa")
|
||||
)
|
||||
(instances
|
||||
(project "fw-anwesenheit"
|
||||
(path "/ccbf1fda-befd-42da-bcb2-5d3829184012"
|
||||
(reference "#PWR012")
|
||||
(unit 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(symbol
|
||||
(lib_id "power:GND")
|
||||
(at 17.78 181.61 0)
|
||||
@@ -11742,7 +11620,7 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
(property "Value" "100R"
|
||||
(property "Value" "150R"
|
||||
(at 140.97 91.44 90)
|
||||
(effects
|
||||
(font
|
||||
@@ -11820,7 +11698,7 @@
|
||||
(justify left)
|
||||
)
|
||||
)
|
||||
(property "Footprint" "Connector_PinSocket_2.00mm:PinSocket_1x02_P2.00mm_Vertical"
|
||||
(property "Footprint" "Connector_PinSocket_2.54mm:PinSocket_1x02_P2.54mm_Vertical"
|
||||
(at 203.835 21.59 90)
|
||||
(effects
|
||||
(font
|
||||
|
||||
122063
pcb/fw-anwesenheit.step
Normal file
122063
pcb/fw-anwesenheit.step
Normal file
File diff suppressed because it is too large
Load Diff
374733
pcb/fw-anwesenheit.stl
Normal file
374733
pcb/fw-anwesenheit.stl
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
2
pcb/fw-anwesenheit/fw-anwesenheit.kicad_pcb
Normal file
2
pcb/fw-anwesenheit/fw-anwesenheit.kicad_pcb
Normal file
@@ -0,0 +1,2 @@
|
||||
(kicad_pcb (version 20241229) (generator "pcbnew") (generator_version "9.0")
|
||||
)
|
||||
@@ -2,18 +2,18 @@
|
||||
"board": {
|
||||
"active_layer": 0,
|
||||
"active_layer_preset": "",
|
||||
"auto_track_width": false,
|
||||
"auto_track_width": true,
|
||||
"hidden_netclasses": [],
|
||||
"hidden_nets": [],
|
||||
"high_contrast_mode": 0,
|
||||
"net_color_mode": 1,
|
||||
"opacity": {
|
||||
"images": 1.0,
|
||||
"images": 0.6,
|
||||
"pads": 1.0,
|
||||
"shapes": 1.0,
|
||||
"tracks": 1.0,
|
||||
"vias": 1.0,
|
||||
"zones": 1.0
|
||||
"zones": 0.6
|
||||
},
|
||||
"selection_filter": {
|
||||
"dimensions": true,
|
||||
@@ -29,70 +29,43 @@
|
||||
"zones": true
|
||||
},
|
||||
"visible_items": [
|
||||
12
|
||||
"vias",
|
||||
"footprint_text",
|
||||
"footprint_anchors",
|
||||
"ratsnest",
|
||||
"grid",
|
||||
"footprints_front",
|
||||
"footprints_back",
|
||||
"footprint_values",
|
||||
"footprint_references",
|
||||
"tracks",
|
||||
"drc_errors",
|
||||
"drawing_sheet",
|
||||
"bitmaps",
|
||||
"pads",
|
||||
"zones",
|
||||
"drc_warnings",
|
||||
"drc_exclusions",
|
||||
"locked_item_shadows",
|
||||
"conflict_shadows",
|
||||
"shapes"
|
||||
],
|
||||
"visible_layers": "fffffff_ffffffff",
|
||||
"visible_layers": "ffffffff_ffffffff_ffffffff_ffffffff",
|
||||
"zone_display_mode": 0
|
||||
},
|
||||
"git": {
|
||||
"repo_password": "",
|
||||
"repo_type": "",
|
||||
"repo_username": "",
|
||||
"ssh_key": ""
|
||||
},
|
||||
"meta": {
|
||||
"filename": "fw-anwesenheit.kicad_prl",
|
||||
"version": 3
|
||||
"version": 5
|
||||
},
|
||||
"net_inspector_panel": {
|
||||
"col_hidden": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
"col_order": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13
|
||||
],
|
||||
"col_widths": [
|
||||
162,
|
||||
147,
|
||||
91,
|
||||
72,
|
||||
91,
|
||||
100,
|
||||
91,
|
||||
76,
|
||||
91,
|
||||
91,
|
||||
91,
|
||||
91,
|
||||
91,
|
||||
91
|
||||
],
|
||||
"col_hidden": [],
|
||||
"col_order": [],
|
||||
"col_widths": [],
|
||||
"custom_group_rules": [],
|
||||
"expanded_rows": [],
|
||||
"filter_by_net_name": true,
|
||||
@@ -103,7 +76,7 @@
|
||||
"show_unconnected_nets": false,
|
||||
"show_zero_pad_nets": false,
|
||||
"sort_ascending": true,
|
||||
"sorting_column": 0
|
||||
"sorting_column": -1
|
||||
},
|
||||
"open_jobsets": [],
|
||||
"project": {
|
||||
@@ -2,226 +2,12 @@
|
||||
"board": {
|
||||
"3dviewports": [],
|
||||
"design_settings": {
|
||||
"defaults": {
|
||||
"apply_defaults_to_fp_fields": false,
|
||||
"apply_defaults_to_fp_shapes": false,
|
||||
"apply_defaults_to_fp_text": false,
|
||||
"board_outline_line_width": 0.05,
|
||||
"copper_line_width": 0.2,
|
||||
"copper_text_italic": false,
|
||||
"copper_text_size_h": 1.5,
|
||||
"copper_text_size_v": 1.5,
|
||||
"copper_text_thickness": 0.3,
|
||||
"copper_text_upright": false,
|
||||
"courtyard_line_width": 0.05,
|
||||
"dimension_precision": 4,
|
||||
"dimension_units": 3,
|
||||
"dimensions": {
|
||||
"arrow_length": 1270000,
|
||||
"extension_offset": 500000,
|
||||
"keep_text_aligned": true,
|
||||
"suppress_zeroes": true,
|
||||
"text_position": 0,
|
||||
"units_format": 0
|
||||
},
|
||||
"fab_line_width": 0.1,
|
||||
"fab_text_italic": false,
|
||||
"fab_text_size_h": 1.0,
|
||||
"fab_text_size_v": 1.0,
|
||||
"fab_text_thickness": 0.15,
|
||||
"fab_text_upright": false,
|
||||
"other_line_width": 0.1,
|
||||
"other_text_italic": false,
|
||||
"other_text_size_h": 1.0,
|
||||
"other_text_size_v": 1.0,
|
||||
"other_text_thickness": 0.15,
|
||||
"other_text_upright": false,
|
||||
"pads": {
|
||||
"drill": 0.0,
|
||||
"height": 1.7,
|
||||
"width": 1.7
|
||||
},
|
||||
"silk_line_width": 0.1,
|
||||
"silk_text_italic": false,
|
||||
"silk_text_size_h": 1.0,
|
||||
"silk_text_size_v": 1.0,
|
||||
"silk_text_thickness": 0.1,
|
||||
"silk_text_upright": false,
|
||||
"zones": {
|
||||
"min_clearance": 0.5
|
||||
}
|
||||
},
|
||||
"diff_pair_dimensions": [
|
||||
{
|
||||
"gap": 0.0,
|
||||
"via_gap": 0.0,
|
||||
"width": 0.0
|
||||
}
|
||||
],
|
||||
"defaults": {},
|
||||
"diff_pair_dimensions": [],
|
||||
"drc_exclusions": [],
|
||||
"meta": {
|
||||
"version": 2
|
||||
},
|
||||
"rule_severities": {
|
||||
"annular_width": "error",
|
||||
"clearance": "error",
|
||||
"connection_width": "warning",
|
||||
"copper_edge_clearance": "error",
|
||||
"copper_sliver": "warning",
|
||||
"courtyards_overlap": "error",
|
||||
"creepage": "error",
|
||||
"diff_pair_gap_out_of_range": "error",
|
||||
"diff_pair_uncoupled_length_too_long": "error",
|
||||
"drill_out_of_range": "error",
|
||||
"duplicate_footprints": "warning",
|
||||
"extra_footprint": "warning",
|
||||
"footprint": "error",
|
||||
"footprint_filters_mismatch": "ignore",
|
||||
"footprint_symbol_mismatch": "warning",
|
||||
"footprint_type_mismatch": "ignore",
|
||||
"hole_clearance": "error",
|
||||
"hole_near_hole": "error",
|
||||
"hole_to_hole": "error",
|
||||
"holes_co_located": "warning",
|
||||
"invalid_outline": "error",
|
||||
"isolated_copper": "warning",
|
||||
"item_on_disabled_layer": "error",
|
||||
"items_not_allowed": "error",
|
||||
"length_out_of_range": "error",
|
||||
"lib_footprint_issues": "warning",
|
||||
"lib_footprint_mismatch": "warning",
|
||||
"malformed_courtyard": "error",
|
||||
"microvia_drill_out_of_range": "error",
|
||||
"mirrored_text_on_front_layer": "warning",
|
||||
"missing_courtyard": "ignore",
|
||||
"missing_footprint": "warning",
|
||||
"net_conflict": "warning",
|
||||
"nonmirrored_text_on_back_layer": "warning",
|
||||
"npth_inside_courtyard": "ignore",
|
||||
"padstack": "warning",
|
||||
"pth_inside_courtyard": "ignore",
|
||||
"shorting_items": "error",
|
||||
"silk_edge_clearance": "warning",
|
||||
"silk_over_copper": "warning",
|
||||
"silk_overlap": "warning",
|
||||
"skew_out_of_range": "error",
|
||||
"solder_mask_bridge": "error",
|
||||
"starved_thermal": "error",
|
||||
"text_height": "warning",
|
||||
"text_on_edge_cuts": "error",
|
||||
"text_thickness": "warning",
|
||||
"through_hole_pad_without_hole": "error",
|
||||
"too_many_vias": "error",
|
||||
"track_angle": "error",
|
||||
"track_dangling": "warning",
|
||||
"track_segment_length": "error",
|
||||
"track_width": "error",
|
||||
"tracks_crossing": "error",
|
||||
"unconnected_items": "error",
|
||||
"unresolved_variable": "error",
|
||||
"via_dangling": "warning",
|
||||
"zones_intersect": "error"
|
||||
},
|
||||
"rules": {
|
||||
"max_error": 0.005,
|
||||
"min_clearance": 0.2,
|
||||
"min_connection": 0.0,
|
||||
"min_copper_edge_clearance": 0.5,
|
||||
"min_groove_width": 0.0,
|
||||
"min_hole_clearance": 0.25,
|
||||
"min_hole_to_hole": 0.2,
|
||||
"min_microvia_diameter": 0.2,
|
||||
"min_microvia_drill": 0.1,
|
||||
"min_resolved_spokes": 2,
|
||||
"min_silk_clearance": 0.0,
|
||||
"min_text_height": 0.8,
|
||||
"min_text_thickness": 0.08,
|
||||
"min_through_hole_diameter": 0.1,
|
||||
"min_track_width": 0.1,
|
||||
"min_via_annular_width": 0.1,
|
||||
"min_via_diameter": 0.3,
|
||||
"solder_mask_to_copper_clearance": 0.0,
|
||||
"use_height_for_length_calcs": true
|
||||
},
|
||||
"teardrop_options": [
|
||||
{
|
||||
"td_onpadsmd": true,
|
||||
"td_onroundshapesonly": false,
|
||||
"td_ontrackend": false,
|
||||
"td_onviapad": true
|
||||
}
|
||||
],
|
||||
"teardrop_parameters": [
|
||||
{
|
||||
"td_allow_use_two_tracks": true,
|
||||
"td_curve_segcount": 0,
|
||||
"td_height_ratio": 1.0,
|
||||
"td_length_ratio": 0.5,
|
||||
"td_maxheight": 2.0,
|
||||
"td_maxlen": 1.0,
|
||||
"td_on_pad_in_zone": false,
|
||||
"td_target_name": "td_round_shape",
|
||||
"td_width_to_size_filter_ratio": 0.9
|
||||
},
|
||||
{
|
||||
"td_allow_use_two_tracks": true,
|
||||
"td_curve_segcount": 0,
|
||||
"td_height_ratio": 1.0,
|
||||
"td_length_ratio": 0.5,
|
||||
"td_maxheight": 2.0,
|
||||
"td_maxlen": 1.0,
|
||||
"td_on_pad_in_zone": false,
|
||||
"td_target_name": "td_rect_shape",
|
||||
"td_width_to_size_filter_ratio": 0.9
|
||||
},
|
||||
{
|
||||
"td_allow_use_two_tracks": true,
|
||||
"td_curve_segcount": 0,
|
||||
"td_height_ratio": 1.0,
|
||||
"td_length_ratio": 0.5,
|
||||
"td_maxheight": 2.0,
|
||||
"td_maxlen": 1.0,
|
||||
"td_on_pad_in_zone": false,
|
||||
"td_target_name": "td_track_end",
|
||||
"td_width_to_size_filter_ratio": 0.9
|
||||
}
|
||||
],
|
||||
"track_widths": [
|
||||
0.0
|
||||
],
|
||||
"tuning_pattern_settings": {
|
||||
"diff_pair_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 1.0
|
||||
},
|
||||
"diff_pair_skew_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 0.6
|
||||
},
|
||||
"single_track_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 0.6
|
||||
}
|
||||
},
|
||||
"via_dimensions": [
|
||||
{
|
||||
"diameter": 0.0,
|
||||
"drill": 0.0
|
||||
}
|
||||
],
|
||||
"zones_allow_external_fillets": false
|
||||
"rules": {},
|
||||
"track_widths": [],
|
||||
"via_dimensions": []
|
||||
},
|
||||
"ipc2581": {
|
||||
"dist": "",
|
||||
@@ -453,6 +239,7 @@
|
||||
"single_global_label": "ignore",
|
||||
"unannotated": "error",
|
||||
"unconnected_wire_endpoint": "warning",
|
||||
"undefined_netclass": "error",
|
||||
"unit_value_mismatch": "error",
|
||||
"unresolved_variable": "error",
|
||||
"wire_dangling": "error"
|
||||
@@ -464,7 +251,7 @@
|
||||
},
|
||||
"meta": {
|
||||
"filename": "fw-anwesenheit.kicad_pro",
|
||||
"version": 1
|
||||
"version": 3
|
||||
},
|
||||
"net_settings": {
|
||||
"classes": [
|
||||
@@ -479,6 +266,7 @@
|
||||
"microvia_drill": 0.1,
|
||||
"name": "Default",
|
||||
"pcb_color": "rgba(0, 0, 0, 0.000)",
|
||||
"priority": 2147483647,
|
||||
"schematic_color": "rgba(0, 0, 0, 0.000)",
|
||||
"track_width": 0.2,
|
||||
"via_diameter": 0.6,
|
||||
@@ -487,7 +275,7 @@
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"version": 3
|
||||
"version": 4
|
||||
},
|
||||
"net_colors": null,
|
||||
"netclass_assignments": null,
|
||||
@@ -498,7 +286,7 @@
|
||||
"gencad": "",
|
||||
"idf": "",
|
||||
"netlist": "",
|
||||
"plot": "production/",
|
||||
"plot": "",
|
||||
"pos_files": "",
|
||||
"specctra_dsn": "",
|
||||
"step": "",
|
||||
@@ -578,7 +366,7 @@
|
||||
"include_excluded_from_bom": true,
|
||||
"name": "Default Editing",
|
||||
"sort_asc": true,
|
||||
"sort_field": "Referenz"
|
||||
"sort_field": "Reference"
|
||||
},
|
||||
"connection_grid_size": 50.0,
|
||||
"drawing": {
|
||||
@@ -620,11 +408,6 @@
|
||||
"subpart_first_id": 65,
|
||||
"subpart_id_separator": 0
|
||||
},
|
||||
"sheets": [
|
||||
[
|
||||
"ccbf1fda-befd-42da-bcb2-5d3829184012",
|
||||
"Root"
|
||||
]
|
||||
],
|
||||
"sheets": [],
|
||||
"text_variables": {}
|
||||
}
|
||||
14
pcb/fw-anwesenheit/fw-anwesenheit.kicad_sch
Normal file
14
pcb/fw-anwesenheit/fw-anwesenheit.kicad_sch
Normal file
@@ -0,0 +1,14 @@
|
||||
(kicad_sch
|
||||
(version 20250114)
|
||||
(generator "eeschema")
|
||||
(generator_version "9.0")
|
||||
(uuid 35cd442a-c7c9-4bc2-bfa5-9414b343d8e4)
|
||||
(paper "A4")
|
||||
(lib_symbols)
|
||||
(sheet_instances
|
||||
(path "/"
|
||||
(page "1")
|
||||
)
|
||||
)
|
||||
(embedded_fonts no)
|
||||
)
|
||||
Binary file not shown.
BIN
pcb/production/backups/fw-anwesenheit_2025-09-01_15-16-16.zip
Normal file
BIN
pcb/production/backups/fw-anwesenheit_2025-09-01_15-16-16.zip
Normal file
Binary file not shown.
BIN
pcb/production/backups/fw-anwesenheit_2025-09-01_15-58-06.zip
Normal file
BIN
pcb/production/backups/fw-anwesenheit_2025-09-01_15-58-06.zip
Normal file
Binary file not shown.
BIN
pcb/production/backups/fw-anwesenheit_2025-09-21_03-36-00.zip
Normal file
BIN
pcb/production/backups/fw-anwesenheit_2025-09-21_03-36-00.zip
Normal file
Binary file not shown.
BIN
pcb/production/backups/fw-anwesenheit_2025-09-21_23-31-28.zip
Normal file
BIN
pcb/production/backups/fw-anwesenheit_2025-09-21_23-31-28.zip
Normal file
Binary file not shown.
35
pcb/production/bom.csv
Normal file
35
pcb/production/bom.csv
Normal file
@@ -0,0 +1,35 @@
|
||||
Designator,Footprint,Quantity,Value,LCSC Part #
|
||||
BT1,Battery_Panasonic_CR2032-HFN_Horizontal_CircularHoles,1,Battery_Cell,
|
||||
BZ1,PinSocket_1x02_P2.54mm_Vertical,1,Buzzer,
|
||||
"C1, C4",0603,2,10µF,
|
||||
"C2, C3, C5",0603,3,100nF,
|
||||
D2,0603,1,LED,
|
||||
J1,PinHeader_1x02_P2.54mm_Vertical,1,Conn_01x02_Pin,
|
||||
J2,PinHeader_1x04_P2.54mm_Vertical,1,I2C,
|
||||
J3,PinHeader_1x03_P2.54mm_Vertical,1,LED,
|
||||
J4,WURTH_693071020811,1,MicroSD,
|
||||
R1,0603,1,150R,
|
||||
"R10, R11, R12, R13, R14, R15, R9",0603,7,47k,
|
||||
R2,0603,1,100R,
|
||||
R3,0603,1,10K,
|
||||
R4,0603,1,20k,
|
||||
"R5, R6",0603,2,4k7,
|
||||
"R7, R8",0603,2,NC,
|
||||
RDM1,RDM6300,1,RDM6300,
|
||||
"TP1, TP10, TP9",TestPoint_Pad_D1.5mm,3,TestPoint,
|
||||
TP11,TestPoint_Pad_D1.5mm,1,MOSI,
|
||||
TP12,TestPoint_Pad_D1.5mm,1,MISO,
|
||||
TP13,TestPoint_Pad_D1.5mm,1,SPI SCL,
|
||||
TP14,TestPoint_Pad_D1.5mm,1,DAT1,
|
||||
TP15,TestPoint_Pad_D1.5mm,1,DAT2,
|
||||
TP2,TestPoint_Pad_D1.5mm,1,+5V,
|
||||
TP3,TestPoint_Pad_D1.5mm,1,GND,
|
||||
TP4,TestPoint_Pad_D1.5mm,1,"3,3V",
|
||||
TP5_2,TestPoint_Pad_D1.5mm,1,Din,
|
||||
TP5,TestPoint_Pad_D1.5mm,1,CS,
|
||||
TP6,TestPoint_Pad_D1.5mm,1,SD_DECT,
|
||||
TP7,TestPoint_Pad_D1.5mm,1,UART_RX,
|
||||
TP8,TestPoint_Pad_D1.5mm,1,UART_TX,
|
||||
U1,XIAO-ESP32C6-SMD,1,XIAO-ESP32-S3-SMD,
|
||||
U2,SOT95P280X145-5N,1,SN74AHCT1G125DBVT,SN74AHCT1G125DBVT
|
||||
U3,SOIC-16W_7.5x10.3mm_P1.27mm,1,DS3231M,
|
||||
|
47
pcb/production/designators.csv
Normal file
47
pcb/production/designators.csv
Normal file
@@ -0,0 +1,47 @@
|
||||
BT1:1
|
||||
BZ1:1
|
||||
C1:1
|
||||
C2:1
|
||||
C3:1
|
||||
C4:1
|
||||
C5:1
|
||||
D2:1
|
||||
J1:1
|
||||
J2:1
|
||||
J3:1
|
||||
J4:1
|
||||
JP1:1
|
||||
R1:1
|
||||
R10:1
|
||||
R11:1
|
||||
R12:1
|
||||
R13:1
|
||||
R14:1
|
||||
R15:1
|
||||
R2:1
|
||||
R3:1
|
||||
R4:1
|
||||
R5:1
|
||||
R6:1
|
||||
R7:1
|
||||
R8:1
|
||||
R9:1
|
||||
RDM1:1
|
||||
TP1:1
|
||||
TP10:1
|
||||
TP11:1
|
||||
TP12:1
|
||||
TP13:1
|
||||
TP14:1
|
||||
TP15:1
|
||||
TP2:1
|
||||
TP3:1
|
||||
TP4:1
|
||||
TP5:2
|
||||
TP6:1
|
||||
TP7:1
|
||||
TP8:1
|
||||
TP9:1
|
||||
U1:1
|
||||
U2:1
|
||||
U3:1
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,92 +0,0 @@
|
||||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*
|
||||
G04 #@! TF.CreationDate,2025-08-23T15:15:08+02:00*
|
||||
G04 #@! TF.ProjectId,fw-anwesenheit,66772d61-6e77-4657-9365-6e686569742e,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Soldermask,Bot*
|
||||
G04 #@! TF.FilePolarity,Negative*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-23 15:15:08*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
G04 APERTURE LIST*
|
||||
G04 Aperture macros list*
|
||||
%AMRoundRect*
|
||||
0 Rectangle with rounded corners*
|
||||
0 $1 Rounding radius*
|
||||
0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners*
|
||||
0 Add a 4 corners polygon primitive as box body*
|
||||
4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0*
|
||||
0 Add four circle primitives for the rounded corners*
|
||||
1,1,$1+$1,$2,$3*
|
||||
1,1,$1+$1,$4,$5*
|
||||
1,1,$1+$1,$6,$7*
|
||||
1,1,$1+$1,$8,$9*
|
||||
0 Add four rect primitives between the rounded corners*
|
||||
20,1,$1+$1,$2,$3,$4,$5,0*
|
||||
20,1,$1+$1,$4,$5,$6,$7,0*
|
||||
20,1,$1+$1,$6,$7,$8,$9,0*
|
||||
20,1,$1+$1,$8,$9,$2,$3,0*%
|
||||
G04 Aperture macros list end*
|
||||
%ADD10R,1.350000X1.350000*%
|
||||
%ADD11C,1.350000*%
|
||||
%ADD12C,2.304000*%
|
||||
%ADD13RoundRect,0.102000X-1.050000X1.050000X-1.050000X-1.050000X1.050000X-1.050000X1.050000X1.050000X0*%
|
||||
%ADD14C,1.000000*%
|
||||
%ADD15C,1.500000*%
|
||||
%ADD16R,1.600000X2.000000*%
|
||||
%ADD17O,1.600000X2.000000*%
|
||||
%ADD18R,1.700000X1.700000*%
|
||||
%ADD19C,1.700000*%
|
||||
G04 APERTURE END LIST*
|
||||
D10*
|
||||
X89916000Y-118888000D03*
|
||||
D11*
|
||||
X89916000Y-120888000D03*
|
||||
D12*
|
||||
X89500000Y-59520000D03*
|
||||
D13*
|
||||
X89500000Y-62060000D03*
|
||||
D12*
|
||||
X104740000Y-87460000D03*
|
||||
X104740000Y-84920000D03*
|
||||
X89500000Y-87460000D03*
|
||||
D13*
|
||||
X89500000Y-92540000D03*
|
||||
D12*
|
||||
X104740000Y-90000000D03*
|
||||
D13*
|
||||
X104740000Y-92540000D03*
|
||||
D12*
|
||||
X104740000Y-82380000D03*
|
||||
X89500000Y-90000000D03*
|
||||
D14*
|
||||
X125750000Y-83600000D03*
|
||||
X117750000Y-83600000D03*
|
||||
D15*
|
||||
X107500000Y-90000000D03*
|
||||
X111000000Y-90000000D03*
|
||||
X128500000Y-90000000D03*
|
||||
D16*
|
||||
X113411000Y-103378000D03*
|
||||
D17*
|
||||
X92911000Y-103378000D03*
|
||||
D15*
|
||||
X125000000Y-90000000D03*
|
||||
D18*
|
||||
X120010000Y-127000000D03*
|
||||
D19*
|
||||
X122550000Y-127000000D03*
|
||||
D15*
|
||||
X114500000Y-90000000D03*
|
||||
D18*
|
||||
X83185000Y-110490000D03*
|
||||
D19*
|
||||
X83185000Y-113030000D03*
|
||||
X83185000Y-115570000D03*
|
||||
X83185000Y-118110000D03*
|
||||
D15*
|
||||
X121500000Y-90000000D03*
|
||||
X118000000Y-90000000D03*
|
||||
M02*
|
||||
@@ -1,27 +0,0 @@
|
||||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*
|
||||
G04 #@! TF.CreationDate,2025-08-23T15:15:08+02:00*
|
||||
G04 #@! TF.ProjectId,fw-anwesenheit,66772d61-6e77-4657-9365-6e686569742e,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Paste,Bot*
|
||||
G04 #@! TF.FilePolarity,Positive*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-23 15:15:08*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
G04 APERTURE LIST*
|
||||
%ADD10R,1.700000X1.700000*%
|
||||
%ADD11C,1.700000*%
|
||||
G04 APERTURE END LIST*
|
||||
D10*
|
||||
X120010000Y-127000000D03*
|
||||
D11*
|
||||
X122550000Y-127000000D03*
|
||||
D10*
|
||||
X83185000Y-110490000D03*
|
||||
D11*
|
||||
X83185000Y-113030000D03*
|
||||
X83185000Y-115570000D03*
|
||||
X83185000Y-118110000D03*
|
||||
M02*
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,96 +0,0 @@
|
||||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*
|
||||
G04 #@! TF.CreationDate,2025-08-23T15:15:08+02:00*
|
||||
G04 #@! TF.ProjectId,fw-anwesenheit,66772d61-6e77-4657-9365-6e686569742e,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Profile,NP*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-23 15:15:08*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
G04 APERTURE LIST*
|
||||
G04 #@! TA.AperFunction,Profile*
|
||||
%ADD10C,1.025000*%
|
||||
G04 #@! TD*
|
||||
G04 #@! TA.AperFunction,Profile*
|
||||
%ADD11C,0.050000*%
|
||||
G04 #@! TD*
|
||||
G04 #@! TA.AperFunction,Profile*
|
||||
%ADD12C,0.010000*%
|
||||
G04 #@! TD*
|
||||
G04 APERTURE END LIST*
|
||||
D10*
|
||||
X85512500Y-123500000D02*
|
||||
G75*
|
||||
G02*
|
||||
X84487500Y-123500000I-512500J0D01*
|
||||
G01*
|
||||
X84487500Y-123500000D02*
|
||||
G75*
|
||||
G02*
|
||||
X85512500Y-123500000I512500J0D01*
|
||||
G01*
|
||||
X85512500Y-85000000D02*
|
||||
G75*
|
||||
G02*
|
||||
X84487500Y-85000000I-512500J0D01*
|
||||
G01*
|
||||
X84487500Y-85000000D02*
|
||||
G75*
|
||||
G02*
|
||||
X85512500Y-85000000I512500J0D01*
|
||||
G01*
|
||||
D11*
|
||||
X81045000Y-79502000D02*
|
||||
X131045000Y-79502000D01*
|
||||
X131045000Y-129502000D01*
|
||||
X81045000Y-129502000D01*
|
||||
X81045000Y-79502000D01*
|
||||
D10*
|
||||
X127512500Y-123500000D02*
|
||||
G75*
|
||||
G02*
|
||||
X126487500Y-123500000I-512500J0D01*
|
||||
G01*
|
||||
X126487500Y-123500000D02*
|
||||
G75*
|
||||
G02*
|
||||
X127512500Y-123500000I512500J0D01*
|
||||
G01*
|
||||
X109512500Y-85000000D02*
|
||||
G75*
|
||||
G02*
|
||||
X108487500Y-85000000I-512500J0D01*
|
||||
G01*
|
||||
X108487500Y-85000000D02*
|
||||
G75*
|
||||
G02*
|
||||
X109512500Y-85000000I512500J0D01*
|
||||
G01*
|
||||
D12*
|
||||
X117400000Y-83100000D02*
|
||||
X118100000Y-83100000D01*
|
||||
X118100000Y-84100000D02*
|
||||
X117400000Y-84100000D01*
|
||||
X116900000Y-83600000D02*
|
||||
G75*
|
||||
G02*
|
||||
X117400000Y-83100000I500000J0D01*
|
||||
G01*
|
||||
X117400000Y-84100000D02*
|
||||
G75*
|
||||
G02*
|
||||
X116900000Y-83600000I0J500000D01*
|
||||
G01*
|
||||
X118100000Y-83100000D02*
|
||||
G75*
|
||||
G02*
|
||||
X118600000Y-83600000I0J-500000D01*
|
||||
G01*
|
||||
X118600000Y-83600000D02*
|
||||
G75*
|
||||
G02*
|
||||
X118100000Y-84100000I-500000J0D01*
|
||||
G01*
|
||||
M02*
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,288 +0,0 @@
|
||||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*
|
||||
G04 #@! TF.CreationDate,2025-08-23T15:15:08+02:00*
|
||||
G04 #@! TF.ProjectId,fw-anwesenheit,66772d61-6e77-4657-9365-6e686569742e,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Soldermask,Top*
|
||||
G04 #@! TF.FilePolarity,Negative*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-23 15:15:08*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
G04 APERTURE LIST*
|
||||
G04 Aperture macros list*
|
||||
%AMRoundRect*
|
||||
0 Rectangle with rounded corners*
|
||||
0 $1 Rounding radius*
|
||||
0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners*
|
||||
0 Add a 4 corners polygon primitive as box body*
|
||||
4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0*
|
||||
0 Add four circle primitives for the rounded corners*
|
||||
1,1,$1+$1,$2,$3*
|
||||
1,1,$1+$1,$4,$5*
|
||||
1,1,$1+$1,$6,$7*
|
||||
1,1,$1+$1,$8,$9*
|
||||
0 Add four rect primitives between the rounded corners*
|
||||
20,1,$1+$1,$2,$3,$4,$5,0*
|
||||
20,1,$1+$1,$4,$5,$6,$7,0*
|
||||
20,1,$1+$1,$6,$7,$8,$9,0*
|
||||
20,1,$1+$1,$8,$9,$2,$3,0*%
|
||||
%AMOutline5P*
|
||||
0 Free polygon, 5 corners , with rotation*
|
||||
0 The origin of the aperture is its center*
|
||||
0 number of corners: always 5*
|
||||
0 $1 to $10 corner X, Y*
|
||||
0 $11 Rotation angle, in degrees counterclockwise*
|
||||
0 create outline with 5 corners*
|
||||
4,1,5,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$1,$2,$11*%
|
||||
%AMOutline6P*
|
||||
0 Free polygon, 6 corners , with rotation*
|
||||
0 The origin of the aperture is its center*
|
||||
0 number of corners: always 6*
|
||||
0 $1 to $12 corner X, Y*
|
||||
0 $13 Rotation angle, in degrees counterclockwise*
|
||||
0 create outline with 6 corners*
|
||||
4,1,6,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$1,$2,$13*%
|
||||
%AMOutline7P*
|
||||
0 Free polygon, 7 corners , with rotation*
|
||||
0 The origin of the aperture is its center*
|
||||
0 number of corners: always 7*
|
||||
0 $1 to $14 corner X, Y*
|
||||
0 $15 Rotation angle, in degrees counterclockwise*
|
||||
0 create outline with 7 corners*
|
||||
4,1,7,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$1,$2,$15*%
|
||||
%AMOutline8P*
|
||||
0 Free polygon, 8 corners , with rotation*
|
||||
0 The origin of the aperture is its center*
|
||||
0 number of corners: always 8*
|
||||
0 $1 to $16 corner X, Y*
|
||||
0 $17 Rotation angle, in degrees counterclockwise*
|
||||
0 create outline with 8 corners*
|
||||
4,1,8,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$1,$2,$17*%
|
||||
%AMFreePoly0*
|
||||
4,1,6,1.000000,0.000000,0.500000,-0.750000,-0.500000,-0.750000,-0.500000,0.750000,0.500000,0.750000,1.000000,0.000000,1.000000,0.000000,$1*%
|
||||
%AMFreePoly1*
|
||||
4,1,6,0.500000,-0.750000,-0.650000,-0.750000,-0.150000,0.000000,-0.650000,0.750000,0.500000,0.750000,0.500000,-0.750000,0.500000,-0.750000,$1*%
|
||||
G04 Aperture macros list end*
|
||||
%ADD10RoundRect,0.225000X0.225000X0.250000X-0.225000X0.250000X-0.225000X-0.250000X0.225000X-0.250000X0*%
|
||||
%ADD11Outline5P,-1.250000X0.510000X-0.910000X0.850000X1.250000X0.850000X1.250000X-0.850000X-1.250000X-0.850000X0.000000*%
|
||||
%ADD12RoundRect,0.170000X-1.080000X-0.680000X1.080000X-0.680000X1.080000X0.680000X-1.080000X0.680000X0*%
|
||||
%ADD13RoundRect,0.250000X-1.000000X-0.600000X1.000000X-0.600000X1.000000X0.600000X-1.000000X0.600000X0*%
|
||||
%ADD14RoundRect,0.525400X0.900400X0.525400X-0.900400X0.525400X-0.900400X-0.525400X0.900400X-0.525400X0*%
|
||||
%ADD15RoundRect,0.300400X0.300400X-1.000400X0.300400X1.000400X-0.300400X1.000400X-0.300400X-1.000400X0*%
|
||||
%ADD16C,1.700000*%
|
||||
%ADD17C,1.500000*%
|
||||
%ADD18RoundRect,0.218750X0.256250X-0.218750X0.256250X0.218750X-0.256250X0.218750X-0.256250X-0.218750X0*%
|
||||
%ADD19RoundRect,0.237500X0.237500X-0.250000X0.237500X0.250000X-0.237500X0.250000X-0.237500X-0.250000X0*%
|
||||
%ADD20RoundRect,0.237500X-0.237500X0.250000X-0.237500X-0.250000X0.237500X-0.250000X0.237500X0.250000X0*%
|
||||
%ADD21RoundRect,0.225000X-0.225000X-0.250000X0.225000X-0.250000X0.225000X0.250000X-0.225000X0.250000X0*%
|
||||
%ADD22RoundRect,0.150000X-0.875000X-0.150000X0.875000X-0.150000X0.875000X0.150000X-0.875000X0.150000X0*%
|
||||
%ADD23R,1.350000X1.350000*%
|
||||
%ADD24C,1.350000*%
|
||||
%ADD25FreePoly0,0.000000*%
|
||||
%ADD26FreePoly1,0.000000*%
|
||||
%ADD27C,2.304000*%
|
||||
%ADD28RoundRect,0.102000X-1.050000X1.050000X-1.050000X-1.050000X1.050000X-1.050000X1.050000X1.050000X0*%
|
||||
%ADD29RoundRect,0.237500X0.250000X0.237500X-0.250000X0.237500X-0.250000X-0.237500X0.250000X-0.237500X0*%
|
||||
%ADD30RoundRect,0.102000X-0.635000X-0.279400X0.635000X-0.279400X0.635000X0.279400X-0.635000X0.279400X0*%
|
||||
%ADD31RoundRect,0.237500X-0.250000X-0.237500X0.250000X-0.237500X0.250000X0.237500X-0.250000X0.237500X0*%
|
||||
%ADD32RoundRect,0.225000X0.250000X-0.225000X0.250000X0.225000X-0.250000X0.225000X-0.250000X-0.225000X0*%
|
||||
%ADD33C,1.000000*%
|
||||
%ADD34RoundRect,0.102000X0.350000X0.950000X-0.350000X0.950000X-0.350000X-0.950000X0.350000X-0.950000X0*%
|
||||
%ADD35RoundRect,0.102000X0.850000X0.900000X-0.850000X0.900000X-0.850000X-0.900000X0.850000X-0.900000X0*%
|
||||
%ADD36RoundRect,0.102000X0.700000X1.300000X-0.700000X1.300000X-0.700000X-1.300000X0.700000X-1.300000X0*%
|
||||
%ADD37RoundRect,0.225000X-0.250000X0.225000X-0.250000X-0.225000X0.250000X-0.225000X0.250000X0.225000X0*%
|
||||
%ADD38R,1.600000X2.000000*%
|
||||
%ADD39O,1.600000X2.000000*%
|
||||
G04 APERTURE END LIST*
|
||||
G36*
|
||||
X117483000Y-126250000D02*
|
||||
G01*
|
||||
X119933000Y-126250000D01*
|
||||
X119933000Y-127750000D01*
|
||||
X117483000Y-127750000D01*
|
||||
X117483000Y-126250000D01*
|
||||
G37*
|
||||
D10*
|
||||
X123775000Y-97500000D03*
|
||||
X122225000Y-97500000D03*
|
||||
D11*
|
||||
X128778000Y-111252000D03*
|
||||
D12*
|
||||
X128778000Y-113792000D03*
|
||||
D13*
|
||||
X128778000Y-116332000D03*
|
||||
D14*
|
||||
X113821600Y-126598500D03*
|
||||
X113821600Y-124058500D03*
|
||||
X113821600Y-121518500D03*
|
||||
X113821600Y-118978500D03*
|
||||
X113821600Y-116438500D03*
|
||||
X113821600Y-113898500D03*
|
||||
X113821600Y-111358500D03*
|
||||
X97656600Y-111358500D03*
|
||||
X97656600Y-113898500D03*
|
||||
X97656600Y-116438500D03*
|
||||
X97656600Y-118978500D03*
|
||||
X97656600Y-121518500D03*
|
||||
X97656600Y-124058500D03*
|
||||
X97656600Y-126598500D03*
|
||||
D15*
|
||||
X107548000Y-113446800D03*
|
||||
X105008000Y-113446800D03*
|
||||
D16*
|
||||
X107040000Y-127620000D03*
|
||||
X104500000Y-127620000D03*
|
||||
X107040000Y-125080000D03*
|
||||
X104500000Y-125080000D03*
|
||||
X107040000Y-122540000D03*
|
||||
X104500000Y-122540000D03*
|
||||
X107040000Y-120000000D03*
|
||||
X104592600Y-120056800D03*
|
||||
D17*
|
||||
X83000000Y-127500000D03*
|
||||
D18*
|
||||
X83500000Y-93787500D03*
|
||||
X83500000Y-92212500D03*
|
||||
D19*
|
||||
X120000000Y-102412500D03*
|
||||
X120000000Y-100587500D03*
|
||||
X122000000Y-102412500D03*
|
||||
X122000000Y-100587500D03*
|
||||
D20*
|
||||
X90000000Y-109087500D03*
|
||||
X90000000Y-110912500D03*
|
||||
D21*
|
||||
X95618000Y-98552000D03*
|
||||
X97168000Y-98552000D03*
|
||||
D17*
|
||||
X84000000Y-103500000D03*
|
||||
D22*
|
||||
X99871000Y-97282000D03*
|
||||
X99871000Y-98552000D03*
|
||||
X99871000Y-99822000D03*
|
||||
X99871000Y-101092000D03*
|
||||
X99871000Y-102362000D03*
|
||||
X99871000Y-103632000D03*
|
||||
X99871000Y-104902000D03*
|
||||
X99871000Y-106172000D03*
|
||||
X109171000Y-106172000D03*
|
||||
X109171000Y-104902000D03*
|
||||
X109171000Y-103632000D03*
|
||||
X109171000Y-102362000D03*
|
||||
X109171000Y-101092000D03*
|
||||
X109171000Y-99822000D03*
|
||||
X109171000Y-98552000D03*
|
||||
X109171000Y-97282000D03*
|
||||
D23*
|
||||
X89916000Y-118888000D03*
|
||||
D24*
|
||||
X89916000Y-120888000D03*
|
||||
D19*
|
||||
X116000000Y-102412500D03*
|
||||
X116000000Y-100587500D03*
|
||||
D17*
|
||||
X86175000Y-118373000D03*
|
||||
D25*
|
||||
X117983000Y-127000000D03*
|
||||
D26*
|
||||
X119433000Y-127000000D03*
|
||||
D27*
|
||||
X89500000Y-59520000D03*
|
||||
D28*
|
||||
X89500000Y-62060000D03*
|
||||
D27*
|
||||
X104740000Y-87460000D03*
|
||||
X104740000Y-84920000D03*
|
||||
X89500000Y-87460000D03*
|
||||
D28*
|
||||
X89500000Y-92540000D03*
|
||||
D27*
|
||||
X104740000Y-90000000D03*
|
||||
D28*
|
||||
X104740000Y-92540000D03*
|
||||
D27*
|
||||
X104740000Y-82380000D03*
|
||||
X89500000Y-90000000D03*
|
||||
D29*
|
||||
X90412500Y-97000000D03*
|
||||
X88587500Y-97000000D03*
|
||||
X90412500Y-99000000D03*
|
||||
X88587500Y-99000000D03*
|
||||
D30*
|
||||
X117704600Y-113560200D03*
|
||||
X117704600Y-114500000D03*
|
||||
X117704600Y-115439800D03*
|
||||
X120295400Y-115439800D03*
|
||||
X120295400Y-113560200D03*
|
||||
D21*
|
||||
X118225000Y-111000000D03*
|
||||
X119775000Y-111000000D03*
|
||||
D20*
|
||||
X86000000Y-92087500D03*
|
||||
X86000000Y-93912500D03*
|
||||
D31*
|
||||
X123087500Y-111000000D03*
|
||||
X124912500Y-111000000D03*
|
||||
D19*
|
||||
X124000000Y-102412500D03*
|
||||
X124000000Y-100587500D03*
|
||||
D17*
|
||||
X84000000Y-100500000D03*
|
||||
X86500000Y-127500000D03*
|
||||
X90000000Y-127500000D03*
|
||||
D19*
|
||||
X128000000Y-102500000D03*
|
||||
X128000000Y-100675000D03*
|
||||
D17*
|
||||
X124500000Y-108500000D03*
|
||||
D19*
|
||||
X118000000Y-102412500D03*
|
||||
X118000000Y-100587500D03*
|
||||
D32*
|
||||
X125984000Y-115583000D03*
|
||||
X125984000Y-114033000D03*
|
||||
D19*
|
||||
X122500000Y-120912500D03*
|
||||
X122500000Y-119087500D03*
|
||||
D20*
|
||||
X90000000Y-113087500D03*
|
||||
X90000000Y-114912500D03*
|
||||
D17*
|
||||
X84000000Y-97500000D03*
|
||||
D33*
|
||||
X125750000Y-83600000D03*
|
||||
X117750000Y-83600000D03*
|
||||
D34*
|
||||
X118550000Y-94650000D03*
|
||||
X119650000Y-94650000D03*
|
||||
X120750000Y-94650000D03*
|
||||
X121850000Y-94650000D03*
|
||||
X122950000Y-94650000D03*
|
||||
X124050000Y-94650000D03*
|
||||
X125150000Y-94650000D03*
|
||||
X126250000Y-94650000D03*
|
||||
X127350000Y-94650000D03*
|
||||
D35*
|
||||
X128900000Y-93600000D03*
|
||||
X113400000Y-93600000D03*
|
||||
D36*
|
||||
X128650000Y-84000000D03*
|
||||
X112950000Y-84000000D03*
|
||||
D19*
|
||||
X126000000Y-102412500D03*
|
||||
X126000000Y-100587500D03*
|
||||
D17*
|
||||
X86175000Y-115373000D03*
|
||||
D19*
|
||||
X120000000Y-120927500D03*
|
||||
X120000000Y-119102500D03*
|
||||
D37*
|
||||
X94500000Y-124225000D03*
|
||||
X94500000Y-125775000D03*
|
||||
D38*
|
||||
X113411000Y-103378000D03*
|
||||
D39*
|
||||
X92911000Y-103378000D03*
|
||||
M02*
|
||||
@@ -1,215 +0,0 @@
|
||||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*
|
||||
G04 #@! TF.CreationDate,2025-08-23T15:15:08+02:00*
|
||||
G04 #@! TF.ProjectId,fw-anwesenheit,66772d61-6e77-4657-9365-6e686569742e,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Paste,Top*
|
||||
G04 #@! TF.FilePolarity,Positive*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-23 15:15:08*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
G04 APERTURE LIST*
|
||||
G04 Aperture macros list*
|
||||
%AMRoundRect*
|
||||
0 Rectangle with rounded corners*
|
||||
0 $1 Rounding radius*
|
||||
0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners*
|
||||
0 Add a 4 corners polygon primitive as box body*
|
||||
4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0*
|
||||
0 Add four circle primitives for the rounded corners*
|
||||
1,1,$1+$1,$2,$3*
|
||||
1,1,$1+$1,$4,$5*
|
||||
1,1,$1+$1,$6,$7*
|
||||
1,1,$1+$1,$8,$9*
|
||||
0 Add four rect primitives between the rounded corners*
|
||||
20,1,$1+$1,$2,$3,$4,$5,0*
|
||||
20,1,$1+$1,$4,$5,$6,$7,0*
|
||||
20,1,$1+$1,$6,$7,$8,$9,0*
|
||||
20,1,$1+$1,$8,$9,$2,$3,0*%
|
||||
%AMOutline5P*
|
||||
0 Free polygon, 5 corners , with rotation*
|
||||
0 The origin of the aperture is its center*
|
||||
0 number of corners: always 5*
|
||||
0 $1 to $10 corner X, Y*
|
||||
0 $11 Rotation angle, in degrees counterclockwise*
|
||||
0 create outline with 5 corners*
|
||||
4,1,5,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$1,$2,$11*%
|
||||
%AMOutline6P*
|
||||
0 Free polygon, 6 corners , with rotation*
|
||||
0 The origin of the aperture is its center*
|
||||
0 number of corners: always 6*
|
||||
0 $1 to $12 corner X, Y*
|
||||
0 $13 Rotation angle, in degrees counterclockwise*
|
||||
0 create outline with 6 corners*
|
||||
4,1,6,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$1,$2,$13*%
|
||||
%AMOutline7P*
|
||||
0 Free polygon, 7 corners , with rotation*
|
||||
0 The origin of the aperture is its center*
|
||||
0 number of corners: always 7*
|
||||
0 $1 to $14 corner X, Y*
|
||||
0 $15 Rotation angle, in degrees counterclockwise*
|
||||
0 create outline with 7 corners*
|
||||
4,1,7,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$1,$2,$15*%
|
||||
%AMOutline8P*
|
||||
0 Free polygon, 8 corners , with rotation*
|
||||
0 The origin of the aperture is its center*
|
||||
0 number of corners: always 8*
|
||||
0 $1 to $16 corner X, Y*
|
||||
0 $17 Rotation angle, in degrees counterclockwise*
|
||||
0 create outline with 8 corners*
|
||||
4,1,8,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$1,$2,$17*%
|
||||
G04 Aperture macros list end*
|
||||
%ADD10RoundRect,0.225000X0.225000X0.250000X-0.225000X0.250000X-0.225000X-0.250000X0.225000X-0.250000X0*%
|
||||
%ADD11Outline5P,-1.250000X0.510000X-0.910000X0.850000X1.250000X0.850000X1.250000X-0.850000X-1.250000X-0.850000X0.000000*%
|
||||
%ADD12RoundRect,0.170000X-1.080000X-0.680000X1.080000X-0.680000X1.080000X0.680000X-1.080000X0.680000X0*%
|
||||
%ADD13RoundRect,0.250000X-1.000000X-0.600000X1.000000X-0.600000X1.000000X0.600000X-1.000000X0.600000X0*%
|
||||
%ADD14RoundRect,0.500000X0.875000X0.500000X-0.875000X0.500000X-0.875000X-0.500000X0.875000X-0.500000X0*%
|
||||
%ADD15RoundRect,0.275000X0.275000X-0.975000X0.275000X0.975000X-0.275000X0.975000X-0.275000X-0.975000X0*%
|
||||
%ADD16C,1.700000*%
|
||||
%ADD17RoundRect,0.218750X0.256250X-0.218750X0.256250X0.218750X-0.256250X0.218750X-0.256250X-0.218750X0*%
|
||||
%ADD18RoundRect,0.237500X0.237500X-0.250000X0.237500X0.250000X-0.237500X0.250000X-0.237500X-0.250000X0*%
|
||||
%ADD19RoundRect,0.237500X-0.237500X0.250000X-0.237500X-0.250000X0.237500X-0.250000X0.237500X0.250000X0*%
|
||||
%ADD20RoundRect,0.225000X-0.225000X-0.250000X0.225000X-0.250000X0.225000X0.250000X-0.225000X0.250000X0*%
|
||||
%ADD21RoundRect,0.150000X-0.875000X-0.150000X0.875000X-0.150000X0.875000X0.150000X-0.875000X0.150000X0*%
|
||||
%ADD22RoundRect,0.237500X0.250000X0.237500X-0.250000X0.237500X-0.250000X-0.237500X0.250000X-0.237500X0*%
|
||||
%ADD23R,1.270000X0.558800*%
|
||||
%ADD24RoundRect,0.237500X-0.250000X-0.237500X0.250000X-0.237500X0.250000X0.237500X-0.250000X0.237500X0*%
|
||||
%ADD25RoundRect,0.225000X0.250000X-0.225000X0.250000X0.225000X-0.250000X0.225000X-0.250000X-0.225000X0*%
|
||||
%ADD26R,0.700000X1.900000*%
|
||||
%ADD27R,1.700000X1.800000*%
|
||||
%ADD28R,1.400000X2.600000*%
|
||||
%ADD29RoundRect,0.225000X-0.250000X0.225000X-0.250000X-0.225000X0.250000X-0.225000X0.250000X0.225000X0*%
|
||||
G04 APERTURE END LIST*
|
||||
D10*
|
||||
X123775000Y-97500000D03*
|
||||
X122225000Y-97500000D03*
|
||||
D11*
|
||||
X128778000Y-111252000D03*
|
||||
D12*
|
||||
X128778000Y-113792000D03*
|
||||
D13*
|
||||
X128778000Y-116332000D03*
|
||||
D14*
|
||||
X113821600Y-126598500D03*
|
||||
X113821600Y-124058500D03*
|
||||
X113821600Y-121518500D03*
|
||||
X113821600Y-118978500D03*
|
||||
X113821600Y-116438500D03*
|
||||
X113821600Y-113898500D03*
|
||||
X113821600Y-111358500D03*
|
||||
X97656600Y-111358500D03*
|
||||
X97656600Y-113898500D03*
|
||||
X97656600Y-116438500D03*
|
||||
X97656600Y-118978500D03*
|
||||
X97656600Y-121518500D03*
|
||||
X97656600Y-124058500D03*
|
||||
X97656600Y-126598500D03*
|
||||
D15*
|
||||
X107548000Y-113446800D03*
|
||||
X105008000Y-113446800D03*
|
||||
D16*
|
||||
X107040000Y-127620000D03*
|
||||
X104500000Y-127620000D03*
|
||||
X107040000Y-125080000D03*
|
||||
X104500000Y-125080000D03*
|
||||
X107040000Y-122540000D03*
|
||||
X104500000Y-122540000D03*
|
||||
X107040000Y-120000000D03*
|
||||
X104592600Y-120056800D03*
|
||||
D17*
|
||||
X83500000Y-93787500D03*
|
||||
X83500000Y-92212500D03*
|
||||
D18*
|
||||
X120000000Y-102412500D03*
|
||||
X120000000Y-100587500D03*
|
||||
X122000000Y-102412500D03*
|
||||
X122000000Y-100587500D03*
|
||||
D19*
|
||||
X90000000Y-109087500D03*
|
||||
X90000000Y-110912500D03*
|
||||
D20*
|
||||
X95618000Y-98552000D03*
|
||||
X97168000Y-98552000D03*
|
||||
D21*
|
||||
X99871000Y-97282000D03*
|
||||
X99871000Y-98552000D03*
|
||||
X99871000Y-99822000D03*
|
||||
X99871000Y-101092000D03*
|
||||
X99871000Y-102362000D03*
|
||||
X99871000Y-103632000D03*
|
||||
X99871000Y-104902000D03*
|
||||
X99871000Y-106172000D03*
|
||||
X109171000Y-106172000D03*
|
||||
X109171000Y-104902000D03*
|
||||
X109171000Y-103632000D03*
|
||||
X109171000Y-102362000D03*
|
||||
X109171000Y-101092000D03*
|
||||
X109171000Y-99822000D03*
|
||||
X109171000Y-98552000D03*
|
||||
X109171000Y-97282000D03*
|
||||
D18*
|
||||
X116000000Y-102412500D03*
|
||||
X116000000Y-100587500D03*
|
||||
D22*
|
||||
X90412500Y-97000000D03*
|
||||
X88587500Y-97000000D03*
|
||||
X90412500Y-99000000D03*
|
||||
X88587500Y-99000000D03*
|
||||
D23*
|
||||
X117704600Y-113560200D03*
|
||||
X117704600Y-114500000D03*
|
||||
X117704600Y-115439800D03*
|
||||
X120295400Y-115439800D03*
|
||||
X120295400Y-113560200D03*
|
||||
D20*
|
||||
X118225000Y-111000000D03*
|
||||
X119775000Y-111000000D03*
|
||||
D19*
|
||||
X86000000Y-92087500D03*
|
||||
X86000000Y-93912500D03*
|
||||
D24*
|
||||
X123087500Y-111000000D03*
|
||||
X124912500Y-111000000D03*
|
||||
D18*
|
||||
X124000000Y-102412500D03*
|
||||
X124000000Y-100587500D03*
|
||||
X128000000Y-102500000D03*
|
||||
X128000000Y-100675000D03*
|
||||
X118000000Y-102412500D03*
|
||||
X118000000Y-100587500D03*
|
||||
D25*
|
||||
X125984000Y-115583000D03*
|
||||
X125984000Y-114033000D03*
|
||||
D18*
|
||||
X122500000Y-120912500D03*
|
||||
X122500000Y-119087500D03*
|
||||
D19*
|
||||
X90000000Y-113087500D03*
|
||||
X90000000Y-114912500D03*
|
||||
D26*
|
||||
X118550000Y-94650000D03*
|
||||
X119650000Y-94650000D03*
|
||||
X120750000Y-94650000D03*
|
||||
X121850000Y-94650000D03*
|
||||
X122950000Y-94650000D03*
|
||||
X124050000Y-94650000D03*
|
||||
X125150000Y-94650000D03*
|
||||
X126250000Y-94650000D03*
|
||||
X127350000Y-94650000D03*
|
||||
D27*
|
||||
X128900000Y-93600000D03*
|
||||
X113400000Y-93600000D03*
|
||||
D28*
|
||||
X128650000Y-84000000D03*
|
||||
X112950000Y-84000000D03*
|
||||
D18*
|
||||
X126000000Y-102412500D03*
|
||||
X126000000Y-100587500D03*
|
||||
X120000000Y-120927500D03*
|
||||
X120000000Y-119102500D03*
|
||||
D29*
|
||||
X94500000Y-124225000D03*
|
||||
X94500000Y-125775000D03*
|
||||
M02*
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,996 +0,0 @@
|
||||
%TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*%
|
||||
%TF.CreationDate,2025-08-23T15:15:25+02:00*%
|
||||
%TF.ProjectId,fw-anwesenheit,66772d61-6e77-4657-9365-6e686569742e,rev?*%
|
||||
%TF.SameCoordinates,Original*%
|
||||
%TF.FileFunction,Drillmap*%
|
||||
%TF.FilePolarity,Positive*%
|
||||
%FSLAX45Y45*%
|
||||
G04 Gerber Fmt 4.5, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-23 15:15:25*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
G04 APERTURE LIST*
|
||||
%ADD10C,1.025000*%
|
||||
%ADD11C,0.050000*%
|
||||
%ADD12C,0.010000*%
|
||||
%ADD13C,0.200000*%
|
||||
%ADD14C,0.100000*%
|
||||
G04 APERTURE END LIST*
|
||||
D10*
|
||||
X8551250Y-12350000D02*
|
||||
G75*
|
||||
G02*
|
||||
X8448750Y-12350000I-51250J0D01*
|
||||
G01*
|
||||
X8448750Y-12350000D02*
|
||||
G75*
|
||||
G02*
|
||||
X8551250Y-12350000I51250J0D01*
|
||||
G01*
|
||||
X8551250Y-8500000D02*
|
||||
G75*
|
||||
G02*
|
||||
X8448750Y-8500000I-51250J0D01*
|
||||
G01*
|
||||
X8448750Y-8500000D02*
|
||||
G75*
|
||||
G02*
|
||||
X8551250Y-8500000I51250J0D01*
|
||||
G01*
|
||||
D11*
|
||||
X8104500Y-7950200D02*
|
||||
X13104500Y-7950200D01*
|
||||
X13104500Y-12950200D01*
|
||||
X8104500Y-12950200D01*
|
||||
X8104500Y-7950200D01*
|
||||
D10*
|
||||
X12751250Y-12350000D02*
|
||||
G75*
|
||||
G02*
|
||||
X12648750Y-12350000I-51250J0D01*
|
||||
G01*
|
||||
X12648750Y-12350000D02*
|
||||
G75*
|
||||
G02*
|
||||
X12751250Y-12350000I51250J0D01*
|
||||
G01*
|
||||
X10951250Y-8500000D02*
|
||||
G75*
|
||||
G02*
|
||||
X10848750Y-8500000I-51250J0D01*
|
||||
G01*
|
||||
X10848750Y-8500000D02*
|
||||
G75*
|
||||
G02*
|
||||
X10951250Y-8500000I51250J0D01*
|
||||
G01*
|
||||
D12*
|
||||
X11740000Y-8310000D02*
|
||||
X11810000Y-8310000D01*
|
||||
X11810000Y-8410000D02*
|
||||
X11740000Y-8410000D01*
|
||||
X11690000Y-8360000D02*
|
||||
G75*
|
||||
G02*
|
||||
X11740000Y-8310000I50000J0D01*
|
||||
G01*
|
||||
X11740000Y-8410000D02*
|
||||
G75*
|
||||
G02*
|
||||
X11690000Y-8360000I0J50000D01*
|
||||
G01*
|
||||
X11810000Y-8310000D02*
|
||||
G75*
|
||||
G02*
|
||||
X11860000Y-8360000I0J-50000D01*
|
||||
G01*
|
||||
X11860000Y-8360000D02*
|
||||
G75*
|
||||
G02*
|
||||
X11810000Y-8410000I-50000J0D01*
|
||||
G01*
|
||||
D13*
|
||||
D14*
|
||||
X11725000Y-8310000D02*
|
||||
X11825000Y-8410000D01*
|
||||
X11825000Y-8310000D02*
|
||||
X11725000Y-8410000D01*
|
||||
X12525000Y-8310000D02*
|
||||
X12625000Y-8410000D01*
|
||||
X12625000Y-8310000D02*
|
||||
X12525000Y-8410000D01*
|
||||
D13*
|
||||
X8362777Y-13264184D02*
|
||||
X8362777Y-13064184D01*
|
||||
X8362777Y-13064184D02*
|
||||
X8410396Y-13064184D01*
|
||||
X8410396Y-13064184D02*
|
||||
X8438967Y-13073708D01*
|
||||
X8438967Y-13073708D02*
|
||||
X8458015Y-13092755D01*
|
||||
X8458015Y-13092755D02*
|
||||
X8467539Y-13111803D01*
|
||||
X8467539Y-13111803D02*
|
||||
X8477063Y-13149898D01*
|
||||
X8477063Y-13149898D02*
|
||||
X8477063Y-13178469D01*
|
||||
X8477063Y-13178469D02*
|
||||
X8467539Y-13216565D01*
|
||||
X8467539Y-13216565D02*
|
||||
X8458015Y-13235612D01*
|
||||
X8458015Y-13235612D02*
|
||||
X8438967Y-13254660D01*
|
||||
X8438967Y-13254660D02*
|
||||
X8410396Y-13264184D01*
|
||||
X8410396Y-13264184D02*
|
||||
X8362777Y-13264184D01*
|
||||
X8562777Y-13264184D02*
|
||||
X8562777Y-13130850D01*
|
||||
X8562777Y-13168946D02*
|
||||
X8572301Y-13149898D01*
|
||||
X8572301Y-13149898D02*
|
||||
X8581824Y-13140374D01*
|
||||
X8581824Y-13140374D02*
|
||||
X8600872Y-13130850D01*
|
||||
X8600872Y-13130850D02*
|
||||
X8619920Y-13130850D01*
|
||||
X8686586Y-13264184D02*
|
||||
X8686586Y-13130850D01*
|
||||
X8686586Y-13064184D02*
|
||||
X8677063Y-13073708D01*
|
||||
X8677063Y-13073708D02*
|
||||
X8686586Y-13083231D01*
|
||||
X8686586Y-13083231D02*
|
||||
X8696110Y-13073708D01*
|
||||
X8696110Y-13073708D02*
|
||||
X8686586Y-13064184D01*
|
||||
X8686586Y-13064184D02*
|
||||
X8686586Y-13083231D01*
|
||||
X8810396Y-13264184D02*
|
||||
X8791348Y-13254660D01*
|
||||
X8791348Y-13254660D02*
|
||||
X8781824Y-13235612D01*
|
||||
X8781824Y-13235612D02*
|
||||
X8781824Y-13064184D01*
|
||||
X8915158Y-13264184D02*
|
||||
X8896110Y-13254660D01*
|
||||
X8896110Y-13254660D02*
|
||||
X8886586Y-13235612D01*
|
||||
X8886586Y-13235612D02*
|
||||
X8886586Y-13064184D01*
|
||||
X9143729Y-13264184D02*
|
||||
X9143729Y-13064184D01*
|
||||
X9143729Y-13064184D02*
|
||||
X9210396Y-13207041D01*
|
||||
X9210396Y-13207041D02*
|
||||
X9277063Y-13064184D01*
|
||||
X9277063Y-13064184D02*
|
||||
X9277063Y-13264184D01*
|
||||
X9458015Y-13264184D02*
|
||||
X9458015Y-13159422D01*
|
||||
X9458015Y-13159422D02*
|
||||
X9448491Y-13140374D01*
|
||||
X9448491Y-13140374D02*
|
||||
X9429444Y-13130850D01*
|
||||
X9429444Y-13130850D02*
|
||||
X9391348Y-13130850D01*
|
||||
X9391348Y-13130850D02*
|
||||
X9372301Y-13140374D01*
|
||||
X9458015Y-13254660D02*
|
||||
X9438967Y-13264184D01*
|
||||
X9438967Y-13264184D02*
|
||||
X9391348Y-13264184D01*
|
||||
X9391348Y-13264184D02*
|
||||
X9372301Y-13254660D01*
|
||||
X9372301Y-13254660D02*
|
||||
X9362777Y-13235612D01*
|
||||
X9362777Y-13235612D02*
|
||||
X9362777Y-13216565D01*
|
||||
X9362777Y-13216565D02*
|
||||
X9372301Y-13197517D01*
|
||||
X9372301Y-13197517D02*
|
||||
X9391348Y-13187993D01*
|
||||
X9391348Y-13187993D02*
|
||||
X9438967Y-13187993D01*
|
||||
X9438967Y-13187993D02*
|
||||
X9458015Y-13178469D01*
|
||||
X9553253Y-13130850D02*
|
||||
X9553253Y-13330850D01*
|
||||
X9553253Y-13140374D02*
|
||||
X9572301Y-13130850D01*
|
||||
X9572301Y-13130850D02*
|
||||
X9610396Y-13130850D01*
|
||||
X9610396Y-13130850D02*
|
||||
X9629444Y-13140374D01*
|
||||
X9629444Y-13140374D02*
|
||||
X9638967Y-13149898D01*
|
||||
X9638967Y-13149898D02*
|
||||
X9648491Y-13168946D01*
|
||||
X9648491Y-13168946D02*
|
||||
X9648491Y-13226088D01*
|
||||
X9648491Y-13226088D02*
|
||||
X9638967Y-13245136D01*
|
||||
X9638967Y-13245136D02*
|
||||
X9629444Y-13254660D01*
|
||||
X9629444Y-13254660D02*
|
||||
X9610396Y-13264184D01*
|
||||
X9610396Y-13264184D02*
|
||||
X9572301Y-13264184D01*
|
||||
X9572301Y-13264184D02*
|
||||
X9553253Y-13254660D01*
|
||||
X9734205Y-13245136D02*
|
||||
X9743729Y-13254660D01*
|
||||
X9743729Y-13254660D02*
|
||||
X9734205Y-13264184D01*
|
||||
X9734205Y-13264184D02*
|
||||
X9724682Y-13254660D01*
|
||||
X9724682Y-13254660D02*
|
||||
X9734205Y-13245136D01*
|
||||
X9734205Y-13245136D02*
|
||||
X9734205Y-13264184D01*
|
||||
X9734205Y-13140374D02*
|
||||
X9743729Y-13149898D01*
|
||||
X9743729Y-13149898D02*
|
||||
X9734205Y-13159422D01*
|
||||
X9734205Y-13159422D02*
|
||||
X9724682Y-13149898D01*
|
||||
X9724682Y-13149898D02*
|
||||
X9734205Y-13140374D01*
|
||||
X9734205Y-13140374D02*
|
||||
X9734205Y-13159422D01*
|
||||
D14*
|
||||
X8002000Y-13542700D02*
|
||||
X8102000Y-13642700D01*
|
||||
X8102000Y-13542700D02*
|
||||
X8002000Y-13642700D01*
|
||||
D13*
|
||||
X8467539Y-13684184D02*
|
||||
X8353253Y-13684184D01*
|
||||
X8410396Y-13684184D02*
|
||||
X8410396Y-13484184D01*
|
||||
X8410396Y-13484184D02*
|
||||
X8391348Y-13512755D01*
|
||||
X8391348Y-13512755D02*
|
||||
X8372301Y-13531803D01*
|
||||
X8372301Y-13531803D02*
|
||||
X8353253Y-13541327D01*
|
||||
X8553253Y-13665136D02*
|
||||
X8562777Y-13674660D01*
|
||||
X8562777Y-13674660D02*
|
||||
X8553253Y-13684184D01*
|
||||
X8553253Y-13684184D02*
|
||||
X8543729Y-13674660D01*
|
||||
X8543729Y-13674660D02*
|
||||
X8553253Y-13665136D01*
|
||||
X8553253Y-13665136D02*
|
||||
X8553253Y-13684184D01*
|
||||
X8686586Y-13484184D02*
|
||||
X8705634Y-13484184D01*
|
||||
X8705634Y-13484184D02*
|
||||
X8724682Y-13493708D01*
|
||||
X8724682Y-13493708D02*
|
||||
X8734205Y-13503231D01*
|
||||
X8734205Y-13503231D02*
|
||||
X8743729Y-13522279D01*
|
||||
X8743729Y-13522279D02*
|
||||
X8753253Y-13560374D01*
|
||||
X8753253Y-13560374D02*
|
||||
X8753253Y-13607993D01*
|
||||
X8753253Y-13607993D02*
|
||||
X8743729Y-13646088D01*
|
||||
X8743729Y-13646088D02*
|
||||
X8734205Y-13665136D01*
|
||||
X8734205Y-13665136D02*
|
||||
X8724682Y-13674660D01*
|
||||
X8724682Y-13674660D02*
|
||||
X8705634Y-13684184D01*
|
||||
X8705634Y-13684184D02*
|
||||
X8686586Y-13684184D01*
|
||||
X8686586Y-13684184D02*
|
||||
X8667539Y-13674660D01*
|
||||
X8667539Y-13674660D02*
|
||||
X8658015Y-13665136D01*
|
||||
X8658015Y-13665136D02*
|
||||
X8648491Y-13646088D01*
|
||||
X8648491Y-13646088D02*
|
||||
X8638967Y-13607993D01*
|
||||
X8638967Y-13607993D02*
|
||||
X8638967Y-13560374D01*
|
||||
X8638967Y-13560374D02*
|
||||
X8648491Y-13522279D01*
|
||||
X8648491Y-13522279D02*
|
||||
X8658015Y-13503231D01*
|
||||
X8658015Y-13503231D02*
|
||||
X8667539Y-13493708D01*
|
||||
X8667539Y-13493708D02*
|
||||
X8686586Y-13484184D01*
|
||||
X8877063Y-13484184D02*
|
||||
X8896110Y-13484184D01*
|
||||
X8896110Y-13484184D02*
|
||||
X8915158Y-13493708D01*
|
||||
X8915158Y-13493708D02*
|
||||
X8924682Y-13503231D01*
|
||||
X8924682Y-13503231D02*
|
||||
X8934205Y-13522279D01*
|
||||
X8934205Y-13522279D02*
|
||||
X8943729Y-13560374D01*
|
||||
X8943729Y-13560374D02*
|
||||
X8943729Y-13607993D01*
|
||||
X8943729Y-13607993D02*
|
||||
X8934205Y-13646088D01*
|
||||
X8934205Y-13646088D02*
|
||||
X8924682Y-13665136D01*
|
||||
X8924682Y-13665136D02*
|
||||
X8915158Y-13674660D01*
|
||||
X8915158Y-13674660D02*
|
||||
X8896110Y-13684184D01*
|
||||
X8896110Y-13684184D02*
|
||||
X8877063Y-13684184D01*
|
||||
X8877063Y-13684184D02*
|
||||
X8858015Y-13674660D01*
|
||||
X8858015Y-13674660D02*
|
||||
X8848491Y-13665136D01*
|
||||
X8848491Y-13665136D02*
|
||||
X8838967Y-13646088D01*
|
||||
X8838967Y-13646088D02*
|
||||
X8829444Y-13607993D01*
|
||||
X8829444Y-13607993D02*
|
||||
X8829444Y-13560374D01*
|
||||
X8829444Y-13560374D02*
|
||||
X8838967Y-13522279D01*
|
||||
X8838967Y-13522279D02*
|
||||
X8848491Y-13503231D01*
|
||||
X8848491Y-13503231D02*
|
||||
X8858015Y-13493708D01*
|
||||
X8858015Y-13493708D02*
|
||||
X8877063Y-13484184D01*
|
||||
X9067539Y-13484184D02*
|
||||
X9086586Y-13484184D01*
|
||||
X9086586Y-13484184D02*
|
||||
X9105634Y-13493708D01*
|
||||
X9105634Y-13493708D02*
|
||||
X9115158Y-13503231D01*
|
||||
X9115158Y-13503231D02*
|
||||
X9124682Y-13522279D01*
|
||||
X9124682Y-13522279D02*
|
||||
X9134205Y-13560374D01*
|
||||
X9134205Y-13560374D02*
|
||||
X9134205Y-13607993D01*
|
||||
X9134205Y-13607993D02*
|
||||
X9124682Y-13646088D01*
|
||||
X9124682Y-13646088D02*
|
||||
X9115158Y-13665136D01*
|
||||
X9115158Y-13665136D02*
|
||||
X9105634Y-13674660D01*
|
||||
X9105634Y-13674660D02*
|
||||
X9086586Y-13684184D01*
|
||||
X9086586Y-13684184D02*
|
||||
X9067539Y-13684184D01*
|
||||
X9067539Y-13684184D02*
|
||||
X9048491Y-13674660D01*
|
||||
X9048491Y-13674660D02*
|
||||
X9038967Y-13665136D01*
|
||||
X9038967Y-13665136D02*
|
||||
X9029444Y-13646088D01*
|
||||
X9029444Y-13646088D02*
|
||||
X9019920Y-13607993D01*
|
||||
X9019920Y-13607993D02*
|
||||
X9019920Y-13560374D01*
|
||||
X9019920Y-13560374D02*
|
||||
X9029444Y-13522279D01*
|
||||
X9029444Y-13522279D02*
|
||||
X9038967Y-13503231D01*
|
||||
X9038967Y-13503231D02*
|
||||
X9048491Y-13493708D01*
|
||||
X9048491Y-13493708D02*
|
||||
X9067539Y-13484184D01*
|
||||
X9219920Y-13684184D02*
|
||||
X9219920Y-13550850D01*
|
||||
X9219920Y-13569898D02*
|
||||
X9229444Y-13560374D01*
|
||||
X9229444Y-13560374D02*
|
||||
X9248491Y-13550850D01*
|
||||
X9248491Y-13550850D02*
|
||||
X9277063Y-13550850D01*
|
||||
X9277063Y-13550850D02*
|
||||
X9296110Y-13560374D01*
|
||||
X9296110Y-13560374D02*
|
||||
X9305634Y-13579422D01*
|
||||
X9305634Y-13579422D02*
|
||||
X9305634Y-13684184D01*
|
||||
X9305634Y-13579422D02*
|
||||
X9315158Y-13560374D01*
|
||||
X9315158Y-13560374D02*
|
||||
X9334205Y-13550850D01*
|
||||
X9334205Y-13550850D02*
|
||||
X9362777Y-13550850D01*
|
||||
X9362777Y-13550850D02*
|
||||
X9381825Y-13560374D01*
|
||||
X9381825Y-13560374D02*
|
||||
X9391348Y-13579422D01*
|
||||
X9391348Y-13579422D02*
|
||||
X9391348Y-13684184D01*
|
||||
X9486586Y-13684184D02*
|
||||
X9486586Y-13550850D01*
|
||||
X9486586Y-13569898D02*
|
||||
X9496110Y-13560374D01*
|
||||
X9496110Y-13560374D02*
|
||||
X9515158Y-13550850D01*
|
||||
X9515158Y-13550850D02*
|
||||
X9543729Y-13550850D01*
|
||||
X9543729Y-13550850D02*
|
||||
X9562777Y-13560374D01*
|
||||
X9562777Y-13560374D02*
|
||||
X9572301Y-13579422D01*
|
||||
X9572301Y-13579422D02*
|
||||
X9572301Y-13684184D01*
|
||||
X9572301Y-13579422D02*
|
||||
X9581825Y-13560374D01*
|
||||
X9581825Y-13560374D02*
|
||||
X9600872Y-13550850D01*
|
||||
X9600872Y-13550850D02*
|
||||
X9629444Y-13550850D01*
|
||||
X9629444Y-13550850D02*
|
||||
X9648491Y-13560374D01*
|
||||
X9648491Y-13560374D02*
|
||||
X9658015Y-13579422D01*
|
||||
X9658015Y-13579422D02*
|
||||
X9658015Y-13684184D01*
|
||||
X10048491Y-13474660D02*
|
||||
X9877063Y-13731803D01*
|
||||
X10305634Y-13484184D02*
|
||||
X10324682Y-13484184D01*
|
||||
X10324682Y-13484184D02*
|
||||
X10343729Y-13493708D01*
|
||||
X10343729Y-13493708D02*
|
||||
X10353253Y-13503231D01*
|
||||
X10353253Y-13503231D02*
|
||||
X10362777Y-13522279D01*
|
||||
X10362777Y-13522279D02*
|
||||
X10372301Y-13560374D01*
|
||||
X10372301Y-13560374D02*
|
||||
X10372301Y-13607993D01*
|
||||
X10372301Y-13607993D02*
|
||||
X10362777Y-13646088D01*
|
||||
X10362777Y-13646088D02*
|
||||
X10353253Y-13665136D01*
|
||||
X10353253Y-13665136D02*
|
||||
X10343729Y-13674660D01*
|
||||
X10343729Y-13674660D02*
|
||||
X10324682Y-13684184D01*
|
||||
X10324682Y-13684184D02*
|
||||
X10305634Y-13684184D01*
|
||||
X10305634Y-13684184D02*
|
||||
X10286587Y-13674660D01*
|
||||
X10286587Y-13674660D02*
|
||||
X10277063Y-13665136D01*
|
||||
X10277063Y-13665136D02*
|
||||
X10267539Y-13646088D01*
|
||||
X10267539Y-13646088D02*
|
||||
X10258015Y-13607993D01*
|
||||
X10258015Y-13607993D02*
|
||||
X10258015Y-13560374D01*
|
||||
X10258015Y-13560374D02*
|
||||
X10267539Y-13522279D01*
|
||||
X10267539Y-13522279D02*
|
||||
X10277063Y-13503231D01*
|
||||
X10277063Y-13503231D02*
|
||||
X10286587Y-13493708D01*
|
||||
X10286587Y-13493708D02*
|
||||
X10305634Y-13484184D01*
|
||||
X10458015Y-13665136D02*
|
||||
X10467539Y-13674660D01*
|
||||
X10467539Y-13674660D02*
|
||||
X10458015Y-13684184D01*
|
||||
X10458015Y-13684184D02*
|
||||
X10448491Y-13674660D01*
|
||||
X10448491Y-13674660D02*
|
||||
X10458015Y-13665136D01*
|
||||
X10458015Y-13665136D02*
|
||||
X10458015Y-13684184D01*
|
||||
X10591348Y-13484184D02*
|
||||
X10610396Y-13484184D01*
|
||||
X10610396Y-13484184D02*
|
||||
X10629444Y-13493708D01*
|
||||
X10629444Y-13493708D02*
|
||||
X10638968Y-13503231D01*
|
||||
X10638968Y-13503231D02*
|
||||
X10648491Y-13522279D01*
|
||||
X10648491Y-13522279D02*
|
||||
X10658015Y-13560374D01*
|
||||
X10658015Y-13560374D02*
|
||||
X10658015Y-13607993D01*
|
||||
X10658015Y-13607993D02*
|
||||
X10648491Y-13646088D01*
|
||||
X10648491Y-13646088D02*
|
||||
X10638968Y-13665136D01*
|
||||
X10638968Y-13665136D02*
|
||||
X10629444Y-13674660D01*
|
||||
X10629444Y-13674660D02*
|
||||
X10610396Y-13684184D01*
|
||||
X10610396Y-13684184D02*
|
||||
X10591348Y-13684184D01*
|
||||
X10591348Y-13684184D02*
|
||||
X10572301Y-13674660D01*
|
||||
X10572301Y-13674660D02*
|
||||
X10562777Y-13665136D01*
|
||||
X10562777Y-13665136D02*
|
||||
X10553253Y-13646088D01*
|
||||
X10553253Y-13646088D02*
|
||||
X10543729Y-13607993D01*
|
||||
X10543729Y-13607993D02*
|
||||
X10543729Y-13560374D01*
|
||||
X10543729Y-13560374D02*
|
||||
X10553253Y-13522279D01*
|
||||
X10553253Y-13522279D02*
|
||||
X10562777Y-13503231D01*
|
||||
X10562777Y-13503231D02*
|
||||
X10572301Y-13493708D01*
|
||||
X10572301Y-13493708D02*
|
||||
X10591348Y-13484184D01*
|
||||
X10724682Y-13484184D02*
|
||||
X10848491Y-13484184D01*
|
||||
X10848491Y-13484184D02*
|
||||
X10781825Y-13560374D01*
|
||||
X10781825Y-13560374D02*
|
||||
X10810396Y-13560374D01*
|
||||
X10810396Y-13560374D02*
|
||||
X10829444Y-13569898D01*
|
||||
X10829444Y-13569898D02*
|
||||
X10838968Y-13579422D01*
|
||||
X10838968Y-13579422D02*
|
||||
X10848491Y-13598469D01*
|
||||
X10848491Y-13598469D02*
|
||||
X10848491Y-13646088D01*
|
||||
X10848491Y-13646088D02*
|
||||
X10838968Y-13665136D01*
|
||||
X10838968Y-13665136D02*
|
||||
X10829444Y-13674660D01*
|
||||
X10829444Y-13674660D02*
|
||||
X10810396Y-13684184D01*
|
||||
X10810396Y-13684184D02*
|
||||
X10753253Y-13684184D01*
|
||||
X10753253Y-13684184D02*
|
||||
X10734206Y-13674660D01*
|
||||
X10734206Y-13674660D02*
|
||||
X10724682Y-13665136D01*
|
||||
X10943729Y-13684184D02*
|
||||
X10981825Y-13684184D01*
|
||||
X10981825Y-13684184D02*
|
||||
X11000872Y-13674660D01*
|
||||
X11000872Y-13674660D02*
|
||||
X11010396Y-13665136D01*
|
||||
X11010396Y-13665136D02*
|
||||
X11029444Y-13636565D01*
|
||||
X11029444Y-13636565D02*
|
||||
X11038968Y-13598469D01*
|
||||
X11038968Y-13598469D02*
|
||||
X11038968Y-13522279D01*
|
||||
X11038968Y-13522279D02*
|
||||
X11029444Y-13503231D01*
|
||||
X11029444Y-13503231D02*
|
||||
X11019920Y-13493708D01*
|
||||
X11019920Y-13493708D02*
|
||||
X11000872Y-13484184D01*
|
||||
X11000872Y-13484184D02*
|
||||
X10962777Y-13484184D01*
|
||||
X10962777Y-13484184D02*
|
||||
X10943729Y-13493708D01*
|
||||
X10943729Y-13493708D02*
|
||||
X10934206Y-13503231D01*
|
||||
X10934206Y-13503231D02*
|
||||
X10924682Y-13522279D01*
|
||||
X10924682Y-13522279D02*
|
||||
X10924682Y-13569898D01*
|
||||
X10924682Y-13569898D02*
|
||||
X10934206Y-13588946D01*
|
||||
X10934206Y-13588946D02*
|
||||
X10943729Y-13598469D01*
|
||||
X10943729Y-13598469D02*
|
||||
X10962777Y-13607993D01*
|
||||
X10962777Y-13607993D02*
|
||||
X11000872Y-13607993D01*
|
||||
X11000872Y-13607993D02*
|
||||
X11019920Y-13598469D01*
|
||||
X11019920Y-13598469D02*
|
||||
X11029444Y-13588946D01*
|
||||
X11029444Y-13588946D02*
|
||||
X11038968Y-13569898D01*
|
||||
X11210396Y-13550850D02*
|
||||
X11210396Y-13684184D01*
|
||||
X11162777Y-13474660D02*
|
||||
X11115158Y-13617517D01*
|
||||
X11115158Y-13617517D02*
|
||||
X11238967Y-13617517D01*
|
||||
X11305634Y-13484184D02*
|
||||
X11305634Y-13522279D01*
|
||||
X11381825Y-13484184D02*
|
||||
X11381825Y-13522279D01*
|
||||
X11677063Y-13760374D02*
|
||||
X11667539Y-13750850D01*
|
||||
X11667539Y-13750850D02*
|
||||
X11648491Y-13722279D01*
|
||||
X11648491Y-13722279D02*
|
||||
X11638968Y-13703231D01*
|
||||
X11638968Y-13703231D02*
|
||||
X11629444Y-13674660D01*
|
||||
X11629444Y-13674660D02*
|
||||
X11619920Y-13627041D01*
|
||||
X11619920Y-13627041D02*
|
||||
X11619920Y-13588946D01*
|
||||
X11619920Y-13588946D02*
|
||||
X11629444Y-13541327D01*
|
||||
X11629444Y-13541327D02*
|
||||
X11638968Y-13512755D01*
|
||||
X11638968Y-13512755D02*
|
||||
X11648491Y-13493708D01*
|
||||
X11648491Y-13493708D02*
|
||||
X11667539Y-13465136D01*
|
||||
X11667539Y-13465136D02*
|
||||
X11677063Y-13455612D01*
|
||||
X11743729Y-13503231D02*
|
||||
X11753253Y-13493708D01*
|
||||
X11753253Y-13493708D02*
|
||||
X11772301Y-13484184D01*
|
||||
X11772301Y-13484184D02*
|
||||
X11819920Y-13484184D01*
|
||||
X11819920Y-13484184D02*
|
||||
X11838968Y-13493708D01*
|
||||
X11838968Y-13493708D02*
|
||||
X11848491Y-13503231D01*
|
||||
X11848491Y-13503231D02*
|
||||
X11858015Y-13522279D01*
|
||||
X11858015Y-13522279D02*
|
||||
X11858015Y-13541327D01*
|
||||
X11858015Y-13541327D02*
|
||||
X11848491Y-13569898D01*
|
||||
X11848491Y-13569898D02*
|
||||
X11734206Y-13684184D01*
|
||||
X11734206Y-13684184D02*
|
||||
X11858015Y-13684184D01*
|
||||
X12096110Y-13684184D02*
|
||||
X12096110Y-13484184D01*
|
||||
X12181825Y-13684184D02*
|
||||
X12181825Y-13579422D01*
|
||||
X12181825Y-13579422D02*
|
||||
X12172301Y-13560374D01*
|
||||
X12172301Y-13560374D02*
|
||||
X12153253Y-13550850D01*
|
||||
X12153253Y-13550850D02*
|
||||
X12124682Y-13550850D01*
|
||||
X12124682Y-13550850D02*
|
||||
X12105634Y-13560374D01*
|
||||
X12105634Y-13560374D02*
|
||||
X12096110Y-13569898D01*
|
||||
X12305634Y-13684184D02*
|
||||
X12286587Y-13674660D01*
|
||||
X12286587Y-13674660D02*
|
||||
X12277063Y-13665136D01*
|
||||
X12277063Y-13665136D02*
|
||||
X12267539Y-13646088D01*
|
||||
X12267539Y-13646088D02*
|
||||
X12267539Y-13588946D01*
|
||||
X12267539Y-13588946D02*
|
||||
X12277063Y-13569898D01*
|
||||
X12277063Y-13569898D02*
|
||||
X12286587Y-13560374D01*
|
||||
X12286587Y-13560374D02*
|
||||
X12305634Y-13550850D01*
|
||||
X12305634Y-13550850D02*
|
||||
X12334206Y-13550850D01*
|
||||
X12334206Y-13550850D02*
|
||||
X12353253Y-13560374D01*
|
||||
X12353253Y-13560374D02*
|
||||
X12362777Y-13569898D01*
|
||||
X12362777Y-13569898D02*
|
||||
X12372301Y-13588946D01*
|
||||
X12372301Y-13588946D02*
|
||||
X12372301Y-13646088D01*
|
||||
X12372301Y-13646088D02*
|
||||
X12362777Y-13665136D01*
|
||||
X12362777Y-13665136D02*
|
||||
X12353253Y-13674660D01*
|
||||
X12353253Y-13674660D02*
|
||||
X12334206Y-13684184D01*
|
||||
X12334206Y-13684184D02*
|
||||
X12305634Y-13684184D01*
|
||||
X12486587Y-13684184D02*
|
||||
X12467539Y-13674660D01*
|
||||
X12467539Y-13674660D02*
|
||||
X12458015Y-13655612D01*
|
||||
X12458015Y-13655612D02*
|
||||
X12458015Y-13484184D01*
|
||||
X12638968Y-13674660D02*
|
||||
X12619920Y-13684184D01*
|
||||
X12619920Y-13684184D02*
|
||||
X12581825Y-13684184D01*
|
||||
X12581825Y-13684184D02*
|
||||
X12562777Y-13674660D01*
|
||||
X12562777Y-13674660D02*
|
||||
X12553253Y-13655612D01*
|
||||
X12553253Y-13655612D02*
|
||||
X12553253Y-13579422D01*
|
||||
X12553253Y-13579422D02*
|
||||
X12562777Y-13560374D01*
|
||||
X12562777Y-13560374D02*
|
||||
X12581825Y-13550850D01*
|
||||
X12581825Y-13550850D02*
|
||||
X12619920Y-13550850D01*
|
||||
X12619920Y-13550850D02*
|
||||
X12638968Y-13560374D01*
|
||||
X12638968Y-13560374D02*
|
||||
X12648491Y-13579422D01*
|
||||
X12648491Y-13579422D02*
|
||||
X12648491Y-13598469D01*
|
||||
X12648491Y-13598469D02*
|
||||
X12553253Y-13617517D01*
|
||||
X12724682Y-13674660D02*
|
||||
X12743730Y-13684184D01*
|
||||
X12743730Y-13684184D02*
|
||||
X12781825Y-13684184D01*
|
||||
X12781825Y-13684184D02*
|
||||
X12800872Y-13674660D01*
|
||||
X12800872Y-13674660D02*
|
||||
X12810396Y-13655612D01*
|
||||
X12810396Y-13655612D02*
|
||||
X12810396Y-13646088D01*
|
||||
X12810396Y-13646088D02*
|
||||
X12800872Y-13627041D01*
|
||||
X12800872Y-13627041D02*
|
||||
X12781825Y-13617517D01*
|
||||
X12781825Y-13617517D02*
|
||||
X12753253Y-13617517D01*
|
||||
X12753253Y-13617517D02*
|
||||
X12734206Y-13607993D01*
|
||||
X12734206Y-13607993D02*
|
||||
X12724682Y-13588946D01*
|
||||
X12724682Y-13588946D02*
|
||||
X12724682Y-13579422D01*
|
||||
X12724682Y-13579422D02*
|
||||
X12734206Y-13560374D01*
|
||||
X12734206Y-13560374D02*
|
||||
X12753253Y-13550850D01*
|
||||
X12753253Y-13550850D02*
|
||||
X12781825Y-13550850D01*
|
||||
X12781825Y-13550850D02*
|
||||
X12800872Y-13560374D01*
|
||||
X12877063Y-13760374D02*
|
||||
X12886587Y-13750850D01*
|
||||
X12886587Y-13750850D02*
|
||||
X12905634Y-13722279D01*
|
||||
X12905634Y-13722279D02*
|
||||
X12915158Y-13703231D01*
|
||||
X12915158Y-13703231D02*
|
||||
X12924682Y-13674660D01*
|
||||
X12924682Y-13674660D02*
|
||||
X12934206Y-13627041D01*
|
||||
X12934206Y-13627041D02*
|
||||
X12934206Y-13588946D01*
|
||||
X12934206Y-13588946D02*
|
||||
X12924682Y-13541327D01*
|
||||
X12924682Y-13541327D02*
|
||||
X12915158Y-13512755D01*
|
||||
X12915158Y-13512755D02*
|
||||
X12905634Y-13493708D01*
|
||||
X12905634Y-13493708D02*
|
||||
X12886587Y-13465136D01*
|
||||
X12886587Y-13465136D02*
|
||||
X12877063Y-13455612D01*
|
||||
X13238968Y-13760374D02*
|
||||
X13229444Y-13750850D01*
|
||||
X13229444Y-13750850D02*
|
||||
X13210396Y-13722279D01*
|
||||
X13210396Y-13722279D02*
|
||||
X13200872Y-13703231D01*
|
||||
X13200872Y-13703231D02*
|
||||
X13191349Y-13674660D01*
|
||||
X13191349Y-13674660D02*
|
||||
X13181825Y-13627041D01*
|
||||
X13181825Y-13627041D02*
|
||||
X13181825Y-13588946D01*
|
||||
X13181825Y-13588946D02*
|
||||
X13191349Y-13541327D01*
|
||||
X13191349Y-13541327D02*
|
||||
X13200872Y-13512755D01*
|
||||
X13200872Y-13512755D02*
|
||||
X13210396Y-13493708D01*
|
||||
X13210396Y-13493708D02*
|
||||
X13229444Y-13465136D01*
|
||||
X13229444Y-13465136D02*
|
||||
X13238968Y-13455612D01*
|
||||
X13315158Y-13550850D02*
|
||||
X13315158Y-13684184D01*
|
||||
X13315158Y-13569898D02*
|
||||
X13324682Y-13560374D01*
|
||||
X13324682Y-13560374D02*
|
||||
X13343730Y-13550850D01*
|
||||
X13343730Y-13550850D02*
|
||||
X13372301Y-13550850D01*
|
||||
X13372301Y-13550850D02*
|
||||
X13391349Y-13560374D01*
|
||||
X13391349Y-13560374D02*
|
||||
X13400872Y-13579422D01*
|
||||
X13400872Y-13579422D02*
|
||||
X13400872Y-13684184D01*
|
||||
X13524682Y-13684184D02*
|
||||
X13505634Y-13674660D01*
|
||||
X13505634Y-13674660D02*
|
||||
X13496111Y-13665136D01*
|
||||
X13496111Y-13665136D02*
|
||||
X13486587Y-13646088D01*
|
||||
X13486587Y-13646088D02*
|
||||
X13486587Y-13588946D01*
|
||||
X13486587Y-13588946D02*
|
||||
X13496111Y-13569898D01*
|
||||
X13496111Y-13569898D02*
|
||||
X13505634Y-13560374D01*
|
||||
X13505634Y-13560374D02*
|
||||
X13524682Y-13550850D01*
|
||||
X13524682Y-13550850D02*
|
||||
X13553253Y-13550850D01*
|
||||
X13553253Y-13550850D02*
|
||||
X13572301Y-13560374D01*
|
||||
X13572301Y-13560374D02*
|
||||
X13581825Y-13569898D01*
|
||||
X13581825Y-13569898D02*
|
||||
X13591349Y-13588946D01*
|
||||
X13591349Y-13588946D02*
|
||||
X13591349Y-13646088D01*
|
||||
X13591349Y-13646088D02*
|
||||
X13581825Y-13665136D01*
|
||||
X13581825Y-13665136D02*
|
||||
X13572301Y-13674660D01*
|
||||
X13572301Y-13674660D02*
|
||||
X13553253Y-13684184D01*
|
||||
X13553253Y-13684184D02*
|
||||
X13524682Y-13684184D01*
|
||||
X13648492Y-13550850D02*
|
||||
X13724682Y-13550850D01*
|
||||
X13677063Y-13484184D02*
|
||||
X13677063Y-13655612D01*
|
||||
X13677063Y-13655612D02*
|
||||
X13686587Y-13674660D01*
|
||||
X13686587Y-13674660D02*
|
||||
X13705634Y-13684184D01*
|
||||
X13705634Y-13684184D02*
|
||||
X13724682Y-13684184D01*
|
||||
X13943730Y-13550850D02*
|
||||
X13943730Y-13750850D01*
|
||||
X13943730Y-13560374D02*
|
||||
X13962777Y-13550850D01*
|
||||
X13962777Y-13550850D02*
|
||||
X14000873Y-13550850D01*
|
||||
X14000873Y-13550850D02*
|
||||
X14019920Y-13560374D01*
|
||||
X14019920Y-13560374D02*
|
||||
X14029444Y-13569898D01*
|
||||
X14029444Y-13569898D02*
|
||||
X14038968Y-13588946D01*
|
||||
X14038968Y-13588946D02*
|
||||
X14038968Y-13646088D01*
|
||||
X14038968Y-13646088D02*
|
||||
X14029444Y-13665136D01*
|
||||
X14029444Y-13665136D02*
|
||||
X14019920Y-13674660D01*
|
||||
X14019920Y-13674660D02*
|
||||
X14000873Y-13684184D01*
|
||||
X14000873Y-13684184D02*
|
||||
X13962777Y-13684184D01*
|
||||
X13962777Y-13684184D02*
|
||||
X13943730Y-13674660D01*
|
||||
X14153253Y-13684184D02*
|
||||
X14134206Y-13674660D01*
|
||||
X14134206Y-13674660D02*
|
||||
X14124682Y-13655612D01*
|
||||
X14124682Y-13655612D02*
|
||||
X14124682Y-13484184D01*
|
||||
X14315158Y-13684184D02*
|
||||
X14315158Y-13579422D01*
|
||||
X14315158Y-13579422D02*
|
||||
X14305634Y-13560374D01*
|
||||
X14305634Y-13560374D02*
|
||||
X14286587Y-13550850D01*
|
||||
X14286587Y-13550850D02*
|
||||
X14248492Y-13550850D01*
|
||||
X14248492Y-13550850D02*
|
||||
X14229444Y-13560374D01*
|
||||
X14315158Y-13674660D02*
|
||||
X14296111Y-13684184D01*
|
||||
X14296111Y-13684184D02*
|
||||
X14248492Y-13684184D01*
|
||||
X14248492Y-13684184D02*
|
||||
X14229444Y-13674660D01*
|
||||
X14229444Y-13674660D02*
|
||||
X14219920Y-13655612D01*
|
||||
X14219920Y-13655612D02*
|
||||
X14219920Y-13636565D01*
|
||||
X14219920Y-13636565D02*
|
||||
X14229444Y-13617517D01*
|
||||
X14229444Y-13617517D02*
|
||||
X14248492Y-13607993D01*
|
||||
X14248492Y-13607993D02*
|
||||
X14296111Y-13607993D01*
|
||||
X14296111Y-13607993D02*
|
||||
X14315158Y-13598469D01*
|
||||
X14381825Y-13550850D02*
|
||||
X14458015Y-13550850D01*
|
||||
X14410396Y-13484184D02*
|
||||
X14410396Y-13655612D01*
|
||||
X14410396Y-13655612D02*
|
||||
X14419920Y-13674660D01*
|
||||
X14419920Y-13674660D02*
|
||||
X14438968Y-13684184D01*
|
||||
X14438968Y-13684184D02*
|
||||
X14458015Y-13684184D01*
|
||||
X14600873Y-13674660D02*
|
||||
X14581825Y-13684184D01*
|
||||
X14581825Y-13684184D02*
|
||||
X14543730Y-13684184D01*
|
||||
X14543730Y-13684184D02*
|
||||
X14524682Y-13674660D01*
|
||||
X14524682Y-13674660D02*
|
||||
X14515158Y-13655612D01*
|
||||
X14515158Y-13655612D02*
|
||||
X14515158Y-13579422D01*
|
||||
X14515158Y-13579422D02*
|
||||
X14524682Y-13560374D01*
|
||||
X14524682Y-13560374D02*
|
||||
X14543730Y-13550850D01*
|
||||
X14543730Y-13550850D02*
|
||||
X14581825Y-13550850D01*
|
||||
X14581825Y-13550850D02*
|
||||
X14600873Y-13560374D01*
|
||||
X14600873Y-13560374D02*
|
||||
X14610396Y-13579422D01*
|
||||
X14610396Y-13579422D02*
|
||||
X14610396Y-13598469D01*
|
||||
X14610396Y-13598469D02*
|
||||
X14515158Y-13617517D01*
|
||||
X14781825Y-13684184D02*
|
||||
X14781825Y-13484184D01*
|
||||
X14781825Y-13674660D02*
|
||||
X14762777Y-13684184D01*
|
||||
X14762777Y-13684184D02*
|
||||
X14724682Y-13684184D01*
|
||||
X14724682Y-13684184D02*
|
||||
X14705634Y-13674660D01*
|
||||
X14705634Y-13674660D02*
|
||||
X14696111Y-13665136D01*
|
||||
X14696111Y-13665136D02*
|
||||
X14686587Y-13646088D01*
|
||||
X14686587Y-13646088D02*
|
||||
X14686587Y-13588946D01*
|
||||
X14686587Y-13588946D02*
|
||||
X14696111Y-13569898D01*
|
||||
X14696111Y-13569898D02*
|
||||
X14705634Y-13560374D01*
|
||||
X14705634Y-13560374D02*
|
||||
X14724682Y-13550850D01*
|
||||
X14724682Y-13550850D02*
|
||||
X14762777Y-13550850D01*
|
||||
X14762777Y-13550850D02*
|
||||
X14781825Y-13560374D01*
|
||||
X14858015Y-13760374D02*
|
||||
X14867539Y-13750850D01*
|
||||
X14867539Y-13750850D02*
|
||||
X14886587Y-13722279D01*
|
||||
X14886587Y-13722279D02*
|
||||
X14896111Y-13703231D01*
|
||||
X14896111Y-13703231D02*
|
||||
X14905634Y-13674660D01*
|
||||
X14905634Y-13674660D02*
|
||||
X14915158Y-13627041D01*
|
||||
X14915158Y-13627041D02*
|
||||
X14915158Y-13588946D01*
|
||||
X14915158Y-13588946D02*
|
||||
X14905634Y-13541327D01*
|
||||
X14905634Y-13541327D02*
|
||||
X14896111Y-13512755D01*
|
||||
X14896111Y-13512755D02*
|
||||
X14886587Y-13493708D01*
|
||||
X14886587Y-13493708D02*
|
||||
X14867539Y-13465136D01*
|
||||
X14867539Y-13465136D02*
|
||||
X14858015Y-13455612D01*
|
||||
M02*
|
||||
@@ -1,17 +0,0 @@
|
||||
M48
|
||||
; DRILL file {KiCad 9.0.3} date 2025-08-23T15:15:25+0200
|
||||
; FORMAT={-:-/ absolute / metric / decimal}
|
||||
; #@! TF.CreationDate,2025-08-23T15:15:25+02:00
|
||||
; #@! TF.GenerationSoftware,Kicad,Pcbnew,9.0.3
|
||||
; #@! TF.FileFunction,NonPlated,1,6,NPTH
|
||||
FMAT,2
|
||||
METRIC
|
||||
; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill
|
||||
T1C1.000
|
||||
%
|
||||
G90
|
||||
G05
|
||||
T1
|
||||
X117.75Y-83.6
|
||||
X125.75Y-83.6
|
||||
M30
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,244 +0,0 @@
|
||||
M48
|
||||
; DRILL file {KiCad 9.0.3} date 2025-08-23T15:15:25+0200
|
||||
; FORMAT={-:-/ absolute / metric / decimal}
|
||||
; #@! TF.CreationDate,2025-08-23T15:15:25+02:00
|
||||
; #@! TF.GenerationSoftware,Kicad,Pcbnew,9.0.3
|
||||
; #@! TF.FileFunction,Plated,1,6,PTH
|
||||
FMAT,2
|
||||
METRIC
|
||||
; #@! TA.AperFunction,Plated,PTH,ViaDrill
|
||||
T1C0.200
|
||||
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
|
||||
T2C0.800
|
||||
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
|
||||
T3C0.850
|
||||
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
|
||||
T4C1.400
|
||||
%
|
||||
G90
|
||||
G05
|
||||
T1
|
||||
X82.677Y-80.645
|
||||
X83.185Y-110.49
|
||||
X83.5Y-92.212
|
||||
X83.95Y-112.96
|
||||
X84.328Y-126.873
|
||||
X84.582Y-116.967
|
||||
X84.709Y-80.645
|
||||
X85.979Y-97.79
|
||||
X86.487Y-99.822
|
||||
X86.741Y-80.645
|
||||
X87.505Y-126.494
|
||||
X88.011Y-117.475
|
||||
X88.519Y-103.124
|
||||
X88.773Y-80.645
|
||||
X90.0Y-109.087
|
||||
X90.0Y-114.912
|
||||
X90.412Y-97.0
|
||||
X90.412Y-99.0
|
||||
X90.805Y-80.645
|
||||
X91.694Y-127.889
|
||||
X92.583Y-119.888
|
||||
X92.71Y-98.044
|
||||
X92.837Y-80.645
|
||||
X94.488Y-124.206
|
||||
X94.488Y-125.73
|
||||
X94.869Y-80.645
|
||||
X94.869Y-128.397
|
||||
X95.25Y-113.157
|
||||
X95.377Y-118.364
|
||||
X95.618Y-98.552
|
||||
X95.885Y-101.092
|
||||
X96.774Y-120.904
|
||||
X96.774Y-121.539
|
||||
X96.774Y-122.174
|
||||
X96.774Y-123.444
|
||||
X96.774Y-124.079
|
||||
X96.774Y-124.714
|
||||
X96.901Y-80.645
|
||||
X96.901Y-128.397
|
||||
X96.926Y-126.086
|
||||
X96.926Y-126.644
|
||||
X96.926Y-127.203
|
||||
X97.168Y-98.552
|
||||
X97.663Y-114.046
|
||||
X97.663Y-116.332
|
||||
X97.663Y-120.904
|
||||
X97.663Y-121.539
|
||||
X97.663Y-122.174
|
||||
X97.663Y-123.444
|
||||
X97.663Y-124.079
|
||||
X97.663Y-124.714
|
||||
X97.688Y-126.086
|
||||
X97.688Y-126.644
|
||||
X97.688Y-127.203
|
||||
X98.044Y-102.362
|
||||
X98.044Y-103.632
|
||||
X98.044Y-104.902
|
||||
X98.044Y-106.172
|
||||
X98.552Y-94.361
|
||||
X98.552Y-120.904
|
||||
X98.552Y-121.539
|
||||
X98.552Y-122.174
|
||||
X98.552Y-123.444
|
||||
X98.552Y-124.079
|
||||
X98.552Y-124.714
|
||||
X98.603Y-126.086
|
||||
X98.603Y-126.644
|
||||
X98.603Y-127.203
|
||||
X98.933Y-80.645
|
||||
X98.933Y-128.397
|
||||
X100.965Y-80.645
|
||||
X100.965Y-128.397
|
||||
X102.489Y-98.552
|
||||
X102.616Y-94.361
|
||||
X102.743Y-123.317
|
||||
X102.997Y-80.645
|
||||
X102.997Y-128.397
|
||||
X103.886Y-107.95
|
||||
X104.267Y-119.761
|
||||
X104.267Y-120.396
|
||||
X104.521Y-125.095
|
||||
X104.648Y-97.663
|
||||
X104.902Y-119.761
|
||||
X104.902Y-120.396
|
||||
X105.029Y-80.645
|
||||
X105.029Y-112.522
|
||||
X105.029Y-113.411
|
||||
X105.475Y-105.0
|
||||
X107.061Y-80.645
|
||||
X107.315Y-112.903
|
||||
X107.315Y-113.665
|
||||
X107.315Y-114.3
|
||||
X107.442Y-107.95
|
||||
X107.823Y-112.903
|
||||
X107.823Y-113.665
|
||||
X107.823Y-114.3
|
||||
X108.839Y-120.396
|
||||
X108.966Y-98.552
|
||||
X108.966Y-112.014
|
||||
X109.093Y-80.645
|
||||
X109.093Y-128.397
|
||||
X109.22Y-97.282
|
||||
X109.791Y-110.68
|
||||
X110.109Y-123.571
|
||||
X110.49Y-115.189
|
||||
X110.744Y-101.092
|
||||
X110.744Y-102.362
|
||||
X110.744Y-103.632
|
||||
X110.744Y-104.902
|
||||
X110.744Y-106.172
|
||||
X110.871Y-123.571
|
||||
X111.125Y-80.645
|
||||
X111.125Y-128.397
|
||||
X111.379Y-107.95
|
||||
X112.903Y-83.947
|
||||
X112.903Y-118.491
|
||||
X113.157Y-80.645
|
||||
X113.157Y-128.397
|
||||
X113.411Y-93.853
|
||||
X113.792Y-126.746
|
||||
X113.822Y-116.438
|
||||
X115.189Y-80.645
|
||||
X115.189Y-128.397
|
||||
X115.443Y-91.821
|
||||
X115.951Y-117.094
|
||||
X116.0Y-102.412
|
||||
X116.078Y-118.491
|
||||
X116.332Y-125.984
|
||||
X116.459Y-125.476
|
||||
X116.967Y-125.349
|
||||
X117.221Y-80.645
|
||||
X117.221Y-128.397
|
||||
X117.475Y-116.84
|
||||
X117.705Y-113.56
|
||||
X117.705Y-115.443
|
||||
X117.729Y-123.571
|
||||
X118.0Y-102.412
|
||||
X118.237Y-110.998
|
||||
X118.364Y-123.571
|
||||
X118.491Y-99.06
|
||||
X118.55Y-94.65
|
||||
X119.253Y-80.645
|
||||
X119.253Y-128.397
|
||||
X119.634Y-126.492
|
||||
X119.634Y-127.0
|
||||
X119.634Y-127.508
|
||||
X119.65Y-94.65
|
||||
X119.761Y-92.329
|
||||
X119.761Y-110.998
|
||||
X120.0Y-102.412
|
||||
X120.0Y-121.0
|
||||
X120.015Y-99.441
|
||||
X120.015Y-119.253
|
||||
X120.294Y-113.589
|
||||
X120.75Y-94.65
|
||||
X121.285Y-80.645
|
||||
X121.285Y-128.397
|
||||
X121.92Y-94.234
|
||||
X121.92Y-95.123
|
||||
X122.0Y-100.587
|
||||
X122.0Y-102.412
|
||||
X122.047Y-99.06
|
||||
X122.174Y-97.536
|
||||
X122.174Y-126.619
|
||||
X122.174Y-127.381
|
||||
X122.301Y-111.887
|
||||
X122.301Y-115.697
|
||||
X122.5Y-119.087
|
||||
X122.5Y-120.912
|
||||
X122.53Y-126.949
|
||||
X122.936Y-94.65
|
||||
X122.936Y-126.619
|
||||
X122.936Y-127.381
|
||||
X123.317Y-80.645
|
||||
X123.317Y-128.397
|
||||
X123.825Y-97.536
|
||||
X124.0Y-102.412
|
||||
X124.079Y-94.234
|
||||
X124.079Y-94.996
|
||||
X125.15Y-94.65
|
||||
X125.349Y-80.645
|
||||
X125.349Y-128.397
|
||||
X125.73Y-92.837
|
||||
X125.984Y-114.046
|
||||
X125.984Y-115.57
|
||||
X126.0Y-102.412
|
||||
X126.25Y-94.65
|
||||
X126.873Y-97.536
|
||||
X127.35Y-94.65
|
||||
X127.381Y-80.645
|
||||
X127.381Y-128.397
|
||||
X128.0Y-102.5
|
||||
X128.219Y-113.284
|
||||
X128.219Y-114.198
|
||||
X128.27Y-115.824
|
||||
X128.27Y-116.713
|
||||
X128.651Y-83.947
|
||||
X128.905Y-93.599
|
||||
X128.981Y-113.741
|
||||
X129.0Y-116.27
|
||||
X129.413Y-80.645
|
||||
X129.413Y-128.397
|
||||
X129.642Y-113.335
|
||||
X129.642Y-114.249
|
||||
X129.794Y-115.824
|
||||
X129.794Y-116.713
|
||||
T2
|
||||
X89.916Y-118.888
|
||||
X89.916Y-120.888
|
||||
T3
|
||||
X92.911Y-103.378
|
||||
X113.411Y-103.378
|
||||
T4
|
||||
X89.5Y-59.52
|
||||
X89.5Y-62.06
|
||||
X89.5Y-87.46
|
||||
X89.5Y-90.0
|
||||
X89.5Y-92.54
|
||||
X104.74Y-82.38
|
||||
X104.74Y-84.92
|
||||
X104.74Y-87.46
|
||||
X104.74Y-90.0
|
||||
X104.74Y-92.54
|
||||
M30
|
||||
BIN
pcb/production/fw-anwesenheit.zip
Normal file
BIN
pcb/production/fw-anwesenheit.zip
Normal file
Binary file not shown.
354
pcb/production/netlist.ipc
Normal file
354
pcb/production/netlist.ipc
Normal file
@@ -0,0 +1,354 @@
|
||||
P CODE 00
|
||||
P UNITS CUST 0
|
||||
P arrayDim N
|
||||
317GND VIA MD0118PA00X+035433Y-045241X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+047750Y-050550X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+046550Y-043700X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+046950Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+044450Y-033050X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+043600Y-040300X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+050950Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+038800Y-048850X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+034150Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+040550Y-050550X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+044550Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+040120Y-047880X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+048850Y-037100X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+049500Y-036550X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+036500Y-038600X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+042300Y-042500X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+040900Y-042500X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+048750Y-038400X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+041150Y-049250X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+038800Y-049100X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+034850Y-040600X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+051100Y-045600X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+047150Y-036350X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+048100Y-050150X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+034950Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+033051Y-044472X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+043600Y-041800X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+044650Y-036950X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+046340Y-045450X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+038450Y-048600X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+047750Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+049600Y-045500X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+050787Y-045776X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+034050Y-039300X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+049350Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+038950Y-050550X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+042850Y-047400X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+038600Y-041300X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+050500Y-045950X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+048100Y-049850X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+050950Y-050550X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+037200Y-048900X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+035750Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+038600Y-041800X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+033200Y-049950X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+049950Y-038400X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+050150Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+033350Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+044550Y-050550X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+043600Y-039800X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+043600Y-041300X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+042950Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+047250Y-039150X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+046340Y-044709X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+041350Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+041200Y-038450X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+048400Y-049850X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+037350Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+037350Y-050550X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+050750Y-036850X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+032550Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+037550Y-046600X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+045450Y-036150X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+046950Y-050550X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+048420Y-050150X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+038950Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+043850Y-042500X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+038150Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+045350Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+046150Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+038100Y-048600X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+046650Y-039000X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+043750Y-050550X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+048550Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+045350Y-050550X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+043750Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+050150Y-050550X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+051100Y-045950X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+046150Y-050550X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+038800Y-048600X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+048050Y-039000X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+043500Y-045350X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+048550Y-050550X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+040550Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+036550Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+049350Y-050550X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+050650Y-033050X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+041350Y-044650X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+042150Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+038600Y-040300X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+043600Y-040800X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+038100Y-048850X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+038150Y-050550X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+041350Y-044300X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+047250Y-046950X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+042950Y-050550X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+041526Y-041339X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+050500Y-045600X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+048850Y-037400X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+039750Y-031750X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+037645Y-038800X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+039750Y-050550X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+038450Y-049100X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+038600Y-040800X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+041640Y-047740X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+038450Y-048850X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+048228Y-046885X0177Y0000R000S-2119174445
|
||||
317GND VIA MD0118PA00X+038100Y-049100X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+050480Y-044960X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+038820Y-050080X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+050480Y-044600X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+038460Y-050080X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+051040Y-044620X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+047360Y-044720X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+038160Y-049860X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+037200Y-049500X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+038820Y-049640X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+034451Y-049801X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+051040Y-044980X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+038820Y-049860X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+047150Y-043700X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+038460Y-049640X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+038460Y-049860X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+049600Y-044900X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+050780Y-044780X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+038160Y-050080X0177Y0000R000S-2119174445
|
||||
317+5V VIA MD0118PA00X+038160Y-049640X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+041050Y-047400X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+032874Y-036304X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+049606Y-040320X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+038255Y-038800X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+040400Y-037150X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+047244Y-047638X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+035595Y-038976X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+048000Y-037450X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+046457Y-040320X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+043350Y-048650X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+040450Y-048550X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+038800Y-037150X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+046350Y-048650X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+048150Y-044050X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+041300Y-047400X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+048031Y-040320X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+038450Y-047600X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+048000Y-037100X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+041300Y-047150X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+046600Y-048650X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+038800Y-047850X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+041050Y-047150X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+048100Y-038400X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+050394Y-040354X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+043650Y-048650X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+038450Y-048100X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+038450Y-047850X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+038800Y-048100X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+045669Y-040320X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+040350Y-038800X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+032750Y-043500X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+035595Y-038189X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+048819Y-040320X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+047244Y-040320X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+038800Y-047600X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+038100Y-048100X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+048228Y-047603X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+038100Y-047850X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+036100Y-050350X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+038100Y-047600X0177Y0000R000S-2119174445
|
||||
317+3.3V VIA MD0118PA00X+048150Y-045550X0177Y0000R000S-2119174445
|
||||
317NET-(R3-PAD1) VIA MD0118PA00X+035433Y-042948X0177Y0000R000S-2119174445
|
||||
317/SD_DECT VIA MD0118PA00X+050138Y-037264X0177Y0000R000S-2119174445
|
||||
317/SD_DECT VIA MD0118PA00X+044800Y-049900X0177Y0000R000S-2119174445
|
||||
317/MISO VIA MD0118PA00X+038450Y-045800X0177Y0000R000S-2119174445
|
||||
317/MISO VIA MD0118PA00X+049272Y-037264X0177Y0000R000S-2119174445
|
||||
317/SPI_SCL VIA MD0118PA00X+048400Y-037264X0177Y0000R000S-2119174445
|
||||
317/SPI_SCL VIA MD0118PA00X+038450Y-044900X0177Y0000R000S-2119174445
|
||||
317/SPI_SCL VIA MD0118PA00X+048031Y-039601X0177Y0000R000S-2119174445
|
||||
317/MOSI VIA MD0118PA00X+037500Y-044550X0177Y0000R000S-2119174445
|
||||
317/MOSI VIA MD0118PA00X+047539Y-037264X0177Y0000R000S-2119174445
|
||||
317/SPI_CS VIA MD0118PA00X+046250Y-046000X0177Y0000R000S-2119174445
|
||||
317/SPI_CS VIA MD0118PA00X+047106Y-037264X0177Y0000R000S-2119174445
|
||||
317/BUZZER VIA MD0118PA00X+044450Y-046650X0177Y0000R000S-2119174445
|
||||
317-GPIO16_D6_TX) VIA MD0118PA00X+036480Y-047320X0177Y0000R000S-2119174445
|
||||
317-GPIO16_D6_TX) VIA MD0118PA00X+045700Y-046650X0177Y0000R000S-2119174445
|
||||
317/I2C_SCL VIA MD0118PA00X+043000Y-038300X0177Y0000R000S-2119174445
|
||||
317/I2C_SCL VIA MD0118PA00X+045600Y-046100X0177Y0000R000S-2119174445
|
||||
317/I2C_SCL VIA MD0118PA00X+043225Y-043575X0177Y0000R000S-2119174445
|
||||
317/I2C_SCL VIA MD0118PA00X+034680Y-046240X0177Y0000R000S-2119174445
|
||||
317/I2C_SDA VIA MD0118PA00X+042900Y-044100X0177Y0000R000S-2119174445
|
||||
317/I2C_SDA VIA MD0118PA00X+042900Y-038800X0177Y0000R000S-2119174445
|
||||
317/I2C_SDA VIA MD0118PA00X+044812Y-045842X0177Y0000R000S-2119174445
|
||||
317/I2C_SDA VIA MD0118PA00X+033300Y-046050X0177Y0000R000S-2119174445
|
||||
317/DAT2 VIA MD0118PA00X+046673Y-037264X0177Y0000R000S-2119174445
|
||||
317/DAT1 VIA MD0118PA00X+049705Y-037264X0177Y0000R000S-2119174445
|
||||
317NET-(J1-PIN_1) VIA MD0118PA00X+047100Y-049800X0177Y0000R000S-2119174445
|
||||
317NET-(J1-PIN_1) VIA MD0118PA00X+047100Y-050000X0177Y0000R000S-2119174445
|
||||
317NET-(J1-PIN_1) VIA MD0118PA00X+047100Y-050200X0177Y0000R000S-2119174445
|
||||
317ET-(U3-~{RST}) VIA MD0118PA00X+033850Y-038500X0177Y0000R000S-2119174445
|
||||
317ET-(U3-~{RST}) VIA MD0118PA00X+037750Y-039800X0177Y0000R000S-2119174445
|
||||
317NET-(JP1-A) VIA MD0118PA00X+042450Y-045000X0177Y0000R000S-2119174445
|
||||
317NET-(JP1-A) VIA MD0118PA00X+045800Y-049600X0177Y0000R000S-2119174445
|
||||
317NET-(JP1-A) VIA MD0118PA00X+042250Y-045000X0177Y0000R000S-2119174445
|
||||
317NET-(JP1-A) VIA MD0118PA00X+042250Y-044750X0177Y0000R000S-2119174445
|
||||
317NET-(JP1-A) VIA MD0118PA00X+042450Y-044450X0177Y0000R000S-2119174445
|
||||
317NET-(JP1-A) VIA MD0118PA00X+046050Y-049350X0177Y0000R000S-2119174445
|
||||
317NET-(JP1-A) VIA MD0118PA00X+042250Y-044450X0177Y0000R000S-2119174445
|
||||
317NET-(JP1-A) VIA MD0118PA00X+045850Y-049400X0177Y0000R000S-2119174445
|
||||
317NET-(JP1-A) VIA MD0118PA00X+042450Y-044750X0177Y0000R000S-2119174445
|
||||
327GND C5 -1 A01X+048730Y-038386X0354Y0374R180S2
|
||||
327+3.3V C5 -2 A01X+048120Y-038386X0354Y0374R180S2
|
||||
327/LED_DIN J3 -1 A01X+050700Y-043800X0984Y0669R000S2
|
||||
327+5V J3 -2 A01X+050700Y-044800X0984Y0669R000S2
|
||||
327GND J3 -3 A01X+050700Y-045800X0984Y0669R000S2
|
||||
327/SD_DECT U1 -1 A01X+044812Y-049842X1083Y0787R180S2
|
||||
327/LED_DRIVER U1 -2 A01X+044812Y-048842X1083Y0787R180S2
|
||||
327/SPI_CS U1 -3 A01X+044812Y-047842X1083Y0787R180S2
|
||||
327/BUZZER U1 -4 A01X+044812Y-046842X1083Y0787R180S2
|
||||
327/I2C_SDA U1 -5 A01X+044812Y-045842X1083Y0787R180S2
|
||||
327/I2C_SCL U1 -6 A01X+044812Y-044842X1083Y0787R180S2
|
||||
327-GPIO16_D6_TX) U1 -7 A01X+044812Y-043842X1083Y0787R180S2
|
||||
327/UART_RX U1 -8 A01X+038447Y-043842X1083Y0787R180S2
|
||||
327/SPI_SCL U1 -9 A01X+038447Y-044842X1083Y0787R180S2
|
||||
327/MISO U1 -10 A01X+038447Y-045842X1083Y0787R180S2
|
||||
327/MOSI U1 -11 A01X+038447Y-046842X1083Y0787R180S2
|
||||
327+3.3V U1 -12 A01X+038447Y-047842X1083Y0787R180S2
|
||||
327GND U1 -13 A01X+038447Y-048842X1083Y0787R180S2
|
||||
327+5V U1 -14 A01X+038447Y-049842X1083Y0787R180S2
|
||||
327NET-(JP1-A) U1 -15 A01X+042342Y-044664X0984Y0433R270S2
|
||||
327GND U1 -16 A01X+041342Y-044664X0984Y0433R270S2
|
||||
327U1-MTDI-PAD17) U1 -17 A01X+042142Y-050244X0669Y0000R180S2
|
||||
327U1-MTDO-PAD18) U1 -18 A01X+041142Y-050244X0669Y0000R180S2
|
||||
327CHIP_EN-PAD19) U1 -19 A01X+042142Y-049244X0669Y0000R180S2
|
||||
327GND U1 -20 A01X+041142Y-049244X0669Y0000R180S2
|
||||
327U1-MTMS-PAD21) U1 -21 A01X+042142Y-048244X0669Y0000R180S2
|
||||
327U1-MTCK-PAD22) U1 -22 A01X+041142Y-048244X0669Y0000R180S2
|
||||
327U1-BOOT-PAD23) U1 -23 A01X+042142Y-047244X0669Y0000R180S2
|
||||
327+3.3V U1 -24 A01X+041178Y-047266X0669Y0000R180S2
|
||||
327GND TP3 -1 A01X+032677Y-050197X0591Y0000R000S2
|
||||
327NET-(D2-K) D2 -1 A01X+032874Y-036924X0344Y0374R270S2
|
||||
327+3.3V D2 -2 A01X+032874Y-036304X0344Y0374R270S2
|
||||
327+3.3V R14 -1 A01X+047244Y-040320X0384Y0374R270S2
|
||||
327/MOSI R14 -2 A01X+047244Y-039601X0384Y0374R270S2
|
||||
327+3.3V R13 -1 A01X+048031Y-040320X0384Y0374R270S2
|
||||
327/SPI_SCL R13 -2 A01X+048031Y-039601X0384Y0374R270S2
|
||||
327NET-(R3-PAD1) R3 -1 A01X+035433Y-042948X0384Y0374R090S2
|
||||
327/UART_RX R3 -2 A01X+035433Y-043666X0384Y0374R090S2
|
||||
327GND C2 -1 A01X+037645Y-038800X0354Y0374R000S2
|
||||
327+3.3V C2 -2 A01X+038255Y-038800X0354Y0374R000S2
|
||||
327NT}{SLASH}SQW) TP1 -1 A01X+033071Y-040748X0591Y0000R000S2
|
||||
327NET-(U3-32KHZ) U3 -1 A01X+039319Y-038300X0807Y0236R000S2
|
||||
327+3.3V U3 -2 A01X+039319Y-038800X0807Y0236R000S2
|
||||
327NT}{SLASH}SQW) U3 -3 A01X+039319Y-039300X0807Y0236R000S2
|
||||
327ET-(U3-~{RST}) U3 -4 A01X+039319Y-039800X0807Y0236R000S2
|
||||
327GND U3 -5 A01X+039319Y-040300X0807Y0236R000S2
|
||||
327GND U3 -6 A01X+039319Y-040800X0807Y0236R000S2
|
||||
327GND U3 -7 A01X+039319Y-041300X0807Y0236R000S2
|
||||
327GND U3 -8 A01X+039319Y-041800X0807Y0236R000S2
|
||||
327GND U3 -9 A01X+042981Y-041800X0807Y0236R000S2
|
||||
327GND U3 -10 A01X+042981Y-041300X0807Y0236R000S2
|
||||
327GND U3 -11 A01X+042981Y-040800X0807Y0236R000S2
|
||||
327GND U3 -12 A01X+042981Y-040300X0807Y0236R000S2
|
||||
327GND U3 -13 A01X+042981Y-039800X0807Y0236R000S2
|
||||
327/BATTERY_CELL U3 -14 A01X+042981Y-039300X0807Y0236R000S2
|
||||
327/I2C_SDA U3 -15 A01X+042981Y-038800X0807Y0236R000S2
|
||||
327/I2C_SCL U3 -16 A01X+042981Y-038300X0807Y0236R000S2
|
||||
317/BUZZER BZ1 -1 D0394PA00X+035400Y-046806X0669Y0669R000S0
|
||||
317GND BZ1 -2 D0394PA00X+035400Y-047806X0669Y0000R000S0
|
||||
327+3.3V R15 -1 A01X+045669Y-040320X0384Y0374R270S2
|
||||
327/DAT2 R15 -2 A01X+045669Y-039601X0384Y0374R270S2
|
||||
327-GPIO16_D6_TX) TP8 -1 A01X+033927Y-046604X0591Y0000R000S2
|
||||
327NET-(JP1-A) JP1 -1 A01X+046450Y-050000X0118Y0118R000S2
|
||||
327NET-(J1-PIN_1) JP1 -2 A01X+047021Y-050000X0118Y0118R000S2
|
||||
317(RDM1-PADANT1) RDM1 -ANT1 D0551PA00X+035236Y-023433X0827Y0000R090S0
|
||||
317(RDM1-PADANT2) RDM1 -ANT2 D0551PA00X+035236Y-024433X0827Y0827R090S0
|
||||
317D-(RDM1-PADD0) RDM1 -D0 D0551PA00X+041236Y-034433X0827Y0000R090S0
|
||||
317GND RDM1 -GND D0551PA00X+041236Y-033433X0827Y0000R090S0
|
||||
317GND RDM1 -GND1 D0551PA00X+035236Y-034433X0827Y0000R090S0
|
||||
317NET-(R1-PAD1) RDM1 -LED D0551PA00X+035236Y-036433X0827Y0827R090S0
|
||||
317D-(RDM1-PADRX) RDM1 -RX D0551PA00X+041236Y-035433X0827Y0000R090S0
|
||||
317NET-(R3-PAD1) RDM1 -TX D0551PA00X+041236Y-036433X0827Y0827R090S0
|
||||
317+5V RDM1 -VCC D0551PA00X+041236Y-032433X0827Y0000R090S0
|
||||
317+5V RDM1 -VCC1 D0551PA00X+035236Y-035433X0827Y0000R090S0
|
||||
327+3.3V R7 -1 A01X+035595Y-038189X0384Y0374R180S2
|
||||
327NET-(U3-32KHZ) R7 -2 A01X+034877Y-038189X0384Y0374R180S2
|
||||
327+3.3V R8 -1 A01X+035595Y-038976X0384Y0374R180S2
|
||||
327NT}{SLASH}SQW) R8 -2 A01X+034877Y-038976X0384Y0374R180S2
|
||||
327GND U2 -1 A01X+046340Y-044709X0500Y0220R000S2
|
||||
327/LED_DRIVER U2 -2 A01X+046340Y-045079X0500Y0220R000S2
|
||||
327GND U2 -3 A01X+046340Y-045449X0500Y0220R000S2
|
||||
327NET-(U2-Y) U2 -4 A01X+047360Y-045449X0500Y0220R000S2
|
||||
327+5V U2 -5 A01X+047360Y-044709X0500Y0220R000S2
|
||||
327GND C3 -1 A01X+046545Y-043701X0354Y0374R000S2
|
||||
327+5V C3 -2 A01X+047156Y-043701X0354Y0374R000S2
|
||||
327NET-(R1-PAD1) R1 -1 A01X+033858Y-036255X0384Y0374R090S2
|
||||
327NET-(D2-K) R1 -2 A01X+033858Y-036973X0384Y0374R090S2
|
||||
327NET-(U2-Y) R2 -1 A01X+048460Y-043701X0384Y0374R000S2
|
||||
327/LED_DIN R2 -2 A01X+049178Y-043701X0384Y0374R000S2
|
||||
327+3.3V R12 -1 A01X+048819Y-040320X0384Y0374R270S2
|
||||
327/MISO R12 -2 A01X+048819Y-039601X0384Y0374R270S2
|
||||
327NET-(U3-32KHZ) TP10 -1 A01X+033071Y-039567X0591Y0000R000S2
|
||||
327+5V TP2 -1 A01X+034055Y-050197X0591Y0000R000S2
|
||||
327+3.3V TP4 -1 A01X+035433Y-050197X0591Y0000R000S2
|
||||
327+3.3V R11 -1 A01X+050394Y-040354X0384Y0374R270S2
|
||||
327/SD_DECT R11 -2 A01X+050394Y-039636X0384Y0374R270S2
|
||||
327/LED_DIN TP5 -1 A01X+049016Y-042717X0591Y0000R000S2
|
||||
327+3.3V R9 -1 A01X+046457Y-040320X0384Y0374R270S2
|
||||
327/SPI_CS R9 -2 A01X+046457Y-039601X0384Y0374R270S2
|
||||
327GND C4 -1 A01X+049600Y-045505X0354Y0374R270S2
|
||||
327+5V C4 -2 A01X+049600Y-044895X0354Y0374R270S2
|
||||
327+3.3V R6 -1 A01X+048228Y-047603X0384Y0374R270S2
|
||||
327GND R6 -2 A01X+048228Y-046885X0384Y0374R270S2
|
||||
327/UART_RX R4 -1 A01X+035433Y-044523X0384Y0374R090S2
|
||||
327GND R4 -2 A01X+035433Y-045241X0384Y0374R090S2
|
||||
327ET-(U3-~{RST}) TP9 -1 A01X+033071Y-038386X0591Y0000R270S2
|
||||
367N/C J4 D0394UA00X+049508Y-032913X0394Y0000R180S0
|
||||
367N/C J4 D0394UA00X+046358Y-032913X0394Y0000R180S0
|
||||
327/DAT2 J4 -1 A01X+046673Y-037264X0276Y0748R180S2
|
||||
327/SPI_CS J4 -2 A01X+047106Y-037264X0276Y0748R180S2
|
||||
327/MOSI J4 -3 A01X+047539Y-037264X0276Y0748R180S2
|
||||
327+3.3V J4 -4 A01X+047972Y-037264X0276Y0748R180S2
|
||||
327/SPI_SCL J4 -5 A01X+048406Y-037264X0276Y0748R180S2
|
||||
327GND J4 -6 A01X+048839Y-037264X0276Y0748R180S2
|
||||
327/MISO J4 -7 A01X+049272Y-037264X0276Y0748R180S2
|
||||
327/DAT1 J4 -8 A01X+049705Y-037264X0276Y0748R180S2
|
||||
327/SD_DECT J4 -9 A01X+050138Y-037264X0276Y0748R180S2
|
||||
327GND J4 -10 A01X+050748Y-036850X0669Y0709R180S2
|
||||
327GND J4 -11 A01X+044646Y-036850X0669Y0709R180S2
|
||||
327GND J4 -12 A01X+050650Y-033071X0551Y1024R180S2
|
||||
327GND J4 -13 A01X+044469Y-033071X0551Y1024R180S2
|
||||
327+3.3V R10 -1 A01X+049606Y-040320X0384Y0374R270S2
|
||||
327/DAT1 R10 -2 A01X+049606Y-039601X0384Y0374R270S2
|
||||
327/UART_RX TP7 -1 A01X+033927Y-045422X0591Y0000R000S2
|
||||
327+3.3V R5 -1 A01X+047244Y-047609X0384Y0374R270S2
|
||||
327GND R5 -2 A01X+047244Y-046891X0384Y0374R270S2
|
||||
327GND C1 -1 A01X+037205Y-048907X0354Y0374R090S2
|
||||
327+5V C1 -2 A01X+037205Y-049518X0354Y0374R090S2
|
||||
327/DAT2 TP15 -1 A06X+042323Y-035433X0591Y0000R000S1
|
||||
327/SPI_CS TP5 -1 A06X+043701Y-035433X0591Y0000R180S1
|
||||
327/SD_DECT TP6 -1 A06X+050591Y-035433X0591Y0000R180S1
|
||||
317/BATTERY_CELL BT1 -1 D0335PA00X+044650Y-040700X0630Y0787R180S0
|
||||
317GND BT1 -2 D0335PA00X+036579Y-040700X0630Y0787R180S0
|
||||
327/DAT1 TP14 -1 A06X+049213Y-035433X0591Y0000R180S1
|
||||
327NET-(J1-PIN_1) J1 -1 A06X+047248Y-050000X0669Y0669R090S1
|
||||
327GND J1 -2 A06X+048248Y-050000X0669Y0000R090S1
|
||||
327/MOSI TP11 -1 A06X+045079Y-035433X0591Y0000R180S1
|
||||
327+3.3V J2 -1 A06X+032750Y-043500X0669Y0669R180S1
|
||||
327GND J2 -2 A06X+032750Y-044500X0669Y0000R180S1
|
||||
327/I2C_SDA J2 -3 A06X+032750Y-045500X0669Y0000R180S1
|
||||
327/I2C_SCL J2 -4 A06X+032750Y-046500X0669Y0000R180S1
|
||||
327/MISO TP12 -1 A06X+047835Y-035433X0591Y0000R180S1
|
||||
327/SPI_SCL TP13 -1 A06X+046457Y-035433X0591Y0000R180S1
|
||||
999
|
||||
29
pcb/production/positions.csv
Normal file
29
pcb/production/positions.csv
Normal file
@@ -0,0 +1,29 @@
|
||||
Designator,Mid X,Mid Y,Rotation,Layer
|
||||
BT1,103.161,-103.378,0.0,bottom
|
||||
BZ1,89.916,-120.158,0.0,top
|
||||
C1,94.5,-125.0,270.0,top
|
||||
C2,96.393,-98.552,0.0,top
|
||||
C3,119.0,-111.0,0.0,top
|
||||
C4,125.984,-114.808,90.0,top
|
||||
C5,123.0,-97.5,180.0,top
|
||||
D2,83.5,-93.0,90.0,top
|
||||
J1,120.01,-127.0,270.0,bottom
|
||||
J2,83.185,-110.49,0.0,bottom
|
||||
J4,120.8,-83.6,180.0,top
|
||||
R1,86.0,-93.0,270.0,top
|
||||
R10,126.0,-101.5,90.0,top
|
||||
R11,128.0,-101.5875,90.0,top
|
||||
R12,124.0,-101.5,90.0,top
|
||||
R13,122.0,-101.5,90.0,top
|
||||
R14,120.0,-101.5,90.0,top
|
||||
R15,116.0,-101.5,90.0,top
|
||||
R2,124.0,-111.0,0.0,top
|
||||
R3,90.0,-110.0,270.0,top
|
||||
R4,90.0,-114.0,270.0,top
|
||||
R5,120.0,-120.015,90.0,top
|
||||
R6,122.5,-120.0,90.0,top
|
||||
R9,118.0,-101.5,90.0,top
|
||||
RDM1,97.12,-76.03,270.0,top
|
||||
U1,105.7391,-119.41425,180.0,top
|
||||
U2,119.0,-114.5,0.0,top
|
||||
U3,104.521,-101.727,270.0,top
|
||||
|
@@ -1,3 +1,2 @@
|
||||
pub mod nfc_reader;
|
||||
pub mod rtc;
|
||||
pub mod buzzer;
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
const DEVICE_TYPE_CODE: u8 = 0b10100000;
|
||||
|
||||
const DEVICE_ADDRESS_CODE: u8 = 0b000000; // 3 bits for device address | default A0 = 0 A1 = 0 A2 = 0
|
||||
|
||||
const WRITE_CODE: u8 = 0b00000000; // 0 for write
|
||||
const READ_CODE: u8 = 0b00000001; // 1 for read
|
||||
|
||||
const DEVICE_ADDRESS_WRITE: u8 = DEVICE_TYPE_CODE | DEVICE_ADDRESS_CODE | WRITE_CODE; // I2C address write for FRAM
|
||||
const DEVICE_ADDRESS_READ: u8 = DEVICE_TYPE_CODE | DEVICE_ADDRESS_CODE | READ_CODE; // I2C address read for FRAM
|
||||
@@ -1,44 +0,0 @@
|
||||
use anyhow::Result;
|
||||
use log::debug;
|
||||
use std::time::Duration;
|
||||
use tokio::time::sleep;
|
||||
|
||||
use crate::hardware::{Buzzer, Hotspot, StatusLed};
|
||||
|
||||
pub struct MockBuzzer {}
|
||||
|
||||
impl Buzzer for MockBuzzer {
|
||||
async fn modulated_tone(&mut self, frequency_hz: f64, duration: Duration) -> Result<()> {
|
||||
debug!("MockBuzzer: modulte tone: {frequency_hz} Hz");
|
||||
sleep(duration).await;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MockLed {}
|
||||
|
||||
impl StatusLed for MockLed {
|
||||
fn turn_off(&mut self) -> Result<()> {
|
||||
debug!("Turn mock LED off");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn turn_on(&mut self, color: rgb::RGB8) -> Result<()> {
|
||||
debug!("Turn mock LED on to: {color}");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MockHotspot {}
|
||||
|
||||
impl Hotspot for MockHotspot {
|
||||
async fn enable_hotspot(&self) -> Result<()> {
|
||||
debug!("Mockhotspot: Enable hotspot");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn disable_hotspot(&self) -> Result<()> {
|
||||
debug!("Mockhotspot: Disable hotspot");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
use embassy_time::{Duration, Timer};
|
||||
use esp_hal::{Async, uart::Uart};
|
||||
use log::{debug, info};
|
||||
use log::{debug, info, warn};
|
||||
|
||||
use crate::TallyPublisher;
|
||||
|
||||
@@ -17,7 +17,15 @@ pub async fn rfid_reader_task(mut uart_device: Uart<'static, Async>, chan: Tally
|
||||
core::fmt::Write::write_fmt(&mut hex_str, format_args!("{:02X} ", byte)).ok();
|
||||
}
|
||||
info!("Read {n} bytes from UART: {hex_str}");
|
||||
chan.publish([1, 0, 2, 5, 0, 8, 12, 15]).await;
|
||||
|
||||
match extract_id(&uart_buffer) {
|
||||
Some(read) => {
|
||||
chan.publish(read.try_into().unwrap()).await;
|
||||
}
|
||||
None => {
|
||||
warn!("Invalid read from the RFID reader");
|
||||
}
|
||||
};
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Error reading from UART: {e}");
|
||||
@@ -26,3 +34,35 @@ pub async fn rfid_reader_task(mut uart_device: Uart<'static, Async>, chan: Tally
|
||||
Timer::after(Duration::from_millis(200)).await;
|
||||
}
|
||||
}
|
||||
|
||||
/// Scans the UART output and retuns the first propper read ID
|
||||
/// This ensures that only valid ID are parsed
|
||||
///
|
||||
/// A valid read looks like this:
|
||||
/// The first byte is always 0x02 (Start of text)
|
||||
/// Followed by 12 Bytes of chars
|
||||
/// Ended by 0x03 (End of text)
|
||||
pub fn extract_id(buffer: &[u8]) -> Option<[u8; 12]> {
|
||||
const STX: u8 = 0x02; // Start of Text ASCII char
|
||||
const ETX: u8 = 0x03; // End of Text ASCII char
|
||||
const ID_LENGTH: usize = 12;
|
||||
const MINIMUM_SEQUENCE: usize = ID_LENGTH + 2; // STX + 12 bytes + ETX
|
||||
|
||||
if buffer.len() < MINIMUM_SEQUENCE {
|
||||
return None;
|
||||
}
|
||||
|
||||
for window_start in 0..=buffer.len() - MINIMUM_SEQUENCE {
|
||||
if buffer[window_start] == STX {
|
||||
let id_end = window_start + ID_LENGTH + 1;
|
||||
|
||||
if buffer[id_end] == ETX {
|
||||
let mut id = [0u8; ID_LENGTH];
|
||||
id.copy_from_slice(&buffer[window_start + 1..id_end]);
|
||||
return Some(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use chrono::{TimeZone, Utc};
|
||||
use ds3231::{
|
||||
Config, DS3231, DS3231Error, InterruptControl, Oscillator, SquareWaveFrequency,
|
||||
TimeRepresentation,
|
||||
Config, DS3231, InterruptControl, Oscillator, SquareWaveFrequency, TimeRepresentation,
|
||||
};
|
||||
use esp_hal::{
|
||||
Async,
|
||||
@@ -9,7 +9,6 @@ use esp_hal::{
|
||||
use log::{debug, error, info};
|
||||
|
||||
use crate::{FEEDBACK_STATE, drivers, feedback};
|
||||
use chrono::{TimeZone, Utc};
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/build_time.rs"));
|
||||
|
||||
@@ -30,10 +29,7 @@ impl RTCClock {
|
||||
|
||||
pub async fn get_time(&mut self) -> u64 {
|
||||
match self.dev.datetime().await {
|
||||
Ok(datetime) => {
|
||||
let utc_time = datetime.and_utc().timestamp() as u64;
|
||||
utc_time
|
||||
}
|
||||
Ok(datetime) => datetime.and_utc().timestamp() as u64,
|
||||
Err(e) => {
|
||||
FEEDBACK_STATE.signal(feedback::FeedbackState::Error);
|
||||
error!("Failed to read RTC datetime: {:?}", e);
|
||||
@@ -56,22 +52,25 @@ pub async fn rtc_config(i2c: I2c<'static, Async>) -> DS3231<I2c<'static, Async>>
|
||||
square_wave_frequency: SquareWaveFrequency::Hz1,
|
||||
interrupt_control: InterruptControl::Interrupt, // Enable interrupt mode
|
||||
battery_backed_square_wave: false,
|
||||
oscillator_enable: Oscillator::Disabled,
|
||||
oscillator_enable: Oscillator::Enabled,
|
||||
};
|
||||
|
||||
match rtc.configure(&rtc_config).await {
|
||||
Ok(_) => info!("DS3231 configured successfully"),
|
||||
Err(e) => {
|
||||
info!("Failed to configure DS3231: {:?}", e);
|
||||
panic!("DS3231 configuration failed");
|
||||
error!("Failed to configure DS3231: {:?}", e);
|
||||
error!("DS3231 configuration failed");
|
||||
FEEDBACK_STATE.signal(feedback::FeedbackState::Error);
|
||||
}
|
||||
}
|
||||
|
||||
if rtc.datetime().await.unwrap() < naive_dt {
|
||||
rtc.set_datetime(&naive_dt).await.unwrap_or_else(|e| {
|
||||
FEEDBACK_STATE.signal(feedback::FeedbackState::Error);
|
||||
error!("Failed to set RTC datetime: {:?}", e);
|
||||
});
|
||||
info!("RTC datetime set to: {}", naive_dt);
|
||||
}
|
||||
|
||||
match rtc.status().await {
|
||||
Ok(mut status) => {
|
||||
@@ -85,12 +84,7 @@ pub async fn rtc_config(i2c: I2c<'static, Async>) -> DS3231<I2c<'static, Async>>
|
||||
Err(e) => info!("Failed to read status: {:?}", e),
|
||||
}
|
||||
|
||||
info!("RTC time is: {:?}", rtc.datetime().await.unwrap());
|
||||
|
||||
rtc
|
||||
}
|
||||
|
||||
pub async fn read_rtc_time<'a>(
|
||||
rtc: &'a mut DS3231<I2c<'static, Async>>,
|
||||
) -> Result<u64, DS3231Error<esp_hal::i2c::master::Error>> {
|
||||
let timestamp_result = rtc.datetime().await?;
|
||||
Ok(timestamp_result.and_utc().timestamp() as u64)
|
||||
}
|
||||
|
||||
190
src/feedback.rs
190
src/feedback.rs
@@ -1,18 +1,18 @@
|
||||
use embassy_time::{Delay, Duration, Timer};
|
||||
use esp_hal::{delay, gpio::Output, peripherals, rmt::ConstChannelAccess};
|
||||
use embassy_time::{Duration, Timer};
|
||||
use esp_hal::gpio::Output;
|
||||
use esp_hal_smartled::SmartLedsAdapterAsync;
|
||||
use log::{debug, error, info};
|
||||
use init::hardware;
|
||||
use log::debug;
|
||||
use smart_leds::SmartLedsWriteAsync;
|
||||
use smart_leds::colors::{BLACK, GREEN, RED, YELLOW};
|
||||
use smart_leds::{brightness, colors::BLUE};
|
||||
use smart_leds::SmartLedsWriteAsync;
|
||||
|
||||
use crate::init::hardware;
|
||||
use crate::{FEEDBACK_STATE, init};
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum FeedbackState {
|
||||
Ack,
|
||||
Nak,
|
||||
Nack,
|
||||
Error,
|
||||
Startup,
|
||||
WIFI,
|
||||
@@ -21,22 +21,42 @@ pub enum FeedbackState {
|
||||
|
||||
const LED_LEVEL: u8 = 255;
|
||||
|
||||
//TODO ERROR STATE: 1 Blink = unknows error, 3 Blink = no sd card
|
||||
|
||||
#[embassy_executor::task]
|
||||
pub async fn feedback_task(mut led: SmartLedsAdapterAsync<ConstChannelAccess<esp_hal::rmt::Tx, 0>, { init::hardware::LED_BUFFER_SIZE }>, buzzer: peripherals::GPIO21<'static>) {
|
||||
pub async fn feedback_task(
|
||||
mut led: SmartLedsAdapterAsync<'static, { hardware::LED_BUFFER_SIZE }>,
|
||||
mut buzzer: Output<'static>,
|
||||
) {
|
||||
debug!("Starting feedback task");
|
||||
let mut buzzer = init::hardware::setup_buzzer(buzzer);
|
||||
loop {
|
||||
let feedback_state = FEEDBACK_STATE.wait().await;
|
||||
match feedback_state {
|
||||
FeedbackState::Ack => {
|
||||
led.write(brightness([GREEN; init::hardware::NUM_LEDS].into_iter(), LED_LEVEL)).await.unwrap();
|
||||
led.write(brightness(
|
||||
[GREEN; init::hardware::NUM_LEDS].into_iter(),
|
||||
LED_LEVEL,
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
buzzer.set_high();
|
||||
Timer::after(Duration::from_millis(100)).await;
|
||||
buzzer.set_low();
|
||||
Timer::after(Duration::from_millis(50)).await;
|
||||
led.write(brightness(
|
||||
[BLACK; init::hardware::NUM_LEDS].into_iter(),
|
||||
LED_LEVEL,
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
FeedbackState::Nak => {
|
||||
led.write(brightness([YELLOW; init::hardware::NUM_LEDS].into_iter(), LED_LEVEL)).await.unwrap();
|
||||
FeedbackState::Nack => {
|
||||
led.write(brightness(
|
||||
[YELLOW; init::hardware::NUM_LEDS].into_iter(),
|
||||
LED_LEVEL,
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
buzzer.set_high();
|
||||
Timer::after(Duration::from_millis(100)).await;
|
||||
buzzer.set_low();
|
||||
@@ -44,10 +64,20 @@ pub async fn feedback_task(mut led: SmartLedsAdapterAsync<ConstChannelAccess<esp
|
||||
buzzer.set_high();
|
||||
Timer::after(Duration::from_millis(100)).await;
|
||||
buzzer.set_low();
|
||||
led.write(brightness([BLACK; init::hardware::NUM_LEDS].into_iter(), LED_LEVEL)).await.unwrap();
|
||||
led.write(brightness(
|
||||
[BLACK; init::hardware::NUM_LEDS].into_iter(),
|
||||
LED_LEVEL,
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
FeedbackState::Error => {
|
||||
led.write(brightness([RED; init::hardware::NUM_LEDS].into_iter(), LED_LEVEL)).await.unwrap();
|
||||
led.write(brightness(
|
||||
[RED; init::hardware::NUM_LEDS].into_iter(),
|
||||
LED_LEVEL,
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
buzzer.set_high();
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
buzzer.set_low();
|
||||
@@ -57,7 +87,12 @@ pub async fn feedback_task(mut led: SmartLedsAdapterAsync<ConstChannelAccess<esp
|
||||
buzzer.set_low();
|
||||
}
|
||||
FeedbackState::Startup => {
|
||||
led.write(brightness([GREEN; init::hardware::NUM_LEDS].into_iter(), LED_LEVEL)).await.unwrap();
|
||||
led.write(brightness(
|
||||
[GREEN; init::hardware::NUM_LEDS].into_iter(),
|
||||
LED_LEVEL,
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
buzzer.set_high();
|
||||
Timer::after(Duration::from_millis(10)).await;
|
||||
buzzer.set_low();
|
||||
@@ -69,119 +104,32 @@ pub async fn feedback_task(mut led: SmartLedsAdapterAsync<ConstChannelAccess<esp
|
||||
buzzer.set_high();
|
||||
Timer::after(Duration::from_millis(100)).await;
|
||||
buzzer.set_low();
|
||||
led.write(brightness([BLACK; init::hardware::NUM_LEDS].into_iter(), LED_LEVEL)).await.unwrap();
|
||||
|
||||
Timer::after(Duration::from_secs(2)).await;
|
||||
led.write(brightness(
|
||||
[BLACK; init::hardware::NUM_LEDS].into_iter(),
|
||||
LED_LEVEL,
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
FeedbackState::WIFI => {
|
||||
led.write(brightness([BLUE; init::hardware::NUM_LEDS].into_iter(), LED_LEVEL)).await.unwrap();
|
||||
led.write(brightness(
|
||||
[BLUE; init::hardware::NUM_LEDS].into_iter(),
|
||||
LED_LEVEL,
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
FeedbackState::Idle => {
|
||||
// Do nothing
|
||||
led.write(brightness(
|
||||
[BLACK; init::hardware::NUM_LEDS].into_iter(),
|
||||
LED_LEVEL,
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
};
|
||||
debug!("Feedback state: {:?}", feedback_state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// async fn beep_ack() {
|
||||
// buzzer.set_high();
|
||||
// buzzer.set_low();
|
||||
// //Timer::after(Duration::from_millis(100)).await;
|
||||
// }
|
||||
|
||||
/* pub async fn failure(&mut self) {
|
||||
let buzzer_handle = Self::beep_nak(&mut self.buzzer);
|
||||
let led_handle = Self::flash_led_for_duration(&mut self.led, RED, LED_BLINK_DURATION);
|
||||
|
||||
let (buzzer_result, _) = join!(buzzer_handle, led_handle);
|
||||
|
||||
buzzer_result.unwrap_or_else(|err| { error!("Failed to buzz: {err}");
|
||||
});
|
||||
|
||||
let _ = self.led_to_status();
|
||||
}
|
||||
|
||||
pub async fn activate_error_state(&mut self) -> Result<()> {
|
||||
self.led.turn_on(RED)?;
|
||||
Self::beep_nak(&mut self.buzzer).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn startup(&mut self){
|
||||
self.device_status = DeviceStatus::Ready;
|
||||
|
||||
let led_handle = Self::flash_led_for_duration(&mut self.led, GREEN, Duration::from_secs(1));
|
||||
let buzzer_handle = Self::beep_startup(&mut self.buzzer);
|
||||
|
||||
let (buzzer_result, led_result) = join!(buzzer_handle, led_handle);
|
||||
|
||||
buzzer_result.unwrap_or_else(|err| {
|
||||
error!("Failed to buzz: {err}");
|
||||
});
|
||||
|
||||
led_result.unwrap_or_else(|err| {
|
||||
error!("Failed to blink led: {err}");
|
||||
});
|
||||
|
||||
let _ = self.led_to_status();
|
||||
}
|
||||
|
||||
|
||||
async fn flash_led_for_duration(led: &mut L, color: RGB8, duration: Duration) -> Result<()> {
|
||||
led.turn_on(color)?;
|
||||
|
||||
sleep(duration).await;
|
||||
|
||||
led.turn_off()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn beep_ack(buzzer: &mut B) -> Result<()> {
|
||||
buzzer
|
||||
.modulated_tone(1200.0, Duration::from_millis(100))
|
||||
.await?;
|
||||
sleep(Duration::from_millis(10)).await;
|
||||
buzzer
|
||||
.modulated_tone(2000.0, Duration::from_millis(50))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn beep_nak(buzzer: &mut B) -> Result<()> {
|
||||
buzzer
|
||||
.modulated_tone(600.0, Duration::from_millis(150))
|
||||
.await?;
|
||||
sleep(Duration::from_millis(100)).await;
|
||||
buzzer
|
||||
.modulated_tone(600.0, Duration::from_millis(150))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn beep_startup(buzzer: &mut B) -> Result<()> {
|
||||
buzzer
|
||||
.modulated_tone(523.0, Duration::from_millis(150))
|
||||
.await?;
|
||||
buzzer
|
||||
.modulated_tone(659.0, Duration::from_millis(150))
|
||||
.await?;
|
||||
buzzer
|
||||
.modulated_tone(784.0, Duration::from_millis(150))
|
||||
.await?;
|
||||
buzzer
|
||||
.modulated_tone(1046.0, Duration::from_millis(200))
|
||||
.await?;
|
||||
|
||||
sleep(Duration::from_millis(100)).await;
|
||||
|
||||
buzzer
|
||||
.modulated_tone(784.0, Duration::from_millis(100))
|
||||
.await?;
|
||||
buzzer
|
||||
.modulated_tone(880.0, Duration::from_millis(200))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod hardware;
|
||||
pub mod network;
|
||||
pub mod wifi;
|
||||
pub mod sd_card;
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_net::Stack;
|
||||
use embassy_time::{Duration, Timer};
|
||||
use embedded_sdmmc_dev::SdCard;
|
||||
use esp_hal::Blocking;
|
||||
use esp_hal::delay::Delay;
|
||||
use esp_hal::gpio::AnyPin;
|
||||
use esp_hal::i2c::master::Config;
|
||||
use esp_hal::peripherals::{
|
||||
self, GPIO0, GPIO1, GPIO2, GPIO10, GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22,
|
||||
GPIO23, I2C0, RMT, SPI2, UART1,
|
||||
GPIO1, GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22, GPIO23, I2C0, RMT, SPI2, UART1,
|
||||
};
|
||||
use esp_hal::rmt::{ConstChannelAccess, Rmt, Tx};
|
||||
use esp_hal::spi::{
|
||||
Mode,
|
||||
master::{Config as Spi_config, Spi},
|
||||
};
|
||||
|
||||
use esp_hal::rmt::Rmt;
|
||||
use esp_hal::spi::master::{Config as Spi_config, Spi};
|
||||
use esp_hal::system::software_reset;
|
||||
use esp_hal::time::Rate;
|
||||
use esp_hal::timer::timg::TimerGroup;
|
||||
use esp_hal::{
|
||||
@@ -20,22 +18,18 @@ use esp_hal::{
|
||||
clock::CpuClock,
|
||||
gpio::{Output, OutputConfig},
|
||||
i2c::master::I2c,
|
||||
timer::systimer::SystemTimer,
|
||||
uart::Uart,
|
||||
};
|
||||
|
||||
use esp_hal_smartled::{SmartLedsAdapterAsync, buffer_size_async};
|
||||
|
||||
use smart_leds::colors::{BLUE, GREEN, RED};
|
||||
use smart_leds::{
|
||||
RGB8, SmartLedsWriteAsync, brightness, gamma,
|
||||
hsv::{Hsv, hsv2rgb},
|
||||
};
|
||||
|
||||
use esp_println::logger::init_logger;
|
||||
use log::{debug, error};
|
||||
use smart_leds::SmartLedsWriteAsync;
|
||||
use smart_leds::brightness;
|
||||
use smart_leds::colors::RED;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::init::network;
|
||||
use crate::init::sd_card::{SDCardPersistence, setup_sdcard};
|
||||
use crate::init::wifi;
|
||||
|
||||
/*************************************************
|
||||
@@ -51,115 +45,141 @@ use crate::init::wifi;
|
||||
* D7 -> GPIO17 -> UART/RX -> Level Shifter A1 -> NFC Reader
|
||||
* D8 -> GPIO19 -> SPI/SCLK
|
||||
* D9 -> GPIO20 -> SPI/MISO
|
||||
* D10 -> GPIO10 -> SPI/MOSI
|
||||
* D10 -> GPIO18 -> SPI/MOSI
|
||||
*
|
||||
*************************************************/
|
||||
|
||||
pub const NUM_LEDS: usize = 66;
|
||||
pub const LED_BUFFER_SIZE: usize = NUM_LEDS * 25;
|
||||
pub const NUM_LEDS: usize = 1;
|
||||
pub const LED_BUFFER_SIZE: usize = buffer_size_async(NUM_LEDS);
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(info: &core::panic::PanicInfo) -> ! {
|
||||
loop {
|
||||
let delay = Delay::new();
|
||||
error!("PANIC: {info}");
|
||||
}
|
||||
delay.delay(esp_hal::time::Duration::from_secs(30));
|
||||
software_reset()
|
||||
}
|
||||
|
||||
esp_bootloader_esp_idf::esp_app_desc!();
|
||||
|
||||
pub async fn hardware_init(
|
||||
spawner: &mut Spawner,
|
||||
) -> (
|
||||
Uart<'static, Async>,
|
||||
Stack<'static>,
|
||||
I2c<'static, Async>,
|
||||
SmartLedsAdapterAsync<ConstChannelAccess<esp_hal::rmt::Tx, 0>, LED_BUFFER_SIZE>,
|
||||
GPIO21<'static>,
|
||||
) {
|
||||
#[derive(Error, Debug)]
|
||||
pub enum HardwareInitError {
|
||||
#[error("Failed to etup UART")]
|
||||
Uart(#[from] esp_hal::uart::ConfigError),
|
||||
|
||||
#[error("Failed to setup I2C")]
|
||||
I2C(#[from] esp_hal::i2c::master::ConfigError),
|
||||
|
||||
#[error("Failed to setup SPI")]
|
||||
Spi(#[from] esp_hal::spi::master::ConfigError),
|
||||
|
||||
#[error("Failed to setuo LED")]
|
||||
Led(#[from] esp_hal::rmt::Error),
|
||||
|
||||
#[error("Failed to setup wifi")]
|
||||
Wifi(#[from] wifi::WifiError),
|
||||
}
|
||||
|
||||
pub struct AppHardware {
|
||||
pub uart: Uart<'static, Async>,
|
||||
pub network_stack: Stack<'static>,
|
||||
pub i2c: I2c<'static, Async>,
|
||||
pub buzzer: Output<'static>,
|
||||
pub sd_present: AnyPin<'static>,
|
||||
pub led: SmartLedsAdapterAsync<'static, LED_BUFFER_SIZE>,
|
||||
pub sdcard: SDCardPersistence,
|
||||
}
|
||||
|
||||
impl AppHardware {
|
||||
pub async fn init(spawner: Spawner) -> Result<Self, HardwareInitError> {
|
||||
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
|
||||
let peripherals = esp_hal::init(config);
|
||||
|
||||
esp_alloc::heap_allocator!(size: 72 * 1024);
|
||||
esp_alloc::heap_allocator!(#[unsafe(link_section = ".dram2_uninit")] size: 65536);
|
||||
|
||||
let timer0 = SystemTimer::new(peripherals.SYSTIMER);
|
||||
esp_hal_embassy::init(timer0.alarm0);
|
||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||
let sw_interrupt =
|
||||
esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
|
||||
esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0);
|
||||
|
||||
init_logger(log::LevelFilter::Debug);
|
||||
|
||||
let timer1 = TimerGroup::new(peripherals.TIMG0);
|
||||
let mut rng = esp_hal::rng::Rng::new(peripherals.RNG);
|
||||
let mut led = setup_led(peripherals.RMT, peripherals.GPIO1)?;
|
||||
let _ = led.write(brightness(
|
||||
[RED; NUM_LEDS].into_iter(),
|
||||
255,
|
||||
))
|
||||
.await;
|
||||
|
||||
let rng = esp_hal::rng::Rng::new();
|
||||
let network_seed = (rng.random() as u64) << 32 | rng.random() as u64;
|
||||
|
||||
wifi::set_antenna_mode(peripherals.GPIO3, peripherals.GPIO14).await;
|
||||
let interfaces = wifi::setup_wifi(timer1.timer0, rng, peripherals.WIFI, spawner);
|
||||
let stack = network::setup_network(network_seed, interfaces.ap, spawner);
|
||||
let interfaces = wifi::setup_wifi(peripherals.WIFI, spawner)?;
|
||||
let network_stack = network::setup_network(network_seed, interfaces.ap, spawner);
|
||||
|
||||
Timer::after(Duration::from_millis(1)).await;
|
||||
init_lvl_shifter(peripherals.GPIO0);
|
||||
|
||||
let uart_device = setup_uart(peripherals.UART1, peripherals.GPIO16, peripherals.GPIO17);
|
||||
let uart_device = setup_uart(peripherals.UART1, peripherals.GPIO16, peripherals.GPIO17)?;
|
||||
|
||||
let i2c_device = setup_i2c(peripherals.I2C0, peripherals.GPIO22, peripherals.GPIO23);
|
||||
let i2c_device = setup_i2c(peripherals.I2C0, peripherals.GPIO22, peripherals.GPIO23)?;
|
||||
|
||||
let spi_device = setup_spi(
|
||||
let sd_det_gpio = peripherals.GPIO0;
|
||||
|
||||
let spi_bus = setup_spi(
|
||||
peripherals.SPI2,
|
||||
peripherals.GPIO19,
|
||||
peripherals.GPIO20,
|
||||
peripherals.GPIO18,
|
||||
)?;
|
||||
|
||||
let sd_cs_pin = Output::new(
|
||||
peripherals.GPIO2,
|
||||
esp_hal::gpio::Level::High,
|
||||
OutputConfig::default(),
|
||||
);
|
||||
|
||||
let sd_card = setup_sdcard(spi_device);
|
||||
let vol_mgr = setup_sdcard(spi_bus, sd_cs_pin);
|
||||
|
||||
let buzzer_gpio = peripherals.GPIO21;
|
||||
let buzzer = setup_buzzer(buzzer_gpio);
|
||||
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
|
||||
let led = setup_led(peripherals.RMT, peripherals.GPIO1);
|
||||
|
||||
debug!("hardware init done");
|
||||
|
||||
(uart_device, stack, i2c_device, led, buzzer_gpio)
|
||||
Ok(Self {
|
||||
uart: uart_device,
|
||||
network_stack,
|
||||
i2c: i2c_device,
|
||||
buzzer,
|
||||
sd_present: sd_det_gpio.into(),
|
||||
led,
|
||||
sdcard: vol_mgr,
|
||||
})
|
||||
}
|
||||
|
||||
// Initialize the level shifter for the NFC reader and LED (output-enable (OE) input is low, all outputs are placed in the high-impedance (Hi-Z) state)
|
||||
fn init_lvl_shifter(oe_pin: GPIO0<'static>) {
|
||||
let mut oe_lvl_shifter =
|
||||
Output::new(oe_pin, esp_hal::gpio::Level::Low, OutputConfig::default().with_drive_mode(esp_hal::gpio::DriveMode::PushPull).with_drive_strength(esp_hal::gpio::DriveStrength::_10mA));
|
||||
oe_lvl_shifter.set_high();
|
||||
}
|
||||
|
||||
fn setup_uart(
|
||||
uart1: UART1<'static>,
|
||||
uart_tx: GPIO16<'static>,
|
||||
uart_rx: GPIO17<'static>,
|
||||
) -> Uart<'static, Async> {
|
||||
let uard_device = Uart::new(uart1, esp_hal::uart::Config::default().with_baudrate(9600));
|
||||
|
||||
match uard_device {
|
||||
Ok(block) => block.with_rx(uart_rx).with_tx(uart_tx).into_async(),
|
||||
Err(e) => {
|
||||
error!("Failed to initialize UART: {e}");
|
||||
panic!(); //TODO panic!
|
||||
}
|
||||
}
|
||||
) -> Result<Uart<'static, Async>, esp_hal::uart::ConfigError> {
|
||||
let uart_device = Uart::new(uart1, esp_hal::uart::Config::default().with_baudrate(9600))?;
|
||||
Ok(uart_device.with_rx(uart_rx).with_tx(uart_tx).into_async())
|
||||
}
|
||||
|
||||
fn setup_i2c(
|
||||
i2c0: I2C0<'static>,
|
||||
sda: GPIO22<'static>,
|
||||
scl: GPIO23<'static>,
|
||||
) -> I2c<'static, Async> {
|
||||
) -> Result<I2c<'static, Async>, esp_hal::i2c::master::ConfigError> {
|
||||
debug!("init I2C");
|
||||
let config = Config::default().with_frequency(Rate::from_khz(400));
|
||||
let i2c = match I2c::new(i2c0, config) {
|
||||
Ok(i2c) => i2c.with_sda(sda).with_scl(scl).into_async(),
|
||||
Err(e) => {
|
||||
error!("Failed to initialize I2C: {:?}", e);
|
||||
panic!(); //TODO panic!
|
||||
}
|
||||
};
|
||||
i2c
|
||||
|
||||
let i2c = I2c::new(i2c0, config)?;
|
||||
|
||||
Ok(i2c.with_sda(sda).with_scl(scl).into_async())
|
||||
}
|
||||
|
||||
fn setup_spi(
|
||||
@@ -167,49 +187,34 @@ fn setup_spi(
|
||||
sck: GPIO19<'static>,
|
||||
miso: GPIO20<'static>,
|
||||
mosi: GPIO18<'static>,
|
||||
cs: GPIO2<'static>,
|
||||
) -> Spi<'static, Async> {
|
||||
let spi = match Spi::new(spi2, Spi_config::default()) {
|
||||
Ok(spi) => spi
|
||||
.with_sck(sck)
|
||||
.with_miso(miso)
|
||||
.with_mosi(mosi)
|
||||
.with_cs(cs)
|
||||
.into_async(),
|
||||
Err(e) => panic!("Failed to initialize SPI: {:?}", e),
|
||||
};
|
||||
spi
|
||||
}
|
||||
|
||||
fn setup_sdcard(spi_device: Spi<'static, Async>) {
|
||||
//let sdcard = SdCard::new(spi_device as embedded_hal::spi::SpiDevice(), delayer)
|
||||
) -> Result<Spi<'static, Blocking>, esp_hal::spi::master::ConfigError> {
|
||||
let spi = Spi::new(spi2, Spi_config::default())?;
|
||||
Ok(spi.with_sck(sck).with_miso(miso).with_mosi(mosi))
|
||||
}
|
||||
|
||||
pub fn setup_buzzer(buzzer_gpio: GPIO21<'static>) -> Output<'static> {
|
||||
let config = esp_hal::gpio::OutputConfig::default()
|
||||
.with_drive_strength(esp_hal::gpio::DriveStrength::_40mA);
|
||||
let buzzer = Output::new(buzzer_gpio, esp_hal::gpio::Level::Low, config);
|
||||
|
||||
buzzer
|
||||
Output::new(buzzer_gpio, esp_hal::gpio::Level::Low, config)
|
||||
}
|
||||
|
||||
fn setup_led(
|
||||
rmt: RMT<'static>,
|
||||
led_gpio: GPIO1<'static>,
|
||||
) -> SmartLedsAdapterAsync<ConstChannelAccess<esp_hal::rmt::Tx, 0>, LED_BUFFER_SIZE> {
|
||||
debug!("setup led");
|
||||
fn setup_led<'a>(
|
||||
rmt: RMT<'a>,
|
||||
led_gpio: GPIO1<'a>,
|
||||
) -> Result<esp_hal_smartled::SmartLedsAdapterAsync<'a, LED_BUFFER_SIZE>, esp_hal::rmt::Error> {
|
||||
let rmt: Rmt<'_, esp_hal::Async> = {
|
||||
let frequency: Rate = Rate::from_mhz(80);
|
||||
Rmt::new(rmt, frequency)
|
||||
}
|
||||
.expect("Failed to initialize RMT")
|
||||
}?
|
||||
.into_async();
|
||||
|
||||
let rmt_channel = rmt.channel0;
|
||||
let rmt_buffer = [0_u32; buffer_size_async(NUM_LEDS)];
|
||||
let rmt_buffer = [esp_hal::rmt::PulseCode::default(); LED_BUFFER_SIZE];
|
||||
|
||||
let led: SmartLedsAdapterAsync<_, LED_BUFFER_SIZE> =
|
||||
SmartLedsAdapterAsync::new(rmt_channel, led_gpio, rmt_buffer);
|
||||
|
||||
led
|
||||
Ok(SmartLedsAdapterAsync::new(
|
||||
rmt_channel,
|
||||
led_gpio,
|
||||
rmt_buffer,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -1,43 +1,41 @@
|
||||
use core::{net::Ipv4Addr, str::FromStr};
|
||||
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_net::{Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4};
|
||||
use embassy_time::{Duration, Timer};
|
||||
use esp_wifi::wifi::WifiDevice;
|
||||
use static_cell::make_static;
|
||||
|
||||
|
||||
pub fn setup_network<'a>(seed: u64, wifi: WifiDevice<'static>, spawner: &mut Spawner) -> Stack<'a> {
|
||||
let gw_ip_addr_str = "192.168.2.1";
|
||||
let gw_ip_addr = Ipv4Addr::from_str(gw_ip_addr_str).expect("failed to parse gateway ip");
|
||||
let config = embassy_net::Config::ipv4_static(StaticConfigV4 {
|
||||
address: Ipv4Cidr::new(gw_ip_addr, 24),
|
||||
gateway: Some(gw_ip_addr),
|
||||
dns_servers: Default::default(),
|
||||
});
|
||||
|
||||
let (stack, runner) =
|
||||
embassy_net::new(wifi, config, make_static!(StackResources::<3>::new()), seed);
|
||||
|
||||
spawner.must_spawn(net_task(runner));
|
||||
spawner.must_spawn(run_dhcp(stack, gw_ip_addr_str));
|
||||
|
||||
stack
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn run_dhcp(stack: Stack<'static>, gw_ip_addr: &'static str) {
|
||||
use core::net::{Ipv4Addr, SocketAddrV4};
|
||||
|
||||
use edge_dhcp::{
|
||||
io::{self, DEFAULT_SERVER_PORT},
|
||||
server::{Server, ServerOptions},
|
||||
};
|
||||
use edge_nal::UdpBind;
|
||||
use edge_nal_embassy::{Udp, UdpBuffers};
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_net::{Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4};
|
||||
use embassy_time::{Duration, Timer};
|
||||
use esp_radio::wifi::WifiDevice;
|
||||
use static_cell::StaticCell;
|
||||
|
||||
let ip = Ipv4Addr::from_str(gw_ip_addr).expect("dhcp task failed to parse gw ip");
|
||||
use crate::webserver::WEB_TAKS_SIZE;
|
||||
|
||||
pub const NETWORK_STACK_SIZE: usize = WEB_TAKS_SIZE + 2; // + 2 for other network taks. Breaks without
|
||||
pub const GW_IP: Ipv4Addr = Ipv4Addr::new(192, 168, 2, 1);
|
||||
|
||||
pub fn setup_network<'a>(seed: u64, wifi: WifiDevice<'static>, spawner: Spawner) -> Stack<'a> {
|
||||
let config = embassy_net::Config::ipv4_static(StaticConfigV4 {
|
||||
address: Ipv4Cidr::new(GW_IP, 24),
|
||||
gateway: Some(GW_IP),
|
||||
dns_servers: Default::default(),
|
||||
});
|
||||
|
||||
static NETWORK_STACK: StaticCell<StackResources<NETWORK_STACK_SIZE>> = StaticCell::new();
|
||||
let nw_stack = NETWORK_STACK.init(StackResources::new());
|
||||
|
||||
let (stack, runner) = embassy_net::new(wifi, config, nw_stack, seed);
|
||||
|
||||
spawner.must_spawn(net_task(runner));
|
||||
spawner.must_spawn(run_dhcp(stack));
|
||||
|
||||
stack
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn run_dhcp(stack: Stack<'static>) {
|
||||
let mut buf = [0u8; 1500];
|
||||
|
||||
let mut gw_buf = [Ipv4Addr::UNSPECIFIED];
|
||||
@@ -50,12 +48,12 @@ async fn run_dhcp(stack: Stack<'static>, gw_ip_addr: &'static str) {
|
||||
DEFAULT_SERVER_PORT,
|
||||
)))
|
||||
.await
|
||||
.unwrap();
|
||||
.expect("Failed to bind socket for DHCP server");
|
||||
|
||||
loop {
|
||||
_ = io::server::run(
|
||||
&mut Server::<_, 64>::new_with_et(ip),
|
||||
&ServerOptions::new(ip, Some(&mut gw_buf)),
|
||||
&mut Server::<_, 64>::new_with_et(GW_IP),
|
||||
&ServerOptions::new(GW_IP, Some(&mut gw_buf)),
|
||||
&mut bound_socket,
|
||||
&mut buf,
|
||||
)
|
||||
@@ -69,4 +67,3 @@ async fn run_dhcp(stack: Stack<'static>, gw_ip_addr: &'static str) {
|
||||
async fn net_task(mut runner: Runner<'static, WifiDevice<'static>>) {
|
||||
runner.run().await;
|
||||
}
|
||||
|
||||
|
||||
275
src/init/sd_card.rs
Normal file
275
src/init/sd_card.rs
Normal file
@@ -0,0 +1,275 @@
|
||||
use alloc::{string::ToString, vec::Vec};
|
||||
use core::str::from_utf8;
|
||||
use embassy_time::Delay;
|
||||
use embedded_hal_bus::spi::ExclusiveDevice;
|
||||
use embedded_sdmmc::{
|
||||
SdCard, SdCardError, ShortFileName, TimeSource, Timestamp, VolumeIdx, VolumeManager,
|
||||
};
|
||||
use esp_hal::{Blocking, gpio::Output, spi::master::Spi};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::store::{
|
||||
AttendanceDay, day::Day, mapping_loader::Name, persistence::Persistence, tally_id::TallyID,
|
||||
};
|
||||
|
||||
pub struct DummyTimesource;
|
||||
|
||||
impl TimeSource for DummyTimesource {
|
||||
fn get_timestamp(&self) -> Timestamp {
|
||||
Timestamp {
|
||||
year_since_1970: 0,
|
||||
zero_indexed_month: 0,
|
||||
zero_indexed_day: 0,
|
||||
hours: 0,
|
||||
minutes: 0,
|
||||
seconds: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type VolMgr = VolumeManager<
|
||||
SdCard<ExclusiveDevice<Spi<'static, Blocking>, Output<'static>, Delay>, Delay>,
|
||||
DummyTimesource,
|
||||
>;
|
||||
|
||||
pub fn setup_sdcard(spi_bus: Spi<'static, Blocking>, cs_pin: Output<'static>) -> SDCardPersistence {
|
||||
let spi_device = ExclusiveDevice::new(spi_bus, cs_pin, Delay).unwrap();
|
||||
let sd_card = SdCard::new(spi_device, Delay);
|
||||
let vol_mgr = VolumeManager::new(sd_card, DummyTimesource);
|
||||
|
||||
SDCardPersistence { vol_mgr }
|
||||
}
|
||||
|
||||
pub struct SDCardPersistence {
|
||||
vol_mgr: VolMgr,
|
||||
}
|
||||
|
||||
impl SDCardPersistence {
|
||||
const MAPPING_DIRNAME: &'static str = "MAPPINGS";
|
||||
|
||||
fn generate_filename_for_day(day: Day) -> Result<ShortFileName, PersistenceError> {
|
||||
let basename = day.to_string();
|
||||
let mut filename: heapless::String<11> = heapless::String::new();
|
||||
filename
|
||||
.push_str(&basename)
|
||||
.map_err(|_| PersistenceError::DayFilename)?;
|
||||
filename
|
||||
.push_str(".JS")
|
||||
.map_err(|_| PersistenceError::DayFilename)?;
|
||||
|
||||
ShortFileName::create_from_str(&filename).map_err(|_| PersistenceError::DayFilename)
|
||||
}
|
||||
|
||||
fn generate_path_for_id(
|
||||
id: TallyID,
|
||||
) -> Result<(ShortFileName, ShortFileName), PersistenceError> {
|
||||
let basename: heapless::String<12> = id.into();
|
||||
let (dir, file) = basename.split_at(6);
|
||||
|
||||
let mut filename: heapless::String<11> = heapless::String::new();
|
||||
filename
|
||||
.push_str(file)
|
||||
.map_err(|_| PersistenceError::IDFilename)?;
|
||||
filename
|
||||
.push_str(".JS")
|
||||
.map_err(|_| PersistenceError::IDFilename)?;
|
||||
|
||||
let mut dirname: heapless::String<11> = heapless::String::new();
|
||||
dirname
|
||||
.push_str(dir)
|
||||
.map_err(|_| PersistenceError::IDFilename)?;
|
||||
|
||||
Ok((
|
||||
ShortFileName::create_from_str(&dirname).map_err(|_| PersistenceError::IDFilename)?,
|
||||
ShortFileName::create_from_str(&filename).map_err(|_| PersistenceError::IDFilename)?,
|
||||
))
|
||||
}
|
||||
|
||||
fn get_tallyid_from_path(
|
||||
dirname: &ShortFileName,
|
||||
filename: &ShortFileName,
|
||||
) -> Result<TallyID, PersistenceError> {
|
||||
let mut id_str: heapless::String<12> = heapless::String::new();
|
||||
|
||||
id_str
|
||||
.push_str(&dirname.to_string())
|
||||
.map_err(|_| PersistenceError::IDFilename)?;
|
||||
id_str
|
||||
.push_str(from_utf8(filename.base_name()).map_err(|_| PersistenceError::IDFilename)?)
|
||||
.map_err(|_| PersistenceError::IDFilename)?;
|
||||
|
||||
let id: TallyID = id_str
|
||||
.try_into()
|
||||
.map_err(|_| PersistenceError::IDFilename)?;
|
||||
|
||||
Ok(id)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum PersistenceError {
|
||||
#[error("Failed to interact with SD card")]
|
||||
SdCard(embedded_sdmmc::Error<SdCardError>),
|
||||
|
||||
#[error("Failed to parse data")]
|
||||
Parseing(#[from] serde_json::Error),
|
||||
|
||||
#[error("Failed to parse Day and Filename")]
|
||||
DayFilename,
|
||||
|
||||
#[error("Failed to parse TallyID for file path")]
|
||||
IDFilename,
|
||||
|
||||
#[error("Item not found")]
|
||||
NotFound,
|
||||
}
|
||||
|
||||
impl From<embedded_sdmmc::Error<SdCardError>> for PersistenceError {
|
||||
fn from(err: embedded_sdmmc::Error<SdCardError>) -> Self {
|
||||
PersistenceError::SdCard(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl Persistence for SDCardPersistence {
|
||||
type Error = PersistenceError;
|
||||
|
||||
async fn load_day(&mut self, day: Day) -> Result<AttendanceDay, Self::Error> {
|
||||
let mut vol_0 = self.vol_mgr.open_volume(VolumeIdx(0))?;
|
||||
let mut root_dir = vol_0.open_root_dir()?;
|
||||
|
||||
let filename = Self::generate_filename_for_day(day)?;
|
||||
let file = root_dir.open_file_in_dir(filename, embedded_sdmmc::Mode::ReadOnly);
|
||||
|
||||
if file.is_err() {
|
||||
return Err(PersistenceError::NotFound);
|
||||
}
|
||||
|
||||
let mut open_file = file?;
|
||||
|
||||
let mut read_buffer: [u8; 1024] = [0; 1024];
|
||||
let read = open_file.read(&mut read_buffer)?;
|
||||
open_file.close()?;
|
||||
|
||||
let day: AttendanceDay = serde_json::from_slice(&read_buffer[..read])?;
|
||||
|
||||
Ok(day)
|
||||
}
|
||||
|
||||
async fn save_day(&mut self, day: Day, data: &AttendanceDay) -> Result<(), Self::Error> {
|
||||
let mut vol_0 = self.vol_mgr.open_volume(VolumeIdx(0))?;
|
||||
let mut root_dir = vol_0.open_root_dir()?;
|
||||
|
||||
let filename = Self::generate_filename_for_day(day)?;
|
||||
|
||||
let mut file =
|
||||
root_dir.open_file_in_dir(filename, embedded_sdmmc::Mode::ReadWriteCreateOrTruncate)?;
|
||||
|
||||
file.write(&serde_json::to_vec(data)?)?;
|
||||
|
||||
file.flush()?;
|
||||
file.close()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn list_days(&mut self) -> Result<Vec<Day>, Self::Error> {
|
||||
let mut vol_0 = self.vol_mgr.open_volume(VolumeIdx(0))?;
|
||||
let mut root_dir = vol_0.open_root_dir()?;
|
||||
|
||||
let mut days_dir = root_dir.open_dir(".")?;
|
||||
|
||||
let mut days: Vec<Day> = Vec::new();
|
||||
days_dir.iterate_dir(|e| {
|
||||
let filename = e.name.clone();
|
||||
|
||||
if let Ok(day) = filename.try_into() {
|
||||
days.push(day);
|
||||
}
|
||||
})?;
|
||||
|
||||
Ok(days)
|
||||
}
|
||||
|
||||
async fn load_mapping_for_id(
|
||||
&mut self,
|
||||
id: crate::store::tally_id::TallyID,
|
||||
) -> Result<crate::store::mapping_loader::Name, Self::Error> {
|
||||
let mut vol_0 = self.vol_mgr.open_volume(VolumeIdx(0))?;
|
||||
let mut root_dir = vol_0.open_root_dir()?;
|
||||
let mut mapping_dir = root_dir.open_dir(Self::MAPPING_DIRNAME)?;
|
||||
|
||||
let (dirname, filename) = Self::generate_path_for_id(id)?;
|
||||
|
||||
let mut dir = mapping_dir.open_dir(dirname)?;
|
||||
let mut file = dir.open_file_in_dir(filename, embedded_sdmmc::Mode::ReadOnly)?;
|
||||
|
||||
let mut read_buffer: [u8; 1024] = [0; 1024];
|
||||
let read_bytes = file.read(&mut read_buffer)?;
|
||||
file.close()?;
|
||||
|
||||
let mapping: Name = serde_json::from_slice(&read_buffer[..read_bytes])?;
|
||||
|
||||
Ok(mapping)
|
||||
}
|
||||
|
||||
async fn save_mapping_for_id(
|
||||
&mut self,
|
||||
id: crate::store::tally_id::TallyID,
|
||||
name: crate::store::mapping_loader::Name,
|
||||
) -> Result<(), Self::Error> {
|
||||
let mut vol_0 = self.vol_mgr.open_volume(VolumeIdx(0))?;
|
||||
let mut root_dir = vol_0.open_root_dir()?;
|
||||
let mut mapping_dir = root_dir.open_dir(Self::MAPPING_DIRNAME)?;
|
||||
|
||||
let (dirname, filename) = Self::generate_path_for_id(id)?;
|
||||
|
||||
let mut dir = if let Ok(dir) = mapping_dir.open_dir(&dirname) {
|
||||
dir
|
||||
} else {
|
||||
mapping_dir.make_dir_in_dir(&dirname)?;
|
||||
mapping_dir.open_dir(&dirname)?
|
||||
};
|
||||
|
||||
let mut file =
|
||||
dir.open_file_in_dir(filename, embedded_sdmmc::Mode::ReadWriteCreateOrTruncate)?;
|
||||
|
||||
file.write(&serde_json::to_vec(&name)?)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn list_mappings(&mut self) -> Result<Vec<TallyID>, Self::Error> {
|
||||
let mut vol_0 = self.vol_mgr.open_volume(VolumeIdx(0))?;
|
||||
let mut root_dir = vol_0.open_root_dir()?;
|
||||
let mut mapping_dir = root_dir.open_dir(Self::MAPPING_DIRNAME)?;
|
||||
let mut ids: Vec<TallyID> = Vec::new();
|
||||
|
||||
let mut dir_names = Vec::new();
|
||||
mapping_dir.iterate_dir(|entry| {
|
||||
if entry.attributes.is_directory()
|
||||
&& entry.name.to_string() != "."
|
||||
&& entry.name.to_string() != ".."
|
||||
{
|
||||
dir_names.push(entry.name.clone());
|
||||
}
|
||||
})?;
|
||||
|
||||
for dirname in dir_names {
|
||||
if let Ok(mut subdir) = mapping_dir.open_dir(&dirname) {
|
||||
let mut file_names = Vec::new();
|
||||
subdir.iterate_dir(|file_entry| {
|
||||
if !file_entry.attributes.is_directory() {
|
||||
file_names.push(file_entry.name.clone());
|
||||
}
|
||||
})?;
|
||||
|
||||
for filename in file_names {
|
||||
let id = Self::get_tallyid_from_path(&dirname, &filename)?;
|
||||
ids.push(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ids)
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,13 @@ use embassy_executor::Spawner;
|
||||
use embassy_time::{Duration, Timer};
|
||||
use esp_hal::gpio::{Output, OutputConfig};
|
||||
use esp_hal::peripherals::{GPIO3, GPIO14, WIFI};
|
||||
use esp_wifi::wifi::{AccessPointConfiguration, Configuration, WifiController, WifiEvent, WifiState};
|
||||
use esp_wifi::{EspWifiRngSource, EspWifiTimerSource, wifi::Interfaces};
|
||||
use static_cell::make_static;
|
||||
use esp_radio::Controller;
|
||||
use esp_radio::wifi::{
|
||||
AccessPointConfig, Interfaces, ModeConfig, WifiApState, WifiController, WifiEvent,
|
||||
};
|
||||
use log::debug;
|
||||
use static_cell::StaticCell;
|
||||
use thiserror::Error;
|
||||
|
||||
pub async fn set_antenna_mode(gpio3: GPIO3<'static>, gpio14: GPIO14<'static>) {
|
||||
let mut rf_switch = Output::new(gpio3, esp_hal::gpio::Level::Low, OutputConfig::default());
|
||||
@@ -18,39 +22,56 @@ pub async fn set_antenna_mode(gpio3: GPIO3<'static>, gpio14: GPIO14<'static>) {
|
||||
antenna_mode.set_low();
|
||||
}
|
||||
|
||||
pub fn setup_wifi<'d: 'static>(
|
||||
timer: impl EspWifiTimerSource + 'd,
|
||||
rng: impl EspWifiRngSource + 'd,
|
||||
wifi: WIFI<'static>,
|
||||
spawner: &mut Spawner,
|
||||
) -> Interfaces<'d> {
|
||||
let esp_wifi_ctrl = make_static!(esp_wifi::init(timer, rng).unwrap());
|
||||
#[derive(Error, Debug)]
|
||||
pub enum WifiError {
|
||||
#[error("Failed to init radio")]
|
||||
Init(#[from] esp_radio::InitializationError),
|
||||
|
||||
let (controller, interfaces) = esp_wifi::wifi::new(esp_wifi_ctrl, wifi).unwrap();
|
||||
#[error("Failed to init wifi")]
|
||||
Wifi(#[from] esp_radio::wifi::WifiError),
|
||||
|
||||
spawner.must_spawn(connection(controller));
|
||||
|
||||
interfaces
|
||||
#[error("Failed to spawn wifi task")]
|
||||
Spawn(#[from] embassy_executor::SpawnError),
|
||||
}
|
||||
|
||||
pub fn setup_wifi<'d: 'static>(
|
||||
wifi: WIFI<'static>,
|
||||
spawner: Spawner,
|
||||
) -> Result<Interfaces<'d>, WifiError> {
|
||||
static ESP_WIFI_CTRL: StaticCell<Controller<'static>> = StaticCell::new();
|
||||
|
||||
let esp_wifi_ctrl = ESP_WIFI_CTRL.init(esp_radio::init()?);
|
||||
|
||||
let config = esp_radio::wifi::Config::default();
|
||||
let (controller, interfaces) = esp_radio::wifi::new(esp_wifi_ctrl, wifi, config)?;
|
||||
|
||||
spawner.spawn(connection(controller))?;
|
||||
|
||||
Ok(interfaces)
|
||||
}
|
||||
#[embassy_executor::task]
|
||||
async fn connection(mut controller: WifiController<'static>) {
|
||||
debug!("start connection task");
|
||||
debug!("Device capabilities: {:?}", controller.capabilities());
|
||||
|
||||
loop {
|
||||
match esp_wifi::wifi::wifi_state() {
|
||||
WifiState::ApStarted => {
|
||||
if esp_radio::wifi::ap_state() == WifiApState::Started {
|
||||
// wait until we're no longer connected
|
||||
controller.wait_for_event(WifiEvent::ApStop).await;
|
||||
Timer::after(Duration::from_millis(5000)).await
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if !matches!(controller.is_started(), Ok(true)) {
|
||||
let client_config = Configuration::AccessPoint(AccessPointConfiguration {
|
||||
ssid: "esp-wifi".try_into().unwrap(),
|
||||
..Default::default()
|
||||
});
|
||||
controller.set_configuration(&client_config).unwrap();
|
||||
let client_config = ModeConfig::AccessPoint(
|
||||
AccessPointConfig::default()
|
||||
.with_ssid(env!("WIFI_SSID").try_into().unwrap())
|
||||
.with_password(env!("WIFI_PASSWD").try_into().unwrap())
|
||||
.with_auth_method(esp_radio::wifi::AuthMethod::Wpa2Personal),
|
||||
);
|
||||
controller.set_config(&client_config).unwrap();
|
||||
debug!("Starting wifi");
|
||||
controller.start_async().await.unwrap();
|
||||
debug!("Wifi started!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
116
src/main.rs
116
src/main.rs
@@ -2,23 +2,34 @@
|
||||
#![no_main]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
#![feature(impl_trait_in_assoc_type)]
|
||||
#![warn(clippy::unwrap_used)]
|
||||
|
||||
use alloc::rc::Rc;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_net::Stack;
|
||||
use embassy_sync::{
|
||||
blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}, channel::Channel, pubsub::{
|
||||
PubSubChannel, Publisher,
|
||||
blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex},
|
||||
mutex::Mutex,
|
||||
pubsub::{
|
||||
PubSubChannel, Publisher, Subscriber,
|
||||
WaitResult::{Lagged, Message},
|
||||
}, signal::Signal
|
||||
},
|
||||
signal::Signal,
|
||||
};
|
||||
use embassy_time::{Duration, Timer};
|
||||
use esp_hal::gpio::InputConfig;
|
||||
use esp_hal::gpio::{AnyPin, Input};
|
||||
use log::{debug, info};
|
||||
use static_cell::make_static;
|
||||
|
||||
use crate::{store::TallyID, webserver::start_webserver};
|
||||
use static_cell::StaticCell;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use crate::{
|
||||
init::{hardware::AppHardware, sd_card::SDCardPersistence},
|
||||
store::{IDStore, day::Day, mapping_loader::MappingLoader, tally_id::TallyID},
|
||||
webserver::start_webserver,
|
||||
};
|
||||
|
||||
mod drivers;
|
||||
mod feedback;
|
||||
mod init;
|
||||
@@ -29,50 +40,101 @@ static FEEDBACK_STATE: Signal<CriticalSectionRawMutex, feedback::FeedbackState>
|
||||
|
||||
type TallyChannel = PubSubChannel<NoopRawMutex, TallyID, 8, 2, 1>;
|
||||
type TallyPublisher = Publisher<'static, NoopRawMutex, TallyID, 8, 2, 1>;
|
||||
type TallySubscriber = Subscriber<'static, NoopRawMutex, TallyID, 8, 2, 1>;
|
||||
type UsedStore = IDStore<SDCardPersistence>;
|
||||
|
||||
#[esp_hal_embassy::main]
|
||||
async fn main(mut spawner: Spawner) {
|
||||
let (uart_device, stack, _i2c, _led, buzzer_gpio) =
|
||||
init::hardware::hardware_init(&mut spawner).await;
|
||||
static CHAN: StaticCell<TallyChannel> = StaticCell::new();
|
||||
|
||||
wait_for_stack_up(stack).await;
|
||||
#[esp_rtos::main]
|
||||
async fn main(spawner: Spawner) -> ! {
|
||||
let app_hardware = AppHardware::init(spawner).await.unwrap();
|
||||
|
||||
info!("Starting up...");
|
||||
|
||||
let chan: &'static mut TallyChannel = make_static!(PubSubChannel::new());
|
||||
let mut rtc = drivers::rtc::RTCClock::new(app_hardware.i2c).await;
|
||||
|
||||
//start_webserver(&mut spawner, stack);
|
||||
let current_day: Day = rtc.get_time().await.into();
|
||||
|
||||
let publisher = chan.publisher().unwrap();
|
||||
let shared_sdcard: Rc<Mutex<CriticalSectionRawMutex, SDCardPersistence>> =
|
||||
Rc::new(Mutex::new(app_hardware.sdcard));
|
||||
|
||||
let mut rtc = drivers::rtc::RTCClock::new(_i2c).await;
|
||||
let store: UsedStore = IDStore::new_from_storage(shared_sdcard.clone(), current_day).await;
|
||||
let shared_store = Rc::new(Mutex::new(store));
|
||||
|
||||
let mapping_loader = MappingLoader::new(shared_sdcard.clone());
|
||||
|
||||
let chan: &'static mut TallyChannel = CHAN.init(PubSubChannel::new());
|
||||
let publisher: TallyPublisher = chan.publisher().unwrap();
|
||||
let mut sub: TallySubscriber = chan.subscriber().unwrap();
|
||||
|
||||
wait_for_stack_up(app_hardware.network_stack).await;
|
||||
|
||||
start_webserver(
|
||||
spawner,
|
||||
app_hardware.network_stack,
|
||||
shared_store.clone(),
|
||||
chan,
|
||||
mapping_loader,
|
||||
);
|
||||
|
||||
/****************************** Spawning tasks ***********************************/
|
||||
debug!("spawing NFC reader task...");
|
||||
spawner.must_spawn(drivers::nfc_reader::rfid_reader_task(
|
||||
uart_device,
|
||||
app_hardware.uart,
|
||||
publisher,
|
||||
));
|
||||
|
||||
debug!("spawing feedback task..");
|
||||
spawner.must_spawn(feedback::feedback_task(_led, buzzer_gpio));
|
||||
/******************************************************************************/
|
||||
spawner.must_spawn(feedback::feedback_task(
|
||||
app_hardware.led,
|
||||
app_hardware.buzzer,
|
||||
));
|
||||
|
||||
let mut sub = chan.subscriber().unwrap();
|
||||
debug!("spawn sd detect task");
|
||||
spawner.must_spawn(sd_detect_task(app_hardware.sd_present));
|
||||
/******************************************************************************/
|
||||
|
||||
debug!("everything spawned");
|
||||
FEEDBACK_STATE.signal(feedback::FeedbackState::Startup);
|
||||
|
||||
loop {
|
||||
rtc.get_time().await;
|
||||
info!("Current RTC time: {}", rtc.get_time().await);
|
||||
Timer::after(Duration::from_millis(1000)).await;
|
||||
let wait_result = sub.next_message().await;
|
||||
match wait_result {
|
||||
Lagged(_) => debug!("Lagged"),
|
||||
Message(msg) => {
|
||||
debug!("Got message: {msg:?}");
|
||||
|
||||
// let wait_result = sub.next_message().await;
|
||||
// match wait_result {
|
||||
// Lagged(_) => debug!("Lagged"),
|
||||
// Message(msg) => debug!("Got message: {msg:?}"),
|
||||
// }
|
||||
let day: Day = rtc.get_time().await.into();
|
||||
let added = shared_store.lock().await.add_id(msg, day).await;
|
||||
|
||||
if added {
|
||||
FEEDBACK_STATE.signal(feedback::FeedbackState::Ack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn sd_detect_task(sd_det_gpio: AnyPin<'static>) {
|
||||
let mut sd_det = Input::new(sd_det_gpio, InputConfig::default());
|
||||
sd_det.wait_for(esp_hal::gpio::Event::AnyEdge).await;
|
||||
|
||||
loop {
|
||||
sd_det.wait_for_any_edge().await;
|
||||
{
|
||||
if sd_det.is_high() {
|
||||
FEEDBACK_STATE.signal(feedback::FeedbackState::Ack);
|
||||
debug!("card insert");
|
||||
}
|
||||
//card is not insert on low
|
||||
else {
|
||||
FEEDBACK_STATE.signal(feedback::FeedbackState::Nack);
|
||||
debug!("card removed");
|
||||
}
|
||||
}
|
||||
//debounce time
|
||||
Timer::after(Duration::from_millis(100)).await;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
63
src/store/day.rs
Normal file
63
src/store/day.rs
Normal file
@@ -0,0 +1,63 @@
|
||||
use core::fmt::Write;
|
||||
|
||||
use embedded_sdmmc::ShortFileName;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Day(u32);
|
||||
|
||||
impl Day {
|
||||
const SECONDS_PER_DAY: u64 = 86_400;
|
||||
|
||||
pub fn new(daystamp: u32) -> Self {
|
||||
Day(daystamp)
|
||||
}
|
||||
|
||||
pub fn new_from_timestamp(time: u64) -> Self {
|
||||
let day = time / Self::SECONDS_PER_DAY;
|
||||
|
||||
if day > u32::MAX as u64 {
|
||||
// TBH this would only happen if about 11 million years have passed
|
||||
// I sure hope i don't have to work on this project any more then
|
||||
// So we just cap it at this
|
||||
Day(u32::MAX)
|
||||
} else {
|
||||
Day(day as u32)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_timestamp(self) -> u64 {
|
||||
(self.0 as u64) * Self::SECONDS_PER_DAY
|
||||
}
|
||||
|
||||
pub fn to_string(self) -> heapless::String<8> {
|
||||
let mut s: heapless::String<8> = heapless::String::new();
|
||||
write!(s, "{:08X}", self.0).unwrap();
|
||||
s
|
||||
}
|
||||
|
||||
pub fn from_hex_str(s: &str) -> Result<Self, &'static str> {
|
||||
if s.len() > 8 {
|
||||
return Err("hex string too long");
|
||||
}
|
||||
|
||||
u32::from_str_radix(s, 16)
|
||||
.map_err(|_| "invalid hex string")
|
||||
.map(Day)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for Day {
|
||||
fn from(value: u64) -> Self {
|
||||
Self::new_from_timestamp(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<ShortFileName> for Day {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: ShortFileName) -> Result<Self, Self::Error> {
|
||||
let name = core::str::from_utf8(value.base_name()).map_err(|_| ())?;
|
||||
Self::from_hex_str(name).map_err(|_| ())
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
use super::TallyID;
|
||||
use alloc::collections::BTreeMap;
|
||||
use alloc::string::String;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct Name {
|
||||
pub first: String,
|
||||
pub last: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct IDMapping {
|
||||
id_map: BTreeMap<TallyID, Name>,
|
||||
}
|
||||
|
||||
impl IDMapping {
|
||||
pub fn new() -> Self {
|
||||
IDMapping {
|
||||
id_map: BTreeMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map(&self, id: &TallyID) -> Option<&Name> {
|
||||
self.id_map.get(id)
|
||||
}
|
||||
|
||||
pub fn add_mapping(&mut self, id: TallyID, name: Name) {
|
||||
self.id_map.insert(id, name);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,22 @@
|
||||
use super::Date;
|
||||
use super::IDMapping;
|
||||
use super::TallyID;
|
||||
use alloc::collections::BTreeMap;
|
||||
use alloc::rc::Rc;
|
||||
use alloc::vec::Vec;
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::mutex::Mutex;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Clone)]
|
||||
use crate::store::day::Day;
|
||||
use crate::store::persistence::Persistence;
|
||||
use crate::store::tally_id::TallyID;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||
pub struct AttendanceDay {
|
||||
date: Date,
|
||||
date: Day,
|
||||
ids: Vec<TallyID>,
|
||||
}
|
||||
|
||||
impl AttendanceDay {
|
||||
fn new(date: Date) -> Self {
|
||||
pub fn new(date: Day) -> Self {
|
||||
Self {
|
||||
date,
|
||||
ids: Vec::new(),
|
||||
@@ -30,42 +35,78 @@ impl AttendanceDay {
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct IDStore {
|
||||
pub days: BTreeMap<Date, AttendanceDay>,
|
||||
pub mapping: IDMapping,
|
||||
pub struct IDStore<T: Persistence> {
|
||||
current_day: AttendanceDay,
|
||||
persistence_layer: Rc<Mutex<CriticalSectionRawMutex, T>>,
|
||||
}
|
||||
|
||||
impl IDStore {
|
||||
pub fn new() -> Self {
|
||||
IDStore {
|
||||
days: BTreeMap::new(),
|
||||
mapping: IDMapping::new(),
|
||||
impl<T: Persistence> IDStore<T> {
|
||||
pub async fn new_from_storage(
|
||||
persistence_layer: Rc<Mutex<CriticalSectionRawMutex, T>>,
|
||||
current_date: Day,
|
||||
) -> Self {
|
||||
let day = persistence_layer
|
||||
.lock()
|
||||
.await
|
||||
.load_day(current_date)
|
||||
.await
|
||||
.unwrap_or(AttendanceDay::new(current_date));
|
||||
|
||||
Self {
|
||||
current_day: day,
|
||||
persistence_layer,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_from_storage() -> Self {
|
||||
// TODO: implement
|
||||
todo!()
|
||||
async fn persist_day(&mut self) -> Result<(), T::Error> {
|
||||
self.persistence_layer
|
||||
.lock()
|
||||
.await
|
||||
.save_day(self.current_day.date, &self.current_day)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Add a new id for the current day
|
||||
/// Returns false if ID is already present at the current day.
|
||||
pub fn add_id(&mut self, id: TallyID) -> bool {
|
||||
self.get_current_day().add_id(id)
|
||||
pub async fn add_id(&mut self, id: TallyID, current_date: Day) -> bool {
|
||||
if self.current_day.date == current_date {
|
||||
let changed = self.current_day.add_id(id);
|
||||
if changed {
|
||||
self.persist_day().await;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
/// Get the `AttendanceDay` of the current day
|
||||
/// Creates a new if not exists
|
||||
pub fn get_current_day(&mut self) -> &mut AttendanceDay {
|
||||
let current_day: Date = 1;
|
||||
let new_day = AttendanceDay::new(current_date);
|
||||
self.current_day = new_day;
|
||||
|
||||
if self.days.contains_key(¤t_day) {
|
||||
return self.days.get_mut(¤t_day).unwrap();
|
||||
let changed = self.current_day.add_id(id);
|
||||
if changed {
|
||||
self.persist_day().await;
|
||||
}
|
||||
changed
|
||||
}
|
||||
|
||||
self.days
|
||||
.insert(current_day, AttendanceDay::new(current_day));
|
||||
/// Load and return a AttendanceDay. Nothing more. Nothing less.
|
||||
pub async fn load_day(&mut self, day: Day) -> Result<AttendanceDay, T::Error> {
|
||||
if day == self.current_day.date {
|
||||
return Ok(self.current_day.clone());
|
||||
}
|
||||
|
||||
self.days.get_mut(¤t_day.clone()).unwrap()
|
||||
self.persistence_layer.lock().await.load_day(day).await
|
||||
}
|
||||
|
||||
pub async fn list_days_in_timespan(
|
||||
&mut self,
|
||||
from: Day,
|
||||
to: Day,
|
||||
) -> Result<Vec<Day>, T::Error> {
|
||||
let all_days = self.persistence_layer.lock().await.list_days().await?;
|
||||
|
||||
Ok(all_days
|
||||
.into_iter()
|
||||
.filter(|e| *e >= from)
|
||||
.filter(|e| *e <= to)
|
||||
.collect())
|
||||
}
|
||||
}
|
||||
|
||||
31
src/store/mapping_loader.rs
Normal file
31
src/store/mapping_loader.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
use alloc::{rc::Rc, string::String, vec::Vec};
|
||||
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::store::{persistence::Persistence, tally_id::TallyID};
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct Name {
|
||||
pub first: String,
|
||||
pub last: String,
|
||||
}
|
||||
|
||||
pub struct MappingLoader<T: Persistence>(Rc<Mutex<CriticalSectionRawMutex, T>>);
|
||||
|
||||
impl<T: Persistence> MappingLoader<T> {
|
||||
pub fn new(persistence_layer: Rc<Mutex<CriticalSectionRawMutex, T>>) -> Self {
|
||||
Self(persistence_layer)
|
||||
}
|
||||
|
||||
pub async fn get_mapping(&self, id: TallyID) -> Result<Name, T::Error> {
|
||||
self.0.lock().await.load_mapping_for_id(id).await
|
||||
}
|
||||
|
||||
pub async fn set_mapping(&self, id: TallyID, name: Name) -> Result<(), T::Error> {
|
||||
self.0.lock().await.save_mapping_for_id(id, name).await
|
||||
}
|
||||
|
||||
pub async fn list_mappings(&self) -> Result<Vec<TallyID>,T::Error> {
|
||||
self.0.lock().await.list_mappings().await
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
mod id_mapping;
|
||||
pub use id_store::{IDStore,AttendanceDay};
|
||||
|
||||
pub mod persistence;
|
||||
mod id_store;
|
||||
|
||||
pub use id_mapping::{IDMapping, Name};
|
||||
pub use id_store::IDStore;
|
||||
|
||||
pub type TallyID = [u8; 8];
|
||||
pub type Date = u64;
|
||||
pub mod tally_id;
|
||||
pub mod day;
|
||||
pub mod mapping_loader;
|
||||
|
||||
15
src/store/persistence.rs
Normal file
15
src/store/persistence.rs
Normal file
@@ -0,0 +1,15 @@
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use crate::store::{day::Day, id_store::AttendanceDay, mapping_loader::Name, tally_id::TallyID};
|
||||
|
||||
pub trait Persistence {
|
||||
type Error: core::error::Error;
|
||||
|
||||
async fn load_day(&mut self, day: Day) -> Result<AttendanceDay, Self::Error>;
|
||||
async fn save_day(&mut self, day: Day, data: &AttendanceDay) -> Result<(), Self::Error>;
|
||||
async fn list_days(&mut self) -> Result<Vec<Day>, Self::Error>;
|
||||
|
||||
async fn load_mapping_for_id(&mut self, id: TallyID) -> Result<Name, Self::Error>;
|
||||
async fn save_mapping_for_id(&mut self, id: TallyID, name: Name) -> Result<(), Self::Error>;
|
||||
async fn list_mappings(&mut self) -> Result<Vec<TallyID>, Self::Error>;
|
||||
}
|
||||
109
src/store/tally_id.rs
Normal file
109
src/store/tally_id.rs
Normal file
@@ -0,0 +1,109 @@
|
||||
use alloc::string::String;
|
||||
use core::{fmt::Display, str::FromStr};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct TallyID([u8; 6]);
|
||||
|
||||
impl FromStr for TallyID {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
s.as_bytes().try_into()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<heapless::String<12>> for TallyID {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: heapless::String<12>) -> Result<Self, Self::Error> {
|
||||
let bytes = value.as_bytes();
|
||||
|
||||
let mut out: [u8; 6] = [0; 6];
|
||||
for i in 0..6 {
|
||||
let hi = hex_val(bytes[2 * i])?;
|
||||
let lo = hex_val(bytes[2 * i + 1])?;
|
||||
out[i] = (hi << 4) | lo;
|
||||
}
|
||||
|
||||
Ok(TallyID(out))
|
||||
}
|
||||
}
|
||||
|
||||
fn hex_val(b: u8) -> Result<u8, ()> {
|
||||
match b {
|
||||
b'0'..=b'9' => Ok(b - b'0'),
|
||||
b'a'..=b'f' => Ok(b - b'a' + 10),
|
||||
b'A'..=b'F' => Ok(b - b'A' + 10),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TallyID> for heapless::String<12> {
|
||||
fn from(value: TallyID) -> Self {
|
||||
const HEX_CHARS: &[u8; 16] = b"0123456789ABCDEF";
|
||||
let mut s: Self = Self::new();
|
||||
|
||||
for &b in &value.0 {
|
||||
// Should be safe to unwrap since the string is already long enough
|
||||
s.push(HEX_CHARS[(b >> 4) as usize] as char).unwrap();
|
||||
s.push(HEX_CHARS[(b & 0x0F) as usize] as char).unwrap();
|
||||
}
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
/// From a array of hex chars
|
||||
impl TryFrom<&[u8]> for TallyID {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
|
||||
if value.len() != 12 {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let mut out: [u8; 6] = [0; 6];
|
||||
for i in 0..6 {
|
||||
let hi = hex_val(value[2 * i])?;
|
||||
let lo = hex_val(value[2 * i + 1])?;
|
||||
out[i] = (hi << 4) | lo;
|
||||
}
|
||||
|
||||
Ok(TallyID(out))
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<[u8; 12]> for TallyID {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: [u8; 12]) -> Result<Self, Self::Error> {
|
||||
Self::try_from(&value as &[u8])
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for TallyID {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
let s: heapless::String<12> = (*self).into();
|
||||
write!(f, "{}", s)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for TallyID {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let s: heapless::String<12> = (*self).into();
|
||||
serializer.serialize_str(&s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for TallyID {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = <String>::deserialize(deserializer)?;
|
||||
TallyID::from_str(&s).map_err(|_| de::Error::custom("Failed to parse Tally ID"))
|
||||
}
|
||||
}
|
||||
136
src/webserver/api.rs
Normal file
136
src/webserver/api.rs
Normal file
@@ -0,0 +1,136 @@
|
||||
use log::error;
|
||||
use picoserve::{
|
||||
extract::{Json, Query, State},
|
||||
response::{self, IntoResponse},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{
|
||||
store::{day::Day, mapping_loader::Name, tally_id::TallyID},
|
||||
webserver::{app::AppState, sse::IDEvents},
|
||||
};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct NewMapping {
|
||||
id: TallyID,
|
||||
name: Name,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct QueryTimespan {
|
||||
from: u64,
|
||||
to: u64,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct QueryDay {
|
||||
timestamp: Option<u64>,
|
||||
day: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct QueryMapping {
|
||||
id: TallyID,
|
||||
}
|
||||
|
||||
// GET /api/mappings
|
||||
pub async fn get_mappings(
|
||||
State(state): State<AppState>,
|
||||
) -> Result<impl IntoResponse, impl IntoResponse> {
|
||||
let loader = state.mapping_loader.lock().await;
|
||||
|
||||
match loader.list_mappings().await {
|
||||
Ok(ids) => Ok(response::Json(ids)),
|
||||
Err(_) => Err((
|
||||
response::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"INTERNAL_SERVER_ERROR",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
// GET /api/mapping
|
||||
pub async fn get_mapping(
|
||||
State(state): State<AppState>,
|
||||
Query(QueryMapping { id }): Query<QueryMapping>,
|
||||
) -> Result<impl IntoResponse, impl IntoResponse> {
|
||||
let loader = state.mapping_loader.lock().await;
|
||||
|
||||
match loader.get_mapping(id).await {
|
||||
Ok(name) => Ok(response::Json(name)),
|
||||
Err(_) => Err((
|
||||
response::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"INTERNAL_SERVER_ERROR",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
// POST /api/mapping
|
||||
pub async fn add_mapping(
|
||||
State(state): State<AppState>,
|
||||
Json(data): Json<NewMapping>,
|
||||
) -> impl IntoResponse {
|
||||
let loader = state.mapping_loader.lock().await;
|
||||
match loader.set_mapping(data.id, data.name).await {
|
||||
Ok(_) => (response::StatusCode::CREATED, ""),
|
||||
Err(_) => (
|
||||
response::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"INTERNAL_SERVER_ERROR",
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// SSE /api/idevent
|
||||
pub async fn get_idevent(
|
||||
State(state): State<AppState>,
|
||||
) -> Result<impl IntoResponse, impl IntoResponse> {
|
||||
match state.chan.subscriber() {
|
||||
Ok(chan) => Ok(response::EventStream(IDEvents(chan))),
|
||||
Err(e) => {
|
||||
error!("Failed to create SSE: {:?}", e);
|
||||
Err((
|
||||
response::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Internal server error",
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GET /api/days
|
||||
pub async fn get_days(
|
||||
State(state): State<AppState>,
|
||||
Query(QueryTimespan { from, to }): Query<QueryTimespan>,
|
||||
) -> impl IntoResponse {
|
||||
let from_day = Day::new_from_timestamp(from);
|
||||
let to_day = Day::new_from_timestamp(to);
|
||||
|
||||
let mut store = state.store.lock().await;
|
||||
|
||||
match store.list_days_in_timespan(from_day, to_day).await {
|
||||
Ok(days) => Ok(response::Json(days)),
|
||||
Err(_) => Err((
|
||||
response::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Internal server error",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
// GET /api/day
|
||||
pub async fn get_day(
|
||||
State(state): State<AppState>,
|
||||
Query(QueryDay { timestamp, day }): Query<QueryDay>,
|
||||
) -> Result<impl IntoResponse, impl IntoResponse> {
|
||||
let parsed_day = timestamp
|
||||
.map(Day::new_from_timestamp)
|
||||
.or_else(|| day.map(Day::new))
|
||||
.ok_or((response::StatusCode::NOT_FOUND, "Not found"))?;
|
||||
|
||||
let mut store = state.store.lock().await;
|
||||
|
||||
match store.load_day(parsed_day).await {
|
||||
Ok(att_day) => Ok(response::Json(att_day)),
|
||||
Err(_) => Err((
|
||||
response::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Internal server error",
|
||||
)),
|
||||
}
|
||||
}
|
||||
36
src/webserver/app.rs
Normal file
36
src/webserver/app.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
use alloc::rc::Rc;
|
||||
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex};
|
||||
use picoserve::{AppWithStateBuilder, routing::get};
|
||||
|
||||
use crate::{
|
||||
TallyChannel, UsedStore,
|
||||
init::sd_card::SDCardPersistence,
|
||||
store::mapping_loader::MappingLoader,
|
||||
webserver::{
|
||||
api::{add_mapping, get_day, get_days, get_idevent, get_mapping, get_mappings},
|
||||
assets::Assets,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
pub store: Rc<Mutex<CriticalSectionRawMutex, UsedStore>>,
|
||||
pub chan: &'static TallyChannel,
|
||||
pub mapping_loader: Rc<Mutex<CriticalSectionRawMutex, MappingLoader<SDCardPersistence>>>,
|
||||
}
|
||||
|
||||
pub struct AppProps;
|
||||
|
||||
impl AppWithStateBuilder for AppProps {
|
||||
type State = AppState;
|
||||
type PathRouter = impl picoserve::routing::PathRouter<AppState>;
|
||||
|
||||
fn build_app(self) -> picoserve::Router<Self::PathRouter, AppState> {
|
||||
picoserve::Router::from_service(Assets)
|
||||
.route("/api/mapping", get(get_mapping).post(add_mapping))
|
||||
.route("/api/mappings", get(get_mappings))
|
||||
.route("/api/idevent", get(get_idevent))
|
||||
.route("/api/days", get(get_days))
|
||||
.route("/api/day", get(get_day))
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user