Compare commits
153 Commits
0e3549a755
...
legacy/v3-
| Author | SHA1 | Date | |
|---|---|---|---|
|
4cc70f96de
|
|||
|
c90174be27
|
|||
|
b569fa4b04
|
|||
|
f71ca7ec6d
|
|||
|
28f7ae20ef
|
|||
|
52049c456e
|
|||
|
e3b7648a3f
|
|||
|
08ee9018cf
|
|||
|
c2929a65ae
|
|||
|
0b386b0ca3
|
|||
|
0ab1ea3635
|
|||
|
ae73f12d1c
|
|||
|
cfe1c2c6d8
|
|||
|
578379c0d9
|
|||
|
2ff219a1cb
|
|||
|
96023c8dc3
|
|||
|
7497a8c05d
|
|||
|
d3d8d829be
|
|||
|
6889ba4561
|
|||
|
18095349f3
|
|||
|
3d8fd893f5
|
|||
|
1bea7ef2f4
|
|||
|
f5b9674840
|
|||
|
6f22881007
|
|||
|
1d8af1b6c4
|
|||
|
2c532359fc
|
|||
|
53819484fb
|
|||
|
1151d099cf
|
|||
|
3feaacd460
|
|||
|
e15e78cc26
|
|||
|
d9aa96a3cb
|
|||
|
ecf989b859
|
|||
|
db401aac55
|
|||
| ecb7707357 | |||
|
4cf7a1c94f
|
|||
|
9155676e06
|
|||
|
e05f3d768f
|
|||
| cf58486cf5 | |||
| cfe23c8a09 | |||
| 3d18b0dbf6 | |||
| 7ebc147f51 | |||
| f0bda32d7a | |||
| 76f59b093d | |||
| 7fc8d0c882 | |||
| 6d5bb5b966 | |||
| 336961f0a0 | |||
| e20b474dfd | |||
| 5b009f50e5 | |||
| d010c5d12a | |||
| b594a02870 | |||
| 1f3349c348 | |||
| 5b0e2b6797 | |||
| 1791f463b7 | |||
| c94f5bdb45 | |||
| 584d6df2d0 | |||
| cd63e76469 | |||
| 4c54edbcea | |||
| 8b938e7687 | |||
| 1c84cd00da | |||
| 1397f5d775 | |||
| 65f6670ca4 | |||
| 049a9d027c | |||
| 4aa25c687b | |||
| b3cc313139 | |||
| be3c4a5095 | |||
| 4160202cdc | |||
| 9de85b6e37 | |||
| 79087c9353 | |||
|
0d495d0f56
|
|||
|
242e748ca0
|
|||
|
f853b6f2b2
|
|||
|
5bc20d312a
|
|||
|
4faae86a6b
|
|||
|
4fa1a05fc3
|
|||
|
3a24dcec53
|
|||
|
e7895577ca
|
|||
|
be9a076b33
|
|||
| 47ad4c70de | |||
| c4aa3a1450 | |||
| f0d89417b6 | |||
| a8e17cda3b | |||
| a38d704498 | |||
| 50b2e994ca | |||
| 7a7f000743 | |||
| d650358bab | |||
| 9f113adf7e | |||
| 735f836458 | |||
| f02d935f40 | |||
| cc4e9efffd | |||
| 5d91daf23d | |||
| 577c38d026 | |||
| 6b711e29fc | |||
| 5fb8705d9a | |||
| e57e87af3f | |||
| 450197c7cd | |||
| 736925f7de | |||
| 1fb9d2ab1b | |||
| ea60d804b3 | |||
| d059b7b1db | |||
| e7b6bda747 | |||
| 04849162cd | |||
|
5621f17e61
|
|||
|
d0e5627815
|
|||
|
7115809f2b
|
|||
|
c1d0ce542c
|
|||
|
b7b08d8747
|
|||
|
8d68f0ef14
|
|||
| 34b20b1f8f | |||
|
71973f8fe9
|
|||
|
506f0c36b5
|
|||
|
4b919b9613
|
|||
| 017078ef8e | |||
| c84e863d0f | |||
| de54afce52 | |||
|
a0e7f97887
|
|||
| 3a2e59874e | |||
|
69077239a5
|
|||
|
e2cbf9618e
|
|||
| fc1991523a | |||
|
c429c829b4
|
|||
| e2cce88390 | |||
| 751f07e6fd | |||
| 04bac4d0b6 | |||
| e24dc77fa9 | |||
| 05400c7c4a | |||
| 6499b18ada | |||
| a9d7936376 | |||
| 38f4ada433 | |||
| 3fe9aaeb6f | |||
| 4f4d15e4a4 | |||
| 9f48b46738 | |||
| 0614a0e1ef | |||
| 9e82d00a91 | |||
| 171b130a29 | |||
| bfc3fbc6e1 | |||
| 26da6b39cc | |||
| a401d4de7b | |||
| 5fe1dc8f40 | |||
| f8274ea7a8 | |||
| 1cae6c4aad | |||
| e3ed41a223 | |||
| 93b169f849 | |||
| ee5c67769b | |||
| 5d3abe0834 | |||
| d4ffa7d2f1 | |||
| 1b1b27e5c1 | |||
| 62d8a38e86 | |||
|
519c8d2c52
|
|||
|
e941a4973d
|
|||
|
2b5c1da484
|
|||
|
cf31ce8d43
|
|||
|
d9c3d4e13c
|
|||
| 7b3b56200d |
9
.gitignore
vendored
9
.gitignore
vendored
@@ -8,6 +8,15 @@ target
|
|||||||
Cargo.lock
|
Cargo.lock
|
||||||
node_modules/
|
node_modules/
|
||||||
rust/src/webserver/bundle.js
|
rust/src/webserver/bundle.js
|
||||||
|
rust/src/webserver/bundle.js.gz
|
||||||
rust/src/webserver/index.html
|
rust/src/webserver/index.html
|
||||||
|
rust/src/webserver/index.html.gz
|
||||||
|
rust/src_webpack/bundle.js
|
||||||
|
rust/src_webpack/bundle.js.gz
|
||||||
|
rust/src_webpack/index.html
|
||||||
|
rust/src_webpack/index.html.gz
|
||||||
rust/build/
|
rust/build/
|
||||||
rust/image.bin
|
rust/image.bin
|
||||||
|
rust/target/
|
||||||
|
rust/Cargo.lock
|
||||||
|
rust/src_webpack/node_modules/
|
||||||
|
|||||||
10
bin/build-esp-plant-dev-tools.sh
Executable file
10
bin/build-esp-plant-dev-tools.sh
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CONTAINER_NAME="localhost/esp-plant-dev-tools:latest"
|
||||||
|
CONTAINER_TOOLS_BASEDIR="$(dirname "$(readlink -f "$0")")"
|
||||||
|
|
||||||
|
pushd "$CONTAINER_TOOLS_BASEDIR"
|
||||||
|
podman build -t "$CONTAINER_NAME" -f "esp-plant-dev-tools.Containerfile" .
|
||||||
|
popd
|
||||||
16
bin/esp-plant-dev-tools.Containerfile
Normal file
16
bin/esp-plant-dev-tools.Containerfile
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
FROM debian:latest
|
||||||
|
|
||||||
|
RUN apt update -y && apt upgrade -y && apt install unzip curl xz-utils nodejs -y
|
||||||
|
|
||||||
|
RUN cd /root && \
|
||||||
|
curl -L -o xpack-riscv-toolchain.tar.gz "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v14.2.0-3/xpack-riscv-none-elf-gcc-14.2.0-3-linux-x64.tar.gz" && \
|
||||||
|
mkdir xpack-toolchain && \
|
||||||
|
tar -xvf xpack-riscv-toolchain.tar.gz -C xpack-toolchain --strip-components=1 && \
|
||||||
|
mv xpack-toolchain/bin/* /usr/local/bin && \
|
||||||
|
mv xpack-toolchain/lib/ /usr/local && \
|
||||||
|
mv xpack-toolchain/lib64/ /usr/local && \
|
||||||
|
mv xpack-toolchain/libexec /usr/local && \
|
||||||
|
mv xpack-toolchain/riscv-none-elf /usr/local && \
|
||||||
|
rm -rf xpack-toolchain xpack-riscv-toolchain.tar.gz
|
||||||
|
|
||||||
|
RUN apt install npm -y
|
||||||
29
bin/npm
Executable file
29
bin/npm
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CONTAINER_IMAGE="localhost/esp-plant-dev-tools:latest"
|
||||||
|
CONTAINER_TOOLS_BASEDIR="$(dirname "$(readlink -f "$0")")"
|
||||||
|
PLANTCTL_PROJECT_DIR="$(readlink -f "$CONTAINER_TOOLS_BASEDIR/..")"
|
||||||
|
|
||||||
|
function _fatal {
|
||||||
|
echo -e "\e[31mERROR\e[0m $(</dev/stdin)$*" 1>&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
declare -a PODMAN_ARGS=(
|
||||||
|
"--rm" "-i" "--log-driver=none"
|
||||||
|
"-v" "$PLANTCTL_PROJECT_DIR:$PLANTCTL_PROJECT_DIR:rw"
|
||||||
|
"-v" "$PWD:$PWD:rw"
|
||||||
|
"-w" "$PWD"
|
||||||
|
)
|
||||||
|
|
||||||
|
[[ -t 1 ]] && PODMAN_ARGS+=("-t")
|
||||||
|
|
||||||
|
if ! podman image exists "$CONTAINER_IMAGE"; then
|
||||||
|
#attempt to build container
|
||||||
|
"$CONTAINER_TOOLS_BASEDIR/build-esp-plant-dev-tools.sh" 1>&2 ||
|
||||||
|
_fatal "faild to build local image, cannot continue! … please ensure you have an internet connection"
|
||||||
|
fi
|
||||||
|
|
||||||
|
podman run "${PODMAN_ARGS[@]}" --entrypoint npm "$CONTAINER_IMAGE" "$@"
|
||||||
29
bin/npx
Executable file
29
bin/npx
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CONTAINER_IMAGE="localhost/esp-plant-dev-tools:latest"
|
||||||
|
CONTAINER_TOOLS_BASEDIR="$(dirname "$(readlink -f "$0")")"
|
||||||
|
PLANTCTL_PROJECT_DIR="$(readlink -f "$CONTAINER_TOOLS_BASEDIR/..")"
|
||||||
|
|
||||||
|
function _fatal {
|
||||||
|
echo -e "\e[31mERROR\e[0m $(</dev/stdin)$*" 1>&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
declare -a PODMAN_ARGS=(
|
||||||
|
"--rm" "-i" "--log-driver=none"
|
||||||
|
"-v" "$PLANTCTL_PROJECT_DIR:$PLANTCTL_PROJECT_DIR:rw"
|
||||||
|
"-v" "$PWD:$PWD:rw"
|
||||||
|
"-w" "$PWD"
|
||||||
|
)
|
||||||
|
|
||||||
|
[[ -t 1 ]] && PODMAN_ARGS+=("-t")
|
||||||
|
|
||||||
|
if ! podman image exists "$CONTAINER_IMAGE"; then
|
||||||
|
#attempt to build container
|
||||||
|
"$CONTAINER_TOOLS_BASEDIR/build-esp-plant-dev-tools.sh" 1>&2 ||
|
||||||
|
_fatal "faild to build local image, cannot continue! … please ensure you have an internet connection"
|
||||||
|
fi
|
||||||
|
|
||||||
|
podman run "${PODMAN_ARGS[@]}" --entrypoint npx "$CONTAINER_IMAGE" "$@"
|
||||||
29
bin/riscv32-unknown-elf-gcc
Executable file
29
bin/riscv32-unknown-elf-gcc
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CONTAINER_IMAGE="localhost/esp-plant-dev-tools:latest"
|
||||||
|
CONTAINER_TOOLS_BASEDIR="$(dirname "$(readlink -f "$0")")"
|
||||||
|
PLANTCTL_PROJECT_DIR="$(readlink -f "$CONTAINER_TOOLS_BASEDIR/..")"
|
||||||
|
|
||||||
|
function _fatal {
|
||||||
|
echo -e "\e[31mERROR\e[0m $(</dev/stdin)$*" 1>&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
declare -a PODMAN_ARGS=(
|
||||||
|
"--rm" "-i" "--log-driver=none"
|
||||||
|
"-v" "$PLANTCTL_PROJECT_DIR:$PLANTCTL_PROJECT_DIR:rw"
|
||||||
|
"-v" "$PWD:$PWD:rw"
|
||||||
|
"-w" "$PWD"
|
||||||
|
)
|
||||||
|
|
||||||
|
[[ -t 1 ]] && PODMAN_ARGS+=("-t")
|
||||||
|
|
||||||
|
if ! podman image exists "$CONTAINER_IMAGE"; then
|
||||||
|
#attempt to build container
|
||||||
|
"$CONTAINER_TOOLS_BASEDIR/build-esp-plant-dev-tools.sh" 1>&2 ||
|
||||||
|
_fatal "faild to build local image, cannot continue! … please ensure you have an internet connection"
|
||||||
|
fi
|
||||||
|
|
||||||
|
podman run "${PODMAN_ARGS[@]}" --entrypoint riscv-none-elf-gcc "$CONTAINER_IMAGE" "$@"
|
||||||
BIN
board/Body1.3mf
Normal file
BIN
board/Body1.3mf
Normal file
Binary file not shown.
@@ -1,82 +0,0 @@
|
|||||||
(kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor)
|
|
||||||
(symbol "CN3306" (in_bom yes) (on_board yes)
|
|
||||||
(property "Reference" "U" (at 5.08 -5.08 0)
|
|
||||||
(effects (font (size 1.27 1.27)))
|
|
||||||
)
|
|
||||||
(property "Value" "" (at 0 0 0)
|
|
||||||
(effects (font (size 1.27 1.27)))
|
|
||||||
)
|
|
||||||
(property "Footprint" "" (at 0 0 0)
|
|
||||||
(effects (font (size 1.27 1.27)) hide)
|
|
||||||
)
|
|
||||||
(property "Datasheet" "" (at 0 0 0)
|
|
||||||
(effects (font (size 1.27 1.27)) hide)
|
|
||||||
)
|
|
||||||
(symbol "CN3306_1_1"
|
|
||||||
(rectangle (start -2.54 7.62) (end 12.7 -16.51)
|
|
||||||
(stroke (width 0) (type default))
|
|
||||||
(fill (type background))
|
|
||||||
)
|
|
||||||
(pin input line (at 15.24 -8.89 180) (length 2.54)
|
|
||||||
(name "FB" (effects (font (size 1.27 1.27))))
|
|
||||||
(number "1" (effects (font (size 1.27 1.27))))
|
|
||||||
)
|
|
||||||
(pin input line (at 5.08 10.16 270) (length 2.54)
|
|
||||||
(name "COME" (effects (font (size 1.27 1.27))))
|
|
||||||
(number "10" (effects (font (size 1.27 1.27))))
|
|
||||||
)
|
|
||||||
(pin input line (at 15.24 -13.97 180) (length 2.54)
|
|
||||||
(name "VCC" (effects (font (size 1.27 1.27))))
|
|
||||||
(number "11" (effects (font (size 1.27 1.27))))
|
|
||||||
)
|
|
||||||
(pin input line (at 15.24 -11.43 180) (length 2.54)
|
|
||||||
(name "VCC" (effects (font (size 1.27 1.27))))
|
|
||||||
(number "12" (effects (font (size 1.27 1.27))))
|
|
||||||
)
|
|
||||||
(pin input line (at 15.24 5.08 180) (length 2.54)
|
|
||||||
(name "DRV" (effects (font (size 1.27 1.27))))
|
|
||||||
(number "13" (effects (font (size 1.27 1.27))))
|
|
||||||
)
|
|
||||||
(pin input line (at 3.81 -19.05 90) (length 2.54)
|
|
||||||
(name "GND" (effects (font (size 1.27 1.27))))
|
|
||||||
(number "14" (effects (font (size 1.27 1.27))))
|
|
||||||
)
|
|
||||||
(pin input line (at 6.35 -19.05 90) (length 2.54)
|
|
||||||
(name "GND" (effects (font (size 1.27 1.27))))
|
|
||||||
(number "15" (effects (font (size 1.27 1.27))))
|
|
||||||
)
|
|
||||||
(pin input line (at 15.24 2.54 180) (length 2.54)
|
|
||||||
(name "ISW" (effects (font (size 1.27 1.27))))
|
|
||||||
(number "16" (effects (font (size 1.27 1.27))))
|
|
||||||
)
|
|
||||||
(pin input line (at -5.08 -10.16 0) (length 2.54)
|
|
||||||
(name "COMP" (effects (font (size 1.27 1.27))))
|
|
||||||
(number "2" (effects (font (size 1.27 1.27))))
|
|
||||||
)
|
|
||||||
(pin input line (at -5.08 -1.27 0) (length 2.54)
|
|
||||||
(name "MPPT" (effects (font (size 1.27 1.27))))
|
|
||||||
(number "3" (effects (font (size 1.27 1.27))))
|
|
||||||
)
|
|
||||||
(pin input line (at -5.08 -7.62 0) (length 2.54)
|
|
||||||
(name "SHDN" (effects (font (size 1.27 1.27))))
|
|
||||||
(number "5" (effects (font (size 1.27 1.27))))
|
|
||||||
)
|
|
||||||
(pin input line (at -5.08 3.81 0) (length 2.54)
|
|
||||||
(name "CHRG" (effects (font (size 1.27 1.27))))
|
|
||||||
(number "6" (effects (font (size 1.27 1.27))))
|
|
||||||
)
|
|
||||||
(pin input line (at -5.08 1.27 0) (length 2.54)
|
|
||||||
(name "DONE" (effects (font (size 1.27 1.27))))
|
|
||||||
(number "7" (effects (font (size 1.27 1.27))))
|
|
||||||
)
|
|
||||||
(pin input line (at 15.24 -3.81 180) (length 2.54)
|
|
||||||
(name "CSP" (effects (font (size 1.27 1.27))))
|
|
||||||
(number "8" (effects (font (size 1.27 1.27))))
|
|
||||||
)
|
|
||||||
(pin input line (at 15.24 -6.35 180) (length 2.54)
|
|
||||||
(name "ONE" (effects (font (size 1.27 1.27))))
|
|
||||||
(number "9" (effects (font (size 1.27 1.27))))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -37,9 +37,9 @@
|
|||||||
"other_text_thickness": 0.15,
|
"other_text_thickness": 0.15,
|
||||||
"other_text_upright": false,
|
"other_text_upright": false,
|
||||||
"pads": {
|
"pads": {
|
||||||
"drill": 0.25,
|
"drill": 1.0,
|
||||||
"height": 0.35,
|
"height": 1.7,
|
||||||
"width": 0.35
|
"width": 1.7
|
||||||
},
|
},
|
||||||
"silk_line_width": 0.12,
|
"silk_line_width": 0.12,
|
||||||
"silk_text_italic": false,
|
"silk_text_italic": false,
|
||||||
@@ -58,12 +58,7 @@
|
|||||||
"width": 0.0
|
"width": 0.0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"drc_exclusions": [
|
"drc_exclusions": [],
|
||||||
[
|
|
||||||
"footprint_symbol_mismatch|177050000|59025000|a624af3d-bffa-4ff7-9554-e16d3c677f69|00000000-0000-0000-0000-000000000000",
|
|
||||||
""
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"meta": {
|
"meta": {
|
||||||
"filename": "board_design_settings.json",
|
"filename": "board_design_settings.json",
|
||||||
"version": 2
|
"version": 2
|
||||||
@@ -96,7 +91,7 @@
|
|||||||
"length_out_of_range": "error",
|
"length_out_of_range": "error",
|
||||||
"lib_footprint_issues": "warning",
|
"lib_footprint_issues": "warning",
|
||||||
"lib_footprint_mismatch": "warning",
|
"lib_footprint_mismatch": "warning",
|
||||||
"malformed_courtyard": "error",
|
"malformed_courtyard": "ignore",
|
||||||
"microvia_drill_out_of_range": "error",
|
"microvia_drill_out_of_range": "error",
|
||||||
"mirrored_text_on_front_layer": "warning",
|
"mirrored_text_on_front_layer": "warning",
|
||||||
"missing_courtyard": "ignore",
|
"missing_courtyard": "ignore",
|
||||||
@@ -467,8 +462,8 @@
|
|||||||
"no_connect_dangling": "warning",
|
"no_connect_dangling": "warning",
|
||||||
"pin_not_connected": "error",
|
"pin_not_connected": "error",
|
||||||
"pin_not_driven": "error",
|
"pin_not_driven": "error",
|
||||||
"pin_to_pin": "error",
|
"pin_to_pin": "ignore",
|
||||||
"power_pin_not_driven": "error",
|
"power_pin_not_driven": "ignore",
|
||||||
"same_local_global_label": "warning",
|
"same_local_global_label": "warning",
|
||||||
"similar_label_and_power": "warning",
|
"similar_label_and_power": "warning",
|
||||||
"similar_labels": "warning",
|
"similar_labels": "warning",
|
||||||
@@ -477,6 +472,7 @@
|
|||||||
"single_global_label": "ignore",
|
"single_global_label": "ignore",
|
||||||
"unannotated": "error",
|
"unannotated": "error",
|
||||||
"unconnected_wire_endpoint": "warning",
|
"unconnected_wire_endpoint": "warning",
|
||||||
|
"undefined_netclass": "error",
|
||||||
"unit_value_mismatch": "error",
|
"unit_value_mismatch": "error",
|
||||||
"unresolved_variable": "error",
|
"unresolved_variable": "error",
|
||||||
"wire_dangling": "error"
|
"wire_dangling": "error"
|
||||||
@@ -1081,7 +1077,7 @@
|
|||||||
},
|
},
|
||||||
"schematic": {
|
"schematic": {
|
||||||
"annotate_start_num": 0,
|
"annotate_start_num": 0,
|
||||||
"bom_export_filename": "",
|
"bom_export_filename": "PlantCtrlESP32.csv",
|
||||||
"bom_fmt_presets": [],
|
"bom_fmt_presets": [],
|
||||||
"bom_fmt_settings": {
|
"bom_fmt_settings": {
|
||||||
"field_delimiter": ",",
|
"field_delimiter": ",",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1 +1 @@
|
|||||||
{"EXTRA_LAYERS": "", "EXTEND_EDGE_CUT": false, "AUTO TRANSLATE": true, "AUTO FILL": true, "EXCLUDE DNP": true}
|
{"EXTRA_LAYERS": "", "ALL_ACTIVE_LAYERS": false, "EXTEND_EDGE_CUT": false, "ALTERNATIVE_EDGE_CUT": false, "AUTO TRANSLATE": true, "AUTO FILL": true, "EXCLUDE DNP": true}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"board": {
|
"board": {
|
||||||
"active_layer": 5,
|
"active_layer": 25,
|
||||||
"active_layer_preset": "All Layers",
|
"active_layer_preset": "All Layers",
|
||||||
"auto_track_width": false,
|
"auto_track_width": false,
|
||||||
"hidden_netclasses": [],
|
"hidden_netclasses": [],
|
||||||
|
|||||||
@@ -58,7 +58,16 @@
|
|||||||
"width": 0.0
|
"width": 0.0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"drc_exclusions": [],
|
"drc_exclusions": [
|
||||||
|
[
|
||||||
|
"copper_edge_clearance|127050000|19750000|9699c74c-42f0-475d-905c-32f2bfc21b27|f47bb74a-cab1-4bf9-acd5-ef1613b09d02",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"starved_thermal|119050000|20500000|7ae79caf-9e0f-4e4d-8ab8-b020d8cfa707|e5f29b1c-951c-45bf-a2c4-47dcea02bfd5|F.Cu",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
],
|
||||||
"meta": {
|
"meta": {
|
||||||
"version": 2
|
"version": 2
|
||||||
},
|
},
|
||||||
@@ -105,7 +114,7 @@
|
|||||||
"silk_overlap": "warning",
|
"silk_overlap": "warning",
|
||||||
"skew_out_of_range": "error",
|
"skew_out_of_range": "error",
|
||||||
"solder_mask_bridge": "error",
|
"solder_mask_bridge": "error",
|
||||||
"starved_thermal": "error",
|
"starved_thermal": "warning",
|
||||||
"text_height": "warning",
|
"text_height": "warning",
|
||||||
"text_on_edge_cuts": "error",
|
"text_on_edge_cuts": "error",
|
||||||
"text_thickness": "warning",
|
"text_thickness": "warning",
|
||||||
@@ -139,7 +148,7 @@
|
|||||||
"min_track_width": 0.0,
|
"min_track_width": 0.0,
|
||||||
"min_via_annular_width": 0.1,
|
"min_via_annular_width": 0.1,
|
||||||
"min_via_diameter": 0.5,
|
"min_via_diameter": 0.5,
|
||||||
"solder_mask_to_copper_clearance": 0.0,
|
"solder_mask_to_copper_clearance": 0.005,
|
||||||
"use_height_for_length_calcs": true
|
"use_height_for_length_calcs": true
|
||||||
},
|
},
|
||||||
"teardrop_options": [
|
"teardrop_options": [
|
||||||
@@ -582,7 +591,7 @@
|
|||||||
"group_by": false,
|
"group_by": false,
|
||||||
"label": "LCSC_PART_NUMBER",
|
"label": "LCSC_PART_NUMBER",
|
||||||
"name": "LCSC_PART_NUMBER",
|
"name": "LCSC_PART_NUMBER",
|
||||||
"show": false
|
"show": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group_by": true,
|
"group_by": true,
|
||||||
|
|||||||
@@ -2735,7 +2735,7 @@
|
|||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp no)
|
(dnp no)
|
||||||
(uuid "0425b7e6-6cf5-40f7-ac09-e360b3fb146c")
|
(uuid "0425b7e6-6cf5-40f7-ac09-e360b3fb146c")
|
||||||
(property "Reference" "R24"
|
(property "Reference" "R3"
|
||||||
(at 190.5 62.23 0)
|
(at 190.5 62.23 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -2798,7 +2798,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "R24")
|
(reference "R3")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -2814,7 +2814,7 @@
|
|||||||
(dnp no)
|
(dnp no)
|
||||||
(fields_autoplaced yes)
|
(fields_autoplaced yes)
|
||||||
(uuid "11b34252-84e7-4de5-96b2-86a1a5342860")
|
(uuid "11b34252-84e7-4de5-96b2-86a1a5342860")
|
||||||
(property "Reference" "L2"
|
(property "Reference" "L1"
|
||||||
(at 171.45 45.085 90)
|
(at 171.45 45.085 90)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -2884,7 +2884,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "L2")
|
(reference "L1")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -2897,7 +2897,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp no)
|
(dnp yes)
|
||||||
(fields_autoplaced yes)
|
(fields_autoplaced yes)
|
||||||
(uuid "17e9522f-7617-435f-bc97-f04977cc30a5")
|
(uuid "17e9522f-7617-435f-bc97-f04977cc30a5")
|
||||||
(property "Reference" "U1"
|
(property "Reference" "U1"
|
||||||
@@ -2982,7 +2982,7 @@
|
|||||||
(dnp no)
|
(dnp no)
|
||||||
(fields_autoplaced yes)
|
(fields_autoplaced yes)
|
||||||
(uuid "20b688f4-63bd-4d15-9259-1efb3da269b2")
|
(uuid "20b688f4-63bd-4d15-9259-1efb3da269b2")
|
||||||
(property "Reference" "C71"
|
(property "Reference" "C4"
|
||||||
(at 207.645 64.7699 0)
|
(at 207.645 64.7699 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -3054,7 +3054,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "C71")
|
(reference "C4")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -3070,7 +3070,7 @@
|
|||||||
(dnp no)
|
(dnp no)
|
||||||
(fields_autoplaced yes)
|
(fields_autoplaced yes)
|
||||||
(uuid "22a34af5-c1f2-4bfa-a346-349e29fb1cf1")
|
(uuid "22a34af5-c1f2-4bfa-a346-349e29fb1cf1")
|
||||||
(property "Reference" "R5"
|
(property "Reference" "R2"
|
||||||
(at 124.46 44.45 90)
|
(at 124.46 44.45 90)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -3078,7 +3078,7 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(property "Value" "2.2Ohm (90mW loss)"
|
(property "Value" "1Ohm"
|
||||||
(at 124.46 46.99 90)
|
(at 124.46 46.99 90)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -3113,7 +3113,7 @@
|
|||||||
(hide yes)
|
(hide yes)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(property "LCSC" "C17513"
|
(property "LCSC" "C25271"
|
||||||
(at 124.46 49.53 0)
|
(at 124.46 49.53 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -3122,7 +3122,7 @@
|
|||||||
(hide yes)
|
(hide yes)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(property "LCSC_PART_NUMBER" "C2930032"
|
(property "LCSC_PART_NUMBER" "C25271"
|
||||||
(at 124.46 49.53 0)
|
(at 124.46 49.53 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -3140,7 +3140,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "R5")
|
(reference "R2")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -3236,7 +3236,7 @@
|
|||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp no)
|
(dnp no)
|
||||||
(uuid "523d86ff-c1fb-4885-b234-1324756802c1")
|
(uuid "523d86ff-c1fb-4885-b234-1324756802c1")
|
||||||
(property "Reference" "R23"
|
(property "Reference" "R1"
|
||||||
(at 190.5 53.34 0)
|
(at 190.5 53.34 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -3299,7 +3299,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "R23")
|
(reference "R1")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -3314,7 +3314,7 @@
|
|||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp no)
|
(dnp no)
|
||||||
(uuid "5c9e2472-0ea9-44fa-9826-1ffbec963aeb")
|
(uuid "5c9e2472-0ea9-44fa-9826-1ffbec963aeb")
|
||||||
(property "Reference" "R22"
|
(property "Reference" "R5"
|
||||||
(at 107.8484 51.308 0)
|
(at 107.8484 51.308 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -3377,7 +3377,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "R22")
|
(reference "R5")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -3392,7 +3392,7 @@
|
|||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp no)
|
(dnp no)
|
||||||
(uuid "63be2ae3-3f0f-4a07-aeae-294be6e75c31")
|
(uuid "63be2ae3-3f0f-4a07-aeae-294be6e75c31")
|
||||||
(property "Reference" "R21"
|
(property "Reference" "R6"
|
||||||
(at 104.648 64.8716 0)
|
(at 104.648 64.8716 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -3455,7 +3455,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "R21")
|
(reference "R6")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -3471,7 +3471,7 @@
|
|||||||
(dnp no)
|
(dnp no)
|
||||||
(fields_autoplaced yes)
|
(fields_autoplaced yes)
|
||||||
(uuid "66d062a4-4adc-4d5b-b235-ae3b04da22cd")
|
(uuid "66d062a4-4adc-4d5b-b235-ae3b04da22cd")
|
||||||
(property "Reference" "C13"
|
(property "Reference" "C2"
|
||||||
(at 133.985 63.4999 0)
|
(at 133.985 63.4999 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -3543,7 +3543,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "C13")
|
(reference "C2")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -3558,7 +3558,7 @@
|
|||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp no)
|
(dnp no)
|
||||||
(uuid "6db97863-981e-4f95-a1fc-506e785ba0c2")
|
(uuid "6db97863-981e-4f95-a1fc-506e785ba0c2")
|
||||||
(property "Reference" "Q2"
|
(property "Reference" "Q1"
|
||||||
(at 95.377 66.1416 0)
|
(at 95.377 66.1416 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -3624,7 +3624,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "Q2")
|
(reference "Q1")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -3640,7 +3640,7 @@
|
|||||||
(dnp no)
|
(dnp no)
|
||||||
(fields_autoplaced yes)
|
(fields_autoplaced yes)
|
||||||
(uuid "76624502-fca9-4ec5-bd55-d8c2393958dd")
|
(uuid "76624502-fca9-4ec5-bd55-d8c2393958dd")
|
||||||
(property "Reference" "C16"
|
(property "Reference" "C5"
|
||||||
(at 163.83 46.99 90)
|
(at 163.83 46.99 90)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -3710,7 +3710,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "C16")
|
(reference "C5")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -3724,7 +3724,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(fields_autoplaced yes)
|
(fields_autoplaced yes)
|
||||||
(uuid "7c62f4d3-1cf7-4fa2-a112-701dfb3880ab")
|
(uuid "7c62f4d3-1cf7-4fa2-a112-701dfb3880ab")
|
||||||
(property "Reference" "LIGHT1"
|
(property "Reference" "LIGHT1"
|
||||||
@@ -3794,7 +3794,7 @@
|
|||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp no)
|
(dnp no)
|
||||||
(uuid "7ff0ccf7-1026-4845-bd57-72661ae57edf")
|
(uuid "7ff0ccf7-1026-4845-bd57-72661ae57edf")
|
||||||
(property "Reference" "Q_PWR1"
|
(property "Reference" "QP_1"
|
||||||
(at 115.57 64.77 0)
|
(at 115.57 64.77 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -3863,7 +3863,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "Q_PWR1")
|
(reference "QP_1")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -3878,7 +3878,7 @@
|
|||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp no)
|
(dnp no)
|
||||||
(uuid "a19bda47-2414-4647-8682-22d4699f150d")
|
(uuid "a19bda47-2414-4647-8682-22d4699f150d")
|
||||||
(property "Reference" "C17"
|
(property "Reference" "C1"
|
||||||
(at 199.39 57.15 0)
|
(at 199.39 57.15 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -3950,7 +3950,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "C17")
|
(reference "C1")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -3963,9 +3963,9 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(uuid "aca8686e-aff2-4166-85c4-f2cbe9ddc5e0")
|
(uuid "aca8686e-aff2-4166-85c4-f2cbe9ddc5e0")
|
||||||
(property "Reference" "I2C3"
|
(property "Reference" "I1"
|
||||||
(at 100.0506 52.5272 90)
|
(at 100.0506 52.5272 90)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -3974,7 +3974,7 @@
|
|||||||
(justify right)
|
(justify right)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(property "Value" "GREEN"
|
(property "Value" "LED White"
|
||||||
(at 97.7392 52.5272 90)
|
(at 97.7392 52.5272 90)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -4028,7 +4028,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "I2C3")
|
(reference "I1")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -4044,7 +4044,7 @@
|
|||||||
(dnp no)
|
(dnp no)
|
||||||
(fields_autoplaced yes)
|
(fields_autoplaced yes)
|
||||||
(uuid "b771ae42-ef20-433b-882c-cd86d5c9dc48")
|
(uuid "b771ae42-ef20-433b-882c-cd86d5c9dc48")
|
||||||
(property "Reference" "U5"
|
(property "Reference" "U2"
|
||||||
(at 143.51 44.45 0)
|
(at 143.51 44.45 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -4126,7 +4126,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "U5")
|
(reference "U2")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -4142,7 +4142,7 @@
|
|||||||
(dnp no)
|
(dnp no)
|
||||||
(fields_autoplaced yes)
|
(fields_autoplaced yes)
|
||||||
(uuid "ce2d65a3-531d-4585-8743-939a548f9d2f")
|
(uuid "ce2d65a3-531d-4585-8743-939a548f9d2f")
|
||||||
(property "Reference" "C72"
|
(property "Reference" "C3"
|
||||||
(at 182.88 53.34 0)
|
(at 182.88 53.34 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -4205,7 +4205,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "C72")
|
(reference "C3")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -4220,7 +4220,7 @@
|
|||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp no)
|
(dnp no)
|
||||||
(uuid "d7286e86-efc2-4c1d-8247-d0443e857cbc")
|
(uuid "d7286e86-efc2-4c1d-8247-d0443e857cbc")
|
||||||
(property "Reference" "R20"
|
(property "Reference" "R7"
|
||||||
(at 98.9584 64.008 0)
|
(at 98.9584 64.008 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -4283,7 +4283,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "R20")
|
(reference "R7")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -4298,7 +4298,7 @@
|
|||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp no)
|
(dnp no)
|
||||||
(uuid "f48fb307-e738-4d85-b552-0cbce90ea597")
|
(uuid "f48fb307-e738-4d85-b552-0cbce90ea597")
|
||||||
(property "Reference" "R19"
|
(property "Reference" "R8"
|
||||||
(at 86.868 69.9516 0)
|
(at 86.868 69.9516 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -4361,7 +4361,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "R19")
|
(reference "R8")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -4376,7 +4376,7 @@
|
|||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp no)
|
(dnp no)
|
||||||
(uuid "fb34f92d-3c0f-49d2-9c25-915e8b197b69")
|
(uuid "fb34f92d-3c0f-49d2-9c25-915e8b197b69")
|
||||||
(property "Reference" "R7"
|
(property "Reference" "R4"
|
||||||
(at 79.9084 69.088 0)
|
(at 79.9084 69.088 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
@@ -4439,7 +4439,7 @@
|
|||||||
(instances
|
(instances
|
||||||
(project "LightOut"
|
(project "LightOut"
|
||||||
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
(path "/2a8304c5-3c9a-4ae8-a3b2-19491060e8fb"
|
||||||
(reference "R7")
|
(reference "R4")
|
||||||
(unit 1)
|
(unit 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"board": {
|
"board": {
|
||||||
"active_layer": 0,
|
"active_layer": 5,
|
||||||
"active_layer_preset": "All Layers",
|
"active_layer_preset": "All Layers",
|
||||||
"auto_track_width": false,
|
"auto_track_width": false,
|
||||||
"hidden_netclasses": [],
|
"hidden_netclasses": [],
|
||||||
|
|||||||
@@ -60,11 +60,47 @@
|
|||||||
],
|
],
|
||||||
"drc_exclusions": [
|
"drc_exclusions": [
|
||||||
[
|
[
|
||||||
"silk_over_copper|115549999|32059610|4d3349dc-5b52-43de-8407-342b46c9ab03|00000000-0000-0000-0000-000000000000",
|
"courtyards_overlap|112084965|21032500|499f5fe7-5885-47c2-974b-f649b529c51e|6df87025-4003-41e5-8291-17fff766dac2",
|
||||||
""
|
""
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"starved_thermal|84500000|37000000|1c111c53-aa66-4ea7-a1fd-488f9eb7dc56|8d490f05-82aa-4679-a53e-ec4019506065|F.Cu",
|
"courtyards_overlap|113305000|20282500|19502f41-24bc-474e-a572-d11957ca9fa9|499f5fe7-5885-47c2-974b-f649b529c51e",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"silk_overlap|110300000|20977500|4acc8ffe-9ac8-4a84-956a-115a7d7b3e4c|57669fc8-8e26-4233-af7a-24a49cb88f5a",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"silk_overlap|112537500|21285000|897a7275-18f3-4da7-9aa2-dd2257c674f9|aef215d0-4617-401a-9e7b-04f4e00e75a8",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"silk_overlap|112537500|23950000|91e8dcc0-f8c0-4d84-aa8d-100828268b67|aef215d0-4617-401a-9e7b-04f4e00e75a8",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"silk_overlap|113440000|21550000|0c747b16-d7ce-4265-bf62-3ef103975f38|d32e574f-a2c5-4328-b36b-1bf733cc7a57",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"silk_overlap|113440000|22327500|0c747b16-d7ce-4265-bf62-3ef103975f38|edcef2ac-d633-4378-9e2e-d34d824f48da",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"silk_overlap|113440000|22327500|729846c7-71d4-40af-9ddc-5c4441b51013|edcef2ac-d633-4378-9e2e-d34d824f48da",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"silk_overlap|113440000|22550000|729846c7-71d4-40af-9ddc-5c4441b51013|d32e574f-a2c5-4328-b36b-1bf733cc7a57",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"starved_thermal|115000000|21190000|1c111c53-aa66-4ea7-a1fd-488f9eb7dc56|96d7d8f0-db01-449e-8fed-d03c5a7d0f39|F.Cu",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"starved_thermal|86675000|37750000|1c111c53-aa66-4ea7-a1fd-488f9eb7dc56|d0eae3f0-eb5a-480d-9ab2-1af2af11e319|F.Cu",
|
||||||
""
|
""
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
@@ -114,7 +150,7 @@
|
|||||||
"silk_overlap": "warning",
|
"silk_overlap": "warning",
|
||||||
"skew_out_of_range": "error",
|
"skew_out_of_range": "error",
|
||||||
"solder_mask_bridge": "error",
|
"solder_mask_bridge": "error",
|
||||||
"starved_thermal": "error",
|
"starved_thermal": "warning",
|
||||||
"text_height": "warning",
|
"text_height": "warning",
|
||||||
"text_on_edge_cuts": "error",
|
"text_on_edge_cuts": "error",
|
||||||
"text_thickness": "warning",
|
"text_thickness": "warning",
|
||||||
@@ -148,7 +184,7 @@
|
|||||||
"min_track_width": 0.0,
|
"min_track_width": 0.0,
|
||||||
"min_via_annular_width": 0.1,
|
"min_via_annular_width": 0.1,
|
||||||
"min_via_diameter": 0.5,
|
"min_via_diameter": 0.5,
|
||||||
"solder_mask_to_copper_clearance": 0.0,
|
"solder_mask_to_copper_clearance": 0.005,
|
||||||
"use_height_for_length_calcs": true
|
"use_height_for_length_calcs": true
|
||||||
},
|
},
|
||||||
"teardrop_options": [
|
"teardrop_options": [
|
||||||
@@ -198,6 +234,7 @@
|
|||||||
"track_widths": [
|
"track_widths": [
|
||||||
0.0,
|
0.0,
|
||||||
0.1,
|
0.1,
|
||||||
|
0.2,
|
||||||
0.5,
|
0.5,
|
||||||
1.0,
|
1.0,
|
||||||
1.5,
|
1.5,
|
||||||
@@ -470,7 +507,7 @@
|
|||||||
"no_connect_dangling": "warning",
|
"no_connect_dangling": "warning",
|
||||||
"pin_not_connected": "error",
|
"pin_not_connected": "error",
|
||||||
"pin_not_driven": "error",
|
"pin_not_driven": "error",
|
||||||
"pin_to_pin": "warning",
|
"pin_to_pin": "ignore",
|
||||||
"power_pin_not_driven": "error",
|
"power_pin_not_driven": "error",
|
||||||
"same_local_global_label": "warning",
|
"same_local_global_label": "warning",
|
||||||
"similar_label_and_power": "warning",
|
"similar_label_and_power": "warning",
|
||||||
@@ -558,6 +595,30 @@
|
|||||||
"name": "Reference",
|
"name": "Reference",
|
||||||
"show": true
|
"show": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "Value",
|
||||||
|
"name": "Value",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "Footprint",
|
||||||
|
"name": "Footprint",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Datasheet",
|
||||||
|
"name": "Datasheet",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Description",
|
||||||
|
"name": "Description",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"group_by": false,
|
"group_by": false,
|
||||||
"label": "Qty",
|
"label": "Qty",
|
||||||
@@ -565,11 +626,89 @@
|
|||||||
"show": true
|
"show": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group_by": true,
|
"group_by": false,
|
||||||
"label": "Value",
|
"label": "#",
|
||||||
"name": "Value",
|
"name": "${ITEM_NUMBER}",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Availability",
|
||||||
|
"name": "Availability",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Check_prices",
|
||||||
|
"name": "Check_prices",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Description_1",
|
||||||
|
"name": "Description_1",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Field5",
|
||||||
|
"name": "Field5",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "LCSC_PART_NUMBER",
|
||||||
|
"name": "LCSC_PART_NUMBER",
|
||||||
"show": true
|
"show": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "MF",
|
||||||
|
"name": "MF",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "MP",
|
||||||
|
"name": "MP",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Package",
|
||||||
|
"name": "Package",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Price",
|
||||||
|
"name": "Price",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Sim.Device",
|
||||||
|
"name": "Sim.Device",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Sim.Pins",
|
||||||
|
"name": "Sim.Pins",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Sim.Type",
|
||||||
|
"name": "Sim.Type",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "SnapEDA_Link",
|
||||||
|
"name": "SnapEDA_Link",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"group_by": true,
|
"group_by": true,
|
||||||
"label": "DNP",
|
"label": "DNP",
|
||||||
@@ -587,24 +726,12 @@
|
|||||||
"label": "Exclude from Board",
|
"label": "Exclude from Board",
|
||||||
"name": "${EXCLUDE_FROM_BOARD}",
|
"name": "${EXCLUDE_FROM_BOARD}",
|
||||||
"show": true
|
"show": true
|
||||||
},
|
|
||||||
{
|
|
||||||
"group_by": true,
|
|
||||||
"label": "Footprint",
|
|
||||||
"name": "Footprint",
|
|
||||||
"show": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"group_by": false,
|
|
||||||
"label": "Datasheet",
|
|
||||||
"name": "Datasheet",
|
|
||||||
"show": true
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"filter_string": "",
|
"filter_string": "",
|
||||||
"group_symbols": true,
|
"group_symbols": true,
|
||||||
"include_excluded_from_bom": true,
|
"include_excluded_from_bom": true,
|
||||||
"name": "Default Editing",
|
"name": "",
|
||||||
"sort_asc": true,
|
"sort_asc": true,
|
||||||
"sort_field": "Reference"
|
"sort_field": "Reference"
|
||||||
},
|
},
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -59,9 +59,9 @@
|
|||||||
(end -37 25.75)
|
(end -37 25.75)
|
||||||
(stroke
|
(stroke
|
||||||
(width 0.05)
|
(width 0.05)
|
||||||
(type default)
|
(type solid)
|
||||||
)
|
)
|
||||||
(layer "Edge.Cuts")
|
(layer "F.SilkS")
|
||||||
(uuid "d893208d-94bf-4628-afce-16c271a81597")
|
(uuid "d893208d-94bf-4628-afce-16c271a81597")
|
||||||
)
|
)
|
||||||
(fp_line
|
(fp_line
|
||||||
@@ -69,9 +69,9 @@
|
|||||||
(end 37 3.75)
|
(end 37 3.75)
|
||||||
(stroke
|
(stroke
|
||||||
(width 0.05)
|
(width 0.05)
|
||||||
(type default)
|
(type solid)
|
||||||
)
|
)
|
||||||
(layer "Edge.Cuts")
|
(layer "F.SilkS")
|
||||||
(uuid "e7c8e738-92f2-4bc1-b1c0-bfc6cdddb430")
|
(uuid "e7c8e738-92f2-4bc1-b1c0-bfc6cdddb430")
|
||||||
)
|
)
|
||||||
(fp_line
|
(fp_line
|
||||||
@@ -79,9 +79,9 @@
|
|||||||
(end 37 25.75)
|
(end 37 25.75)
|
||||||
(stroke
|
(stroke
|
||||||
(width 0.05)
|
(width 0.05)
|
||||||
(type default)
|
(type solid)
|
||||||
)
|
)
|
||||||
(layer "Edge.Cuts")
|
(layer "F.SilkS")
|
||||||
(uuid "bff1db86-47a1-47dd-bed5-8a9912edae2a")
|
(uuid "bff1db86-47a1-47dd-bed5-8a9912edae2a")
|
||||||
)
|
)
|
||||||
(fp_line
|
(fp_line
|
||||||
@@ -89,9 +89,9 @@
|
|||||||
(end -37 25.75)
|
(end -37 25.75)
|
||||||
(stroke
|
(stroke
|
||||||
(width 0.05)
|
(width 0.05)
|
||||||
(type default)
|
(type solid)
|
||||||
)
|
)
|
||||||
(layer "Edge.Cuts")
|
(layer "F.SilkS")
|
||||||
(uuid "0c7608c2-fdf4-4830-90bc-0872989771ea")
|
(uuid "0c7608c2-fdf4-4830-90bc-0872989771ea")
|
||||||
)
|
)
|
||||||
(fp_text user "${REFERENCE}"
|
(fp_text user "${REFERENCE}"
|
||||||
|
|||||||
198216
board/modules/MPPT/MPPT.step
198216
board/modules/MPPT/MPPT.step
File diff suppressed because it is too large
Load Diff
BIN
board/modules/MPPT/battery-charging.png
Normal file
BIN
board/modules/MPPT/battery-charging.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
6
board/modules/MPPT/battery-charging.svg
Normal file
6
board/modules/MPPT/battery-charging.svg
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-battery-charging" viewBox="0 0 16 16">
|
||||||
|
<path d="M9.585 2.568a.5.5 0 0 1 .226.58L8.677 6.832h1.99a.5.5 0 0 1 .364.843l-5.334 5.667a.5.5 0 0 1-.842-.49L5.99 9.167H4a.5.5 0 0 1-.364-.843l5.333-5.667a.5.5 0 0 1 .616-.09z"/>
|
||||||
|
<path d="M2 4h4.332l-.94 1H2a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h2.38l-.308 1H2a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2"/>
|
||||||
|
<path d="M2 6h2.45L2.908 7.639A1.5 1.5 0 0 0 3.313 10H2zm8.595-2-.308 1H12a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1H9.276l-.942 1H12a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2z"/>
|
||||||
|
<path d="M12 10h-1.783l1.542-1.639q.146-.156.241-.34zm0-3.354V6h-.646a1.5 1.5 0 0 1 .646.646M16 8a1.5 1.5 0 0 1-1.5 1.5v-3A1.5 1.5 0 0 1 16 8"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 738 B |
@@ -1,6 +1,6 @@
|
|||||||
(sym_lib_table
|
(sym_lib_table
|
||||||
(version 7)
|
(version 7)
|
||||||
(lib (name "CN3795")(type "KiCad")(uri "/home/empire/workspace/PlantCtrl/board/CN3795.kicad_sym")(options "")(descr ""))
|
(lib (name "CN3795")(type "KiCad")(uri "${KIPRJMOD}/symbols/CN3795.kicad_sym")(options "")(descr ""))
|
||||||
(lib (name "MPPT")(type "KiCad")(uri "${KIPRJMOD}/MPPT.kicad_sym")(options "")(descr ""))
|
(lib (name "MPPT")(type "KiCad")(uri "${KIPRJMOD}/MPPT.kicad_sym")(options "")(descr ""))
|
||||||
(lib (name "ESP32-DEVKITC-32D")(type "KiCad")(uri "/home/empire/workspace/PlantCtrl/board/kicad-stuff/ESP32/ESP32-DEVKITC-32D.kicad_sym")(options "")(descr ""))
|
(lib (name "SL2300")(type "KiCad")(uri "${KIPRJMOD}/symbols/SL2300.kicad_sym")(options "")(descr ""))
|
||||||
)
|
)
|
||||||
|
|||||||
278
board/modules/MPPT/symbols/SL2300.kicad_sym
Normal file
278
board/modules/MPPT/symbols/SL2300.kicad_sym
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
(kicad_symbol_lib
|
||||||
|
(version 20241209)
|
||||||
|
(generator "kicad_symbol_editor")
|
||||||
|
(generator_version "9.0")
|
||||||
|
(symbol "SL2300"
|
||||||
|
(pin_names
|
||||||
|
(offset 1.016)
|
||||||
|
)
|
||||||
|
(exclude_from_sim no)
|
||||||
|
(in_bom yes)
|
||||||
|
(on_board yes)
|
||||||
|
(property "Reference" "Q"
|
||||||
|
(at 0 0 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Value" "SL2300"
|
||||||
|
(at 7.62 0 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Footprint" ""
|
||||||
|
(at 0 0 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Datasheet" ""
|
||||||
|
(at 0 0 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Description" ""
|
||||||
|
(at 0 0 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(symbol "SL2300_1_1"
|
||||||
|
(polyline
|
||||||
|
(pts
|
||||||
|
(xy -1.016 1.905) (xy -1.016 -1.905)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0.254)
|
||||||
|
(type solid)
|
||||||
|
)
|
||||||
|
(fill
|
||||||
|
(type none)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(polyline
|
||||||
|
(pts
|
||||||
|
(xy -1.016 0) (xy -3.81 0)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type solid)
|
||||||
|
)
|
||||||
|
(fill
|
||||||
|
(type none)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(polyline
|
||||||
|
(pts
|
||||||
|
(xy -0.508 2.286) (xy -0.508 1.27)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0.254)
|
||||||
|
(type solid)
|
||||||
|
)
|
||||||
|
(fill
|
||||||
|
(type none)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(polyline
|
||||||
|
(pts
|
||||||
|
(xy -0.508 0.508) (xy -0.508 -0.508)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0.254)
|
||||||
|
(type solid)
|
||||||
|
)
|
||||||
|
(fill
|
||||||
|
(type none)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(polyline
|
||||||
|
(pts
|
||||||
|
(xy -0.508 -1.27) (xy -0.508 -2.286)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0.254)
|
||||||
|
(type solid)
|
||||||
|
)
|
||||||
|
(fill
|
||||||
|
(type none)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(polyline
|
||||||
|
(pts
|
||||||
|
(xy -0.508 -1.778) (xy 2.032 -1.778) (xy 2.032 1.778) (xy -0.508 1.778)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type solid)
|
||||||
|
)
|
||||||
|
(fill
|
||||||
|
(type none)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(polyline
|
||||||
|
(pts
|
||||||
|
(xy -0.254 0) (xy 0.762 0.381) (xy 0.762 -0.381) (xy -0.254 0)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type solid)
|
||||||
|
)
|
||||||
|
(fill
|
||||||
|
(type outline)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(circle
|
||||||
|
(center 0.381 0)
|
||||||
|
(radius 2.794)
|
||||||
|
(stroke
|
||||||
|
(width 0.254)
|
||||||
|
(type solid)
|
||||||
|
)
|
||||||
|
(fill
|
||||||
|
(type none)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(polyline
|
||||||
|
(pts
|
||||||
|
(xy 1.27 2.54) (xy 1.27 1.778)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type solid)
|
||||||
|
)
|
||||||
|
(fill
|
||||||
|
(type none)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(circle
|
||||||
|
(center 1.27 1.778)
|
||||||
|
(radius 0.254)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type solid)
|
||||||
|
)
|
||||||
|
(fill
|
||||||
|
(type outline)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(circle
|
||||||
|
(center 1.27 -1.778)
|
||||||
|
(radius 0.254)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type solid)
|
||||||
|
)
|
||||||
|
(fill
|
||||||
|
(type outline)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(polyline
|
||||||
|
(pts
|
||||||
|
(xy 1.27 -2.54) (xy 1.27 0) (xy -0.508 0)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type solid)
|
||||||
|
)
|
||||||
|
(fill
|
||||||
|
(type none)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(polyline
|
||||||
|
(pts
|
||||||
|
(xy 1.524 0.508) (xy 1.651 0.381) (xy 2.413 0.381) (xy 2.54 0.254)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type solid)
|
||||||
|
)
|
||||||
|
(fill
|
||||||
|
(type none)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(polyline
|
||||||
|
(pts
|
||||||
|
(xy 2.032 0.381) (xy 1.651 -0.254) (xy 2.413 -0.254) (xy 2.032 0.381)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type solid)
|
||||||
|
)
|
||||||
|
(fill
|
||||||
|
(type none)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(pin input line
|
||||||
|
(at -6.35 0 0)
|
||||||
|
(length 2.54)
|
||||||
|
(name "G"
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(number "1"
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(pin passive line
|
||||||
|
(at 1.27 5.08 270)
|
||||||
|
(length 2.54)
|
||||||
|
(name "D"
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(number "3"
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(pin passive line
|
||||||
|
(at 1.27 -5.08 90)
|
||||||
|
(length 2.54)
|
||||||
|
(name "S"
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(number "2"
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(embedded_fonts no)
|
||||||
|
)
|
||||||
|
)
|
||||||
@@ -428,7 +428,7 @@
|
|||||||
(symbol "Sensor_1_1"
|
(symbol "Sensor_1_1"
|
||||||
(rectangle
|
(rectangle
|
||||||
(start -5.08 -1.27)
|
(start -5.08 -1.27)
|
||||||
(end 5.08 -29.21)
|
(end 5.08 -34.29)
|
||||||
(stroke
|
(stroke
|
||||||
(width 0)
|
(width 0)
|
||||||
(type solid)
|
(type solid)
|
||||||
@@ -455,7 +455,7 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(pin no_connect line
|
(pin power_in line
|
||||||
(at 7.62 -5.08 180)
|
(at 7.62 -5.08 180)
|
||||||
(length 2.54)
|
(length 2.54)
|
||||||
(name "VBAT"
|
(name "VBAT"
|
||||||
@@ -527,10 +527,10 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(pin output line
|
(pin input line
|
||||||
(at 7.62 -15.24 180)
|
(at 7.62 -15.24 180)
|
||||||
(length 2.54)
|
(length 2.54)
|
||||||
(name "GND"
|
(name "CAN_H"
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
(size 1.27 1.27)
|
(size 1.27 1.27)
|
||||||
@@ -545,10 +545,10 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(pin output line
|
(pin input line
|
||||||
(at 7.62 -17.78 180)
|
(at 7.62 -17.78 180)
|
||||||
(length 2.54)
|
(length 2.54)
|
||||||
(name "GND"
|
(name "CAN_L"
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
(size 1.27 1.27)
|
(size 1.27 1.27)
|
||||||
@@ -635,6 +635,42 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
(pin output line
|
||||||
|
(at 7.62 -30.48 180)
|
||||||
|
(length 2.54)
|
||||||
|
(name "GND"
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(number "12"
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(pin output line
|
||||||
|
(at 7.62 -33.02 180)
|
||||||
|
(length 2.54)
|
||||||
|
(name "GND"
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(number "13"
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
(embedded_fonts no)
|
(embedded_fonts no)
|
||||||
)
|
)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"board": {
|
"board": {
|
||||||
"active_layer": 0,
|
"active_layer": 5,
|
||||||
"active_layer_preset": "All Layers",
|
"active_layer_preset": "All Layers",
|
||||||
"auto_track_width": false,
|
"auto_track_width": false,
|
||||||
"hidden_netclasses": [],
|
"hidden_netclasses": [],
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
"shapes"
|
"shapes"
|
||||||
],
|
],
|
||||||
"visible_layers": "ffffffff_ffffffff_ffffffff_ffffffff",
|
"visible_layers": "ffffffff_ffffffff_ffffffff_ffffffff",
|
||||||
"zone_display_mode": 1
|
"zone_display_mode": 0
|
||||||
},
|
},
|
||||||
"git": {
|
"git": {
|
||||||
"repo_type": "",
|
"repo_type": "",
|
||||||
|
|||||||
@@ -62,10 +62,6 @@
|
|||||||
[
|
[
|
||||||
"footprint_type_mismatch|145100000|72500000|5ecd01c7-e707-43f2-ada2-bb695111d219|00000000-0000-0000-0000-000000000000",
|
"footprint_type_mismatch|145100000|72500000|5ecd01c7-e707-43f2-ada2-bb695111d219|00000000-0000-0000-0000-000000000000",
|
||||||
""
|
""
|
||||||
],
|
|
||||||
[
|
|
||||||
"silk_over_copper|177059610|78100001|e5735006-b5a9-492a-868f-a91cc93975c2|00000000-0000-0000-0000-000000000000",
|
|
||||||
""
|
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"meta": {
|
"meta": {
|
||||||
@@ -600,6 +596,12 @@
|
|||||||
"name": "${ITEM_NUMBER}",
|
"name": "${ITEM_NUMBER}",
|
||||||
"show": false
|
"show": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Field5",
|
||||||
|
"name": "Field5",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"group_by": false,
|
"group_by": false,
|
||||||
"label": "LCSC_PART_NUMBER",
|
"label": "LCSC_PART_NUMBER",
|
||||||
|
|||||||
@@ -593,190 +593,6 @@
|
|||||||
)
|
)
|
||||||
(embedded_fonts no)
|
(embedded_fonts no)
|
||||||
)
|
)
|
||||||
(symbol "Device:R_Shunt"
|
|
||||||
(pin_numbers
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
(pin_names
|
|
||||||
(offset 0)
|
|
||||||
)
|
|
||||||
(exclude_from_sim no)
|
|
||||||
(in_bom yes)
|
|
||||||
(on_board yes)
|
|
||||||
(property "Reference" "R"
|
|
||||||
(at -4.445 0 90)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "Value" "R_Shunt"
|
|
||||||
(at -2.54 0 90)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "Footprint" ""
|
|
||||||
(at -1.778 0 90)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "Datasheet" "~"
|
|
||||||
(at 0 0 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "Description" "Shunt resistor"
|
|
||||||
(at 0 0 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "ki_keywords" "R res shunt resistor"
|
|
||||||
(at 0 0 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "ki_fp_filters" "R_*Shunt*"
|
|
||||||
(at 0 0 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(symbol "R_Shunt_0_1"
|
|
||||||
(rectangle
|
|
||||||
(start -1.016 -2.54)
|
|
||||||
(end 1.016 2.54)
|
|
||||||
(stroke
|
|
||||||
(width 0.254)
|
|
||||||
(type default)
|
|
||||||
)
|
|
||||||
(fill
|
|
||||||
(type none)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(polyline
|
|
||||||
(pts
|
|
||||||
(xy 0 -2.54) (xy 1.27 -2.54)
|
|
||||||
)
|
|
||||||
(stroke
|
|
||||||
(width 0)
|
|
||||||
(type default)
|
|
||||||
)
|
|
||||||
(fill
|
|
||||||
(type none)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(polyline
|
|
||||||
(pts
|
|
||||||
(xy 1.27 2.54) (xy 0 2.54)
|
|
||||||
)
|
|
||||||
(stroke
|
|
||||||
(width 0)
|
|
||||||
(type default)
|
|
||||||
)
|
|
||||||
(fill
|
|
||||||
(type none)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(symbol "R_Shunt_1_1"
|
|
||||||
(pin passive line
|
|
||||||
(at 0 5.08 270)
|
|
||||||
(length 2.54)
|
|
||||||
(name "1"
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(number "1"
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(pin passive line
|
|
||||||
(at 0 -5.08 90)
|
|
||||||
(length 2.54)
|
|
||||||
(name "4"
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(number "4"
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(pin passive line
|
|
||||||
(at 3.81 2.54 180)
|
|
||||||
(length 2.54)
|
|
||||||
(name "2"
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(number "2"
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(pin passive line
|
|
||||||
(at 3.81 -2.54 180)
|
|
||||||
(length 2.54)
|
|
||||||
(name "3"
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(number "3"
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(embedded_fonts no)
|
|
||||||
)
|
|
||||||
(symbol "Diode:BAS40-04"
|
(symbol "Diode:BAS40-04"
|
||||||
(pin_names
|
(pin_names
|
||||||
(offset 1.016)
|
(offset 1.016)
|
||||||
@@ -2351,7 +2167,7 @@
|
|||||||
)
|
)
|
||||||
(uuid "a692c3ed-8364-41a4-a25b-0517c8420c06")
|
(uuid "a692c3ed-8364-41a4-a25b-0517c8420c06")
|
||||||
)
|
)
|
||||||
(text "Address 0101-000 -> dec 40"
|
(text "Address 1000010 -> dec 66"
|
||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(at 70.358 47.498 0)
|
(at 70.358 47.498 0)
|
||||||
(effects
|
(effects
|
||||||
@@ -2414,6 +2230,12 @@
|
|||||||
(color 0 0 0 0)
|
(color 0 0 0 0)
|
||||||
(uuid "4396d9fd-e4b3-4774-89c0-f5879b587ea9")
|
(uuid "4396d9fd-e4b3-4774-89c0-f5879b587ea9")
|
||||||
)
|
)
|
||||||
|
(junction
|
||||||
|
(at 36.83 85.09)
|
||||||
|
(diameter 0)
|
||||||
|
(color 0 0 0 0)
|
||||||
|
(uuid "50facde5-c849-43d8-9b86-fae1afb52c8a")
|
||||||
|
)
|
||||||
(junction
|
(junction
|
||||||
(at 276.86 200.66)
|
(at 276.86 200.66)
|
||||||
(diameter 0)
|
(diameter 0)
|
||||||
@@ -2450,6 +2272,12 @@
|
|||||||
(color 0 0 0 0)
|
(color 0 0 0 0)
|
||||||
(uuid "78e83bad-91e3-4858-9956-66ba0240bfef")
|
(uuid "78e83bad-91e3-4858-9956-66ba0240bfef")
|
||||||
)
|
)
|
||||||
|
(junction
|
||||||
|
(at 38.1 77.47)
|
||||||
|
(diameter 0)
|
||||||
|
(color 0 0 0 0)
|
||||||
|
(uuid "7c52ad28-f246-4488-981a-94a88c75e0ef")
|
||||||
|
)
|
||||||
(junction
|
(junction
|
||||||
(at 153.67 106.68)
|
(at 153.67 106.68)
|
||||||
(diameter 0)
|
(diameter 0)
|
||||||
@@ -2462,6 +2290,12 @@
|
|||||||
(color 0 0 0 0)
|
(color 0 0 0 0)
|
||||||
(uuid "94038c3f-a8df-486c-9c85-7d546ccf7920")
|
(uuid "94038c3f-a8df-486c-9c85-7d546ccf7920")
|
||||||
)
|
)
|
||||||
|
(junction
|
||||||
|
(at 38.1 85.09)
|
||||||
|
(diameter 0)
|
||||||
|
(color 0 0 0 0)
|
||||||
|
(uuid "9691379e-03c5-4356-a84d-995a6f4284dd")
|
||||||
|
)
|
||||||
(junction
|
(junction
|
||||||
(at 243.84 200.66)
|
(at 243.84 200.66)
|
||||||
(diameter 0)
|
(diameter 0)
|
||||||
@@ -2504,6 +2338,12 @@
|
|||||||
(color 0 0 0 0)
|
(color 0 0 0 0)
|
||||||
(uuid "c79d365a-7eb5-4e17-a150-46b714151130")
|
(uuid "c79d365a-7eb5-4e17-a150-46b714151130")
|
||||||
)
|
)
|
||||||
|
(junction
|
||||||
|
(at 36.83 77.47)
|
||||||
|
(diameter 0)
|
||||||
|
(color 0 0 0 0)
|
||||||
|
(uuid "c7b1301d-d308-4c17-a26d-b8bee9e65bbc")
|
||||||
|
)
|
||||||
(junction
|
(junction
|
||||||
(at 213.36 200.66)
|
(at 213.36 200.66)
|
||||||
(diameter 0)
|
(diameter 0)
|
||||||
@@ -2622,6 +2462,16 @@
|
|||||||
)
|
)
|
||||||
(uuid "11ad0b0e-d605-4139-9c31-76050fb20950")
|
(uuid "11ad0b0e-d605-4139-9c31-76050fb20950")
|
||||||
)
|
)
|
||||||
|
(wire
|
||||||
|
(pts
|
||||||
|
(xy 40.64 77.47) (xy 38.1 77.47)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(uuid "13d97c0b-b70b-49c9-aee8-997f1f330cae")
|
||||||
|
)
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 243.84 200.66) (xy 242.57 200.66)
|
(xy 243.84 200.66) (xy 242.57 200.66)
|
||||||
@@ -2792,6 +2642,16 @@
|
|||||||
)
|
)
|
||||||
(uuid "4a91f5f7-45a0-40bb-932c-88a1af0c72eb")
|
(uuid "4a91f5f7-45a0-40bb-932c-88a1af0c72eb")
|
||||||
)
|
)
|
||||||
|
(wire
|
||||||
|
(pts
|
||||||
|
(xy 36.83 76.2) (xy 36.83 77.47)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(uuid "4d75715b-5c03-4f74-962e-65303cc18dcc")
|
||||||
|
)
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 158.75 106.68) (xy 161.29 106.68)
|
(xy 158.75 106.68) (xy 161.29 106.68)
|
||||||
@@ -2962,6 +2822,16 @@
|
|||||||
)
|
)
|
||||||
(uuid "6e6bde6b-710f-46fe-ae64-dcc1c9cb2654")
|
(uuid "6e6bde6b-710f-46fe-ae64-dcc1c9cb2654")
|
||||||
)
|
)
|
||||||
|
(wire
|
||||||
|
(pts
|
||||||
|
(xy 40.64 83.82) (xy 40.64 85.09)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(uuid "6e7fb4b0-87a6-438b-8d87-5f176f93d6c3")
|
||||||
|
)
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 270.51 213.36) (xy 265.43 213.36)
|
(xy 270.51 213.36) (xy 265.43 213.36)
|
||||||
@@ -3012,6 +2882,16 @@
|
|||||||
)
|
)
|
||||||
(uuid "760f68c3-55c4-4d63-b9d1-1242153327ac")
|
(uuid "760f68c3-55c4-4d63-b9d1-1242153327ac")
|
||||||
)
|
)
|
||||||
|
(wire
|
||||||
|
(pts
|
||||||
|
(xy 35.56 77.47) (xy 36.83 77.47)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(uuid "77bf4909-a56c-4f8d-a61a-7f5fa4f91e92")
|
||||||
|
)
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 213.36 200.66) (xy 212.09 200.66)
|
(xy 213.36 200.66) (xy 212.09 200.66)
|
||||||
@@ -3182,6 +3062,36 @@
|
|||||||
)
|
)
|
||||||
(uuid "a3f0835a-3b5b-47e1-8a75-e220b9b2620a")
|
(uuid "a3f0835a-3b5b-47e1-8a75-e220b9b2620a")
|
||||||
)
|
)
|
||||||
|
(wire
|
||||||
|
(pts
|
||||||
|
(xy 36.83 85.09) (xy 38.1 85.09)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(uuid "a60e5812-7a8a-4db3-bf7a-9e5827aab165")
|
||||||
|
)
|
||||||
|
(wire
|
||||||
|
(pts
|
||||||
|
(xy 36.83 77.47) (xy 38.1 77.47)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(uuid "a74e0287-43ed-4a83-a2e5-58597c0b71ad")
|
||||||
|
)
|
||||||
|
(wire
|
||||||
|
(pts
|
||||||
|
(xy 40.64 78.74) (xy 40.64 77.47)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(uuid "a757fb93-eac8-4231-94e7-e6b64d10a357")
|
||||||
|
)
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 177.8 213.36) (xy 172.72 213.36)
|
(xy 177.8 213.36) (xy 172.72 213.36)
|
||||||
@@ -3262,6 +3172,16 @@
|
|||||||
)
|
)
|
||||||
(uuid "b1f63e57-8eca-4368-acdd-39768cad7ee8")
|
(uuid "b1f63e57-8eca-4368-acdd-39768cad7ee8")
|
||||||
)
|
)
|
||||||
|
(wire
|
||||||
|
(pts
|
||||||
|
(xy 36.83 85.09) (xy 36.83 86.36)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(uuid "b4069663-4cfa-4aa6-97c3-bc3f1da5fcc2")
|
||||||
|
)
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 243.84 168.91) (xy 243.84 200.66)
|
(xy 243.84 168.91) (xy 243.84 200.66)
|
||||||
@@ -3302,6 +3222,16 @@
|
|||||||
)
|
)
|
||||||
(uuid "c8d6b6fe-9173-45b5-904c-d6a48c165dfb")
|
(uuid "c8d6b6fe-9173-45b5-904c-d6a48c165dfb")
|
||||||
)
|
)
|
||||||
|
(wire
|
||||||
|
(pts
|
||||||
|
(xy 40.64 85.09) (xy 38.1 85.09)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(uuid "cb9c59ae-5f9e-4b3b-ba2b-b145eb8a3682")
|
||||||
|
)
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 156.21 106.68) (xy 153.67 106.68)
|
(xy 156.21 106.68) (xy 153.67 106.68)
|
||||||
@@ -3402,6 +3332,16 @@
|
|||||||
)
|
)
|
||||||
(uuid "e3e23ab7-a47a-492a-8f7f-b8876d21c5ce")
|
(uuid "e3e23ab7-a47a-492a-8f7f-b8876d21c5ce")
|
||||||
)
|
)
|
||||||
|
(wire
|
||||||
|
(pts
|
||||||
|
(xy 35.56 85.09) (xy 36.83 85.09)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(uuid "e45e4aa6-79d6-4533-8f3c-950a8c425958")
|
||||||
|
)
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 184.15 200.66) (xy 186.69 200.66)
|
(xy 184.15 200.66) (xy 186.69 200.66)
|
||||||
@@ -5452,6 +5392,91 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
(symbol
|
||||||
|
(lib_id "Device:R")
|
||||||
|
(at 35.56 81.28 180)
|
||||||
|
(unit 1)
|
||||||
|
(exclude_from_sim no)
|
||||||
|
(in_bom yes)
|
||||||
|
(on_board yes)
|
||||||
|
(dnp no)
|
||||||
|
(fields_autoplaced yes)
|
||||||
|
(uuid "06c66de4-05db-4145-a783-1ccae1cba266")
|
||||||
|
(property "Reference" "R22"
|
||||||
|
(at 29.21 81.28 90)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Value" "100mOhm"
|
||||||
|
(at 31.75 81.28 90)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Footprint" "Resistor_SMD:R_1206_3216Metric"
|
||||||
|
(at 37.338 81.28 90)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Datasheet" "~"
|
||||||
|
(at 35.56 81.28 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Description" "Resistor"
|
||||||
|
(at 35.56 81.28 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Field5" ""
|
||||||
|
(at 35.56 81.28 90)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "LCSC_PART_NUMBER" "C25334"
|
||||||
|
(at 35.56 81.28 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(pin "2"
|
||||||
|
(uuid "621f9ffa-bc53-4f17-8c67-70556274e5d5")
|
||||||
|
)
|
||||||
|
(pin "1"
|
||||||
|
(uuid "6c18da2f-eff2-4a53-8887-8bcae3c50e33")
|
||||||
|
)
|
||||||
|
(instances
|
||||||
|
(project "PumpOutput"
|
||||||
|
(path "/fa7c93d2-7670-4cd5-85ee-82ddfb7f2ba1"
|
||||||
|
(reference "R22")
|
||||||
|
(unit 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
(symbol
|
(symbol
|
||||||
(lib_id "Diode:BAS40-04")
|
(lib_id "Diode:BAS40-04")
|
||||||
(at 342.9 200.66 270)
|
(at 342.9 200.66 270)
|
||||||
@@ -8115,88 +8140,6 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(symbol
|
|
||||||
(lib_id "Device:R_Shunt")
|
|
||||||
(at 36.83 81.28 0)
|
|
||||||
(unit 1)
|
|
||||||
(exclude_from_sim no)
|
|
||||||
(in_bom yes)
|
|
||||||
(on_board yes)
|
|
||||||
(dnp no)
|
|
||||||
(uuid "a1bb7c77-426c-4d47-bf3d-412e55f41696")
|
|
||||||
(property "Reference" "R1"
|
|
||||||
(at 31.115 81.28 90)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "Value" "0.06"
|
|
||||||
(at 33.655 81.28 90)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "Footprint" "board:R_Shunt_Vishay_WSK2512_6332Metric_T1.19mm"
|
|
||||||
(at 35.052 81.28 90)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "Datasheet" "~"
|
|
||||||
(at 36.83 81.28 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "Description" ""
|
|
||||||
(at 36.83 81.28 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "LCSC_PART_NUMBER" "C252688"
|
|
||||||
(at 36.83 81.28 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(pin "1"
|
|
||||||
(uuid "e0a8ea80-0f81-4231-b874-03b9f5249a2e")
|
|
||||||
)
|
|
||||||
(pin "2"
|
|
||||||
(uuid "bcf029db-6ab1-45fd-8230-ea25cd4b8e39")
|
|
||||||
)
|
|
||||||
(pin "3"
|
|
||||||
(uuid "c3fc705b-3f3f-4a16-a58f-f5731609e069")
|
|
||||||
)
|
|
||||||
(pin "4"
|
|
||||||
(uuid "3f9ec63d-9486-46fd-80da-2e3026ee305c")
|
|
||||||
)
|
|
||||||
(instances
|
|
||||||
(project "PumpOutput"
|
|
||||||
(path "/fa7c93d2-7670-4cd5-85ee-82ddfb7f2ba1"
|
|
||||||
(reference "R1")
|
|
||||||
(unit 1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(symbol
|
(symbol
|
||||||
(lib_id "Device:R")
|
(lib_id "Device:R")
|
||||||
(at 107.95 209.55 0)
|
(at 107.95 209.55 0)
|
||||||
@@ -9567,6 +9510,91 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
(symbol
|
||||||
|
(lib_id "Device:R")
|
||||||
|
(at 38.1 81.28 180)
|
||||||
|
(unit 1)
|
||||||
|
(exclude_from_sim no)
|
||||||
|
(in_bom yes)
|
||||||
|
(on_board yes)
|
||||||
|
(dnp no)
|
||||||
|
(fields_autoplaced yes)
|
||||||
|
(uuid "cd915e50-d838-4be3-a347-a21c637844fb")
|
||||||
|
(property "Reference" "R23"
|
||||||
|
(at 31.75 81.28 90)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Value" "100mOhm"
|
||||||
|
(at 34.29 81.28 90)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Footprint" "Resistor_SMD:R_1206_3216Metric"
|
||||||
|
(at 39.878 81.28 90)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Datasheet" "~"
|
||||||
|
(at 38.1 81.28 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Description" "Resistor"
|
||||||
|
(at 38.1 81.28 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Field5" ""
|
||||||
|
(at 38.1 81.28 90)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "LCSC_PART_NUMBER" "C25334"
|
||||||
|
(at 38.1 81.28 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(pin "2"
|
||||||
|
(uuid "7fe843c2-c5dd-443c-ae77-3b0b38ae2e61")
|
||||||
|
)
|
||||||
|
(pin "1"
|
||||||
|
(uuid "ff40a99b-897c-44a2-95ab-a9ce9db21ed7")
|
||||||
|
)
|
||||||
|
(instances
|
||||||
|
(project "PumpOutput"
|
||||||
|
(path "/fa7c93d2-7670-4cd5-85ee-82ddfb7f2ba1"
|
||||||
|
(reference "R23")
|
||||||
|
(unit 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
(symbol
|
(symbol
|
||||||
(lib_id "Device:LED")
|
(lib_id "Device:LED")
|
||||||
(at 148.59 102.87 90)
|
(at 148.59 102.87 90)
|
||||||
|
|||||||
@@ -1,105 +1,124 @@
|
|||||||
P CODE 00
|
P CODE 00
|
||||||
P UNITS CUST 0
|
P UNITS CUST 0
|
||||||
P arrayDim N
|
P arrayDim N
|
||||||
317GND VIA MD0118PA00X+039921Y-034803X0236Y0000R000S3
|
317VBAT VIA MD0118PA00X+070000Y-031653X0236Y0000R000S3
|
||||||
317GND VIA MD0118PA00X+073071Y-034803X0236Y0000R000S3
|
317VBAT VIA MD0118PA00X+068198Y-031624X0236Y0000R000S3
|
||||||
317GND VIA MD0118PA00X+075512Y-034803X0236Y0000R000S3
|
317GND VIA MD0118PA00X+044783Y-034803X0236Y0000R000S3
|
||||||
317GND VIA MD0118PA00X+070000Y-034803X0236Y0000R000S3
|
317GND VIA MD0118PA00X+043012Y-034843X0236Y0000R000S3
|
||||||
317GND VIA MD0118PA00X+061339Y-034803X0236Y0000R000S3
|
317GND VIA MD0118PA00X+048720Y-034803X0236Y0000R000S3
|
||||||
317GND VIA MD0118PA00X+048346Y-034803X0236Y0000R000S3
|
317GND VIA MD0118PA00X+056496Y-034803X0236Y0000R000S3
|
||||||
317GND VIA MD0118PA00X+057008Y-034803X0236Y0000R000S3
|
317GND VIA MD0118PA00X+071949Y-034803X0236Y0000R000S3
|
||||||
|
317GND VIA MD0118PA00X+057874Y-034803X0236Y0000R000S3
|
||||||
|
317GND VIA MD0118PA00X+071453Y-034485X0236Y0000R000S3
|
||||||
317GND VIA MD0118PA00X+065669Y-034803X0236Y0000R000S3
|
317GND VIA MD0118PA00X+065669Y-034803X0236Y0000R000S3
|
||||||
|
317GND VIA MD0118PA00X+050689Y-034803X0236Y0000R000S3
|
||||||
|
317GND VIA MD0118PA00X+062598Y-034803X0236Y0000R000S3
|
||||||
|
317GND VIA MD0118PA00X+068406Y-034803X0236Y0000R000S3
|
||||||
|
317GND VIA MD0118PA00X+064469Y-034803X0236Y0000R000S3
|
||||||
|
317GND VIA MD0118PA00X+042126Y-034843X0236Y0000R000S3
|
||||||
|
317GND VIA MD0118PA00X+046949Y-034803X0236Y0000R000S3
|
||||||
|
317GND VIA MD0118PA00X+060433Y-034803X0236Y0000R000S3
|
||||||
|
317GND VIA MD0118PA00X+046063Y-034803X0236Y0000R000S3
|
||||||
|
317GND VIA MD0118PA00X+069587Y-034803X0236Y0000R000S3
|
||||||
|
317GND VIA MD0118PA00X+058661Y-034803X0236Y0000R000S3
|
||||||
|
317GND VIA MD0118PA00X+068113Y-033900X0236Y0000R000S3
|
||||||
317GND VIA MD0118PA00X+052677Y-034803X0236Y0000R000S3
|
317GND VIA MD0118PA00X+052677Y-034803X0236Y0000R000S3
|
||||||
317GND VIA MD0118PA00X+044173Y-034803X0236Y0000R000S3
|
317GND VIA MD0118PA00X+054724Y-034803X0236Y0000R000S3
|
||||||
3175K_VBAT VIA MD0118PA00X+061122Y-032776X0236Y0000R000S3
|
317GND VIA MD0118PA00X+053937Y-034803X0236Y0000R000S3
|
||||||
3175K_VBAT VIA MD0118PA00X+065650Y-032874X0236Y0000R000S3
|
317GND VIA MD0118PA00X+050000Y-034803X0236Y0000R000S3
|
||||||
3175K_VBAT VIA MD0118PA00X+069726Y-033248X0236Y0000R000S3
|
317GND VIA MD0118PA00X+061811Y-034803X0236Y0000R000S3
|
||||||
317T-(P_FAULT1-K) VIA MD0118PA00X+062894Y-033563X0236Y0000R000S3
|
3175K_VBAT VIA MD0118PA00X+070866Y-031969X0236Y0000R000S3
|
||||||
317T-(P_FAULT1-K) VIA MD0118PA00X+067283Y-033583X0236Y0000R000S3
|
3175K_VBAT VIA MD0118PA00X+062598Y-032087X0236Y0000R000S3
|
||||||
|
3175K_VBAT VIA MD0118PA00X+064055Y-032087X0236Y0000R000S3
|
||||||
|
3175K_VBAT VIA MD0118PA00X+066378Y-032087X0236Y0000R000S3
|
||||||
|
317T-(P_FAULT1-K) VIA MD0118PA00X+063543Y-033504X0236Y0000R000S3
|
||||||
|
317T-(P_FAULT1-K) VIA MD0118PA00X+067126Y-033583X0236Y0000R000S3
|
||||||
317T-(P_FAULT1-K) VIA MD0118PA00X+071535Y-033622X0236Y0000R000S3
|
317T-(P_FAULT1-K) VIA MD0118PA00X+071535Y-033622X0236Y0000R000S3
|
||||||
317T-(P_FAULT1-A) VIA MD0118PA00X+075577Y-032918X0236Y0000R000S3
|
317T-(P_FAULT1-A) VIA MD0118PA00X+074134Y-033169X0236Y0000R000S3
|
||||||
317T-(P_FAULT1-A) VIA MD0118PA00X+041890Y-032480X0236Y0000R000S3
|
317T-(P_FAULT1-A) VIA MD0118PA00X+044488Y-032599X0236Y0000R000S3
|
||||||
317T-(P_FAULT2-A) VIA MD0118PA00X+075263Y-032896X0236Y0000R000S3
|
317T-(P_FAULT2-A) VIA MD0118PA00X+048386Y-032796X0236Y0000R000S3
|
||||||
317T-(P_FAULT2-A) VIA MD0118PA00X+046102Y-032948X0236Y0000R000S3
|
317T-(P_FAULT2-A) VIA MD0118PA00X+073858Y-033150X0236Y0000R000S3
|
||||||
317T-(P_FAULT3-A) VIA MD0118PA00X+050236Y-032908X0236Y0000R000S3
|
317T-(P_FAULT3-A) VIA MD0118PA00X+073543Y-033150X0236Y0000R000S3
|
||||||
317T-(P_FAULT3-A) VIA MD0118PA00X+075019Y-032697X0236Y0000R000S3
|
317T-(P_FAULT3-A) VIA MD0118PA00X+052165Y-032875X0236Y0000R000S3
|
||||||
317T-(P_FAULT4-A) VIA MD0118PA00X+054646Y-032908X0236Y0000R000S3
|
317T-(P_FAULT4-A) VIA MD0118PA00X+056260Y-032954X0236Y0000R000S3
|
||||||
317T-(P_FAULT4-A) VIA MD0118PA00X+074802Y-032468X0236Y0000R000S3
|
317T-(P_FAULT4-A) VIA MD0118PA00X+073228Y-033150X0236Y0000R000S3
|
||||||
317T-(P_FAULT5-A) VIA MD0118PA00X+074539Y-032643X0236Y0000R000S3
|
317T-(P_FAULT5-A) VIA MD0118PA00X+074724Y-031850X0236Y0000R000S3
|
||||||
317T-(P_FAULT5-A) VIA MD0118PA00X+059055Y-032908X0236Y0000R000S3
|
317T-(P_FAULT5-A) VIA MD0118PA00X+060157Y-032441X0236Y0000R000S3
|
||||||
317T-(P_FAULT6-A) VIA MD0118PA00X+063268Y-032908X0236Y0000R000S3
|
317T-(P_FAULT6-A) VIA MD0118PA00X+074409Y-031850X0236Y0000R000S3
|
||||||
317T-(P_FAULT6-A) VIA MD0118PA00X+074279Y-032819X0236Y0000R000S3
|
317T-(P_FAULT6-A) VIA MD0118PA00X+064055Y-032362X0236Y0000R000S3
|
||||||
317T-(P_FAULT7-A) VIA MD0118PA00X+067598Y-032948X0236Y0000R000S3
|
317T-(P_FAULT7-A) VIA MD0118PA00X+067126Y-032165X0236Y0000R000S3
|
||||||
317T-(P_FAULT7-A) VIA MD0118PA00X+074006Y-032977X0236Y0000R000S3
|
317T-(P_FAULT7-A) VIA MD0118PA00X+074094Y-031850X0236Y0000R000S3
|
||||||
317T-(P_FAULT8-A) VIA MD0118PA00X+073740Y-034055X0236Y0000R000S3
|
317T-(P_FAULT8-A) VIA MD0118PA00X+073780Y-031850X0236Y0000R000S3
|
||||||
317T-(P_FAULT8-A) VIA MD0118PA00X+071969Y-033268X0236Y0000R000S3
|
317T-(P_FAULT8-A) VIA MD0118PA00X+071417Y-031850X0236Y0000R000S3
|
||||||
317PUMP1 VIA MD0118PA00X+041811Y-037638X0236Y0000R000S3
|
317PUMP1 VIA MD0118PA00X+073425Y-034646X0236Y0000R000S3
|
||||||
317PUMP1 VIA MD0118PA00X+073465Y-038898X0236Y0000R000S3
|
317PUMP1 VIA MD0118PA00X+045374Y-036713X0236Y0000R000S3
|
||||||
317PUMP3 VIA MD0118PA00X+073937Y-038583X0236Y0000R000S3
|
317PUMP3 VIA MD0118PA00X+053248Y-036319X0236Y0000R000S3
|
||||||
317PUMP3 VIA MD0118PA00X+050354Y-037638X0236Y0000R000S3
|
317PUMP3 VIA MD0118PA00X+074370Y-034449X0236Y0000R000S3
|
||||||
317PUMP4 VIA MD0118PA00X+074173Y-038819X0236Y0000R000S3
|
317PUMP4 VIA MD0118PA00X+074764Y-034331X0236Y0000R000S3
|
||||||
317PUMP4 VIA MD0118PA00X+054646Y-037638X0236Y0000R000S3
|
317PUMP4 VIA MD0118PA00X+057185Y-036122X0236Y0000R000S3
|
||||||
317PUMP5 VIA MD0118PA00X+074528Y-038661X0236Y0000R000S3
|
317PUMP5 VIA MD0118PA00X+061024Y-036024X0236Y0000R000S3
|
||||||
317PUMP5 VIA MD0118PA00X+058976Y-037658X0236Y0000R000S3
|
317PUMP5 VIA MD0118PA00X+075079Y-034252X0236Y0000R000S3
|
||||||
317PUMP6 VIA MD0118PA00X+074764Y-038386X0236Y0000R000S3
|
317PUMP6 VIA MD0118PA00X+075354Y-034134X0236Y0000R000S3
|
||||||
317PUMP6 VIA MD0118PA00X+063484Y-037598X0236Y0000R000S3
|
317PUMP6 VIA MD0118PA00X+064654Y-035649X0236Y0000R000S3
|
||||||
317PUMP7 VIA MD0118PA00X+067638Y-037598X0236Y0000R000S3
|
317PUMP7 VIA MD0118PA00X+068898Y-035630X0236Y0000R000S3
|
||||||
317PUMP7 VIA MD0118PA00X+075001Y-038179X0236Y0000R000S3
|
317PUMP7 VIA MD0118PA00X+075551Y-033937X0236Y0000R000S3
|
||||||
317PUMP8 VIA MD0118PA00X+075276Y-037953X0236Y0000R000S3
|
317PUMP2 VIA MD0118PA00X+073858Y-034567X0236Y0000R000S3
|
||||||
317PUMP8 VIA MD0118PA00X+071969Y-037953X0236Y0000R000S3
|
317PUMP2 VIA MD0118PA00X+049311Y-036516X0236Y0000R000S3
|
||||||
317PUMP2 VIA MD0118PA00X+046102Y-037598X0236Y0000R000S3
|
3173_3V VIA MD0118PA00X+068287Y-033051X0236Y0000R000S3
|
||||||
317PUMP2 VIA MD0118PA00X+073740Y-038307X0236Y0000R000S3
|
3173_3V VIA MD0118PA00X+071929Y-033268X0236Y0000R000S3
|
||||||
3173_3V VIA MD0118PA00X+072726Y-032903X0236Y0000R000S3
|
317SDA VIA MD0118PA00X+069796Y-033232X0236Y0000R000S3
|
||||||
3173_3V VIA MD0118PA00X+067992Y-032953X0236Y0000R000S3
|
317SDA VIA MD0118PA00X+072677Y-033150X0236Y0000R000S3
|
||||||
317SDA VIA MD0118PA00X+069685Y-034173X0236Y0000R000S3
|
317SCL VIA MD0118PA00X+070039Y-033103X0236Y0000R000S3
|
||||||
317SDA VIA MD0118PA00X+072933Y-034173X0236Y0000R000S3
|
317SCL VIA MD0118PA00X+072953Y-033150X0236Y0000R000S3
|
||||||
317SCL VIA MD0118PA00X+068363Y-034012X0236Y0000R000S3
|
327VCC R23 -1 A01X+069281Y-031654X0443Y0689R000S2
|
||||||
317SCL VIA MD0118PA00X+073228Y-033957X0236Y0000R000S3
|
327VBAT R23 -2 A01X+070433Y-031654X0443Y0689R000S2
|
||||||
327PUMP3 R16 -1 A01X+050315Y-036073X0315Y0374R270S2
|
327VCC R22 -1 A01X+067416Y-031654X0443Y0689R000S2
|
||||||
327NET-(Q3-G) R16 -2 A01X+050315Y-035423X0315Y0374R270S2
|
327VBAT R22 -2 A01X+068568Y-031654X0443Y0689R000S2
|
||||||
327NET-(Q3-G) Q3 -1 A01X+049621Y-035984X0354Y0315R180S2
|
327PUMP3 R16 -1 A01X+052195Y-033858X0315Y0374R180S2
|
||||||
327GND Q3 -2 A01X+049621Y-035236X0354Y0315R180S2
|
327NET-(Q3-G) R16 -2 A01X+051545Y-033858X0315Y0374R180S2
|
||||||
327-(PUMP3-PIN_1) Q3 -3 A01X+048834Y-035610X0354Y0315R180S2
|
327NET-(Q3-G) Q3 -1 A01X+052657Y-035984X0354Y0315R180S2
|
||||||
327NET-(Q5-G) Q5 -1 A01X+058297Y-035984X0354Y0315R180S2
|
327GND Q3 -2 A01X+052657Y-035236X0354Y0315R180S2
|
||||||
327GND Q5 -2 A01X+058297Y-035236X0354Y0315R180S2
|
327-(PUMP3-PIN_1) Q3 -3 A01X+051870Y-035610X0354Y0315R180S2
|
||||||
327-(PUMP5-PIN_1) Q5 -3 A01X+057510Y-035610X0354Y0315R180S2
|
327NET-(Q5-G) Q5 -1 A01X+060443Y-035984X0354Y0315R180S2
|
||||||
327NET-(Q1-G) Q1 -1 A01X+041132Y-035984X0354Y0315R180S2
|
327GND Q5 -2 A01X+060443Y-035236X0354Y0315R180S2
|
||||||
327GND Q1 -2 A01X+041132Y-035236X0354Y0315R180S2
|
327-(PUMP5-PIN_1) Q5 -3 A01X+059656Y-035610X0354Y0315R180S2
|
||||||
327-(PUMP1-PIN_1) Q1 -3 A01X+040344Y-035610X0354Y0315R180S2
|
327NET-(Q1-G) Q1 -1 A01X+044783Y-035984X0354Y0315R180S2
|
||||||
317-(PUMP8-PIN_1) PUMP8 -1 D0394PA00X+069503Y-037362X0669Y0787R000S0
|
327GND Q1 -2 A01X+044783Y-035236X0354Y0315R180S2
|
||||||
317VCC PUMP8 -2 D0394PA00X+070487Y-037362X0669Y0787R000S0
|
327-(PUMP1-PIN_1) Q1 -3 A01X+043996Y-035610X0354Y0315R180S2
|
||||||
317-(PUMP7-PIN_1) PUMP7 -1 D0394PA00X+065172Y-037382X0669Y0787R000S0
|
317-(PUMP8-PIN_1) PUMP8 -1 D0394PA00X+070551Y-037362X0669Y0787R000S0
|
||||||
317VCC PUMP7 -2 D0394PA00X+066156Y-037382X0669Y0787R000S0
|
317VCC PUMP8 -2 D0394PA00X+071535Y-037362X0669Y0787R000S0
|
||||||
327NET-(Q6-G) Q6 -1 A01X+062613Y-035984X0354Y0315R180S2
|
317-(PUMP7-PIN_1) PUMP7 -1 D0394PA00X+066535Y-037382X0669Y0787R000S0
|
||||||
327GND Q6 -2 A01X+062613Y-035236X0354Y0315R180S2
|
317VCC PUMP7 -2 D0394PA00X+067520Y-037382X0669Y0787R000S0
|
||||||
327-(PUMP6-PIN_1) Q6 -3 A01X+061826Y-035610X0354Y0315R180S2
|
327NET-(Q6-G) Q6 -1 A01X+064469Y-035984X0354Y0315R180S2
|
||||||
327PUMP8 R19 -1 A01X+071969Y-036033X0315Y0374R270S2
|
327GND Q6 -2 A01X+064469Y-035236X0354Y0315R180S2
|
||||||
327NET-(Q8-G) R19 -2 A01X+071969Y-035384X0315Y0374R270S2
|
327-(PUMP6-PIN_1) Q6 -3 A01X+063681Y-035610X0354Y0315R180S2
|
||||||
327NET-(Q5-G) R10 -1 A01X+058041Y-033898X0315Y0374R180S2
|
327PUMP8 R19 -1 A01X+073199Y-036024X0315Y0374R180S2
|
||||||
327GND R10 -2 A01X+057392Y-033898X0315Y0374R180S2
|
327NET-(Q8-G) R19 -2 A01X+072549Y-036024X0315Y0374R180S2
|
||||||
327T-(P_FAULT1-K) P_FAUL-1 A01X+058504Y-033164X0384Y0551R270S2
|
327NET-(Q5-G) R10 -1 A01X+058661Y-033829X0315Y0374R090S2
|
||||||
327T-(P_FAULT5-A) P_FAUL-2 A01X+058504Y-032426X0384Y0551R270S2
|
327GND R10 -2 A01X+058661Y-034478X0315Y0374R090S2
|
||||||
327NET-(Q6-G) R11 -1 A01X+062333Y-033898X0315Y0374R180S2
|
327T-(P_FAULT1-K) P_FAUL-1 A01X+059646Y-033164X0384Y0551R270S2
|
||||||
327GND R11 -2 A01X+061683Y-033898X0315Y0374R180S2
|
327T-(P_FAULT5-A) P_FAUL-2 A01X+059646Y-032426X0384Y0551R270S2
|
||||||
327-(PUMP6-PIN_1) PUMP_D-1 A01X+061811Y-033164X0384Y0551R270S2
|
327NET-(Q6-G) R11 -1 A01X+062598Y-033829X0315Y0374R090S2
|
||||||
3275K_VBAT PUMP_D-2 A01X+061811Y-032426X0384Y0551R270S2
|
327GND R11 -2 A01X+062598Y-034478X0315Y0374R090S2
|
||||||
327PUMP6 R21 -1 A01X+063484Y-037234X0315Y0374R270S2
|
327-(PUMP6-PIN_1) PUMP_D-1 A01X+062598Y-033164X0384Y0551R270S2
|
||||||
327NET-(Q6-G) R21 -2 A01X+063484Y-036585X0315Y0374R270S2
|
3275K_VBAT PUMP_D-2 A01X+062598Y-032426X0384Y0551R270S2
|
||||||
327-(PUMP2-PIN_1) PUMP_D-1 A01X+044660Y-033204X0384Y0551R270S2
|
327PUMP6 R21 -1 A01X+064104Y-033858X0315Y0374R180S2
|
||||||
3275K_VBAT PUMP_D-2 A01X+044660Y-032466X0384Y0551R270S2
|
327NET-(Q6-G) R21 -2 A01X+063455Y-033858X0315Y0374R180S2
|
||||||
327PUMP1 R14 -1 A01X+041890Y-036073X0315Y0374R270S2
|
327-(PUMP2-PIN_1) PUMP_D-1 A01X+046949Y-033145X0384Y0551R270S2
|
||||||
327NET-(Q1-G) R14 -2 A01X+041890Y-035423X0315Y0374R270S2
|
3275K_VBAT PUMP_D-2 A01X+046949Y-032406X0384Y0551R270S2
|
||||||
327NET-(Q2-G) R7 -1 A01X+045167Y-033898X0315Y0374R180S2
|
327PUMP1 R14 -1 A01X+044488Y-033858X0315Y0374R180S2
|
||||||
327GND R7 -2 A01X+044518Y-033898X0315Y0374R180S2
|
327NET-(Q1-G) R14 -2 A01X+043839Y-033858X0315Y0374R180S2
|
||||||
327T-(P_FAULT1-K) P_FAUL-1 A01X+054173Y-033164X0384Y0551R270S2
|
327NET-(Q2-G) R7 -1 A01X+046949Y-033829X0315Y0374R090S2
|
||||||
327T-(P_FAULT4-A) P_FAUL-2 A01X+054173Y-032426X0384Y0551R270S2
|
327GND R7 -2 A01X+046949Y-034478X0315Y0374R090S2
|
||||||
327NET-(Q7-G) R12 -1 A01X+066663Y-033937X0315Y0374R180S2
|
327T-(P_FAULT1-K) P_FAUL-1 A01X+055709Y-033164X0384Y0551R270S2
|
||||||
327GND R12 -2 A01X+066014Y-033937X0315Y0374R180S2
|
327T-(P_FAULT4-A) P_FAUL-2 A01X+055709Y-032426X0384Y0551R270S2
|
||||||
327NET-(Q4-G) Q4 -1 A01X+053967Y-035984X0354Y0315R180S2
|
327NET-(Q7-G) R12 -1 A01X+065945Y-033829X0315Y0374R090S2
|
||||||
327GND Q4 -2 A01X+053967Y-035236X0354Y0315R180S2
|
327GND R12 -2 A01X+065945Y-034478X0315Y0374R090S2
|
||||||
327-(PUMP4-PIN_1) Q4 -3 A01X+053179Y-035610X0354Y0315R180S2
|
327NET-(Q4-G) Q4 -1 A01X+056521Y-035984X0354Y0315R180S2
|
||||||
327-(PUMP5-PIN_1) PUMP_D-1 A01X+057520Y-033164X0384Y0551R270S2
|
327GND Q4 -2 A01X+056521Y-035236X0354Y0315R180S2
|
||||||
3275K_VBAT PUMP_D-2 A01X+057520Y-032426X0384Y0551R270S2
|
327-(PUMP4-PIN_1) Q4 -3 A01X+055733Y-035610X0354Y0315R180S2
|
||||||
|
327-(PUMP5-PIN_1) PUMP_D-1 A01X+058661Y-033164X0384Y0551R270S2
|
||||||
|
3275K_VBAT PUMP_D-2 A01X+058661Y-032426X0384Y0551R270S2
|
||||||
327GND C3 -1 A01X+067913Y-034099X0423Y0374R270S2
|
327GND C3 -1 A01X+067913Y-034099X0423Y0374R270S2
|
||||||
3273_3V C3 -2 A01X+067913Y-033420X0423Y0374R270S2
|
3273_3V C3 -2 A01X+067913Y-033420X0423Y0374R270S2
|
||||||
327NET-(U2-IN+) U2 -1 A01X+069380Y-033159X0522Y0197R090S2
|
327NET-(U2-IN+) U2 -1 A01X+069380Y-033159X0522Y0197R090S2
|
||||||
@@ -112,133 +131,129 @@ P arrayDim N
|
|||||||
327SDA U2 -8 A01X+069380Y-034055X0522Y0197R090S2
|
327SDA U2 -8 A01X+069380Y-034055X0522Y0197R090S2
|
||||||
327-(PUMP8-PIN_1) PUMP_D-1 A01X+070472Y-033204X0384Y0551R270S2
|
327-(PUMP8-PIN_1) PUMP_D-1 A01X+070472Y-033204X0384Y0551R270S2
|
||||||
3275K_VBAT PUMP_D-2 A01X+070472Y-032466X0384Y0551R270S2
|
3275K_VBAT PUMP_D-2 A01X+070472Y-032466X0384Y0551R270S2
|
||||||
327-(PUMP1-PIN_1) PUMP_D-1 A01X+040463Y-033204X0384Y0551R270S2
|
327-(PUMP1-PIN_1) PUMP_D-1 A01X+043012Y-033169X0384Y0551R270S2
|
||||||
3275K_VBAT PUMP_D-2 A01X+040463Y-032466X0384Y0551R270S2
|
3275K_VBAT PUMP_D-2 A01X+043012Y-032431X0384Y0551R270S2
|
||||||
317GND U1 -1 D0394PA00X+076024Y-031181X0669Y0669R090S0
|
317GND U1 -1 D0394PA00X+076024Y-031181X0669Y0669R090S0
|
||||||
317GND U1 -2 D0394PA00X+076181Y-039173X0669Y0669R000S0
|
317GND U1 -2 D0394PA00X+068937Y-039173X0669Y0669R000S0
|
||||||
317GND U1 -3 D0394PA00X+037933Y-039173X0669Y0669R000S0
|
317GND U1 -3 D0394PA00X+045315Y-039173X0669Y0669R000S0
|
||||||
317GND U1 -4 D0394PA00X+037933Y-031004X0669Y0669R000S0
|
317GND U1 -4 D0394PA00X+041969Y-031004X0669Y0669R000S0
|
||||||
317SCL U1 -5 D0394PA00X+075024Y-031181X0669Y0669R090S0
|
317SCL U1 -5 D0394PA00X+075024Y-031181X0669Y0669R090S0
|
||||||
317SDA U1 -6 D0394PA00X+074024Y-031181X0669Y0669R090S0
|
317SDA U1 -6 D0394PA00X+074024Y-031181X0669Y0669R090S0
|
||||||
3173_3V U1 -7 D0394PA00X+073024Y-031181X0669Y0669R090S0
|
3173_3V U1 -7 D0394PA00X+073024Y-031181X0669Y0669R090S0
|
||||||
317VBAT U1 -8 D0394PA00X+072024Y-031181X0669Y0669R090S0
|
317VBAT U1 -8 D0394PA00X+072024Y-031181X0669Y0669R090S0
|
||||||
3273-~{INT}-PAD1) U3 -1 A01X+072726Y-036260X0689Y0177R270S2
|
3273-~{INT}-PAD1) U3 -1 A01X+072726Y-035197X0689Y0177R270S2
|
||||||
327GND U3 -2 A01X+072982Y-036260X0689Y0177R270S2
|
327GND U3 -2 A01X+072982Y-035197X0689Y0177R270S2
|
||||||
327GND U3 -3 A01X+073238Y-036260X0689Y0177R270S2
|
327GND U3 -3 A01X+073238Y-035197X0689Y0177R270S2
|
||||||
327PUMP1 U3 -4 A01X+073494Y-036260X0689Y0177R270S2
|
327PUMP1 U3 -4 A01X+073494Y-035197X0689Y0177R270S2
|
||||||
327PUMP2 U3 -5 A01X+073750Y-036260X0689Y0177R270S2
|
327PUMP2 U3 -5 A01X+073750Y-035197X0689Y0177R270S2
|
||||||
327PUMP3 U3 -6 A01X+074006Y-036260X0689Y0177R270S2
|
327PUMP3 U3 -6 A01X+074006Y-035197X0689Y0177R270S2
|
||||||
327PUMP4 U3 -7 A01X+074262Y-036260X0689Y0177R270S2
|
327PUMP4 U3 -7 A01X+074262Y-035197X0689Y0177R270S2
|
||||||
327PUMP5 U3 -8 A01X+074518Y-036260X0689Y0177R270S2
|
327PUMP5 U3 -8 A01X+074518Y-035197X0689Y0177R270S2
|
||||||
327PUMP6 U3 -9 A01X+074774Y-036260X0689Y0177R270S2
|
327PUMP6 U3 -9 A01X+074774Y-035197X0689Y0177R270S2
|
||||||
327PUMP7 U3 -10 A01X+075030Y-036260X0689Y0177R270S2
|
327PUMP7 U3 -10 A01X+075030Y-035197X0689Y0177R270S2
|
||||||
327PUMP8 U3 -11 A01X+075285Y-036260X0689Y0177R270S2
|
327PUMP8 U3 -11 A01X+075285Y-035197X0689Y0177R270S2
|
||||||
327GND U3 -12 A01X+075541Y-036260X0689Y0177R270S2
|
327GND U3 -12 A01X+075541Y-035197X0689Y0177R270S2
|
||||||
327T-(P_FAULT1-A) U3 -13 A01X+075541Y-033425X0689Y0177R270S2
|
327T-(P_FAULT1-A) U3 -13 A01X+075541Y-032362X0689Y0177R270S2
|
||||||
327T-(P_FAULT2-A) U3 -14 A01X+075285Y-033425X0689Y0177R270S2
|
327T-(P_FAULT2-A) U3 -14 A01X+075285Y-032362X0689Y0177R270S2
|
||||||
327T-(P_FAULT3-A) U3 -15 A01X+075030Y-033425X0689Y0177R270S2
|
327T-(P_FAULT3-A) U3 -15 A01X+075030Y-032362X0689Y0177R270S2
|
||||||
327T-(P_FAULT4-A) U3 -16 A01X+074774Y-033425X0689Y0177R270S2
|
327T-(P_FAULT4-A) U3 -16 A01X+074774Y-032362X0689Y0177R270S2
|
||||||
327T-(P_FAULT5-A) U3 -17 A01X+074518Y-033425X0689Y0177R270S2
|
327T-(P_FAULT5-A) U3 -17 A01X+074518Y-032362X0689Y0177R270S2
|
||||||
327T-(P_FAULT6-A) U3 -18 A01X+074262Y-033425X0689Y0177R270S2
|
327T-(P_FAULT6-A) U3 -18 A01X+074262Y-032362X0689Y0177R270S2
|
||||||
327T-(P_FAULT7-A) U3 -19 A01X+074006Y-033425X0689Y0177R270S2
|
327T-(P_FAULT7-A) U3 -19 A01X+074006Y-032362X0689Y0177R270S2
|
||||||
327T-(P_FAULT8-A) U3 -20 A01X+073750Y-033425X0689Y0177R270S2
|
327T-(P_FAULT8-A) U3 -20 A01X+073750Y-032362X0689Y0177R270S2
|
||||||
327GND U3 -21 A01X+073494Y-033425X0689Y0177R270S2
|
327GND U3 -21 A01X+073494Y-032362X0689Y0177R270S2
|
||||||
327SCL U3 -22 A01X+073238Y-033425X0689Y0177R270S2
|
327SCL U3 -22 A01X+073238Y-032362X0689Y0177R270S2
|
||||||
327SDA U3 -23 A01X+072982Y-033425X0689Y0177R270S2
|
327SDA U3 -23 A01X+072982Y-032362X0689Y0177R270S2
|
||||||
3273_3V U3 -24 A01X+072726Y-033425X0689Y0177R270S2
|
3273_3V U3 -24 A01X+072726Y-032362X0689Y0177R270S2
|
||||||
327VBAT R1 -1 A01X+070073Y-031148X0902Y0799R180S2
|
317-(PUMP5-PIN_1) PUMP5 -1 D0394PA00X+058661Y-037382X0669Y0787R000S0
|
||||||
327NET-(R1-PAD2) R1 -2 A01X+070248Y-031898X0551Y0299R180S2
|
317VCC PUMP5 -2 D0394PA00X+059646Y-037382X0669Y0787R000S0
|
||||||
327NET-(R1-PAD3) R1 -3 A01X+067547Y-031898X0551Y0299R180S2
|
327-(PUMP3-PIN_1) PUMP_D-1 A01X+050689Y-033164X0384Y0551R270S2
|
||||||
327VCC R1 -4 A01X+067722Y-031148X0902Y0799R180S2
|
3275K_VBAT PUMP_D-2 A01X+050689Y-032426X0384Y0551R270S2
|
||||||
317-(PUMP5-PIN_1) PUMP5 -1 D0394PA00X+056526Y-037382X0669Y0787R000S0
|
327PUMP7 R20 -1 A01X+067254Y-033957X0315Y0374R180S2
|
||||||
317VCC PUMP5 -2 D0394PA00X+057510Y-037382X0669Y0787R000S0
|
327NET-(Q7-G) R20 -2 A01X+066604Y-033957X0315Y0374R180S2
|
||||||
327-(PUMP3-PIN_1) PUMP_D-1 A01X+048819Y-033164X0384Y0551R270S2
|
|
||||||
3275K_VBAT PUMP_D-2 A01X+048819Y-032426X0384Y0551R270S2
|
|
||||||
327PUMP7 R20 -1 A01X+067638Y-037175X0315Y0374R270S2
|
|
||||||
327NET-(Q7-G) R20 -2 A01X+067638Y-036526X0315Y0374R270S2
|
|
||||||
327T-(P_FAULT1-K) P_FAUL-1 A01X+067141Y-033204X0384Y0551R270S2
|
327T-(P_FAULT1-K) P_FAUL-1 A01X+067141Y-033204X0384Y0551R270S2
|
||||||
327T-(P_FAULT7-A) P_FAUL-2 A01X+067141Y-032466X0384Y0551R270S2
|
327T-(P_FAULT7-A) P_FAUL-2 A01X+067141Y-032466X0384Y0551R270S2
|
||||||
317-(PUMP6-PIN_1) PUMP6 -1 D0394PA00X+060842Y-037382X0669Y0787R000S0
|
317-(PUMP6-PIN_1) PUMP6 -1 D0394PA00X+062598Y-037382X0669Y0787R000S0
|
||||||
317VCC PUMP6 -2 D0394PA00X+061826Y-037382X0669Y0787R000S0
|
317VCC PUMP6 -2 D0394PA00X+063583Y-037382X0669Y0787R000S0
|
||||||
327VCC C2 -1 A01X+055709Y-033858X0463Y0571R000S2
|
327VCC C2 -1 A01X+065251Y-033071X0463Y0571R180S2
|
||||||
327GND C2 -2 A01X+056526Y-033858X0463Y0571R000S2
|
327GND C2 -2 A01X+064434Y-033071X0463Y0571R180S2
|
||||||
327NET-(R1-PAD2) R3 -1 A01X+069783Y-032480X0315Y0374R180S2
|
327VBAT R3 -1 A01X+069783Y-032480X0315Y0374R180S2
|
||||||
327NET-(U2-IN+) R3 -2 A01X+069134Y-032480X0315Y0374R180S2
|
327NET-(U2-IN+) R3 -2 A01X+069134Y-032480X0315Y0374R180S2
|
||||||
327NET-(U2-IN-) R2 -1 A01X+068533Y-032480X0315Y0374R180S2
|
327NET-(U2-IN-) R2 -1 A01X+068533Y-032480X0315Y0374R180S2
|
||||||
327NET-(R1-PAD3) R2 -2 A01X+067884Y-032480X0315Y0374R180S2
|
327VCC R2 -2 A01X+067884Y-032480X0315Y0374R180S2
|
||||||
327-(PUMP7-PIN_1) PUMP_D-1 A01X+066156Y-033204X0384Y0551R270S2
|
327-(PUMP7-PIN_1) PUMP_D-1 A01X+066156Y-033204X0384Y0551R270S2
|
||||||
3275K_VBAT PUMP_D-2 A01X+066156Y-032466X0384Y0551R270S2
|
3275K_VBAT PUMP_D-2 A01X+066156Y-032466X0384Y0551R270S2
|
||||||
327NET-(Q2-G) Q2 -1 A01X+045354Y-036024X0354Y0315R180S2
|
327NET-(Q2-G) Q2 -1 A01X+048720Y-035984X0354Y0315R180S2
|
||||||
327GND Q2 -2 A01X+045354Y-035276X0354Y0315R180S2
|
327GND Q2 -2 A01X+048720Y-035236X0354Y0315R180S2
|
||||||
327-(PUMP2-PIN_1) Q2 -3 A01X+044567Y-035650X0354Y0315R180S2
|
327-(PUMP2-PIN_1) Q2 -3 A01X+047933Y-035610X0354Y0315R180S2
|
||||||
327T-(P_FAULT1-K) P_FAUL-1 A01X+045645Y-033204X0384Y0551R270S2
|
327T-(P_FAULT1-K) P_FAUL-1 A01X+047933Y-033145X0384Y0551R270S2
|
||||||
327T-(P_FAULT2-A) P_FAUL-2 A01X+045645Y-032466X0384Y0551R270S2
|
327T-(P_FAULT2-A) P_FAUL-2 A01X+047933Y-032406X0384Y0551R270S2
|
||||||
327GND D3 -1 A01X+047062Y-035236X0581Y0236R000S2
|
327GND D3 -1 A01X+050000Y-035236X0581Y0236R000S2
|
||||||
327VCC D3 -2 A01X+047062Y-035984X0581Y0236R000S2
|
327VCC D3 -2 A01X+050000Y-035984X0581Y0236R000S2
|
||||||
327-(PUMP3-PIN_1) D3 -3 A01X+047800Y-035610X0581Y0236R000S2
|
327-(PUMP3-PIN_1) D3 -3 A01X+050738Y-035610X0581Y0236R000S2
|
||||||
327GND D6 -1 A01X+060054Y-035217X0581Y0236R000S2
|
327GND D6 -1 A01X+061811Y-035217X0581Y0236R000S2
|
||||||
327VCC D6 -2 A01X+060054Y-035965X0581Y0236R000S2
|
327VCC D6 -2 A01X+061811Y-035965X0581Y0236R000S2
|
||||||
327-(PUMP6-PIN_1) D6 -3 A01X+060792Y-035591X0581Y0236R000S2
|
327-(PUMP6-PIN_1) D6 -3 A01X+062549Y-035591X0581Y0236R000S2
|
||||||
327T-(P_FAULT1-K) P_FAUL-1 A01X+049764Y-033164X0384Y0551R270S2
|
327T-(P_FAULT1-K) P_FAUL-1 A01X+051673Y-033164X0384Y0551R270S2
|
||||||
327T-(P_FAULT3-A) P_FAUL-2 A01X+049764Y-032426X0384Y0551R270S2
|
327T-(P_FAULT3-A) P_FAUL-2 A01X+051673Y-032426X0384Y0551R270S2
|
||||||
327T-(P_FAULT1-K) P_FAUL-1 A01X+062795Y-033164X0384Y0551R270S2
|
327T-(P_FAULT1-K) P_FAUL-1 A01X+063583Y-033164X0384Y0551R270S2
|
||||||
327T-(P_FAULT6-A) P_FAUL-2 A01X+062795Y-032426X0384Y0551R270S2
|
327T-(P_FAULT6-A) P_FAUL-2 A01X+063583Y-032426X0384Y0551R270S2
|
||||||
317-(PUMP3-PIN_1) PUMP3 -1 D0394PA00X+047849Y-037382X0669Y0787R000S0
|
317-(PUMP3-PIN_1) PUMP3 -1 D0394PA00X+050787Y-037382X0669Y0787R000S0
|
||||||
317VCC PUMP3 -2 D0394PA00X+048834Y-037382X0669Y0787R000S0
|
317VCC PUMP3 -2 D0394PA00X+051772Y-037382X0669Y0787R000S0
|
||||||
327GND C1 -1 A01X+072200Y-032382X0423Y0374R000S2
|
327GND C1 -1 A01X+071255Y-033937X0423Y0374R000S2
|
||||||
3273_3V C1 -2 A01X+072879Y-032382X0423Y0374R000S2
|
3273_3V C1 -2 A01X+071934Y-033937X0423Y0374R000S2
|
||||||
327NET-(Q8-G) R13 -1 A01X+070994Y-033937X0315Y0374R180S2
|
327NET-(Q8-G) R13 -1 A01X+069951Y-033937X0315Y0374R000S2
|
||||||
327GND R13 -2 A01X+070344Y-033937X0315Y0374R180S2
|
327GND R13 -2 A01X+070600Y-033937X0315Y0374R000S2
|
||||||
327GND D2 -1 A01X+042913Y-035256X0581Y0236R000S2
|
327GND D2 -1 A01X+046088Y-035256X0581Y0236R000S2
|
||||||
327VCC D2 -2 A01X+042913Y-036004X0581Y0236R000S2
|
327VCC D2 -2 A01X+046088Y-036004X0581Y0236R000S2
|
||||||
327-(PUMP2-PIN_1) D2 -3 A01X+043652Y-035630X0581Y0236R000S2
|
327-(PUMP2-PIN_1) D2 -3 A01X+046826Y-035630X0581Y0236R000S2
|
||||||
327VCC R5 -1 A01X+038189Y-033120X0315Y0374R270S2
|
327VCC R5 -1 A01X+065089Y-032283X0315Y0374R180S2
|
||||||
3275K_VBAT R5 -2 A01X+038189Y-032470X0315Y0374R270S2
|
3275K_VBAT R5 -2 A01X+064439Y-032283X0315Y0374R180S2
|
||||||
327GND D5 -1 A01X+055738Y-035236X0581Y0236R000S2
|
327GND D5 -1 A01X+057884Y-035236X0581Y0236R000S2
|
||||||
327VCC D5 -2 A01X+055738Y-035984X0581Y0236R000S2
|
327VCC D5 -2 A01X+057884Y-035984X0581Y0236R000S2
|
||||||
327-(PUMP5-PIN_1) D5 -3 A01X+056476Y-035610X0581Y0236R000S2
|
327-(PUMP5-PIN_1) D5 -3 A01X+058622Y-035610X0581Y0236R000S2
|
||||||
327PUMP4 R17 -1 A01X+054646Y-036073X0315Y0374R270S2
|
327PUMP4 R17 -1 A01X+056230Y-033858X0315Y0374R180S2
|
||||||
327NET-(Q4-G) R17 -2 A01X+054646Y-035423X0315Y0374R270S2
|
327NET-(Q4-G) R17 -2 A01X+055581Y-033858X0315Y0374R180S2
|
||||||
317-(PUMP2-PIN_1) PUMP2 -1 D0394PA00X+043676Y-037382X0669Y0787R000S0
|
317-(PUMP2-PIN_1) PUMP2 -1 D0394PA00X+046850Y-037382X0669Y0787R000S0
|
||||||
317VCC PUMP2 -2 D0394PA00X+044660Y-037382X0669Y0787R000S0
|
317VCC PUMP2 -2 D0394PA00X+047835Y-037382X0669Y0787R000S0
|
||||||
327T-(P_FAULT1-K) P_FAUL-1 A01X+041447Y-033204X0384Y0551R270S2
|
327T-(P_FAULT1-K) P_FAUL-1 A01X+043996Y-033145X0384Y0551R270S2
|
||||||
327T-(P_FAULT1-A) P_FAUL-2 A01X+041447Y-032466X0384Y0551R270S2
|
327T-(P_FAULT1-A) P_FAUL-2 A01X+043996Y-032406X0384Y0551R270S2
|
||||||
327PUMP5 R18 -1 A01X+058976Y-036073X0315Y0374R270S2
|
327PUMP5 R18 -1 A01X+060167Y-033858X0315Y0374R180S2
|
||||||
327NET-(Q5-G) R18 -2 A01X+058976Y-035423X0315Y0374R270S2
|
327NET-(Q5-G) R18 -2 A01X+059518Y-033858X0315Y0374R180S2
|
||||||
327GND D1 -1 A01X+038691Y-035256X0581Y0236R000S2
|
327GND D1 -1 A01X+042077Y-035256X0581Y0236R000S2
|
||||||
327VCC D1 -2 A01X+038691Y-036004X0581Y0236R000S2
|
327VCC D1 -2 A01X+042077Y-036004X0581Y0236R000S2
|
||||||
327-(PUMP1-PIN_1) D1 -3 A01X+039429Y-035630X0581Y0236R000S2
|
327-(PUMP1-PIN_1) D1 -3 A01X+042815Y-035630X0581Y0236R000S2
|
||||||
327-(PUMP4-PIN_1) PUMP_D-1 A01X+053189Y-033164X0384Y0551R270S2
|
327-(PUMP4-PIN_1) PUMP_D-1 A01X+054724Y-033164X0384Y0551R270S2
|
||||||
3275K_VBAT PUMP_D-2 A01X+053189Y-032426X0384Y0551R270S2
|
3275K_VBAT PUMP_D-2 A01X+054724Y-032426X0384Y0551R270S2
|
||||||
327NET-(Q8-G) Q8 -1 A01X+071275Y-035965X0354Y0315R180S2
|
327NET-(Q8-G) Q8 -1 A01X+071949Y-035965X0354Y0315R180S2
|
||||||
327GND Q8 -2 A01X+071275Y-035217X0354Y0315R180S2
|
327GND Q8 -2 A01X+071949Y-035217X0354Y0315R180S2
|
||||||
327-(PUMP8-PIN_1) Q8 -3 A01X+070487Y-035591X0354Y0315R180S2
|
327-(PUMP8-PIN_1) Q8 -3 A01X+071161Y-035591X0354Y0315R180S2
|
||||||
327GND D4 -1 A01X+051407Y-035236X0581Y0236R000S2
|
327GND D4 -1 A01X+053962Y-035236X0581Y0236R000S2
|
||||||
327VCC D4 -2 A01X+051407Y-035984X0581Y0236R000S2
|
327VCC D4 -2 A01X+053962Y-035984X0581Y0236R000S2
|
||||||
327-(PUMP4-PIN_1) D4 -3 A01X+052146Y-035610X0581Y0236R000S2
|
327-(PUMP4-PIN_1) D4 -3 A01X+054700Y-035610X0581Y0236R000S2
|
||||||
317-(PUMP1-PIN_1) PUMP1 -1 D0394PA00X+039478Y-037402X0669Y0787R000S0
|
317-(PUMP1-PIN_1) PUMP1 -1 D0394PA00X+042913Y-037402X0669Y0787R000S0
|
||||||
317VCC PUMP1 -2 D0394PA00X+040463Y-037402X0669Y0787R000S0
|
317VCC PUMP1 -2 D0394PA00X+043898Y-037402X0669Y0787R000S0
|
||||||
327T-(P_FAULT1-K) P_FAUL-1 A01X+071417Y-033204X0384Y0551R270S2
|
327T-(P_FAULT1-K) P_FAUL-1 A01X+071417Y-033204X0384Y0551R270S2
|
||||||
327T-(P_FAULT8-A) P_FAUL-2 A01X+071417Y-032466X0384Y0551R270S2
|
327T-(P_FAULT8-A) P_FAUL-2 A01X+071417Y-032466X0384Y0551R270S2
|
||||||
327GND R4 -1 A01X+042884Y-032677X0315Y0374R180S2
|
327GND R4 -1 A01X+046260Y-034478X0315Y0374R270S2
|
||||||
327T-(P_FAULT1-K) R4 -2 A01X+042234Y-032677X0315Y0374R180S2
|
327T-(P_FAULT1-K) R4 -2 A01X+046260Y-033829X0315Y0374R270S2
|
||||||
327PUMP2 R15 -1 A01X+046063Y-036112X0315Y0374R270S2
|
327PUMP2 R15 -1 A01X+048455Y-033858X0315Y0374R180S2
|
||||||
327NET-(Q2-G) R15 -2 A01X+046063Y-035463X0315Y0374R270S2
|
327NET-(Q2-G) R15 -2 A01X+047805Y-033858X0315Y0374R180S2
|
||||||
317-(PUMP4-PIN_1) PUMP4 -1 D0394PA00X+052195Y-037382X0669Y0787R000S0
|
317-(PUMP4-PIN_1) PUMP4 -1 D0394PA00X+054724Y-037382X0669Y0787R000S0
|
||||||
317VCC PUMP4 -2 D0394PA00X+053179Y-037382X0669Y0787R000S0
|
317VCC PUMP4 -2 D0394PA00X+055709Y-037382X0669Y0787R000S0
|
||||||
327NET-(Q3-G) R8 -1 A01X+049350Y-033858X0315Y0374R180S2
|
327NET-(Q3-G) R8 -1 A01X+050689Y-033858X0315Y0374R090S2
|
||||||
327GND R8 -2 A01X+048701Y-033858X0315Y0374R180S2
|
327GND R8 -2 A01X+050689Y-034508X0315Y0374R090S2
|
||||||
327NET-(Q1-G) R6 -1 A01X+040955Y-033858X0315Y0374R180S2
|
327NET-(Q1-G) R6 -1 A01X+043012Y-033829X0315Y0374R090S2
|
||||||
327GND R6 -2 A01X+040305Y-033858X0315Y0374R180S2
|
327GND R6 -2 A01X+043012Y-034478X0315Y0374R090S2
|
||||||
327NET-(Q7-G) Q7 -1 A01X+066944Y-035984X0354Y0315R180S2
|
327NET-(Q7-G) Q7 -1 A01X+068406Y-035984X0354Y0315R180S2
|
||||||
327GND Q7 -2 A01X+066944Y-035236X0354Y0315R180S2
|
327GND Q7 -2 A01X+068406Y-035236X0354Y0315R180S2
|
||||||
327-(PUMP7-PIN_1) Q7 -3 A01X+066156Y-035610X0354Y0315R180S2
|
327-(PUMP7-PIN_1) Q7 -3 A01X+067618Y-035610X0354Y0315R180S2
|
||||||
327GND D7 -1 A01X+064385Y-035236X0581Y0236R000S2
|
327GND D7 -1 A01X+065797Y-035236X0581Y0236R000S2
|
||||||
327VCC D7 -2 A01X+064385Y-035984X0581Y0236R000S2
|
327VCC D7 -2 A01X+065797Y-035984X0581Y0236R000S2
|
||||||
327-(PUMP7-PIN_1) D7 -3 A01X+065123Y-035610X0581Y0236R000S2
|
327-(PUMP7-PIN_1) D7 -3 A01X+066535Y-035610X0581Y0236R000S2
|
||||||
327GND D8 -1 A01X+068716Y-035236X0581Y0236R000S2
|
327GND D8 -1 A01X+069636Y-035236X0581Y0236R000S2
|
||||||
327VCC D8 -2 A01X+068716Y-035984X0581Y0236R000S2
|
327VCC D8 -2 A01X+069636Y-035984X0581Y0236R000S2
|
||||||
327-(PUMP8-PIN_1) D8 -3 A01X+069454Y-035610X0581Y0236R000S2
|
327-(PUMP8-PIN_1) D8 -3 A01X+070374Y-035610X0581Y0236R000S2
|
||||||
327NET-(Q4-G) R9 -1 A01X+053711Y-033898X0315Y0374R180S2
|
327NET-(Q4-G) R9 -1 A01X+054724Y-033829X0315Y0374R090S2
|
||||||
327GND R9 -2 A01X+053061Y-033898X0315Y0374R180S2
|
327GND R9 -2 A01X+054724Y-034478X0315Y0374R090S2
|
||||||
999
|
999
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -58,20 +58,7 @@
|
|||||||
"width": 0.0
|
"width": 0.0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"drc_exclusions": [
|
"drc_exclusions": [],
|
||||||
[
|
|
||||||
"silk_over_copper|98836040|49235000|02eec4a9-10aa-4ffd-acfb-ce06a25de154|00000000-0000-0000-0000-000000000000",
|
|
||||||
""
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"silk_over_copper|98836040|49235000|1e5edd9f-7842-4f7f-b4f4-7be08845a9d9|00000000-0000-0000-0000-000000000000",
|
|
||||||
""
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"silk_over_copper|98836040|49235000|a2ae2bdf-d2ce-446d-9eca-7a31fd18eea4|00000000-0000-0000-0000-000000000000",
|
|
||||||
""
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"meta": {
|
"meta": {
|
||||||
"version": 2
|
"version": 2
|
||||||
},
|
},
|
||||||
@@ -148,11 +135,11 @@
|
|||||||
"min_silk_clearance": 0.0,
|
"min_silk_clearance": 0.0,
|
||||||
"min_text_height": 0.8,
|
"min_text_height": 0.8,
|
||||||
"min_text_thickness": 0.08,
|
"min_text_thickness": 0.08,
|
||||||
"min_through_hole_diameter": 0.15,
|
"min_through_hole_diameter": 0.25,
|
||||||
"min_track_width": 0.0,
|
"min_track_width": 0.0,
|
||||||
"min_via_annular_width": 0.05,
|
"min_via_annular_width": 0.05,
|
||||||
"min_via_diameter": 0.25,
|
"min_via_diameter": 0.25,
|
||||||
"solder_mask_to_copper_clearance": 0.0,
|
"solder_mask_to_copper_clearance": 0.005,
|
||||||
"use_height_for_length_calcs": true
|
"use_height_for_length_calcs": true
|
||||||
},
|
},
|
||||||
"teardrop_options": [
|
"teardrop_options": [
|
||||||
@@ -237,8 +224,8 @@
|
|||||||
"drill": 0.0
|
"drill": 0.0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"diameter": 0.25,
|
"diameter": 0.3,
|
||||||
"drill": 0.15
|
"drill": 0.25
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"zones_allow_external_fillets": false
|
"zones_allow_external_fillets": false
|
||||||
@@ -591,7 +578,7 @@
|
|||||||
"group_by": false,
|
"group_by": false,
|
||||||
"label": "LCSC_PART_NUMBER",
|
"label": "LCSC_PART_NUMBER",
|
||||||
"name": "LCSC_PART_NUMBER",
|
"name": "LCSC_PART_NUMBER",
|
||||||
"show": false
|
"show": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group_by": false,
|
"group_by": false,
|
||||||
|
|||||||
@@ -13415,7 +13415,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(fields_autoplaced yes)
|
(fields_autoplaced yes)
|
||||||
(uuid "0e6bfc7c-a8ca-4acb-86b3-da7634fcf4cd")
|
(uuid "0e6bfc7c-a8ca-4acb-86b3-da7634fcf4cd")
|
||||||
(property "Reference" "CD1"
|
(property "Reference" "CD1"
|
||||||
@@ -14637,7 +14637,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(uuid "259a9ea1-51b5-4996-afc6-3a5d2a7eae89")
|
(uuid "259a9ea1-51b5-4996-afc6-3a5d2a7eae89")
|
||||||
(property "Reference" "SD7"
|
(property "Reference" "SD7"
|
||||||
(at 380.238 167.894 0)
|
(at 380.238 167.894 0)
|
||||||
@@ -15496,7 +15496,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(uuid "38ddd4b3-ab82-4cf2-9ba9-1bbde465d66e")
|
(uuid "38ddd4b3-ab82-4cf2-9ba9-1bbde465d66e")
|
||||||
(property "Reference" "SD2"
|
(property "Reference" "SD2"
|
||||||
(at 241.808 166.624 0)
|
(at 241.808 166.624 0)
|
||||||
@@ -15907,7 +15907,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(uuid "44ad3365-09c5-4acc-a334-941b9df2f3eb")
|
(uuid "44ad3365-09c5-4acc-a334-941b9df2f3eb")
|
||||||
(property "Reference" "SD9"
|
(property "Reference" "SD9"
|
||||||
(at 241.808 241.554 0)
|
(at 241.808 241.554 0)
|
||||||
@@ -16624,7 +16624,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(uuid "559263d0-487d-489c-9d5e-c1ccbadeede2")
|
(uuid "559263d0-487d-489c-9d5e-c1ccbadeede2")
|
||||||
(property "Reference" "SD5"
|
(property "Reference" "SD5"
|
||||||
(at 446.278 167.894 0)
|
(at 446.278 167.894 0)
|
||||||
@@ -16935,7 +16935,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(fields_autoplaced yes)
|
(fields_autoplaced yes)
|
||||||
(uuid "5b64d75d-2004-49a4-b8d2-de19648ebfe7")
|
(uuid "5b64d75d-2004-49a4-b8d2-de19648ebfe7")
|
||||||
(property "Reference" "SIGNAL1"
|
(property "Reference" "SIGNAL1"
|
||||||
@@ -17250,7 +17250,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(uuid "5f9b896c-7554-4260-a44c-1ec6e751f7df")
|
(uuid "5f9b896c-7554-4260-a44c-1ec6e751f7df")
|
||||||
(property "Reference" "SD14"
|
(property "Reference" "SD14"
|
||||||
(at 380.238 242.824 0)
|
(at 380.238 242.824 0)
|
||||||
@@ -17397,7 +17397,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(uuid "63e9631d-ca47-4964-89e4-7c459387d5a9")
|
(uuid "63e9631d-ca47-4964-89e4-7c459387d5a9")
|
||||||
(property "Reference" "SD3"
|
(property "Reference" "SD3"
|
||||||
(at 311.658 169.164 0)
|
(at 311.658 169.164 0)
|
||||||
@@ -18829,7 +18829,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(uuid "8081e0c8-926f-45f6-b7a5-d43c8b9f78c7")
|
(uuid "8081e0c8-926f-45f6-b7a5-d43c8b9f78c7")
|
||||||
(property "Reference" "SD12"
|
(property "Reference" "SD12"
|
||||||
(at 311.658 242.824 0)
|
(at 311.658 242.824 0)
|
||||||
@@ -19014,7 +19014,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(uuid "8332b305-364d-4759-9189-c5914c392da8")
|
(uuid "8332b305-364d-4759-9189-c5914c392da8")
|
||||||
(property "Reference" "SD15"
|
(property "Reference" "SD15"
|
||||||
(at 413.258 242.824 0)
|
(at 413.258 242.824 0)
|
||||||
@@ -19359,7 +19359,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(uuid "866d3e46-9c45-4fae-aa67-7dab00a7b166")
|
(uuid "866d3e46-9c45-4fae-aa67-7dab00a7b166")
|
||||||
(property "Reference" "SD4"
|
(property "Reference" "SD4"
|
||||||
(at 345.948 169.164 0)
|
(at 345.948 169.164 0)
|
||||||
@@ -21582,7 +21582,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(uuid "af84268b-3582-43cd-bb08-e521691e5e49")
|
(uuid "af84268b-3582-43cd-bb08-e521691e5e49")
|
||||||
(property "Reference" "SD6"
|
(property "Reference" "SD6"
|
||||||
(at 413.258 167.894 0)
|
(at 413.258 167.894 0)
|
||||||
@@ -21981,7 +21981,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(uuid "bf083f22-5823-4c87-a76d-aef17403b41a")
|
(uuid "bf083f22-5823-4c87-a76d-aef17403b41a")
|
||||||
(property "Reference" "SD10"
|
(property "Reference" "SD10"
|
||||||
(at 277.368 242.824 0)
|
(at 277.368 242.824 0)
|
||||||
@@ -22057,7 +22057,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(uuid "bf9a07a3-eb45-49b1-917e-8007235fdd95")
|
(uuid "bf9a07a3-eb45-49b1-917e-8007235fdd95")
|
||||||
(property "Reference" "SD1"
|
(property "Reference" "SD1"
|
||||||
(at 277.368 167.894 0)
|
(at 277.368 167.894 0)
|
||||||
@@ -23105,7 +23105,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(uuid "ddf1113a-50c6-4b9f-a704-a95f99ded398")
|
(uuid "ddf1113a-50c6-4b9f-a704-a95f99ded398")
|
||||||
(property "Reference" "SD13"
|
(property "Reference" "SD13"
|
||||||
(at 446.278 242.824 0)
|
(at 446.278 242.824 0)
|
||||||
@@ -23773,7 +23773,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(uuid "edc15427-b163-4349-be98-b42b20a3f5b7")
|
(uuid "edc15427-b163-4349-be98-b42b20a3f5b7")
|
||||||
(property "Reference" "SD8"
|
(property "Reference" "SD8"
|
||||||
(at 480.568 167.894 0)
|
(at 480.568 167.894 0)
|
||||||
@@ -24088,7 +24088,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(uuid "f425808c-0508-41b4-a31f-7be79ef999cd")
|
(uuid "f425808c-0508-41b4-a31f-7be79ef999cd")
|
||||||
(property "Reference" "SD11"
|
(property "Reference" "SD11"
|
||||||
(at 345.948 242.824 0)
|
(at 345.948 242.824 0)
|
||||||
@@ -24522,7 +24522,7 @@
|
|||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
(on_board yes)
|
(on_board yes)
|
||||||
(dnp yes)
|
(dnp no)
|
||||||
(uuid "fb1f82f5-b488-4bfc-8aff-38fede4a4c6e")
|
(uuid "fb1f82f5-b488-4bfc-8aff-38fede4a4c6e")
|
||||||
(property "Reference" "SD16"
|
(property "Reference" "SD16"
|
||||||
(at 480.568 242.824 0)
|
(at 480.568 242.824 0)
|
||||||
|
|||||||
208
board/modules/Sensors_can/Sensors/Sensor.pretty/Sensor.kicad_mod
Normal file
208
board/modules/Sensors_can/Sensors/Sensor.pretty/Sensor.kicad_mod
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
(footprint "Sensor"
|
||||||
|
(version 20241229)
|
||||||
|
(generator "pcbnew")
|
||||||
|
(generator_version "9.0")
|
||||||
|
(layer "F.Cu")
|
||||||
|
(property "Reference" "REF**"
|
||||||
|
(at 0 -0.5 0)
|
||||||
|
(unlocked yes)
|
||||||
|
(layer "F.SilkS")
|
||||||
|
(uuid "f71e9c26-7923-4e5c-828e-153927862740")
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1 1)
|
||||||
|
(thickness 0.1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Value" "Sensor"
|
||||||
|
(at 0 1 0)
|
||||||
|
(unlocked yes)
|
||||||
|
(layer "F.Fab")
|
||||||
|
(uuid "d40c7203-0c06-49e1-8672-dbd216694fc8")
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1 1)
|
||||||
|
(thickness 0.15)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Datasheet" ""
|
||||||
|
(at 0 0 0)
|
||||||
|
(unlocked yes)
|
||||||
|
(layer "F.Fab")
|
||||||
|
(hide yes)
|
||||||
|
(uuid "6720cb18-0687-4d55-a6ad-3ccf0819eac2")
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1 1)
|
||||||
|
(thickness 0.15)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Description" ""
|
||||||
|
(at 0 0 0)
|
||||||
|
(unlocked yes)
|
||||||
|
(layer "F.Fab")
|
||||||
|
(hide yes)
|
||||||
|
(uuid "43905e6e-773d-4d5e-8d72-57c092c3495a")
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1 1)
|
||||||
|
(thickness 0.15)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(attr smd)
|
||||||
|
(fp_line
|
||||||
|
(start -45 -18)
|
||||||
|
(end 41 -18)
|
||||||
|
(stroke
|
||||||
|
(width 0.1)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(layer "F.SilkS")
|
||||||
|
(uuid "e63ec799-95c4-407e-acc9-9c7e6d3e330c")
|
||||||
|
)
|
||||||
|
(fp_line
|
||||||
|
(start -45 24)
|
||||||
|
(end -45 -18)
|
||||||
|
(stroke
|
||||||
|
(width 0.1)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(layer "F.SilkS")
|
||||||
|
(uuid "a66c286b-432b-493d-9619-2dd4fbfdb21c")
|
||||||
|
)
|
||||||
|
(fp_line
|
||||||
|
(start -44 24)
|
||||||
|
(end -45 24)
|
||||||
|
(stroke
|
||||||
|
(width 0.1)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(layer "F.SilkS")
|
||||||
|
(uuid "71526e68-71d4-4b13-ab74-482657a06849")
|
||||||
|
)
|
||||||
|
(fp_line
|
||||||
|
(start 41 -18)
|
||||||
|
(end 41 24)
|
||||||
|
(stroke
|
||||||
|
(width 0.1)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(layer "F.SilkS")
|
||||||
|
(uuid "55554342-bbff-4d1b-b931-67fb7eaa5895")
|
||||||
|
)
|
||||||
|
(fp_line
|
||||||
|
(start 41 24)
|
||||||
|
(end -44 24)
|
||||||
|
(stroke
|
||||||
|
(width 0.1)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(layer "F.SilkS")
|
||||||
|
(uuid "2dc0ee59-36f6-407e-821a-c6acfe3ea887")
|
||||||
|
)
|
||||||
|
(fp_text user "${REFERENCE}"
|
||||||
|
(at 0 2.5 0)
|
||||||
|
(unlocked yes)
|
||||||
|
(layer "F.Fab")
|
||||||
|
(uuid "befc0725-b201-4f81-b0dc-b327becad9ba")
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1 1)
|
||||||
|
(thickness 0.15)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(pad "1" thru_hole rect
|
||||||
|
(at -42.4 -15.3)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "5538ac99-6e48-4111-a3df-8ff33be72ff3")
|
||||||
|
)
|
||||||
|
(pad "2" thru_hole circle
|
||||||
|
(at -42.4 -12.76)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "0c1d4a6c-7871-46ae-a262-a8223571975e")
|
||||||
|
)
|
||||||
|
(pad "3" thru_hole circle
|
||||||
|
(at -42.4 -10.22)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "70df4148-0415-45a2-8365-0977fcda45a1")
|
||||||
|
)
|
||||||
|
(pad "4" thru_hole circle
|
||||||
|
(at -42.4 -7.68)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "179dd332-2ab2-4917-91ec-35f232b45ce3")
|
||||||
|
)
|
||||||
|
(pad "5" thru_hole circle
|
||||||
|
(at -42.4 -5.14)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "17bc8f3a-4727-4e31-90f4-8252dff5ad1c")
|
||||||
|
)
|
||||||
|
(pad "6" thru_hole circle
|
||||||
|
(at -42.4 -2.6)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "eee06414-e977-45a8-a5e0-618644284d45")
|
||||||
|
)
|
||||||
|
(pad "7" thru_hole rect
|
||||||
|
(at -0.5 -12)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "536f0038-06c5-45e5-b1c8-898a364f6ec4")
|
||||||
|
)
|
||||||
|
(pad "8" thru_hole rect
|
||||||
|
(at 39.5 -16)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "3e0cdbaa-8219-48c4-bb0a-fd4f0e78a390")
|
||||||
|
)
|
||||||
|
(pad "9" thru_hole rect
|
||||||
|
(at 39.5 22.5)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "f01565c2-eadd-4451-9dea-2ebe28d872f0")
|
||||||
|
)
|
||||||
|
(pad "10" thru_hole rect
|
||||||
|
(at -0.5 15)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "56ec7c50-069f-4f46-9b83-ac18e4928930")
|
||||||
|
)
|
||||||
|
(pad "11" thru_hole rect
|
||||||
|
(at -43 22.5)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "f423be21-13b8-46de-8e19-e48325411a29")
|
||||||
|
)
|
||||||
|
(embedded_fonts no)
|
||||||
|
)
|
||||||
5377
board/modules/Sensors_can/Sensors/Sensors.kicad_pcb
Normal file
5377
board/modules/Sensors_can/Sensors/Sensors.kicad_pcb
Normal file
File diff suppressed because it is too large
Load Diff
136
board/modules/Sensors_can/Sensors/Sensors.kicad_prl
Normal file
136
board/modules/Sensors_can/Sensors/Sensors.kicad_prl
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
{
|
||||||
|
"board": {
|
||||||
|
"active_layer": 6,
|
||||||
|
"active_layer_preset": "All Layers",
|
||||||
|
"auto_track_width": false,
|
||||||
|
"hidden_netclasses": [],
|
||||||
|
"hidden_nets": [],
|
||||||
|
"high_contrast_mode": 0,
|
||||||
|
"net_color_mode": 1,
|
||||||
|
"opacity": {
|
||||||
|
"images": 0.6,
|
||||||
|
"pads": 1.0,
|
||||||
|
"shapes": 1.0,
|
||||||
|
"tracks": 1.0,
|
||||||
|
"vias": 1.0,
|
||||||
|
"zones": 0.6
|
||||||
|
},
|
||||||
|
"selection_filter": {
|
||||||
|
"dimensions": true,
|
||||||
|
"footprints": true,
|
||||||
|
"graphics": true,
|
||||||
|
"keepouts": true,
|
||||||
|
"lockedItems": false,
|
||||||
|
"otherItems": true,
|
||||||
|
"pads": true,
|
||||||
|
"text": true,
|
||||||
|
"tracks": true,
|
||||||
|
"vias": true,
|
||||||
|
"zones": true
|
||||||
|
},
|
||||||
|
"visible_items": [
|
||||||
|
"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",
|
||||||
|
"locked_item_shadows",
|
||||||
|
"conflict_shadows",
|
||||||
|
"shapes"
|
||||||
|
],
|
||||||
|
"visible_layers": "ffffffff_ffffffff_ffffffff_ffffffff",
|
||||||
|
"zone_display_mode": 1
|
||||||
|
},
|
||||||
|
"git": {
|
||||||
|
"repo_type": "",
|
||||||
|
"repo_username": "",
|
||||||
|
"ssh_key": ""
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"filename": "Sensors.kicad_prl",
|
||||||
|
"version": 5
|
||||||
|
},
|
||||||
|
"net_inspector_panel": {
|
||||||
|
"col_hidden": [
|
||||||
|
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
|
||||||
|
],
|
||||||
|
"col_widths": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"custom_group_rules": [],
|
||||||
|
"expanded_rows": [],
|
||||||
|
"filter_by_net_name": true,
|
||||||
|
"filter_by_netclass": true,
|
||||||
|
"filter_text": "",
|
||||||
|
"group_by_constraint": false,
|
||||||
|
"group_by_netclass": false,
|
||||||
|
"show_unconnected_nets": false,
|
||||||
|
"show_zero_pad_nets": false,
|
||||||
|
"sort_ascending": true,
|
||||||
|
"sorting_column": 0
|
||||||
|
},
|
||||||
|
"open_jobsets": [],
|
||||||
|
"project": {
|
||||||
|
"files": []
|
||||||
|
},
|
||||||
|
"schematic": {
|
||||||
|
"selection_filter": {
|
||||||
|
"graphics": true,
|
||||||
|
"images": true,
|
||||||
|
"labels": true,
|
||||||
|
"lockedItems": false,
|
||||||
|
"otherItems": true,
|
||||||
|
"pins": true,
|
||||||
|
"symbols": true,
|
||||||
|
"text": true,
|
||||||
|
"wires": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
674
board/modules/Sensors_can/Sensors/Sensors.kicad_pro
Normal file
674
board/modules/Sensors_can/Sensors/Sensors.kicad_pro
Normal file
@@ -0,0 +1,674 @@
|
|||||||
|
{
|
||||||
|
"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.8,
|
||||||
|
"height": 1.27,
|
||||||
|
"width": 2.54
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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_to_hole": "warning",
|
||||||
|
"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": "ignore",
|
||||||
|
"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": "ignore",
|
||||||
|
"silk_over_copper": "warning",
|
||||||
|
"silk_overlap": "warning",
|
||||||
|
"skew_out_of_range": "error",
|
||||||
|
"solder_mask_bridge": "error",
|
||||||
|
"starved_thermal": "warning",
|
||||||
|
"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.0,
|
||||||
|
"min_connection": 0.0,
|
||||||
|
"min_copper_edge_clearance": 0.5,
|
||||||
|
"min_groove_width": 0.0,
|
||||||
|
"min_hole_clearance": 0.15,
|
||||||
|
"min_hole_to_hole": 0.25,
|
||||||
|
"min_microvia_diameter": 0.2,
|
||||||
|
"min_microvia_drill": 0.1,
|
||||||
|
"min_resolved_spokes": 2,
|
||||||
|
"min_silk_clearance": 0.0,
|
||||||
|
"min_text_height": 0.8,
|
||||||
|
"min_text_thickness": 0.08,
|
||||||
|
"min_through_hole_diameter": 0.25,
|
||||||
|
"min_track_width": 0.0,
|
||||||
|
"min_via_annular_width": 0.05,
|
||||||
|
"min_via_diameter": 0.25,
|
||||||
|
"solder_mask_to_copper_clearance": 0.005,
|
||||||
|
"use_height_for_length_calcs": true
|
||||||
|
},
|
||||||
|
"teardrop_options": [
|
||||||
|
{
|
||||||
|
"td_onpthpad": true,
|
||||||
|
"td_onroundshapesonly": false,
|
||||||
|
"td_onsmdpad": true,
|
||||||
|
"td_ontrackend": false,
|
||||||
|
"td_onvia": 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,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"diameter": 0.3,
|
||||||
|
"drill": 0.25
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"zones_allow_external_fillets": false
|
||||||
|
},
|
||||||
|
"ipc2581": {
|
||||||
|
"dist": "",
|
||||||
|
"distpn": "",
|
||||||
|
"internal_id": "",
|
||||||
|
"mfg": "",
|
||||||
|
"mpn": ""
|
||||||
|
},
|
||||||
|
"layer_pairs": [],
|
||||||
|
"layer_presets": [],
|
||||||
|
"viewports": []
|
||||||
|
},
|
||||||
|
"boards": [],
|
||||||
|
"cvpcb": {
|
||||||
|
"equivalence_files": []
|
||||||
|
},
|
||||||
|
"erc": {
|
||||||
|
"erc_exclusions": [],
|
||||||
|
"meta": {
|
||||||
|
"version": 0
|
||||||
|
},
|
||||||
|
"pin_map": [
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"rule_severities": {
|
||||||
|
"bus_definition_conflict": "error",
|
||||||
|
"bus_entry_needed": "error",
|
||||||
|
"bus_to_bus_conflict": "error",
|
||||||
|
"bus_to_net_conflict": "error",
|
||||||
|
"different_unit_footprint": "error",
|
||||||
|
"different_unit_net": "error",
|
||||||
|
"duplicate_reference": "error",
|
||||||
|
"duplicate_sheet_names": "error",
|
||||||
|
"endpoint_off_grid": "warning",
|
||||||
|
"extra_units": "error",
|
||||||
|
"footprint_filter": "ignore",
|
||||||
|
"footprint_link_issues": "warning",
|
||||||
|
"four_way_junction": "ignore",
|
||||||
|
"global_label_dangling": "warning",
|
||||||
|
"hier_label_mismatch": "error",
|
||||||
|
"label_dangling": "error",
|
||||||
|
"label_multiple_wires": "warning",
|
||||||
|
"lib_symbol_issues": "warning",
|
||||||
|
"lib_symbol_mismatch": "warning",
|
||||||
|
"missing_bidi_pin": "warning",
|
||||||
|
"missing_input_pin": "warning",
|
||||||
|
"missing_power_pin": "error",
|
||||||
|
"missing_unit": "warning",
|
||||||
|
"multiple_net_names": "warning",
|
||||||
|
"net_not_bus_member": "warning",
|
||||||
|
"no_connect_connected": "warning",
|
||||||
|
"no_connect_dangling": "warning",
|
||||||
|
"pin_not_connected": "error",
|
||||||
|
"pin_not_driven": "error",
|
||||||
|
"pin_to_pin": "ignore",
|
||||||
|
"power_pin_not_driven": "ignore",
|
||||||
|
"same_local_global_label": "warning",
|
||||||
|
"similar_label_and_power": "warning",
|
||||||
|
"similar_labels": "warning",
|
||||||
|
"similar_power": "warning",
|
||||||
|
"simulation_model_issue": "ignore",
|
||||||
|
"single_global_label": "ignore",
|
||||||
|
"unannotated": "error",
|
||||||
|
"unconnected_wire_endpoint": "warning",
|
||||||
|
"unit_value_mismatch": "error",
|
||||||
|
"unresolved_variable": "error",
|
||||||
|
"wire_dangling": "error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libraries": {
|
||||||
|
"pinned_footprint_libs": [],
|
||||||
|
"pinned_symbol_libs": []
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"filename": "Sensors.kicad_pro",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"net_settings": {
|
||||||
|
"classes": [
|
||||||
|
{
|
||||||
|
"bus_width": 12,
|
||||||
|
"clearance": 0.15,
|
||||||
|
"diff_pair_gap": 0.25,
|
||||||
|
"diff_pair_via_gap": 0.25,
|
||||||
|
"diff_pair_width": 0.2,
|
||||||
|
"line_style": 0,
|
||||||
|
"microvia_diameter": 0.3,
|
||||||
|
"microvia_drill": 0.1,
|
||||||
|
"name": "Default",
|
||||||
|
"pcb_color": "rgba(0, 0, 0, 0.000)",
|
||||||
|
"priority": 2147483647,
|
||||||
|
"schematic_color": "rgba(0, 0, 0, 0.000)",
|
||||||
|
"track_width": 0.2,
|
||||||
|
"via_diameter": 0.6,
|
||||||
|
"via_drill": 0.3,
|
||||||
|
"wire_width": 6
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"version": 4
|
||||||
|
},
|
||||||
|
"net_colors": null,
|
||||||
|
"netclass_assignments": null,
|
||||||
|
"netclass_patterns": []
|
||||||
|
},
|
||||||
|
"pcbnew": {
|
||||||
|
"last_paths": {
|
||||||
|
"gencad": "",
|
||||||
|
"idf": "",
|
||||||
|
"netlist": "",
|
||||||
|
"plot": "",
|
||||||
|
"pos_files": "",
|
||||||
|
"specctra_dsn": "",
|
||||||
|
"step": "Sensors.step",
|
||||||
|
"svg": "",
|
||||||
|
"vrml": ""
|
||||||
|
},
|
||||||
|
"page_layout_descr_file": ""
|
||||||
|
},
|
||||||
|
"schematic": {
|
||||||
|
"annotate_start_num": 0,
|
||||||
|
"bom_export_filename": "${PROJECTNAME}.csv",
|
||||||
|
"bom_fmt_presets": [],
|
||||||
|
"bom_fmt_settings": {
|
||||||
|
"field_delimiter": ",",
|
||||||
|
"keep_line_breaks": false,
|
||||||
|
"keep_tabs": false,
|
||||||
|
"name": "CSV",
|
||||||
|
"ref_delimiter": ",",
|
||||||
|
"ref_range_delimiter": "",
|
||||||
|
"string_delimiter": "\""
|
||||||
|
},
|
||||||
|
"bom_presets": [],
|
||||||
|
"bom_settings": {
|
||||||
|
"exclude_dnp": false,
|
||||||
|
"fields_ordered": [
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Reference",
|
||||||
|
"name": "Reference",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "Value",
|
||||||
|
"name": "Value",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "Footprint",
|
||||||
|
"name": "Footprint",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Datasheet",
|
||||||
|
"name": "Datasheet",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Description",
|
||||||
|
"name": "Description",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Qty",
|
||||||
|
"name": "${QUANTITY}",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "#",
|
||||||
|
"name": "${ITEM_NUMBER}",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "LCSC_PART_NUMBER",
|
||||||
|
"name": "LCSC_PART_NUMBER",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Sim.Device",
|
||||||
|
"name": "Sim.Device",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Sim.Pins",
|
||||||
|
"name": "Sim.Pins",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Sim.Type",
|
||||||
|
"name": "Sim.Type",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "DNP",
|
||||||
|
"name": "${DNP}",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "Exclude from BOM",
|
||||||
|
"name": "${EXCLUDE_FROM_BOM}",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "Exclude from Board",
|
||||||
|
"name": "${EXCLUDE_FROM_BOARD}",
|
||||||
|
"show": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"filter_string": "",
|
||||||
|
"group_symbols": true,
|
||||||
|
"include_excluded_from_bom": true,
|
||||||
|
"name": "",
|
||||||
|
"sort_asc": true,
|
||||||
|
"sort_field": "Reference"
|
||||||
|
},
|
||||||
|
"connection_grid_size": 50.0,
|
||||||
|
"drawing": {
|
||||||
|
"dashed_lines_dash_length_ratio": 12.0,
|
||||||
|
"dashed_lines_gap_length_ratio": 3.0,
|
||||||
|
"default_line_thickness": 6.0,
|
||||||
|
"default_text_size": 50.0,
|
||||||
|
"field_names": [],
|
||||||
|
"intersheets_ref_own_page": false,
|
||||||
|
"intersheets_ref_prefix": "",
|
||||||
|
"intersheets_ref_short": false,
|
||||||
|
"intersheets_ref_show": false,
|
||||||
|
"intersheets_ref_suffix": "",
|
||||||
|
"junction_size_choice": 3,
|
||||||
|
"label_size_ratio": 0.375,
|
||||||
|
"operating_point_overlay_i_precision": 3,
|
||||||
|
"operating_point_overlay_i_range": "~A",
|
||||||
|
"operating_point_overlay_v_precision": 3,
|
||||||
|
"operating_point_overlay_v_range": "~V",
|
||||||
|
"overbar_offset_ratio": 1.23,
|
||||||
|
"pin_symbol_size": 25.0,
|
||||||
|
"text_offset_ratio": 0.15
|
||||||
|
},
|
||||||
|
"legacy_lib_dir": "",
|
||||||
|
"legacy_lib_list": [],
|
||||||
|
"meta": {
|
||||||
|
"version": 1
|
||||||
|
},
|
||||||
|
"net_format_name": "",
|
||||||
|
"page_layout_descr_file": "",
|
||||||
|
"plot_directory": "",
|
||||||
|
"space_save_all_events": true,
|
||||||
|
"spice_current_sheet_as_root": false,
|
||||||
|
"spice_external_command": "spice \"%I\"",
|
||||||
|
"spice_model_current_sheet_as_root": true,
|
||||||
|
"spice_save_all_currents": false,
|
||||||
|
"spice_save_all_dissipations": false,
|
||||||
|
"spice_save_all_voltages": false,
|
||||||
|
"subpart_first_id": 65,
|
||||||
|
"subpart_id_separator": 0
|
||||||
|
},
|
||||||
|
"sheets": [
|
||||||
|
[
|
||||||
|
"46346c04-8bed-48b4-837b-9342dd403232",
|
||||||
|
"Root"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"text_variables": {}
|
||||||
|
}
|
||||||
3405
board/modules/Sensors_can/Sensors/Sensors.kicad_sch
Normal file
3405
board/modules/Sensors_can/Sensors/Sensors.kicad_sch
Normal file
File diff suppressed because it is too large
Load Diff
35338
board/modules/Sensors_can/Sensors/Sensors.step
Normal file
35338
board/modules/Sensors_can/Sensors/Sensors.step
Normal file
File diff suppressed because it is too large
Load Diff
4
board/modules/Sensors_can/Sensors/sym-lib-table
Normal file
4
board/modules/Sensors_can/Sensors/sym-lib-table
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
(sym_lib_table
|
||||||
|
(version 7)
|
||||||
|
(lib (name "Modules")(type "KiCad")(uri "/home/empire/workspace/PlantCtrl/board/modules/Modules.kicad_sym")(options "")(descr ""))
|
||||||
|
)
|
||||||
14
board/modules/Sensors_can/ch32-sensor/.cargo/config.toml
Normal file
14
board/modules/Sensors_can/ch32-sensor/.cargo/config.toml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[build]
|
||||||
|
target = "riscv32imc-unknown-none-elf"
|
||||||
|
|
||||||
|
[target."riscv32imc-unknown-none-elf"]
|
||||||
|
rustflags = [
|
||||||
|
# "-C", "link-arg=-Tlink.x",
|
||||||
|
]
|
||||||
|
# runner = "riscv64-unknown-elf-gdb -q -x openocd.gdb"
|
||||||
|
# runner = "riscv-none-embed-gdb -q -x openocd.gdb"
|
||||||
|
# runner = "gdb -q -x openocd.gdb"
|
||||||
|
# runner = "wlink -v flash"
|
||||||
|
|
||||||
|
runner = "wlink -v flash --enable-sdi-print --watch-serial --erase"
|
||||||
|
# runner = "wlink -v flash"
|
||||||
7
board/modules/Sensors_can/ch32-sensor/.gdbinit
Normal file
7
board/modules/Sensors_can/ch32-sensor/.gdbinit
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
target extended-remote :3333
|
||||||
|
set remotetimeout 2000
|
||||||
|
|
||||||
|
#symbol-file target/riscv32imc-unknown-none-elf/release/ch32v203-examples
|
||||||
|
file target/riscv32imc-unknown-none-elf/release/bms
|
||||||
|
|
||||||
|
monitor reset halt
|
||||||
1
board/modules/Sensors_can/ch32-sensor/.gitignore
vendored
Normal file
1
board/modules/Sensors_can/ch32-sensor/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
target
|
||||||
43
board/modules/Sensors_can/ch32-sensor/Cargo.toml
Normal file
43
board/modules/Sensors_can/ch32-sensor/Cargo.toml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
[package]
|
||||||
|
name = "bms"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
ch32-hal = { git = "https://github.com/ch32-rs/ch32-hal", features = [
|
||||||
|
"ch32v203c8t6",
|
||||||
|
"memory-x",
|
||||||
|
"embassy",
|
||||||
|
"rt",
|
||||||
|
"time-driver-tim2",
|
||||||
|
], default-features = false }
|
||||||
|
|
||||||
|
embassy-executor = { version = "0.7.0", features = [
|
||||||
|
"arch-riscv32",
|
||||||
|
"executor-thread",
|
||||||
|
] }
|
||||||
|
|
||||||
|
embassy-time = { version = "0.4.0" }
|
||||||
|
embassy-usb = { version = "0.3.0" }
|
||||||
|
embassy-futures = { version = "0.1.0" }
|
||||||
|
|
||||||
|
# This is okay because we should automatically use whatever ch32-hal uses
|
||||||
|
qingke-rt = "*"
|
||||||
|
qingke = "*"
|
||||||
|
|
||||||
|
panic-halt = "1.0"
|
||||||
|
|
||||||
|
embedded-hal = "1.0.0"
|
||||||
|
heapless = "0.8.0"
|
||||||
|
micromath = { version = "2.1.0", features = ["num-traits"] }
|
||||||
|
embedded-can = "0.4.1"
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
#lto = true
|
||||||
|
opt-level = 1
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
strip = false # symbols are not flashed to the microcontroller, so don't strip them.
|
||||||
|
#lto = true
|
||||||
|
debug = true
|
||||||
|
opt-level = "z" # Optimize for size.
|
||||||
72
board/modules/Sensors_can/ch32-sensor/README.md
Normal file
72
board/modules/Sensors_can/ch32-sensor/README.md
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
|
||||||
|
# ch32v203-bms
|
||||||
|
|
||||||
|
A simple battery management controller software.
|
||||||
|
|
||||||
|
## CAN bus and hardware address
|
||||||
|
|
||||||
|
This firmware exposes a CAN interface on the CH32V203 and uses 4 hardware address pins to allow up to 16 sensors on the same bus.
|
||||||
|
|
||||||
|
- CAN pins (default mapping):
|
||||||
|
- CAN RX: PA11
|
||||||
|
- CAN TX: PA12
|
||||||
|
- Address select pins (with internal pull-ups):
|
||||||
|
- A0: PA0
|
||||||
|
- A1: PA1
|
||||||
|
- A2: PA2
|
||||||
|
- A3: PA3
|
||||||
|
|
||||||
|
Wire each address pin to GND to set its corresponding bit to 1. The 4-bit address range is 0..15. The node’s CAN Standard ID is `0x100 | addr`, i.e. 0x100..0x10F. The CAN acceptance filter is configured to only accept frames with the node’s own ID.
|
||||||
|
|
||||||
|
Adjust the pins above if your PCB routes CAN or address lines to different pads.
|
||||||
|
|
||||||
|
## 555 timer (software) emulation mode
|
||||||
|
|
||||||
|
To save the BOM cost of a classic NE555 in simple oscillator applications, this firmware implements a minimal 555-like Schmitt trigger using the MCU’s ADC and a GPIO, approximating the behavior when the capacitor is charged/discharged via Q through a resistor, and the combined Trigger/Threshold senses the capacitor node.
|
||||||
|
|
||||||
|
- Pins used:
|
||||||
|
- Q output: PB2
|
||||||
|
- Combined Trigger/Threshold (ADC input): PA0
|
||||||
|
- Wiring:
|
||||||
|
- PB2 (Q) -> series resistor R -> capacitor node
|
||||||
|
- Capacitor node -> capacitor to GND
|
||||||
|
- Capacitor node -> PA0 (ADC input)
|
||||||
|
- Behavior:
|
||||||
|
- When ADC(PA0) <= ~1/3 Vref, PB2 is driven High.
|
||||||
|
- When ADC(PA0) >= ~2/3 Vref, PB2 is driven Low.
|
||||||
|
- Hysteresis avoids chatter; the actual charge/discharge dynamics follow your chosen R and C.
|
||||||
|
- Notes:
|
||||||
|
- Use an appropriate resistor from PB2 to the capacitor to set oscillation frequency. Start with 10k..100k and adjust with C.
|
||||||
|
- Ensure PA0 is routed to the capacitor node and left high impedance (no strong pull-ups/downs) so the ADC can sense the analog voltage.
|
||||||
|
- PB2 drives the on-board LED (if present), so the LED might blink at the oscillation frequency.
|
||||||
|
|
||||||
|
This mode is implemented in `src/main.rs` using `hal::adc::Adc::convert(&mut pin, SampleTime::...)` to take periodic samples and a simple state machine to toggle the Q output based on ~1/3 and ~2/3 Vref thresholds.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
cargo build --release
|
||||||
|
```
|
||||||
|
|
||||||
|
## Flash
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
wchisp config reset
|
||||||
|
wchip wchisp flash target/riscv32imc-unknown-none-elf/release/bms
|
||||||
|
```
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
|
||||||
|
For debugging purposes a container file is provided together with wrapper scripts to start the containerized `openocd` and `riscv-gdb` transparently. The wrapper scripts assume that `podman` is setup.
|
||||||
|
|
||||||
|
Starting Debug server
|
||||||
|
|
||||||
|
```
|
||||||
|
./bin/openocd
|
||||||
|
```
|
||||||
|
|
||||||
|
Connecting with gdb for interactive debugging
|
||||||
|
|
||||||
|
```
|
||||||
|
./bin/gdb -f target/riscv32imc-unknown-none-elf/release/bms
|
||||||
|
```
|
||||||
10
board/modules/Sensors_can/ch32-sensor/bin/build-wch-tools-container.sh
Executable file
10
board/modules/Sensors_can/ch32-sensor/bin/build-wch-tools-container.sh
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CONTAINER_NAME="localhost/wch-dev-tools:latest"
|
||||||
|
CONTAINER_TOOLS_BASEDIR="$(dirname "$(readlink -f "$0")")"
|
||||||
|
|
||||||
|
pushd "$CONTAINER_TOOLS_BASEDIR"
|
||||||
|
podman build -t "$CONTAINER_NAME" -f "../wch-tools.Containerfile" .
|
||||||
|
popd
|
||||||
29
board/modules/Sensors_can/ch32-sensor/bin/gdb
Executable file
29
board/modules/Sensors_can/ch32-sensor/bin/gdb
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CONTAINER_IMAGE="localhost/wch-dev-tools:latest"
|
||||||
|
CONTAINER_TOOLS_BASEDIR="$(dirname "$(readlink -f "$0")")"
|
||||||
|
|
||||||
|
function _fatal {
|
||||||
|
echo -e "\e[31mERROR\e[0m $(</dev/stdin)$*" 1>&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
declare -a PODMAN_ARGS=(
|
||||||
|
"--rm" "-i" "--log-driver=none"
|
||||||
|
"--network=host"
|
||||||
|
"--pid=host"
|
||||||
|
"-v" "$PWD:$PWD:rw"
|
||||||
|
"-w" "$PWD"
|
||||||
|
)
|
||||||
|
|
||||||
|
[[ -t 1 ]] && PODMAN_ARGS+=("-t")
|
||||||
|
|
||||||
|
if ! podman image exists "$CONTAINER_IMAGE"; then
|
||||||
|
#attempt to build container
|
||||||
|
"$CONTAINER_TOOLS_BASEDIR/build-wch-tools-container.sh" 1>&2 ||
|
||||||
|
_fatal "faild to build local image, cannot continue! … please ensure you have an internet connection"
|
||||||
|
fi
|
||||||
|
|
||||||
|
podman run "${PODMAN_ARGS[@]}" --entrypoint riscv-none-elf-gdb-py3 "$CONTAINER_IMAGE" "$@"
|
||||||
44
board/modules/Sensors_can/ch32-sensor/bin/openocd
Executable file
44
board/modules/Sensors_can/ch32-sensor/bin/openocd
Executable file
@@ -0,0 +1,44 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CONTAINER_IMAGE="localhost/wch-dev-tools:latest"
|
||||||
|
CONTAINER_TOOLS_BASEDIR="$(dirname "$(readlink -f "$0")")"
|
||||||
|
|
||||||
|
function _fatal {
|
||||||
|
echo -e "\e[31mERROR\e[0m $(</dev/stdin)$*" 1>&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
declare -a PODMAN_ARGS=(
|
||||||
|
"--rm" "-i" "--log-driver=none"
|
||||||
|
"--network=host"
|
||||||
|
"-v" "$PWD:$PWD:rw"
|
||||||
|
"-w" "$PWD"
|
||||||
|
)
|
||||||
|
|
||||||
|
for device in /dev/bus/usb/*/*; do
|
||||||
|
if udevadm info "$device" | grep -q "ID_VENDOR=wch.cn" && \
|
||||||
|
udevadm info "$device" | grep -q "ID_MODEL=WCH-Link"; then
|
||||||
|
DEBUGGER_DEV_PATH="$device"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -z "${DEBUGGER_DEV_PATH:-}" ]]; then
|
||||||
|
echo "Could not find hardware debugger … Exiting!" 1>&2
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
# add jlink to podman device
|
||||||
|
PODMAN_ARGS+=("--device=$DEBUGGER_DEV_PATH")
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ -t 1 ]] && PODMAN_ARGS+=("-t")
|
||||||
|
|
||||||
|
if ! podman image exists "$CONTAINER_IMAGE"; then
|
||||||
|
#attempt to build container
|
||||||
|
"$CONTAINER_TOOLS_BASEDIR/build-wch-tools-container.sh" 1>&2 ||
|
||||||
|
_fatal "faild to build local image, cannot continue! … please ensure you have an internet connection"
|
||||||
|
fi
|
||||||
|
|
||||||
|
podman run "${PODMAN_ARGS[@]}" --entrypoint openocd "$CONTAINER_IMAGE" "$@"
|
||||||
11
board/modules/Sensors_can/ch32-sensor/build.rs
Normal file
11
board/modules/Sensors_can/ch32-sensor/build.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fn main() {
|
||||||
|
// println!("cargo:rustc-link-arg-bins=--nmagic");
|
||||||
|
println!("cargo:rustc-link-arg-bins=-Tlink.x");
|
||||||
|
// println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
|
||||||
|
|
||||||
|
let out_dir = std::env::var("OUT_DIR").unwrap();
|
||||||
|
let out_dir = std::path::PathBuf::from(out_dir);
|
||||||
|
std::fs::write(out_dir.join("memory.x"), include_bytes!("memory.x")).unwrap();
|
||||||
|
println!("cargo:rustc-link-search={}", out_dir.display());
|
||||||
|
println!("cargo:rerun-if-changed=memory.x");
|
||||||
|
}
|
||||||
125
board/modules/Sensors_can/ch32-sensor/memory.x
Normal file
125
board/modules/Sensors_can/ch32-sensor/memory.x
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
/* CH32V203c8t6 */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH : ORIGIN = 0x00000000, LENGTH = 64K /* BANK_1 */
|
||||||
|
RAM : ORIGIN = 0x20000000, LENGTH = 20K
|
||||||
|
}
|
||||||
|
REGION_ALIAS("REGION_TEXT", FLASH);
|
||||||
|
REGION_ALIAS("REGION_RODATA", FLASH);
|
||||||
|
REGION_ALIAS("REGION_DATA", RAM);
|
||||||
|
REGION_ALIAS("REGION_BSS", RAM);
|
||||||
|
REGION_ALIAS("REGION_HEAP", RAM);
|
||||||
|
REGION_ALIAS("REGION_STACK", RAM);
|
||||||
|
|
||||||
|
/* fault handlers */
|
||||||
|
|
||||||
|
PROVIDE(InstructionMisaligned = ExceptionHandler);
|
||||||
|
PROVIDE(InstructionFault = ExceptionHandler);
|
||||||
|
PROVIDE(IllegalInstruction = ExceptionHandler);
|
||||||
|
PROVIDE(Breakpoint = ExceptionHandler);
|
||||||
|
PROVIDE(LoadMisaligned = ExceptionHandler);
|
||||||
|
PROVIDE(LoadFault = ExceptionHandler);
|
||||||
|
PROVIDE(StoreMisaligned = ExceptionHandler);
|
||||||
|
PROVIDE(StoreFault = ExceptionHandler);;
|
||||||
|
PROVIDE(UserEnvCall = ExceptionHandler);
|
||||||
|
PROVIDE(SupervisorEnvCall = ExceptionHandler);
|
||||||
|
PROVIDE(MachineEnvCall = ExceptionHandler);
|
||||||
|
PROVIDE(InstructionPageFault = ExceptionHandler);
|
||||||
|
PROVIDE(LoadPageFault = ExceptionHandler);
|
||||||
|
PROVIDE(StorePageFault = ExceptionHandler);
|
||||||
|
|
||||||
|
/* core interrupt handlers */
|
||||||
|
|
||||||
|
PROVIDE(NonMaskableInt = DefaultHandler);
|
||||||
|
PROVIDE(Software = DefaultHandler);
|
||||||
|
|
||||||
|
/* external interrupt handlers */
|
||||||
|
|
||||||
|
PROVIDE(WWDG = DefaultHandler);
|
||||||
|
PROVIDE(PVD = DefaultHandler);
|
||||||
|
PROVIDE(TAMPER = DefaultHandler);
|
||||||
|
PROVIDE(RTC = DefaultHandler);
|
||||||
|
PROVIDE(FLASH = DefaultHandler);
|
||||||
|
PROVIDE(RCC = DefaultHandler);
|
||||||
|
PROVIDE(EXTI0 = DefaultHandler);
|
||||||
|
PROVIDE(EXTI1 = DefaultHandler);
|
||||||
|
PROVIDE(EXTI2 = DefaultHandler);
|
||||||
|
PROVIDE(EXTI3 = DefaultHandler);
|
||||||
|
PROVIDE(EXTI4 = DefaultHandler);
|
||||||
|
PROVIDE(DMA1_CHANNEL1 = DefaultHandler);
|
||||||
|
PROVIDE(DMA1_CHANNEL2 = DefaultHandler);
|
||||||
|
PROVIDE(DMA1_CHANNEL3 = DefaultHandler);
|
||||||
|
PROVIDE(DMA1_CHANNEL4 = DefaultHandler);
|
||||||
|
PROVIDE(DMA1_CHANNEL5 = DefaultHandler);
|
||||||
|
PROVIDE(DMA1_CHANNEL6 = DefaultHandler);
|
||||||
|
PROVIDE(DMA1_CHANNEL7 = DefaultHandler);
|
||||||
|
PROVIDE(ADC = DefaultHandler);
|
||||||
|
PROVIDE(USB_HP_CAN1_TX = DefaultHandler);
|
||||||
|
/*PROVIDE(USB_LP_CAN1_RX0 = DefaultHandler);*/
|
||||||
|
PROVIDE(CAN1_RX1 = DefaultHandler);
|
||||||
|
PROVIDE(CAN1_SCE = DefaultHandler);
|
||||||
|
PROVIDE(EXTI9_5 = DefaultHandler);
|
||||||
|
PROVIDE(TIM1_BRK = DefaultHandler);
|
||||||
|
PROVIDE(TIM1_UP_ = DefaultHandler);
|
||||||
|
PROVIDE(TIM1_TRG_COM = DefaultHandler);
|
||||||
|
PROVIDE(TIM1_CC = DefaultHandler);
|
||||||
|
PROVIDE(TIM2 = DefaultHandler);
|
||||||
|
PROVIDE(TIM3 = DefaultHandler);
|
||||||
|
PROVIDE(TIM4 = DefaultHandler);
|
||||||
|
PROVIDE(I2C1_EV = DefaultHandler);
|
||||||
|
PROVIDE(I2C1_ER = DefaultHandler);
|
||||||
|
PROVIDE(I2C2_EV = DefaultHandler);
|
||||||
|
PROVIDE(I2C2_ER = DefaultHandler);
|
||||||
|
PROVIDE(SPI1 = DefaultHandler);
|
||||||
|
PROVIDE(SPI2 = DefaultHandler);
|
||||||
|
PROVIDE(USART1 = DefaultHandler);
|
||||||
|
PROVIDE(USART2 = DefaultHandler);
|
||||||
|
PROVIDE(USART3 = DefaultHandler);
|
||||||
|
PROVIDE(EXTI15_10 = DefaultHandler);
|
||||||
|
PROVIDE(RTCALARM = DefaultHandler);
|
||||||
|
PROVIDE(USBWAKE_UP = DefaultHandler);
|
||||||
|
PROVIDE(TIM8_BRK = DefaultHandler);
|
||||||
|
PROVIDE(TIM8_UP_ = DefaultHandler);
|
||||||
|
PROVIDE(TIM8_TRG_COM = DefaultHandler);
|
||||||
|
PROVIDE(TIM8_CC = DefaultHandler);
|
||||||
|
PROVIDE(RNG = DefaultHandler);
|
||||||
|
PROVIDE(FSMC = DefaultHandler);
|
||||||
|
PROVIDE(SDIO = DefaultHandler);
|
||||||
|
PROVIDE(TIM5 = DefaultHandler);
|
||||||
|
PROVIDE(SPI3 = DefaultHandler);
|
||||||
|
PROVIDE(UART4 = DefaultHandler);
|
||||||
|
PROVIDE(UART5 = DefaultHandler);
|
||||||
|
PROVIDE(TIM6 = DefaultHandler);
|
||||||
|
PROVIDE(TIM7 = DefaultHandler);
|
||||||
|
PROVIDE(DMA2_CHANNEL1 = DefaultHandler);
|
||||||
|
PROVIDE(DMA2_CHANNEL2 = DefaultHandler);
|
||||||
|
PROVIDE(DMA2_CHANNEL3 = DefaultHandler);
|
||||||
|
PROVIDE(DMA2_CHANNEL4 = DefaultHandler);
|
||||||
|
PROVIDE(DMA2_CHANNEL5 = DefaultHandler);
|
||||||
|
PROVIDE(ETH = DefaultHandler);
|
||||||
|
PROVIDE(ETH_WKUP = DefaultHandler);
|
||||||
|
PROVIDE(CAN2_TX = DefaultHandler);
|
||||||
|
PROVIDE(CAN2_RX0 = DefaultHandler);
|
||||||
|
PROVIDE(CAN2_RX1 = DefaultHandler);
|
||||||
|
PROVIDE(CAN2_SCE = DefaultHandler);
|
||||||
|
PROVIDE(OTG_FS = DefaultHandler);
|
||||||
|
PROVIDE(USBHSWAKEUP = DefaultHandler);
|
||||||
|
PROVIDE(USBHS = DefaultHandler);
|
||||||
|
PROVIDE(DVP = DefaultHandler);
|
||||||
|
PROVIDE(UART6 = DefaultHandler);
|
||||||
|
PROVIDE(UART7 = DefaultHandler);
|
||||||
|
PROVIDE(UART8 = DefaultHandler);
|
||||||
|
PROVIDE(TIM9_BRK = DefaultHandler);
|
||||||
|
PROVIDE(TIM9_UP_ = DefaultHandler);
|
||||||
|
PROVIDE(TIM9_TRG_COM = DefaultHandler);
|
||||||
|
PROVIDE(TIM9_CC = DefaultHandler);
|
||||||
|
PROVIDE(TIM10_BRK = DefaultHandler);
|
||||||
|
PROVIDE(TIM10_UP_ = DefaultHandler);
|
||||||
|
PROVIDE(TIM10_TRG_COM = DefaultHandler);
|
||||||
|
PROVIDE(TIM10_CC = DefaultHandler);
|
||||||
|
PROVIDE(DMA2_CHANNEL6 = DefaultHandler);
|
||||||
|
PROVIDE(DMA2_CHANNEL7 = DefaultHandler);
|
||||||
|
PROVIDE(DMA2_CHANNEL8 = DefaultHandler);
|
||||||
|
PROVIDE(DMA2_CHANNEL9 = DefaultHandler);
|
||||||
|
PROVIDE(DMA2_CHANNEL10 = DefaultHandler);
|
||||||
|
PROVIDE(DMA2_CHANNEL11 = DefaultHandler);
|
||||||
17
board/modules/Sensors_can/ch32-sensor/openocd.cfg
Normal file
17
board/modules/Sensors_can/ch32-sensor/openocd.cfg
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
set _CHIPNAME ch32v203
|
||||||
|
set _TARGETNAME $_CHIPNAME.cpu
|
||||||
|
|
||||||
|
#bindto 0.0.0.0
|
||||||
|
|
||||||
|
adapter driver wlinke
|
||||||
|
adapter speed 6000
|
||||||
|
transport select sdi
|
||||||
|
|
||||||
|
sdi newtap $_CHIPNAME cpu -irlen 5 --expected-id 0x00001
|
||||||
|
target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME
|
||||||
|
$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1
|
||||||
|
set _FLASHNAME $_CHIPNAME.flash
|
||||||
|
|
||||||
|
flash bank $_FLASHNAME wch_rsicv 0x00000000 0 0 0 $_TARGETNAME.0
|
||||||
|
|
||||||
|
init
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
[toolchain]
|
||||||
|
channel = "nightly"
|
||||||
61
board/modules/Sensors_can/ch32-sensor/src/main.rs
Normal file
61
board/modules/Sensors_can/ch32-sensor/src/main.rs
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
#![feature(impl_trait_in_assoc_type)]
|
||||||
|
|
||||||
|
// Simple 555-like oscillator implemented in firmware.
|
||||||
|
// - Q output: PB2 (also drives the on-board LED if present)
|
||||||
|
// - Combined Trigger/Threshold analog input: PA0 (capacitor node)
|
||||||
|
// Wiring suggestion:
|
||||||
|
// Q (PB2) --[R]--+-- C -- GND
|
||||||
|
// |
|
||||||
|
// PA0 (ADC input)
|
||||||
|
// The firmware toggles Q high when PA0 <= 1/3 Vref and low when PA0 >= 2/3 Vref.
|
||||||
|
|
||||||
|
use embassy_executor::Spawner;
|
||||||
|
use embassy_time::Timer;
|
||||||
|
use hal::gpio::{Level, Output};
|
||||||
|
use {ch32_hal as hal, panic_halt as _};
|
||||||
|
|
||||||
|
use hal::adc::{Adc, SampleTime};
|
||||||
|
|
||||||
|
#[embassy_executor::main(entry = "qingke_rt::entry")]
|
||||||
|
async fn main(_spawner: Spawner) -> ! {
|
||||||
|
let p = hal::init(Default::default());
|
||||||
|
|
||||||
|
// Q output on PB2
|
||||||
|
let mut q = Output::new(p.PB2, Level::Low, Default::default());
|
||||||
|
|
||||||
|
// ADC on PA0 for combined Trigger/Threshold input
|
||||||
|
let mut adc = Adc::new(p.ADC1, Default::default());
|
||||||
|
let mut trig_thres = p.PA0; // analog-capable pin used as ADC channel
|
||||||
|
|
||||||
|
// ADC characteristics: assume 12-bit if HAL doesn't expose it.
|
||||||
|
// If the HAL provides a method to query resolution, prefer that.
|
||||||
|
let full_scale: u16 = 4095; // 12-bit default
|
||||||
|
let thr_low: u16 = (full_scale as u32 / 3) as u16; // ~1/3 Vref
|
||||||
|
let thr_high: u16 = ((full_scale as u32 * 2) / 3) as u16; // ~2/3 Vref
|
||||||
|
|
||||||
|
// Start with Q low. State variable to avoid redundant toggles.
|
||||||
|
let mut q_high = false;
|
||||||
|
q.set_low();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// Read capacitor node voltage via ADC
|
||||||
|
let sample: u16 = adc.convert(&mut trig_thres, SampleTime::CYCLES239_5);
|
||||||
|
|
||||||
|
// Implement Schmitt trigger behavior like NE555 using thresholds
|
||||||
|
if !q_high && sample <= thr_low {
|
||||||
|
// Trigger: voltage fell below 1/3 Vref -> set output high
|
||||||
|
q.set_high();
|
||||||
|
q_high = true;
|
||||||
|
} else if q_high && sample >= thr_high {
|
||||||
|
// Threshold: voltage rose above 2/3 Vref -> set output low
|
||||||
|
q.set_low();
|
||||||
|
q_high = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Small delay to reduce CPU usage; adjust for responsiveness/noise
|
||||||
|
Timer::after_micros(200).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
FROM debian:bookworm
|
||||||
|
|
||||||
|
RUN apt update -y && apt upgrade -y && apt install git libjaylink-dev libusb-1.0-0 unzip curl libhidapi-hidraw0 xz-utils -y
|
||||||
|
|
||||||
|
RUN cd /root && \
|
||||||
|
curl -L -o mrs-toolchain.tar.xz "https://github.com/ch32-riscv-ug/MounRiver_Studio_Community_miror/releases/download/1.92-toolchain/MRS_Toolchain_Linux_x64_V1.92.tar.xz" && \
|
||||||
|
mkdir mrs-toolchain && \
|
||||||
|
tar -xvf mrs-toolchain.tar.xz -C mrs-toolchain --strip-components=1 && \
|
||||||
|
mv mrs-toolchain/OpenOCD/bin/openocd /usr/local/bin && \
|
||||||
|
mv mrs-toolchain/OpenOCD/share/openocd /usr/local/share && \
|
||||||
|
# mv mrs-toolchain/RISC-V_Embedded_GCC12/bin/riscv-none-elf-gdb /usr/local/bin && \ # both toolchains in MRS are to old to work with emacs dape
|
||||||
|
# mv mrs-toolchain/RISC-V_Embedded_GCC12/libexec /usr/local && \ # both toolchains in MRS are to old to work with emacs dape
|
||||||
|
rm -rf mrs-toolchain mrs-toolchain.tar.xz && \
|
||||||
|
# Use up to date xpack toolchains for gdb
|
||||||
|
curl -L -o xpack-riscv-toolchain.tar.gz "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v14.2.0-3/xpack-riscv-none-elf-gcc-14.2.0-3-linux-x64.tar.gz" && \
|
||||||
|
mkdir xpack-toolchain && \
|
||||||
|
tar -xvf xpack-riscv-toolchain.tar.gz -C xpack-toolchain --strip-components=1 && \
|
||||||
|
mv xpack-toolchain/bin/* /usr/local/bin && \
|
||||||
|
mv xpack-toolchain/lib/ /usr/local && \
|
||||||
|
mv xpack-toolchain/lib64/ /usr/local && \
|
||||||
|
mv xpack-toolchain/libexec /usr/local && \
|
||||||
|
mv xpack-toolchain/riscv-none-elf /usr/local && \
|
||||||
|
rm -rf xpack-toolchain xpack-riscv-toolchain.tar.gz
|
||||||
|
|
||||||
|
RUN mkdir -p /root/.config/gdb && echo "set auto-load safe-path /" >> /root/.config/gdb/gdbinit
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/usr/bin/bash" ]
|
||||||
@@ -0,0 +1,208 @@
|
|||||||
|
(footprint "Sensor"
|
||||||
|
(version 20241229)
|
||||||
|
(generator "pcbnew")
|
||||||
|
(generator_version "9.0")
|
||||||
|
(layer "F.Cu")
|
||||||
|
(property "Reference" "REF**"
|
||||||
|
(at 0 -0.5 0)
|
||||||
|
(unlocked yes)
|
||||||
|
(layer "F.SilkS")
|
||||||
|
(uuid "f71e9c26-7923-4e5c-828e-153927862740")
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1 1)
|
||||||
|
(thickness 0.1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Value" "Sensor"
|
||||||
|
(at 0 1 0)
|
||||||
|
(unlocked yes)
|
||||||
|
(layer "F.Fab")
|
||||||
|
(uuid "d40c7203-0c06-49e1-8672-dbd216694fc8")
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1 1)
|
||||||
|
(thickness 0.15)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Datasheet" ""
|
||||||
|
(at 0 0 0)
|
||||||
|
(unlocked yes)
|
||||||
|
(layer "F.Fab")
|
||||||
|
(hide yes)
|
||||||
|
(uuid "6720cb18-0687-4d55-a6ad-3ccf0819eac2")
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1 1)
|
||||||
|
(thickness 0.15)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Description" ""
|
||||||
|
(at 0 0 0)
|
||||||
|
(unlocked yes)
|
||||||
|
(layer "F.Fab")
|
||||||
|
(hide yes)
|
||||||
|
(uuid "43905e6e-773d-4d5e-8d72-57c092c3495a")
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1 1)
|
||||||
|
(thickness 0.15)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(attr smd)
|
||||||
|
(fp_line
|
||||||
|
(start -45 -18)
|
||||||
|
(end 41 -18)
|
||||||
|
(stroke
|
||||||
|
(width 0.1)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(layer "F.SilkS")
|
||||||
|
(uuid "e63ec799-95c4-407e-acc9-9c7e6d3e330c")
|
||||||
|
)
|
||||||
|
(fp_line
|
||||||
|
(start -45 24)
|
||||||
|
(end -45 -18)
|
||||||
|
(stroke
|
||||||
|
(width 0.1)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(layer "F.SilkS")
|
||||||
|
(uuid "a66c286b-432b-493d-9619-2dd4fbfdb21c")
|
||||||
|
)
|
||||||
|
(fp_line
|
||||||
|
(start -44 24)
|
||||||
|
(end -45 24)
|
||||||
|
(stroke
|
||||||
|
(width 0.1)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(layer "F.SilkS")
|
||||||
|
(uuid "71526e68-71d4-4b13-ab74-482657a06849")
|
||||||
|
)
|
||||||
|
(fp_line
|
||||||
|
(start 41 -18)
|
||||||
|
(end 41 24)
|
||||||
|
(stroke
|
||||||
|
(width 0.1)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(layer "F.SilkS")
|
||||||
|
(uuid "55554342-bbff-4d1b-b931-67fb7eaa5895")
|
||||||
|
)
|
||||||
|
(fp_line
|
||||||
|
(start 41 24)
|
||||||
|
(end -44 24)
|
||||||
|
(stroke
|
||||||
|
(width 0.1)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(layer "F.SilkS")
|
||||||
|
(uuid "2dc0ee59-36f6-407e-821a-c6acfe3ea887")
|
||||||
|
)
|
||||||
|
(fp_text user "${REFERENCE}"
|
||||||
|
(at 0 2.5 0)
|
||||||
|
(unlocked yes)
|
||||||
|
(layer "F.Fab")
|
||||||
|
(uuid "befc0725-b201-4f81-b0dc-b327becad9ba")
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1 1)
|
||||||
|
(thickness 0.15)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(pad "1" thru_hole rect
|
||||||
|
(at -42.4 -15.3)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "5538ac99-6e48-4111-a3df-8ff33be72ff3")
|
||||||
|
)
|
||||||
|
(pad "2" thru_hole circle
|
||||||
|
(at -42.4 -12.76)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "0c1d4a6c-7871-46ae-a262-a8223571975e")
|
||||||
|
)
|
||||||
|
(pad "3" thru_hole circle
|
||||||
|
(at -42.4 -10.22)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "70df4148-0415-45a2-8365-0977fcda45a1")
|
||||||
|
)
|
||||||
|
(pad "4" thru_hole circle
|
||||||
|
(at -42.4 -7.68)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "179dd332-2ab2-4917-91ec-35f232b45ce3")
|
||||||
|
)
|
||||||
|
(pad "5" thru_hole circle
|
||||||
|
(at -42.4 -5.14)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "17bc8f3a-4727-4e31-90f4-8252dff5ad1c")
|
||||||
|
)
|
||||||
|
(pad "6" thru_hole circle
|
||||||
|
(at -42.4 -2.6)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "eee06414-e977-45a8-a5e0-618644284d45")
|
||||||
|
)
|
||||||
|
(pad "7" thru_hole rect
|
||||||
|
(at -0.5 -12)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "536f0038-06c5-45e5-b1c8-898a364f6ec4")
|
||||||
|
)
|
||||||
|
(pad "8" thru_hole rect
|
||||||
|
(at 39.5 -16)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "3e0cdbaa-8219-48c4-bb0a-fd4f0e78a390")
|
||||||
|
)
|
||||||
|
(pad "9" thru_hole rect
|
||||||
|
(at 39.5 22.5)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "f01565c2-eadd-4451-9dea-2ebe28d872f0")
|
||||||
|
)
|
||||||
|
(pad "10" thru_hole rect
|
||||||
|
(at -0.5 15)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "56ec7c50-069f-4f46-9b83-ac18e4928930")
|
||||||
|
)
|
||||||
|
(pad "11" thru_hole rect
|
||||||
|
(at -43 22.5)
|
||||||
|
(size 1.7 1.7)
|
||||||
|
(drill 1)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(uuid "f423be21-13b8-46de-8e19-e48325411a29")
|
||||||
|
)
|
||||||
|
(embedded_fonts no)
|
||||||
|
)
|
||||||
36510
board/modules/Sensors_simplified/Sensors/Sensors.kicad_pcb
Normal file
36510
board/modules/Sensors_simplified/Sensors/Sensors.kicad_pcb
Normal file
File diff suppressed because it is too large
Load Diff
136
board/modules/Sensors_simplified/Sensors/Sensors.kicad_prl
Normal file
136
board/modules/Sensors_simplified/Sensors/Sensors.kicad_prl
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
{
|
||||||
|
"board": {
|
||||||
|
"active_layer": 0,
|
||||||
|
"active_layer_preset": "All Layers",
|
||||||
|
"auto_track_width": false,
|
||||||
|
"hidden_netclasses": [],
|
||||||
|
"hidden_nets": [],
|
||||||
|
"high_contrast_mode": 0,
|
||||||
|
"net_color_mode": 1,
|
||||||
|
"opacity": {
|
||||||
|
"images": 0.6,
|
||||||
|
"pads": 1.0,
|
||||||
|
"shapes": 1.0,
|
||||||
|
"tracks": 1.0,
|
||||||
|
"vias": 1.0,
|
||||||
|
"zones": 0.6
|
||||||
|
},
|
||||||
|
"selection_filter": {
|
||||||
|
"dimensions": true,
|
||||||
|
"footprints": true,
|
||||||
|
"graphics": true,
|
||||||
|
"keepouts": true,
|
||||||
|
"lockedItems": false,
|
||||||
|
"otherItems": true,
|
||||||
|
"pads": true,
|
||||||
|
"text": true,
|
||||||
|
"tracks": true,
|
||||||
|
"vias": true,
|
||||||
|
"zones": true
|
||||||
|
},
|
||||||
|
"visible_items": [
|
||||||
|
"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",
|
||||||
|
"locked_item_shadows",
|
||||||
|
"conflict_shadows",
|
||||||
|
"shapes"
|
||||||
|
],
|
||||||
|
"visible_layers": "ffffffff_ffffffff_ffffffff_ffffffff",
|
||||||
|
"zone_display_mode": 1
|
||||||
|
},
|
||||||
|
"git": {
|
||||||
|
"repo_type": "",
|
||||||
|
"repo_username": "",
|
||||||
|
"ssh_key": ""
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"filename": "Sensors.kicad_prl",
|
||||||
|
"version": 5
|
||||||
|
},
|
||||||
|
"net_inspector_panel": {
|
||||||
|
"col_hidden": [
|
||||||
|
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
|
||||||
|
],
|
||||||
|
"col_widths": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"custom_group_rules": [],
|
||||||
|
"expanded_rows": [],
|
||||||
|
"filter_by_net_name": true,
|
||||||
|
"filter_by_netclass": true,
|
||||||
|
"filter_text": "",
|
||||||
|
"group_by_constraint": false,
|
||||||
|
"group_by_netclass": false,
|
||||||
|
"show_unconnected_nets": false,
|
||||||
|
"show_zero_pad_nets": false,
|
||||||
|
"sort_ascending": true,
|
||||||
|
"sorting_column": 0
|
||||||
|
},
|
||||||
|
"open_jobsets": [],
|
||||||
|
"project": {
|
||||||
|
"files": []
|
||||||
|
},
|
||||||
|
"schematic": {
|
||||||
|
"selection_filter": {
|
||||||
|
"graphics": true,
|
||||||
|
"images": true,
|
||||||
|
"labels": true,
|
||||||
|
"lockedItems": false,
|
||||||
|
"otherItems": true,
|
||||||
|
"pins": true,
|
||||||
|
"symbols": true,
|
||||||
|
"text": true,
|
||||||
|
"wires": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
675
board/modules/Sensors_simplified/Sensors/Sensors.kicad_pro
Normal file
675
board/modules/Sensors_simplified/Sensors/Sensors.kicad_pro
Normal file
@@ -0,0 +1,675 @@
|
|||||||
|
{
|
||||||
|
"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.8,
|
||||||
|
"height": 1.27,
|
||||||
|
"width": 2.54
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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_to_hole": "warning",
|
||||||
|
"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": "ignore",
|
||||||
|
"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": "warning",
|
||||||
|
"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.0,
|
||||||
|
"min_connection": 0.0,
|
||||||
|
"min_copper_edge_clearance": 0.5,
|
||||||
|
"min_groove_width": 0.0,
|
||||||
|
"min_hole_clearance": 0.15,
|
||||||
|
"min_hole_to_hole": 0.25,
|
||||||
|
"min_microvia_diameter": 0.2,
|
||||||
|
"min_microvia_drill": 0.1,
|
||||||
|
"min_resolved_spokes": 2,
|
||||||
|
"min_silk_clearance": 0.0,
|
||||||
|
"min_text_height": 0.8,
|
||||||
|
"min_text_thickness": 0.08,
|
||||||
|
"min_through_hole_diameter": 0.25,
|
||||||
|
"min_track_width": 0.0,
|
||||||
|
"min_via_annular_width": 0.05,
|
||||||
|
"min_via_diameter": 0.25,
|
||||||
|
"solder_mask_to_copper_clearance": 0.005,
|
||||||
|
"use_height_for_length_calcs": true
|
||||||
|
},
|
||||||
|
"teardrop_options": [
|
||||||
|
{
|
||||||
|
"td_onpthpad": true,
|
||||||
|
"td_onroundshapesonly": false,
|
||||||
|
"td_onsmdpad": true,
|
||||||
|
"td_ontrackend": false,
|
||||||
|
"td_onvia": 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,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"diameter": 0.3,
|
||||||
|
"drill": 0.25
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"zones_allow_external_fillets": false
|
||||||
|
},
|
||||||
|
"ipc2581": {
|
||||||
|
"dist": "",
|
||||||
|
"distpn": "",
|
||||||
|
"internal_id": "",
|
||||||
|
"mfg": "",
|
||||||
|
"mpn": ""
|
||||||
|
},
|
||||||
|
"layer_pairs": [],
|
||||||
|
"layer_presets": [],
|
||||||
|
"viewports": []
|
||||||
|
},
|
||||||
|
"boards": [],
|
||||||
|
"cvpcb": {
|
||||||
|
"equivalence_files": []
|
||||||
|
},
|
||||||
|
"erc": {
|
||||||
|
"erc_exclusions": [],
|
||||||
|
"meta": {
|
||||||
|
"version": 0
|
||||||
|
},
|
||||||
|
"pin_map": [
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"rule_severities": {
|
||||||
|
"bus_definition_conflict": "error",
|
||||||
|
"bus_entry_needed": "error",
|
||||||
|
"bus_to_bus_conflict": "error",
|
||||||
|
"bus_to_net_conflict": "error",
|
||||||
|
"different_unit_footprint": "error",
|
||||||
|
"different_unit_net": "error",
|
||||||
|
"duplicate_reference": "error",
|
||||||
|
"duplicate_sheet_names": "error",
|
||||||
|
"endpoint_off_grid": "warning",
|
||||||
|
"extra_units": "error",
|
||||||
|
"footprint_filter": "ignore",
|
||||||
|
"footprint_link_issues": "warning",
|
||||||
|
"four_way_junction": "ignore",
|
||||||
|
"global_label_dangling": "warning",
|
||||||
|
"hier_label_mismatch": "error",
|
||||||
|
"label_dangling": "error",
|
||||||
|
"label_multiple_wires": "warning",
|
||||||
|
"lib_symbol_issues": "warning",
|
||||||
|
"lib_symbol_mismatch": "warning",
|
||||||
|
"missing_bidi_pin": "warning",
|
||||||
|
"missing_input_pin": "warning",
|
||||||
|
"missing_power_pin": "error",
|
||||||
|
"missing_unit": "warning",
|
||||||
|
"multiple_net_names": "warning",
|
||||||
|
"net_not_bus_member": "warning",
|
||||||
|
"no_connect_connected": "warning",
|
||||||
|
"no_connect_dangling": "warning",
|
||||||
|
"pin_not_connected": "error",
|
||||||
|
"pin_not_driven": "error",
|
||||||
|
"pin_to_pin": "ignore",
|
||||||
|
"power_pin_not_driven": "ignore",
|
||||||
|
"same_local_global_label": "warning",
|
||||||
|
"similar_label_and_power": "warning",
|
||||||
|
"similar_labels": "warning",
|
||||||
|
"similar_power": "warning",
|
||||||
|
"simulation_model_issue": "ignore",
|
||||||
|
"single_global_label": "ignore",
|
||||||
|
"unannotated": "error",
|
||||||
|
"unconnected_wire_endpoint": "warning",
|
||||||
|
"undefined_netclass": "error",
|
||||||
|
"unit_value_mismatch": "error",
|
||||||
|
"unresolved_variable": "error",
|
||||||
|
"wire_dangling": "error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libraries": {
|
||||||
|
"pinned_footprint_libs": [],
|
||||||
|
"pinned_symbol_libs": []
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"filename": "Sensors.kicad_pro",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"net_settings": {
|
||||||
|
"classes": [
|
||||||
|
{
|
||||||
|
"bus_width": 12,
|
||||||
|
"clearance": 0.15,
|
||||||
|
"diff_pair_gap": 0.25,
|
||||||
|
"diff_pair_via_gap": 0.25,
|
||||||
|
"diff_pair_width": 0.2,
|
||||||
|
"line_style": 0,
|
||||||
|
"microvia_diameter": 0.3,
|
||||||
|
"microvia_drill": 0.1,
|
||||||
|
"name": "Default",
|
||||||
|
"pcb_color": "rgba(0, 0, 0, 0.000)",
|
||||||
|
"priority": 2147483647,
|
||||||
|
"schematic_color": "rgba(0, 0, 0, 0.000)",
|
||||||
|
"track_width": 0.2,
|
||||||
|
"via_diameter": 0.6,
|
||||||
|
"via_drill": 0.3,
|
||||||
|
"wire_width": 6
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"version": 4
|
||||||
|
},
|
||||||
|
"net_colors": null,
|
||||||
|
"netclass_assignments": null,
|
||||||
|
"netclass_patterns": []
|
||||||
|
},
|
||||||
|
"pcbnew": {
|
||||||
|
"last_paths": {
|
||||||
|
"gencad": "",
|
||||||
|
"idf": "",
|
||||||
|
"netlist": "",
|
||||||
|
"plot": "",
|
||||||
|
"pos_files": "",
|
||||||
|
"specctra_dsn": "",
|
||||||
|
"step": "Sensors.step",
|
||||||
|
"svg": "",
|
||||||
|
"vrml": ""
|
||||||
|
},
|
||||||
|
"page_layout_descr_file": ""
|
||||||
|
},
|
||||||
|
"schematic": {
|
||||||
|
"annotate_start_num": 0,
|
||||||
|
"bom_export_filename": "${PROJECTNAME}.csv",
|
||||||
|
"bom_fmt_presets": [],
|
||||||
|
"bom_fmt_settings": {
|
||||||
|
"field_delimiter": ",",
|
||||||
|
"keep_line_breaks": false,
|
||||||
|
"keep_tabs": false,
|
||||||
|
"name": "CSV",
|
||||||
|
"ref_delimiter": ",",
|
||||||
|
"ref_range_delimiter": "",
|
||||||
|
"string_delimiter": "\""
|
||||||
|
},
|
||||||
|
"bom_presets": [],
|
||||||
|
"bom_settings": {
|
||||||
|
"exclude_dnp": false,
|
||||||
|
"fields_ordered": [
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Reference",
|
||||||
|
"name": "Reference",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "Value",
|
||||||
|
"name": "Value",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "Footprint",
|
||||||
|
"name": "Footprint",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Datasheet",
|
||||||
|
"name": "Datasheet",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Description",
|
||||||
|
"name": "Description",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Qty",
|
||||||
|
"name": "${QUANTITY}",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "#",
|
||||||
|
"name": "${ITEM_NUMBER}",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "LCSC_PART_NUMBER",
|
||||||
|
"name": "LCSC_PART_NUMBER",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Sim.Device",
|
||||||
|
"name": "Sim.Device",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Sim.Pins",
|
||||||
|
"name": "Sim.Pins",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Sim.Type",
|
||||||
|
"name": "Sim.Type",
|
||||||
|
"show": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "DNP",
|
||||||
|
"name": "${DNP}",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "Exclude from BOM",
|
||||||
|
"name": "${EXCLUDE_FROM_BOM}",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "Exclude from Board",
|
||||||
|
"name": "${EXCLUDE_FROM_BOARD}",
|
||||||
|
"show": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"filter_string": "",
|
||||||
|
"group_symbols": true,
|
||||||
|
"include_excluded_from_bom": true,
|
||||||
|
"name": "",
|
||||||
|
"sort_asc": true,
|
||||||
|
"sort_field": "Reference"
|
||||||
|
},
|
||||||
|
"connection_grid_size": 50.0,
|
||||||
|
"drawing": {
|
||||||
|
"dashed_lines_dash_length_ratio": 12.0,
|
||||||
|
"dashed_lines_gap_length_ratio": 3.0,
|
||||||
|
"default_line_thickness": 6.0,
|
||||||
|
"default_text_size": 50.0,
|
||||||
|
"field_names": [],
|
||||||
|
"intersheets_ref_own_page": false,
|
||||||
|
"intersheets_ref_prefix": "",
|
||||||
|
"intersheets_ref_short": false,
|
||||||
|
"intersheets_ref_show": false,
|
||||||
|
"intersheets_ref_suffix": "",
|
||||||
|
"junction_size_choice": 3,
|
||||||
|
"label_size_ratio": 0.375,
|
||||||
|
"operating_point_overlay_i_precision": 3,
|
||||||
|
"operating_point_overlay_i_range": "~A",
|
||||||
|
"operating_point_overlay_v_precision": 3,
|
||||||
|
"operating_point_overlay_v_range": "~V",
|
||||||
|
"overbar_offset_ratio": 1.23,
|
||||||
|
"pin_symbol_size": 25.0,
|
||||||
|
"text_offset_ratio": 0.15
|
||||||
|
},
|
||||||
|
"legacy_lib_dir": "",
|
||||||
|
"legacy_lib_list": [],
|
||||||
|
"meta": {
|
||||||
|
"version": 1
|
||||||
|
},
|
||||||
|
"net_format_name": "",
|
||||||
|
"page_layout_descr_file": "",
|
||||||
|
"plot_directory": "",
|
||||||
|
"space_save_all_events": true,
|
||||||
|
"spice_current_sheet_as_root": false,
|
||||||
|
"spice_external_command": "spice \"%I\"",
|
||||||
|
"spice_model_current_sheet_as_root": true,
|
||||||
|
"spice_save_all_currents": false,
|
||||||
|
"spice_save_all_dissipations": false,
|
||||||
|
"spice_save_all_voltages": false,
|
||||||
|
"subpart_first_id": 65,
|
||||||
|
"subpart_id_separator": 0
|
||||||
|
},
|
||||||
|
"sheets": [
|
||||||
|
[
|
||||||
|
"46346c04-8bed-48b4-837b-9342dd403232",
|
||||||
|
"Root"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"text_variables": {}
|
||||||
|
}
|
||||||
15385
board/modules/Sensors_simplified/Sensors/Sensors.kicad_sch
Normal file
15385
board/modules/Sensors_simplified/Sensors/Sensors.kicad_sch
Normal file
File diff suppressed because it is too large
Load Diff
35338
board/modules/Sensors_simplified/Sensors/Sensors.step
Normal file
35338
board/modules/Sensors_simplified/Sensors/Sensors.step
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
|||||||
|
{"EXTRA_LAYERS": "", "ALL_ACTIVE_LAYERS": false, "EXTEND_EDGE_CUT": false, "ALTERNATIVE_EDGE_CUT": false, "AUTO TRANSLATE": true, "AUTO FILL": true, "EXCLUDE DNP": false}
|
||||||
4
board/modules/Sensors_simplified/Sensors/fp-lib-table
Normal file
4
board/modules/Sensors_simplified/Sensors/fp-lib-table
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
(fp_lib_table
|
||||||
|
(version 7)
|
||||||
|
(lib (name "Sensor")(type "KiCad")(uri "${KIPRJMOD}/Sensor.pretty")(options "")(descr ""))
|
||||||
|
)
|
||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
case/PlantCtrl Case v9.f3z
Normal file
BIN
case/PlantCtrl Case v9.f3z
Normal file
Binary file not shown.
BIN
case/case.3mf
BIN
case/case.3mf
Binary file not shown.
@@ -1,26 +1,31 @@
|
|||||||
[build]
|
[build]
|
||||||
#target = "xtensa-esp32-espidf"
|
rustflags = [
|
||||||
target = "riscv32imac-esp-espidf"
|
# Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.)
|
||||||
|
# NOTE: May negatively impact performance of produced code
|
||||||
|
"-C", "force-frame-pointers",
|
||||||
|
"-Z", "stack-protector=all",
|
||||||
|
"-C", "link-arg=-Tlinkall.x",
|
||||||
|
]
|
||||||
|
|
||||||
[target.riscv32imac-esp-espidf]
|
target = "riscv32imac-unknown-none-elf"
|
||||||
linker = "ldproxy"
|
|
||||||
|
[target.riscv32imac-unknown-none-elf]
|
||||||
|
runner = "espflash flash --monitor --chip esp32c6 --baud 921600 --partition-table partitions.csv"
|
||||||
#runner = "espflash flash --monitor --baud 921600 --partition-table partitions.csv -b no-reset" # Select this runner in case of usb ttl
|
#runner = "espflash flash --monitor --baud 921600 --partition-table partitions.csv -b no-reset" # Select this runner in case of usb ttl
|
||||||
#runner = "espflash flash --monitor --baud 921600 --flash-size 16mb --partition-table partitions.csv"
|
#runner = "espflash flash --monitor"
|
||||||
runner = "cargo runner"
|
#runner = "cargo runner"
|
||||||
|
|
||||||
|
|
||||||
#runner = "espflash flash --monitor --partition-table partitions.csv -b no-reset" # create upgrade image file for webupload
|
#runner = "espflash flash --monitor --partition-table partitions.csv -b no-reset" # create upgrade image file for webupload
|
||||||
# runner = espflash erase-parts otadata //ensure flash is clean
|
# runner = espflash erase-parts otadata //ensure flash is clean
|
||||||
|
|
||||||
rustflags = [ "--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110
|
[env]
|
||||||
|
CHRONO_TZ_TIMEZONE_FILTER = "UTC|America/New_York|America/Chicago|America/Los_Angeles|Europe/London|Europe/Berlin|Europe/Paris|Asia/Tokyo|Asia/Shanghai|Asia/Kolkata|Australia/Sydney|America/Sao_Paulo|Africa/Johannesburg|Asia/Dubai|Pacific/Auckland"
|
||||||
|
CARGO_WORKSPACE_DIR = { value = "", relative = true }
|
||||||
|
ESP_LOG = "info"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[unstable]
|
[unstable]
|
||||||
build-std = ["std", "panic_abort"]
|
build-std = ["alloc", "core"]
|
||||||
|
|
||||||
[env]
|
|
||||||
MCU="esp32c6"
|
|
||||||
# Note: this variable is not used by the pio builder (`cargo build --features pio`)
|
|
||||||
ESP_IDF_VERSION = "v5.2.1"
|
|
||||||
CHRONO_TZ_TIMEZONE_FILTER="UTC|Europe/Berlin"
|
|
||||||
CARGO_WORKSPACE_DIR = { value = "", relative = true }
|
|
||||||
RUST_BACKTRACE = "full"
|
|
||||||
|
|||||||
18
rust/.idea/dictionaries/project.xml
generated
Normal file
18
rust/.idea/dictionaries/project.xml
generated
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<component name="ProjectDictionaryState">
|
||||||
|
<dictionary name="project">
|
||||||
|
<words>
|
||||||
|
<w>boardtest</w>
|
||||||
|
<w>buildtime</w>
|
||||||
|
<w>deepsleep</w>
|
||||||
|
<w>githash</w>
|
||||||
|
<w>lamptest</w>
|
||||||
|
<w>lightstate</w>
|
||||||
|
<w>mppt</w>
|
||||||
|
<w>plantstate</w>
|
||||||
|
<w>pumptest</w>
|
||||||
|
<w>sntp</w>
|
||||||
|
<w>vergen</w>
|
||||||
|
<w>wifiscan</w>
|
||||||
|
</words>
|
||||||
|
</dictionary>
|
||||||
|
</component>
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
<component name="InspectionProjectProfileManager">
|
||||||
<profile version="1.0">
|
<profile version="1.0">
|
||||||
<option name="myName" value="Project Default" />
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<Languages>
|
||||||
|
<language minSize="102" name="Rust" />
|
||||||
|
</Languages>
|
||||||
|
</inspection_tool>
|
||||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="NewCrateVersionAvailable" enabled="true" level="INFORMATION" enabled_by_default="true" />
|
||||||
</profile>
|
</profile>
|
||||||
</component>
|
</component>
|
||||||
2931
rust/Cargo.lock
generated
Normal file
2931
rust/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
142
rust/Cargo.toml
142
rust/Cargo.toml
@@ -1,24 +1,18 @@
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "plant-ctrl2"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Empire Phoenix"]
|
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
resolver = "2"
|
name = "plant-ctrl2"
|
||||||
#rust-version = "1.71"
|
rust-version = "1.86"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
[profile.dev]
|
# Explicitly configure the binary target and disable building it as a test/bench.
|
||||||
# Explicitly disable LTO which the Xtensa codegen backend has issues
|
[[bin]]
|
||||||
lto = false
|
name = "plant-ctrl2"
|
||||||
strip = false
|
path = "src/main.rs"
|
||||||
debug = true
|
# Prevent IDEs/Cargo from trying to compile a test harness for this no_std binary.
|
||||||
overflow-checks = true
|
test = false
|
||||||
panic = "abort"
|
bench = false
|
||||||
incremental = true
|
doc = false
|
||||||
opt-level = "s"
|
|
||||||
|
|
||||||
[profile.dev.build-override]
|
|
||||||
opt-level = 1
|
|
||||||
incremental = true
|
|
||||||
|
|
||||||
[package.metadata.cargo_runner]
|
[package.metadata.cargo_runner]
|
||||||
# The string `$TARGET_FILE` will be replaced with the path from cargo.
|
# The string `$TARGET_FILE` will be replaced with the path from cargo.
|
||||||
@@ -33,68 +27,100 @@ command = [
|
|||||||
"partitions.csv"
|
"partitions.csv"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
#this strips the bootloader, we need that tho
|
||||||
|
#strip = true
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
lto = "fat"
|
||||||
|
debug = false
|
||||||
|
overflow-checks = true
|
||||||
|
panic = "abort"
|
||||||
|
incremental = true
|
||||||
|
opt-level = "z"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
lto = "fat"
|
||||||
|
#debug = false
|
||||||
|
overflow-checks = true
|
||||||
|
panic = "abort"
|
||||||
|
incremental = false
|
||||||
|
opt-level = "z"
|
||||||
|
|
||||||
[package.metadata.espflash]
|
[package.metadata.espflash]
|
||||||
partition_table = "partitions.csv"
|
partition_table = "partitions.csv"
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["std", "embassy", "esp-idf-svc/native"]
|
|
||||||
pio = ["esp-idf-svc/pio"]
|
|
||||||
std = ["alloc", "esp-idf-svc/binstart", "esp-idf-svc/std"]
|
|
||||||
alloc = ["esp-idf-svc/alloc"]
|
|
||||||
nightly = ["esp-idf-svc/nightly"]
|
|
||||||
experimental = ["esp-idf-svc/experimental"]
|
|
||||||
embassy = ["esp-idf-svc/embassy-sync", "esp-idf-svc/critical-section", "esp-idf-svc/embassy-time-driver"]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
#ESP stuff
|
#ESP stuff
|
||||||
embedded-svc = { version = "0.28.1", features = ["experimental"] }
|
log = "0.4.28"
|
||||||
esp-idf-hal = "0.45.2"
|
esp-bootloader-esp-idf = { version = "0.5.0", features = ["esp32c6", "log-04"] }
|
||||||
esp-idf-sys = { version = "0.36.1", features = ["binstart", "native"] }
|
esp-hal = { version = "1.1.0", features = ["esp32c6", "log-04"] }
|
||||||
esp-idf-svc = { version = "0.51.0", default-features = false }
|
esp-rtos = { version = "0.3.0", features = ["esp32c6", "embassy", "esp-radio"] }
|
||||||
|
esp-backtrace = { version = "0.19.0", features = ["esp32c6", "panic-handler", "println", "colors", "custom-halt"] }
|
||||||
|
esp-println = { version = "0.17.0", features = ["esp32c6", "log-04", "auto"] }
|
||||||
|
esp-storage = { version = "0.9.0", features = ["esp32c6"] }
|
||||||
|
esp-radio = { version = "0.18.0", features = ["esp32c6", "log-04", "wifi", "unstable"] }
|
||||||
|
esp-alloc = { version = "0.10.0", features = ["esp32c6", "internal-heap-stats"] }
|
||||||
|
|
||||||
|
# Async runtime (Embassy core)
|
||||||
|
embassy-executor = { version = "0.10.0", features = ["log", "nightly"] }
|
||||||
|
embassy-time = { version = "0.5.1", features = ["log"], default-features = false }
|
||||||
|
embassy-sync = { version = "0.8.0", features = ["log"] }
|
||||||
|
|
||||||
|
# Networking and protocol stacks
|
||||||
|
embassy-net = { version = "0.8.0", features = ["dhcpv4", "log", "medium-ethernet", "tcp", "udp", "proto-ipv4", "dns", "proto-ipv6"] }
|
||||||
|
sntpc = { version = "0.6.1", default-features = false, features = ["log", "embassy-socket", "embassy-socket-ipv6"] }
|
||||||
|
edge-dhcp = "0.7.0"
|
||||||
|
edge-nal = "0.6.0"
|
||||||
|
edge-nal-embassy = "0.8.1"
|
||||||
|
edge-http = { version = "0.7.0", features = ["log"] }
|
||||||
|
|
||||||
|
esp32c6 = { version = "0.23.2" }
|
||||||
|
|
||||||
|
# Hardware abstraction traits and HAL adapters
|
||||||
embedded-hal = "1.0.0"
|
embedded-hal = "1.0.0"
|
||||||
heapless = { version = "0.8", features = ["serde"] }
|
embedded-storage = "0.3.1"
|
||||||
embedded-hal-bus = { version = "0.2.0", features = ["std"] }
|
embassy-embedded-hal = "0.6.0"
|
||||||
|
nb = "1.1.0"
|
||||||
|
|
||||||
#Hardware additional driver
|
#Hardware additional driver
|
||||||
ds18b20 = "0.1.1"
|
|
||||||
bq34z100 = { version = "0.3.0", features = ["flashstream"] }
|
#bq34z100 = { version = "0.3.0", default-features = false }
|
||||||
one-wire-bus = "0.1.1"
|
lib-bms-protocol = { git = "https://gitea.wlandt.de/judge/ch32-bms.git", default-features = false }
|
||||||
|
onewire = "0.4.0"
|
||||||
|
#strum = { version = "0.27.0", default-feature = false, features = ["derive"] }
|
||||||
ds323x = "0.6.0"
|
ds323x = "0.6.0"
|
||||||
|
|
||||||
#pure code dependencies
|
|
||||||
once_cell = "1.19.0"
|
|
||||||
anyhow = { version = "1.0.75", features = ["std", "backtrace"] }
|
|
||||||
strum = { version = "0.27.0", features = ["derive"] }
|
|
||||||
measurements = "0.11.0"
|
|
||||||
|
|
||||||
#json
|
#json
|
||||||
serde = { version = "1.0.192", features = ["derive"] }
|
serde = { version = "1.0.219", features = ["derive", "alloc"], default-features = false }
|
||||||
serde_json = "1.0.108"
|
serde_json = { version = "1.0.143", default-features = false, features = ["alloc"] }
|
||||||
|
|
||||||
#timezone
|
chrono = { version = "0.4.42", default-features = false, features = ["iana-time-zone", "alloc", "serde"] }
|
||||||
chrono = { version = "0.4.23", default-features = false , features = ["iana-time-zone" , "alloc"] }
|
chrono-tz = { version = "0.10.4", default-features = false, features = ["filter-by-regex"] }
|
||||||
chrono-tz = {version="0.8.0", default-features = false , features = [ "filter-by-regex" ]}
|
|
||||||
eeprom24x = "0.7.2"
|
eeprom24x = "0.7.2"
|
||||||
url = "2.5.3"
|
|
||||||
crc = "3.2.1"
|
crc = "3.2.1"
|
||||||
bincode = "1.3.3"
|
|
||||||
ringbuffer = "0.15.0"
|
|
||||||
text-template = "0.1.0"
|
|
||||||
strum_macros = "0.27.0"
|
strum_macros = "0.27.0"
|
||||||
esp-ota = { version = "0.2.2", features = ["log"] }
|
|
||||||
unit-enum = "1.4.1"
|
unit-enum = "1.4.1"
|
||||||
|
pca9535 = { version = "2.0.0" }
|
||||||
|
ina219 = { version = "0.2.0" }
|
||||||
|
portable-atomic = "1.11.1"
|
||||||
|
async-trait = "0.1.89"
|
||||||
|
bq34z100 = { version = "0.4.0", default-features = false }
|
||||||
|
static_cell = "2.1.1"
|
||||||
|
littlefs2 = { version = "0.6.1", features = ["c-stubs", "alloc"] }
|
||||||
|
littlefs2-core = "0.1.1"
|
||||||
|
bytemuck = { version = "1.23.2", features = ["derive", "min_const_generics", "pod_saturating", "extern_crate_alloc"] }
|
||||||
|
deranged = "0.5.3"
|
||||||
|
bincode = { version = "2.0.1", default-features = false, features = ["derive"] }
|
||||||
|
option-lock = { version = "0.3.1", default-features = false }
|
||||||
|
measurements = "0.11.1"
|
||||||
|
heapless = { version = "0.7.17", features = ["serde"] }
|
||||||
|
mcutie = { path = "./src/mcutie_3_0_0/", default-features = false, features = ["log"] }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
#esp-idf-hal = { git = "https://github.com/esp-rs/esp-idf-hal.git" }
|
|
||||||
#esp-idf-hal = { git = "https://github.com/empirephoenix/esp-idf-hal.git" }
|
|
||||||
#esp-idf-sys = { git = "https://github.com/empirephoenix/esp-idf-sys.git" }
|
|
||||||
#esp-idf-sys = { git = "https://github.com/esp-rs/esp-idf-sys.git" }
|
|
||||||
#esp-idf-svc = { git = "https://github.com/esp-rs/esp-idf-svc.git" }
|
|
||||||
#bq34z100 = { path = "../../bq34z100_rust" }
|
#bq34z100 = { path = "../../bq34z100_rust" }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cc = "=1.1.30"
|
|
||||||
embuild = { version= "0.32.0", features = ["espidf"]}
|
|
||||||
vergen = { version = "8.2.6", features = ["build", "git", "gitcl"] }
|
vergen = { version = "8.2.6", features = ["build", "git", "gitcl"] }
|
||||||
|
|||||||
22
rust/all.sh
Executable file
22
rust/all.sh
Executable file
@@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
"${SCRIPT_DIR}/build_website.sh"
|
||||||
|
|
||||||
|
cargo build --release
|
||||||
|
espflash save-image \
|
||||||
|
--bootloader "${SCRIPT_DIR}/bootloader.bin" \
|
||||||
|
--partition-table "${SCRIPT_DIR}/partitions.csv" \
|
||||||
|
--chip esp32c6 \
|
||||||
|
target/riscv32imac-unknown-none-elf/release/plant-ctrl2 \
|
||||||
|
"${SCRIPT_DIR}/image.bin"
|
||||||
|
|
||||||
|
espflash flash --monitor \
|
||||||
|
--bootloader "${SCRIPT_DIR}/bootloader.bin" \
|
||||||
|
--chip esp32c6 \
|
||||||
|
--baud 921600 \
|
||||||
|
--partition-table "${SCRIPT_DIR}/partitions.csv" \
|
||||||
|
target/riscv32imac-unknown-none-elf/release/plant-ctrl2
|
||||||
BIN
rust/bootloader.bin
Normal file
BIN
rust/bootloader.bin
Normal file
Binary file not shown.
@@ -1,42 +1,56 @@
|
|||||||
use std::process::Command;
|
|
||||||
|
|
||||||
use vergen::EmitBuilder;
|
use vergen::EmitBuilder;
|
||||||
fn main() {
|
|
||||||
println!("cargo:rerun-if-changed=./src/src_webpack");
|
|
||||||
Command::new("rm")
|
|
||||||
.arg("./src/webserver/bundle.js")
|
|
||||||
.output()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
match Command::new("cmd").spawn() {
|
fn linker_be_nice() {
|
||||||
Ok(_) => {
|
let args: Vec<String> = std::env::args().collect();
|
||||||
println!("Assuming build on windows");
|
if args.len() > 1 {
|
||||||
let output = Command::new("cmd")
|
let kind = &args[1];
|
||||||
.arg("/K")
|
let what = &args[2];
|
||||||
.arg("npx")
|
|
||||||
.arg("webpack")
|
match kind.as_str() {
|
||||||
.current_dir("./src_webpack")
|
"undefined-symbol" => match what.as_str() {
|
||||||
.output()
|
"_defmt_timestamp" => {
|
||||||
.unwrap();
|
eprintln!();
|
||||||
println!("status: {}", output.status);
|
eprintln!("💡 `defmt` not found - make sure `defmt.x` is added as a linker script and you have included `use defmt_rtt as _;`");
|
||||||
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
eprintln!();
|
||||||
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
}
|
||||||
assert!(output.status.success());
|
"_stack_start" => {
|
||||||
}
|
eprintln!();
|
||||||
Err(_) => {
|
eprintln!("💡 Is the linker script `linkall.x` missing?");
|
||||||
println!("Assuming build on linux");
|
eprintln!();
|
||||||
let output = Command::new("npx")
|
}
|
||||||
.arg("webpack")
|
"esp_wifi_preempt_enable"
|
||||||
.current_dir("./src_webpack")
|
| "esp_wifi_preempt_yield_task"
|
||||||
.output()
|
| "esp_wifi_preempt_task_create" => {
|
||||||
.unwrap();
|
eprintln!();
|
||||||
println!("status: {}", output.status);
|
eprintln!("💡 `esp-wifi` has no scheduler enabled. Make sure you have the `builtin-scheduler` feature enabled, or that you provide an external scheduler.");
|
||||||
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
eprintln!();
|
||||||
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
}
|
||||||
assert!(output.status.success());
|
"embedded_test_linker_file_not_added_to_rustflags" => {
|
||||||
|
eprintln!();
|
||||||
|
eprintln!("💡 `embedded-test` not found - make sure `embedded-test.x` is added as a linker script for tests");
|
||||||
|
eprintln!();
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
},
|
||||||
|
// we don't have anything helpful for "missing-lib" yet
|
||||||
|
_ => {
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::process::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
embuild::espidf::sysenv::output();
|
println!(
|
||||||
|
"cargo:rustc-link-arg=--error-handling-script={}",
|
||||||
|
std::env::current_exe().unwrap().display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
linker_be_nice();
|
||||||
|
// Non-existent path causes Cargo to always re-run this script,
|
||||||
|
// keeping VERGEN_BUILD_TIMESTAMP fresh on every build.
|
||||||
|
println!("cargo:rerun-if-changed=ALWAYS_REBUILD_SENTINEL");
|
||||||
let _ = EmitBuilder::builder().all_git().all_build().emit();
|
let _ = EmitBuilder::builder().all_git().all_build().emit();
|
||||||
}
|
}
|
||||||
|
|||||||
21
rust/build_website.sh
Executable file
21
rust/build_website.sh
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
WEBPACK_DIR="${SCRIPT_DIR}/src_webpack"
|
||||||
|
WEBSERVER_DIR="${SCRIPT_DIR}/src/webserver"
|
||||||
|
|
||||||
|
rm -f "${WEBSERVER_DIR}/index.html.gz"
|
||||||
|
rm -f "${WEBSERVER_DIR}/bundle.js.gz"
|
||||||
|
rm -f "${WEBPACK_DIR}/index.html.gz"
|
||||||
|
rm -f "${WEBPACK_DIR}/bundle.js.gz"
|
||||||
|
rm -f "${WEBPACK_DIR}/index.html"
|
||||||
|
rm -f "${WEBPACK_DIR}/bundle.js"
|
||||||
|
|
||||||
|
pushd "${WEBPACK_DIR}"
|
||||||
|
npm install
|
||||||
|
npx webpack build
|
||||||
|
cp index.html.gz "${WEBSERVER_DIR}/index.html.gz"
|
||||||
|
cp bundle.js.gz "${WEBSERVER_DIR}/bundle.js.gz"
|
||||||
|
popd
|
||||||
7
rust/erase_ota.sh
Executable file
7
rust/erase_ota.sh
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
cargo espflash erase-parts otadata --partition-table "${SCRIPT_DIR}/partitions.csv"
|
||||||
8
rust/espflash.toml
Normal file
8
rust/espflash.toml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[connection]
|
||||||
|
|
||||||
|
[[usb_device]]
|
||||||
|
vid = "303a"
|
||||||
|
pid = "1001"
|
||||||
|
|
||||||
|
[flash]
|
||||||
|
size = "16MB"
|
||||||
15
rust/flash.sh
Executable file
15
rust/flash.sh
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
"${SCRIPT_DIR}/build_website.sh"
|
||||||
|
|
||||||
|
cargo build --release
|
||||||
|
espflash flash --monitor \
|
||||||
|
--bootloader "${SCRIPT_DIR}/bootloader.bin" \
|
||||||
|
--chip esp32c6 \
|
||||||
|
--baud 921600 \
|
||||||
|
--partition-table "${SCRIPT_DIR}/partitions.csv" \
|
||||||
|
target/riscv32imac-unknown-none-elf/release/plant-ctrl2
|
||||||
17
rust/image_build.sh
Executable file
17
rust/image_build.sh
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
rm -f "${SCRIPT_DIR}/image.bin"
|
||||||
|
|
||||||
|
"${SCRIPT_DIR}/build_website.sh"
|
||||||
|
|
||||||
|
cargo build --release
|
||||||
|
espflash save-image \
|
||||||
|
--bootloader "${SCRIPT_DIR}/bootloader.bin" \
|
||||||
|
--partition-table "${SCRIPT_DIR}/partitions.csv" \
|
||||||
|
--chip esp32c6 \
|
||||||
|
target/riscv32imac-unknown-none-elf/release/plant-ctrl2 \
|
||||||
|
"${SCRIPT_DIR}/image.bin"
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
nvs, data, nvs, , 16k,
|
nvs, data, nvs, , 16k,
|
||||||
otadata, data, ota, , 8k,
|
otadata, data, ota, , 8k,
|
||||||
phy_init, data, phy, , 4k,
|
phy_init, data, phy, , 4k,
|
||||||
ota_0, app, ota_0, , 5632k,
|
ota_0, app, ota_0, , 3968k,
|
||||||
ota_1, app, ota_1, , 5632k,
|
ota_1, app, ota_1, , 3968k,
|
||||||
storage, data, spiffs, , 5000k,
|
storage, data, littlefs,, 8M,
|
||||||
|
|||||||
|
@@ -1,3 +1,2 @@
|
|||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly"
|
channel = "nightly"
|
||||||
toolchain = "esp"
|
|
||||||
|
|||||||
@@ -1,19 +1,20 @@
|
|||||||
use std::str::FromStr;
|
use crate::hal::PLANT_COUNT;
|
||||||
|
use crate::plant_state::PlantWateringMode;
|
||||||
use chrono_tz::{Europe::Berlin, Tz};
|
use alloc::string::String;
|
||||||
|
use core::str::FromStr;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::PLANT_COUNT;
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub struct NetworkConfig {
|
pub struct NetworkConfig {
|
||||||
pub ap_ssid: heapless::String<32>,
|
pub ap_ssid: heapless::String<32>,
|
||||||
pub ssid: Option<heapless::String<32>>,
|
pub ssid: Option<heapless::String<32>>,
|
||||||
pub password: Option<heapless::String<64>>,
|
pub password: Option<heapless::String<64>>,
|
||||||
pub mqtt_url: Option<heapless::String<128>>,
|
pub mqtt_url: Option<String>,
|
||||||
pub base_topic: Option<heapless::String<64>>,
|
pub base_topic: Option<heapless::String<64>>,
|
||||||
pub timezone: heapless::String<64>,
|
pub mqtt_user: Option<String>,
|
||||||
|
pub mqtt_password: Option<String>,
|
||||||
|
pub max_wait: u32,
|
||||||
}
|
}
|
||||||
impl Default for NetworkConfig {
|
impl Default for NetworkConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
@@ -23,7 +24,9 @@ impl Default for NetworkConfig {
|
|||||||
password: None,
|
password: None,
|
||||||
mqtt_url: None,
|
mqtt_url: None,
|
||||||
base_topic: None,
|
base_topic: None,
|
||||||
timezone: heapless::String::from_str("Europe/Berlin").unwrap(),
|
mqtt_user: None,
|
||||||
|
mqtt_password: None,
|
||||||
|
max_wait: 10000,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -60,6 +63,7 @@ pub struct TankConfig {
|
|||||||
pub tank_warn_percent: u8,
|
pub tank_warn_percent: u8,
|
||||||
pub tank_empty_percent: u8,
|
pub tank_empty_percent: u8,
|
||||||
pub tank_full_percent: u8,
|
pub tank_full_percent: u8,
|
||||||
|
pub ml_per_pulse: f32,
|
||||||
}
|
}
|
||||||
impl Default for TankConfig {
|
impl Default for TankConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
@@ -70,50 +74,83 @@ impl Default for TankConfig {
|
|||||||
tank_warn_percent: 40,
|
tank_warn_percent: 40,
|
||||||
tank_empty_percent: 5,
|
tank_empty_percent: 5,
|
||||||
tank_full_percent: 95,
|
tank_full_percent: 95,
|
||||||
|
ml_per_pulse: 0.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
|
||||||
|
pub enum BatteryBoardVersion {
|
||||||
|
#[default]
|
||||||
|
Disabled,
|
||||||
|
BQ34Z100G1,
|
||||||
|
WchI2cSlave,
|
||||||
|
}
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
|
||||||
|
pub enum BoardVersion {
|
||||||
|
#[default]
|
||||||
|
INITIAL,
|
||||||
|
V3,
|
||||||
|
V4,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
|
||||||
|
pub struct BoardHardware {
|
||||||
|
pub board: BoardVersion,
|
||||||
|
pub battery: BatteryBoardVersion,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub struct PlantControllerConfig {
|
pub struct PlantControllerConfig {
|
||||||
|
pub hardware: BoardHardware,
|
||||||
pub network: NetworkConfig,
|
pub network: NetworkConfig,
|
||||||
pub tank: TankConfig,
|
pub tank: TankConfig,
|
||||||
pub night_lamp: NightLampConfig,
|
pub night_lamp: NightLampConfig,
|
||||||
pub plants: [PlantConfig; PLANT_COUNT],
|
pub plants: [PlantConfig; PLANT_COUNT],
|
||||||
|
pub timezone: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub struct PlantConfig {
|
pub struct PlantConfig {
|
||||||
pub mode: Mode,
|
pub mode: PlantWateringMode,
|
||||||
pub target_moisture: u8,
|
pub target_moisture: f32,
|
||||||
|
pub min_moisture: f32,
|
||||||
pub pump_time_s: u16,
|
pub pump_time_s: u16,
|
||||||
|
pub pump_limit_ml: u16,
|
||||||
pub pump_cooldown_min: u16,
|
pub pump_cooldown_min: u16,
|
||||||
pub pump_hour_start: u8,
|
pub pump_hour_start: u8,
|
||||||
pub pump_hour_end: u8,
|
pub pump_hour_end: u8,
|
||||||
|
pub sensor_a: bool,
|
||||||
pub sensor_b: bool,
|
pub sensor_b: bool,
|
||||||
pub max_consecutive_pump_count: u8,
|
pub max_consecutive_pump_count: u8,
|
||||||
|
pub moisture_sensor_min_frequency: Option<f32>, // Optional min frequency
|
||||||
|
pub moisture_sensor_max_frequency: Option<f32>, // Optional max frequency
|
||||||
|
pub min_pump_current_ma: u16,
|
||||||
|
pub max_pump_current_ma: u16,
|
||||||
|
pub ignore_current_error: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PlantConfig {
|
impl Default for PlantConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
mode: Mode::OFF,
|
mode: PlantWateringMode::OFF,
|
||||||
target_moisture: 40,
|
target_moisture: 40.,
|
||||||
|
min_moisture: 30.,
|
||||||
pump_time_s: 30,
|
pump_time_s: 30,
|
||||||
|
pump_limit_ml: 5000,
|
||||||
pump_cooldown_min: 60,
|
pump_cooldown_min: 60,
|
||||||
pump_hour_start: 9,
|
pump_hour_start: 9,
|
||||||
pump_hour_end: 20,
|
pump_hour_end: 20,
|
||||||
|
sensor_a: true,
|
||||||
sensor_b: false,
|
sensor_b: false,
|
||||||
max_consecutive_pump_count: 10,
|
max_consecutive_pump_count: 10,
|
||||||
|
moisture_sensor_min_frequency: None, // No override by default
|
||||||
|
moisture_sensor_max_frequency: None, // No override by default
|
||||||
|
min_pump_current_ma: 10,
|
||||||
|
max_pump_current_ma: 3000,
|
||||||
|
ignore_current_error: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
|
||||||
pub enum Mode {
|
|
||||||
OFF,
|
|
||||||
TargetMoisture,
|
|
||||||
TimerOnly,
|
|
||||||
TimerAndDeadzone,
|
|
||||||
}
|
|
||||||
|
|||||||
321
rust/src/fat_error.rs
Normal file
321
rust/src/fat_error.rs
Normal file
@@ -0,0 +1,321 @@
|
|||||||
|
use alloc::format;
|
||||||
|
use alloc::string::{String, ToString};
|
||||||
|
use core::convert::Infallible;
|
||||||
|
use core::fmt;
|
||||||
|
use core::str::Utf8Error;
|
||||||
|
use embassy_embedded_hal::shared_bus::I2cDeviceError;
|
||||||
|
use embassy_executor::SpawnError;
|
||||||
|
use embassy_sync::mutex::TryLockError;
|
||||||
|
use esp_hal::i2c::master::ConfigError;
|
||||||
|
use esp_hal::pcnt::unit::{InvalidHighLimit, InvalidLowLimit};
|
||||||
|
use esp_radio::wifi::WifiError;
|
||||||
|
use ina219::errors::{BusVoltageReadError, ShuntVoltageReadError};
|
||||||
|
use littlefs2_core::PathError;
|
||||||
|
use onewire::Error;
|
||||||
|
use pca9535::ExpanderError;
|
||||||
|
|
||||||
|
//All error superconstruct
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum FatError {
|
||||||
|
OneWireError {
|
||||||
|
error: Error<Infallible>,
|
||||||
|
},
|
||||||
|
String {
|
||||||
|
error: String,
|
||||||
|
},
|
||||||
|
LittleFSError {
|
||||||
|
error: littlefs2_core::Error,
|
||||||
|
},
|
||||||
|
PathError {
|
||||||
|
error: PathError,
|
||||||
|
},
|
||||||
|
TryLockError {
|
||||||
|
error: TryLockError,
|
||||||
|
},
|
||||||
|
WifiError {
|
||||||
|
error: WifiError,
|
||||||
|
},
|
||||||
|
SerdeError {
|
||||||
|
error: serde_json::Error,
|
||||||
|
},
|
||||||
|
PreconditionFailed {
|
||||||
|
error: String,
|
||||||
|
},
|
||||||
|
NoBatteryMonitor,
|
||||||
|
SpawnError {
|
||||||
|
error: SpawnError,
|
||||||
|
},
|
||||||
|
OTAError,
|
||||||
|
PartitionError {
|
||||||
|
error: esp_bootloader_esp_idf::partitions::Error,
|
||||||
|
},
|
||||||
|
I2CConfigError {
|
||||||
|
error: ConfigError,
|
||||||
|
},
|
||||||
|
DS323 {
|
||||||
|
error: String,
|
||||||
|
},
|
||||||
|
Eeprom24x {
|
||||||
|
error: String,
|
||||||
|
},
|
||||||
|
ExpanderError {
|
||||||
|
error: String,
|
||||||
|
},
|
||||||
|
SNTPError {
|
||||||
|
error: sntpc::Error,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type FatResult<T> = Result<T, FatError>;
|
||||||
|
|
||||||
|
impl fmt::Display for FatError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
FatError::SpawnError { error } => {
|
||||||
|
write!(f, "SpawnError {:?}", error.to_string())
|
||||||
|
}
|
||||||
|
FatError::OneWireError { error } => write!(f, "OneWireError {:?}", error),
|
||||||
|
FatError::String { error } => write!(f, "{}", error),
|
||||||
|
FatError::LittleFSError { error } => write!(f, "LittleFSError {:?}", error),
|
||||||
|
FatError::PathError { error } => write!(f, "PathError {:?}", error),
|
||||||
|
FatError::TryLockError { error } => write!(f, "TryLockError {:?}", error),
|
||||||
|
FatError::WifiError { error } => write!(f, "WifiError {:?}", error),
|
||||||
|
FatError::SerdeError { error } => write!(f, "SerdeError {:?}", error),
|
||||||
|
FatError::PreconditionFailed { error } => write!(f, "PreconditionFailed {:?}", error),
|
||||||
|
FatError::PartitionError { error } => {
|
||||||
|
write!(f, "PartitionError {:?}", error)
|
||||||
|
}
|
||||||
|
FatError::NoBatteryMonitor => {
|
||||||
|
write!(f, "No Battery Monitor")
|
||||||
|
}
|
||||||
|
FatError::I2CConfigError { error } => write!(f, "I2CConfigError {:?}", error),
|
||||||
|
FatError::DS323 { error } => write!(f, "DS323 {:?}", error),
|
||||||
|
FatError::Eeprom24x { error } => write!(f, "Eeprom24x {:?}", error),
|
||||||
|
FatError::ExpanderError { error } => write!(f, "ExpanderError {:?}", error),
|
||||||
|
FatError::SNTPError { error } => write!(f, "SNTPError {error:?}"),
|
||||||
|
FatError::OTAError => {
|
||||||
|
write!(f, "OTA missing partition")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! bail {
|
||||||
|
($msg:literal $(,)?) => {
|
||||||
|
return $crate::fat_error::fat_bail($msg)
|
||||||
|
};
|
||||||
|
($fmt:literal, $($arg:tt)*) => {
|
||||||
|
return $crate::fat_error::fat_bail(&alloc::format!($fmt, $($arg)*))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fat_bail<X>(message: &str) -> Result<X, FatError> {
|
||||||
|
Err(FatError::String {
|
||||||
|
error: message.to_string(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ContextExt<T> {
|
||||||
|
fn context<C>(self, context: C) -> Result<T, FatError>
|
||||||
|
where
|
||||||
|
C: AsRef<str>;
|
||||||
|
}
|
||||||
|
impl<T> ContextExt<T> for Option<T> {
|
||||||
|
fn context<C>(self, context: C) -> Result<T, FatError>
|
||||||
|
where
|
||||||
|
C: AsRef<str>,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
Some(value) => Ok(value),
|
||||||
|
None => Err(FatError::PreconditionFailed {
|
||||||
|
error: context.as_ref().to_string(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, E> ContextExt<T> for Result<T, E>
|
||||||
|
where
|
||||||
|
E: fmt::Debug,
|
||||||
|
{
|
||||||
|
fn context<C>(self, context: C) -> Result<T, FatError>
|
||||||
|
where
|
||||||
|
C: AsRef<str>,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
Ok(value) => Ok(value),
|
||||||
|
Err(err) => Err(FatError::String {
|
||||||
|
error: format!("{}: {:?}", context.as_ref(), err),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl From<Error<Infallible>> for FatError {
|
||||||
|
fn from(error: Error<Infallible>) -> Self {
|
||||||
|
FatError::OneWireError { error }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<littlefs2_core::Error> for FatError {
|
||||||
|
fn from(value: littlefs2_core::Error) -> Self {
|
||||||
|
FatError::LittleFSError { error: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<PathError> for FatError {
|
||||||
|
fn from(value: PathError) -> Self {
|
||||||
|
FatError::PathError { error: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<TryLockError> for FatError {
|
||||||
|
fn from(value: TryLockError) -> Self {
|
||||||
|
FatError::TryLockError { error: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<WifiError> for FatError {
|
||||||
|
fn from(value: WifiError) -> Self {
|
||||||
|
FatError::WifiError { error: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<serde_json::error::Error> for FatError {
|
||||||
|
fn from(value: serde_json::Error) -> Self {
|
||||||
|
FatError::SerdeError { error: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SpawnError> for FatError {
|
||||||
|
fn from(value: SpawnError) -> Self {
|
||||||
|
FatError::SpawnError { error: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<sntpc::Error> for FatError {
|
||||||
|
fn from(value: sntpc::Error) -> Self {
|
||||||
|
FatError::SNTPError { error: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<esp_bootloader_esp_idf::partitions::Error> for FatError {
|
||||||
|
fn from(value: esp_bootloader_esp_idf::partitions::Error) -> Self {
|
||||||
|
FatError::PartitionError { error: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Utf8Error> for FatError {
|
||||||
|
fn from(value: Utf8Error) -> Self {
|
||||||
|
FatError::String {
|
||||||
|
error: value.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: core::fmt::Debug> From<edge_http::io::Error<E>> for FatError {
|
||||||
|
fn from(value: edge_http::io::Error<E>) -> Self {
|
||||||
|
FatError::String {
|
||||||
|
error: format!("{:?}", value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: core::fmt::Debug> From<ds323x::Error<E>> for FatError {
|
||||||
|
fn from(value: ds323x::Error<E>) -> Self {
|
||||||
|
FatError::DS323 {
|
||||||
|
error: format!("{:?}", value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: core::fmt::Debug> From<eeprom24x::Error<E>> for FatError {
|
||||||
|
fn from(value: eeprom24x::Error<E>) -> Self {
|
||||||
|
FatError::Eeprom24x {
|
||||||
|
error: format!("{:?}", value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: core::fmt::Debug> From<ExpanderError<I2cDeviceError<E>>> for FatError {
|
||||||
|
fn from(value: ExpanderError<I2cDeviceError<E>>) -> Self {
|
||||||
|
FatError::ExpanderError {
|
||||||
|
error: format!("{:?}", value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<bincode::error::DecodeError> for FatError {
|
||||||
|
fn from(value: bincode::error::DecodeError) -> Self {
|
||||||
|
FatError::Eeprom24x {
|
||||||
|
error: format!("{:?}", value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<bincode::error::EncodeError> for FatError {
|
||||||
|
fn from(value: bincode::error::EncodeError) -> Self {
|
||||||
|
FatError::Eeprom24x {
|
||||||
|
error: format!("{:?}", value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ConfigError> for FatError {
|
||||||
|
fn from(value: ConfigError) -> Self {
|
||||||
|
FatError::I2CConfigError { error: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: core::fmt::Debug> From<I2cDeviceError<E>> for FatError {
|
||||||
|
fn from(value: I2cDeviceError<E>) -> Self {
|
||||||
|
FatError::String {
|
||||||
|
error: format!("{:?}", value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: core::fmt::Debug> From<BusVoltageReadError<I2cDeviceError<E>>> for FatError {
|
||||||
|
fn from(value: BusVoltageReadError<I2cDeviceError<E>>) -> Self {
|
||||||
|
FatError::String {
|
||||||
|
error: format!("{:?}", value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<E: core::fmt::Debug> From<ShuntVoltageReadError<I2cDeviceError<E>>> for FatError {
|
||||||
|
fn from(value: ShuntVoltageReadError<I2cDeviceError<E>>) -> Self {
|
||||||
|
FatError::String {
|
||||||
|
error: format!("{:?}", value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Infallible> for FatError {
|
||||||
|
fn from(value: Infallible) -> Self {
|
||||||
|
panic!("Infallible error: {:?}", value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<InvalidLowLimit> for FatError {
|
||||||
|
fn from(value: InvalidLowLimit) -> Self {
|
||||||
|
FatError::String {
|
||||||
|
error: format!("{:?}", value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<InvalidHighLimit> for FatError {
|
||||||
|
fn from(value: InvalidHighLimit) -> Self {
|
||||||
|
FatError::String {
|
||||||
|
error: format!("{:?}", value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<chrono::format::ParseError> for FatError {
|
||||||
|
fn from(value: chrono::format::ParseError) -> Self {
|
||||||
|
FatError::String {
|
||||||
|
error: format!("Parsing error: {value:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
265
rust/src/hal/battery.rs
Normal file
265
rust/src/hal/battery.rs
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
use crate::fat_error::{FatError, FatResult};
|
||||||
|
use crate::hal::Box;
|
||||||
|
use alloc::string::String;
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use bq34z100::{Bq34z100g1, Bq34z100g1Driver, Flags};
|
||||||
|
use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
|
||||||
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
|
use esp_hal::delay::Delay;
|
||||||
|
use esp_hal::i2c::master::I2c;
|
||||||
|
use esp_hal::Blocking;
|
||||||
|
use measurements::Temperature;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
pub trait BatteryInteraction {
|
||||||
|
async fn state_charge_percent(&mut self) -> FatResult<f32>;
|
||||||
|
async fn remaining_milli_ampere_hour(&mut self) -> FatResult<u16>;
|
||||||
|
async fn max_milli_ampere_hour(&mut self) -> FatResult<u16>;
|
||||||
|
async fn design_milli_ampere_hour(&mut self) -> FatResult<u16>;
|
||||||
|
async fn voltage_milli_volt(&mut self) -> FatResult<u16>;
|
||||||
|
async fn average_current_milli_ampere(&mut self) -> FatResult<i16>;
|
||||||
|
async fn cycle_count(&mut self) -> FatResult<u16>;
|
||||||
|
async fn state_health_percent(&mut self) -> FatResult<u16>;
|
||||||
|
async fn bat_temperature(&mut self) -> FatResult<u16>;
|
||||||
|
async fn get_battery_state(&mut self) -> FatResult<BatteryState>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub struct BatteryInfo {
|
||||||
|
pub voltage_milli_volt: u16,
|
||||||
|
pub average_current_milli_ampere: i16,
|
||||||
|
pub cycle_count: u16,
|
||||||
|
pub design_milli_ampere_hour: u16,
|
||||||
|
pub remaining_milli_ampere_hour: u16,
|
||||||
|
pub state_of_charge: f32,
|
||||||
|
pub state_of_health: u16,
|
||||||
|
pub temperature: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub enum BatteryError {
|
||||||
|
NoBatteryMonitor,
|
||||||
|
CommunicationError(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub enum BatteryState {
|
||||||
|
Unknown,
|
||||||
|
Info(BatteryInfo),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If no battery monitor is installed this implementation will be used
|
||||||
|
pub struct NoBatteryMonitor {}
|
||||||
|
#[async_trait]
|
||||||
|
impl BatteryInteraction for NoBatteryMonitor {
|
||||||
|
async fn state_charge_percent(&mut self) -> FatResult<f32> {
|
||||||
|
// No monitor configured: assume full battery for lightstate logic
|
||||||
|
Ok(100.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn remaining_milli_ampere_hour(&mut self) -> FatResult<u16> {
|
||||||
|
Err(FatError::NoBatteryMonitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn max_milli_ampere_hour(&mut self) -> FatResult<u16> {
|
||||||
|
Err(FatError::NoBatteryMonitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn design_milli_ampere_hour(&mut self) -> FatResult<u16> {
|
||||||
|
Err(FatError::NoBatteryMonitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn voltage_milli_volt(&mut self) -> FatResult<u16> {
|
||||||
|
Err(FatError::NoBatteryMonitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn average_current_milli_ampere(&mut self) -> FatResult<i16> {
|
||||||
|
Err(FatError::NoBatteryMonitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn cycle_count(&mut self) -> FatResult<u16> {
|
||||||
|
Err(FatError::NoBatteryMonitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn state_health_percent(&mut self) -> FatResult<u16> {
|
||||||
|
Err(FatError::NoBatteryMonitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn bat_temperature(&mut self) -> FatResult<u16> {
|
||||||
|
Err(FatError::NoBatteryMonitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_battery_state(&mut self) -> FatResult<BatteryState> {
|
||||||
|
Ok(BatteryState::Unknown)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO implement this battery monitor kind once controller is complete
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct WchI2cSlave {}
|
||||||
|
|
||||||
|
pub type I2cDev = I2cDevice<'static, CriticalSectionRawMutex, I2c<'static, Blocking>>;
|
||||||
|
|
||||||
|
pub struct BQ34Z100G1 {
|
||||||
|
pub battery_driver: Bq34z100g1Driver<I2cDev, Delay>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl BatteryInteraction for BQ34Z100G1 {
|
||||||
|
async fn state_charge_percent(&mut self) -> FatResult<f32> {
|
||||||
|
self.battery_driver
|
||||||
|
.state_of_charge()
|
||||||
|
.map(|v| v as f32)
|
||||||
|
.map_err(|e| FatError::String {
|
||||||
|
error: alloc::format!("{:?}", e),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn remaining_milli_ampere_hour(&mut self) -> FatResult<u16> {
|
||||||
|
self.battery_driver
|
||||||
|
.remaining_capacity()
|
||||||
|
.map_err(|e| FatError::String {
|
||||||
|
error: alloc::format!("{:?}", e),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn max_milli_ampere_hour(&mut self) -> FatResult<u16> {
|
||||||
|
self.battery_driver
|
||||||
|
.full_charge_capacity()
|
||||||
|
.map_err(|e| FatError::String {
|
||||||
|
error: alloc::format!("{:?}", e),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn design_milli_ampere_hour(&mut self) -> FatResult<u16> {
|
||||||
|
self.battery_driver
|
||||||
|
.design_capacity()
|
||||||
|
.map_err(|e| FatError::String {
|
||||||
|
error: alloc::format!("{:?}", e),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn voltage_milli_volt(&mut self) -> FatResult<u16> {
|
||||||
|
self.battery_driver.voltage().map_err(|e| FatError::String {
|
||||||
|
error: alloc::format!("{:?}", e),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn average_current_milli_ampere(&mut self) -> FatResult<i16> {
|
||||||
|
self.battery_driver
|
||||||
|
.average_current()
|
||||||
|
.map_err(|e| FatError::String {
|
||||||
|
error: alloc::format!("{:?}", e),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn cycle_count(&mut self) -> FatResult<u16> {
|
||||||
|
self.battery_driver
|
||||||
|
.cycle_count()
|
||||||
|
.map_err(|e| FatError::String {
|
||||||
|
error: alloc::format!("{:?}", e),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn state_health_percent(&mut self) -> FatResult<u16> {
|
||||||
|
self.battery_driver
|
||||||
|
.state_of_health()
|
||||||
|
.map_err(|e| FatError::String {
|
||||||
|
error: alloc::format!("{:?}", e),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn bat_temperature(&mut self) -> FatResult<u16> {
|
||||||
|
self.battery_driver
|
||||||
|
.temperature()
|
||||||
|
.map_err(|e| FatError::String {
|
||||||
|
error: alloc::format!("{:?}", e),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_battery_state(&mut self) -> FatResult<BatteryState> {
|
||||||
|
Ok(BatteryState::Info(BatteryInfo {
|
||||||
|
voltage_milli_volt: self.voltage_milli_volt().await?,
|
||||||
|
average_current_milli_ampere: self.average_current_milli_ampere().await?,
|
||||||
|
cycle_count: self.cycle_count().await?,
|
||||||
|
design_milli_ampere_hour: self.design_milli_ampere_hour().await?,
|
||||||
|
remaining_milli_ampere_hour: self.remaining_milli_ampere_hour().await?,
|
||||||
|
state_of_charge: self.state_charge_percent().await?,
|
||||||
|
state_of_health: self.state_health_percent().await?,
|
||||||
|
temperature: self.bat_temperature().await?,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_battery_bq34z100(
|
||||||
|
battery_driver: &mut Bq34z100g1Driver<I2cDevice<CriticalSectionRawMutex, I2c<Blocking>>, Delay>,
|
||||||
|
) -> FatResult<()> {
|
||||||
|
log::info!("Try communicating with battery");
|
||||||
|
let fwversion = battery_driver.fw_version().unwrap_or_else(|e| {
|
||||||
|
log::info!("Firmware {:?}", e);
|
||||||
|
0
|
||||||
|
});
|
||||||
|
log::info!("fw version is {}", fwversion);
|
||||||
|
|
||||||
|
let design_capacity = battery_driver.design_capacity().unwrap_or_else(|e| {
|
||||||
|
log::info!("Design capacity {:?}", e);
|
||||||
|
0
|
||||||
|
});
|
||||||
|
log::info!("Design Capacity {}", design_capacity);
|
||||||
|
if design_capacity == 1000 {
|
||||||
|
log::info!("Still stock configuring battery, readouts are likely to be wrong!");
|
||||||
|
}
|
||||||
|
|
||||||
|
let flags = battery_driver.get_flags_decoded().unwrap_or(Flags {
|
||||||
|
fast_charge_allowed: false,
|
||||||
|
full_chage: false,
|
||||||
|
charging_not_allowed: false,
|
||||||
|
charge_inhibit: false,
|
||||||
|
bat_low: false,
|
||||||
|
bat_high: false,
|
||||||
|
over_temp_discharge: false,
|
||||||
|
over_temp_charge: false,
|
||||||
|
discharge: false,
|
||||||
|
state_of_charge_f: false,
|
||||||
|
state_of_charge_1: false,
|
||||||
|
cf: false,
|
||||||
|
ocv_taken: false,
|
||||||
|
});
|
||||||
|
log::info!("Flags {:?}", flags);
|
||||||
|
|
||||||
|
let chem_id = battery_driver.chem_id().unwrap_or_else(|e| {
|
||||||
|
log::info!("Chemid {:?}", e);
|
||||||
|
0
|
||||||
|
});
|
||||||
|
|
||||||
|
let bat_temp = battery_driver.internal_temperature().unwrap_or_else(|e| {
|
||||||
|
log::info!("Bat Temp {:?}", e);
|
||||||
|
0
|
||||||
|
});
|
||||||
|
let temp_c = Temperature::from_kelvin(bat_temp as f64 / 10_f64).as_celsius();
|
||||||
|
let voltage = battery_driver.voltage().unwrap_or_else(|e| {
|
||||||
|
log::info!("Bat volt {:?}", e);
|
||||||
|
0
|
||||||
|
});
|
||||||
|
let current = battery_driver.current().unwrap_or_else(|e| {
|
||||||
|
log::info!("Bat current {:?}", e);
|
||||||
|
0
|
||||||
|
});
|
||||||
|
let state = battery_driver.state_of_charge().unwrap_or_else(|e| {
|
||||||
|
log::info!("Bat Soc {:?}", e);
|
||||||
|
0
|
||||||
|
});
|
||||||
|
let charge_voltage = battery_driver.charge_voltage().unwrap_or_else(|e| {
|
||||||
|
log::info!("Bat Charge Volt {:?}", e);
|
||||||
|
0
|
||||||
|
});
|
||||||
|
let charge_current = battery_driver.charge_current().unwrap_or_else(|e| {
|
||||||
|
log::info!("Bat Charge Current {:?}", e);
|
||||||
|
0
|
||||||
|
});
|
||||||
|
log::info!("ChemId: {} Current voltage {} and current {} with charge {}% and temp {} CVolt: {} CCur {}", chem_id, voltage, current, state, temp_c, charge_voltage, charge_current);
|
||||||
|
let _ = battery_driver.unsealed();
|
||||||
|
let _ = battery_driver.it_enable();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
455
rust/src/hal/esp.rs
Normal file
455
rust/src/hal/esp.rs
Normal file
@@ -0,0 +1,455 @@
|
|||||||
|
use crate::bail;
|
||||||
|
use crate::config::{NetworkConfig, PlantControllerConfig};
|
||||||
|
use crate::hal::PLANT_COUNT;
|
||||||
|
use crate::log::{log, LogMessage};
|
||||||
|
use alloc::vec;
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use esp_hal::Blocking;
|
||||||
|
use esp_hal::uart::Uart;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use crate::fat_error::{ContextExt, FatError, FatResult};
|
||||||
|
use crate::hal::little_fs2storage_adapter::LittleFs2Filesystem;
|
||||||
|
use alloc::string::ToString;
|
||||||
|
use alloc::sync::Arc;
|
||||||
|
use alloc::{format, string::String, vec::Vec};
|
||||||
|
use core::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||||
|
use core::str::FromStr;
|
||||||
|
use core::sync::atomic::Ordering;
|
||||||
|
use embassy_executor::Spawner;
|
||||||
|
use embassy_net::{DhcpConfig, IpAddress, Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4};
|
||||||
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
|
use embassy_sync::mutex::{Mutex, MutexGuard};
|
||||||
|
use embassy_time::{Duration, Timer, WithTimeout};
|
||||||
|
use embedded_storage::nor_flash::{check_erase, NorFlash, ReadNorFlash, RmwNorFlashStorage};
|
||||||
|
use esp_bootloader_esp_idf::ota::OtaImageState::Valid;
|
||||||
|
use esp_bootloader_esp_idf::ota::{Ota, OtaImageState};
|
||||||
|
use esp_bootloader_esp_idf::partitions::{AppPartitionSubType, FlashRegion};
|
||||||
|
use esp_hal::gpio::{Input, RtcPinWithResistors};
|
||||||
|
use esp_hal::rng::Rng;
|
||||||
|
use esp_hal::rtc_cntl::{
|
||||||
|
sleep::{TimerWakeupSource, WakeupLevel},
|
||||||
|
Rtc,
|
||||||
|
};
|
||||||
|
use esp_hal::system::software_reset;
|
||||||
|
use esp_println::println;
|
||||||
|
use esp_radio::wifi::ap::{AccessPointConfig, AccessPointInfo};
|
||||||
|
use esp_radio::wifi::scan::{ScanConfig, ScanTypeConfig};
|
||||||
|
use esp_radio::wifi::sta::StationConfig;
|
||||||
|
use esp_radio::wifi::{AuthenticationMethod, Config, Interface, WifiController};
|
||||||
|
use esp_storage::FlashStorage;
|
||||||
|
use littlefs2::fs::Filesystem;
|
||||||
|
use littlefs2_core::{FileType, PathBuf, SeekFrom};
|
||||||
|
use log::{info, warn, error};
|
||||||
|
use portable_atomic::AtomicBool;
|
||||||
|
|
||||||
|
use super::shared_flash::MutexFlashStorage;
|
||||||
|
use crate::network::{net_task, run_dhcp};
|
||||||
|
|
||||||
|
#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))]
|
||||||
|
static mut LAST_WATERING_TIMESTAMP: [i64; PLANT_COUNT] = [0; PLANT_COUNT];
|
||||||
|
#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))]
|
||||||
|
static mut CONSECUTIVE_WATERING_PLANT: [u32; PLANT_COUNT] = [0; PLANT_COUNT];
|
||||||
|
#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))]
|
||||||
|
static mut LOW_VOLTAGE_DETECTED: i8 = 0;
|
||||||
|
#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))]
|
||||||
|
static mut RESTART_TO_CONF: i8 = 0;
|
||||||
|
#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))]
|
||||||
|
static mut LAST_CORROSION_PROTECTION_CHECK_DAY: i8 = -1;
|
||||||
|
|
||||||
|
|
||||||
|
const CONFIG_FILE: &str = "config.json";
|
||||||
|
|
||||||
|
#[derive(Serialize, Debug)]
|
||||||
|
pub struct FileInfo {
|
||||||
|
filename: String,
|
||||||
|
size: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Debug)]
|
||||||
|
pub struct FileList {
|
||||||
|
total: usize,
|
||||||
|
used: usize,
|
||||||
|
files: Vec<FileInfo>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Minimal esp-idf equivalent for gpio_hold on esp32c6 via ROM functions
|
||||||
|
extern "C" {
|
||||||
|
fn gpio_pad_hold(gpio_num: u32);
|
||||||
|
fn gpio_pad_unhold(gpio_num: u32);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn hold_enable(gpio_num: u8) {
|
||||||
|
unsafe { gpio_pad_hold(gpio_num as u32) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn hold_disable(gpio_num: u8) {
|
||||||
|
unsafe { gpio_pad_unhold(gpio_num as u32) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Esp<'a> {
|
||||||
|
pub fs: Arc<Mutex<CriticalSectionRawMutex, Filesystem<'static, LittleFs2Filesystem>>>,
|
||||||
|
pub rng: Rng,
|
||||||
|
//first starter (ap or sta will take these)
|
||||||
|
pub interface_sta: Option<Interface<'static>>,
|
||||||
|
pub interface_ap: Option<Interface<'static>>,
|
||||||
|
pub controller: Arc<Mutex<CriticalSectionRawMutex, WifiController<'static>>>,
|
||||||
|
|
||||||
|
pub boot_button: Input<'a>,
|
||||||
|
|
||||||
|
// RTC-capable GPIO used as external wake source (store the raw peripheral)
|
||||||
|
pub wake_gpio1: esp_hal::peripherals::GPIO1<'static>,
|
||||||
|
pub uart0: Uart<'a, Blocking>,
|
||||||
|
|
||||||
|
pub rtc: Rtc<'a>,
|
||||||
|
|
||||||
|
pub ota: Ota<'static, RmwNorFlashStorage<'static, &'static mut MutexFlashStorage>>,
|
||||||
|
pub ota_target: &'static mut FlashRegion<'static, MutexFlashStorage>,
|
||||||
|
pub current: AppPartitionSubType,
|
||||||
|
pub slot0_state: OtaImageState,
|
||||||
|
pub slot1_state: OtaImageState,
|
||||||
|
}
|
||||||
|
|
||||||
|
// SAFETY: On this target we never move Esp across OS threads; the firmware runs single-core
|
||||||
|
// cooperative tasks with Embassy. All interior mutability of non-Send peripherals is gated
|
||||||
|
// behind &mut self or embassy_sync Mutex with CriticalSectionRawMutex, which does not rely on
|
||||||
|
// thread scheduling. Therefore it is sound to mark Esp as Send to satisfy trait object bounds
|
||||||
|
// (e.g., Box<dyn BoardInteraction + Send>). If you add fields that are accessed from multiple
|
||||||
|
// CPU cores/threads, reconsider this.
|
||||||
|
unsafe impl Send for Esp<'_> {}
|
||||||
|
|
||||||
|
impl Esp<'_> {
|
||||||
|
pub fn get_time(&self) -> DateTime<Utc> {
|
||||||
|
DateTime::from_timestamp_micros(self.rtc.current_time_us() as i64)
|
||||||
|
.unwrap_or(DateTime::UNIX_EPOCH)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_time(&mut self, time: DateTime<Utc>) {
|
||||||
|
self.rtc.set_current_time_us(time.timestamp_micros() as u64);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn read_serial_line(&mut self) -> FatResult<Option<alloc::string::String>> {
|
||||||
|
let mut buf = [0u8; 1];
|
||||||
|
let mut line = String::new();
|
||||||
|
loop {
|
||||||
|
match self.uart0.read_buffered(&mut buf) {
|
||||||
|
Ok(read) => {
|
||||||
|
if read == 0 {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
let c = buf[0] as char;
|
||||||
|
if c == '\n' {
|
||||||
|
return Ok(Some(line));
|
||||||
|
}
|
||||||
|
line.push(c);
|
||||||
|
}
|
||||||
|
Err(error) => {
|
||||||
|
if line.is_empty() {
|
||||||
|
return Ok(None);
|
||||||
|
} else {
|
||||||
|
error!("Error reading serial line: {error:?}");
|
||||||
|
// If we already have some data, we should probably wait a bit or just return what we have?
|
||||||
|
// But the protocol expects a full line or message.
|
||||||
|
// For simplicity in config mode, we can block here or just return None if nothing is there yet.
|
||||||
|
// However, if we started receiving, we should probably finish or timeout.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub(crate) async fn delete_file(&self, filename: String) -> FatResult<()> {
|
||||||
|
let file = PathBuf::try_from(filename.as_str())?;
|
||||||
|
let access = self.fs.lock().await;
|
||||||
|
access.remove(&*file)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
pub(crate) async fn write_file(
|
||||||
|
&mut self,
|
||||||
|
filename: String,
|
||||||
|
offset: u32,
|
||||||
|
buf: &[u8],
|
||||||
|
) -> Result<(), FatError> {
|
||||||
|
let file = PathBuf::try_from(filename.as_str())?;
|
||||||
|
let access = self.fs.lock().await;
|
||||||
|
access.open_file_with_options_and_then(
|
||||||
|
|options| options.read(true).write(true).create(true),
|
||||||
|
&*file,
|
||||||
|
|file| {
|
||||||
|
file.seek(SeekFrom::Start(offset))?;
|
||||||
|
file.write(buf)?;
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_size(&mut self, filename: String) -> FatResult<usize> {
|
||||||
|
let file = PathBuf::try_from(filename.as_str())?;
|
||||||
|
let access = self.fs.lock().await;
|
||||||
|
let data = access.metadata(&*file)?;
|
||||||
|
Ok(data.len())
|
||||||
|
}
|
||||||
|
pub(crate) async fn get_file(
|
||||||
|
&mut self,
|
||||||
|
filename: String,
|
||||||
|
chunk: u32,
|
||||||
|
) -> FatResult<([u8; 512], usize)> {
|
||||||
|
use littlefs2::io::Error as lfs2Error;
|
||||||
|
|
||||||
|
let file = PathBuf::try_from(filename.as_str())?;
|
||||||
|
let access = self.fs.lock().await;
|
||||||
|
let mut buf = [0_u8; 512];
|
||||||
|
let mut read = 0;
|
||||||
|
let offset = chunk * buf.len() as u32;
|
||||||
|
access.open_file_with_options_and_then(
|
||||||
|
|options| options.read(true),
|
||||||
|
&*file,
|
||||||
|
|file| {
|
||||||
|
let length = file.len()? as u32;
|
||||||
|
if length == 0 {
|
||||||
|
Err(lfs2Error::IO)
|
||||||
|
} else if length > offset {
|
||||||
|
file.seek(SeekFrom::Start(offset))?;
|
||||||
|
read = file.read(&mut buf)?;
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
//exactly at end, do nothing
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
Ok((buf, read))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn write_ota(&mut self, offset: u32, buf: &[u8]) -> Result<(), FatError> {
|
||||||
|
let _ = check_erase(self.ota_target, offset, offset + 4096);
|
||||||
|
info!("erasing and writing block 0x{offset:x}");
|
||||||
|
self.ota_target.erase(offset, offset + 4096)?;
|
||||||
|
|
||||||
|
let mut temp = vec![0; buf.len()];
|
||||||
|
let read_back = temp.as_mut_slice();
|
||||||
|
//change to nor flash, align writes!
|
||||||
|
self.ota_target.write(offset, buf)?;
|
||||||
|
self.ota_target.read(offset, read_back)?;
|
||||||
|
if buf != read_back {
|
||||||
|
info!("Expected {buf:?} but got {read_back:?}");
|
||||||
|
bail!(
|
||||||
|
"Flash error, read back does not match write buffer at offset {:x}",
|
||||||
|
offset
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn finalize_ota(&mut self) -> Result<(), FatError> {
|
||||||
|
let current = self.ota.current_app_partition()?;
|
||||||
|
if self.ota.current_ota_state()? != Valid {
|
||||||
|
info!("Validating current slot {current:?} as it was able to ota");
|
||||||
|
self.ota.set_current_ota_state(Valid)?;
|
||||||
|
}
|
||||||
|
let next = match current {
|
||||||
|
AppPartitionSubType::Ota0 => AppPartitionSubType::Ota1,
|
||||||
|
AppPartitionSubType::Ota1 => AppPartitionSubType::Ota0,
|
||||||
|
_ => {
|
||||||
|
bail!("Invalid current slot {current:?} for ota");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
self.ota.set_current_app_partition(next)?;
|
||||||
|
info!("switched slot");
|
||||||
|
self.ota.set_current_ota_state(OtaImageState::New)?;
|
||||||
|
info!("switched state for new partition");
|
||||||
|
let state_new = self.ota.current_ota_state()?;
|
||||||
|
info!("state on new partition now {state_new:?}");
|
||||||
|
self.set_restart_to_conf(true);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// let current = ota.current_slot()?;
|
||||||
|
// println!(
|
||||||
|
// "current image state {:?} (only relevant if the bootloader was built with auto-rollback support)",
|
||||||
|
// ota.current_ota_state()
|
||||||
|
// );
|
||||||
|
// println!("current {:?} - next {:?}", current, current.next());
|
||||||
|
// let ota_state = ota.current_ota_state()?;
|
||||||
|
|
||||||
|
pub(crate) fn mode_override_pressed(&mut self) -> bool {
|
||||||
|
self.boot_button.is_low()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn wifi_scan(&mut self) -> FatResult<Vec<AccessPointInfo>> {
|
||||||
|
info!("start wifi scan");
|
||||||
|
let mut lock = self.controller.try_lock()?;
|
||||||
|
info!("start wifi scan lock");
|
||||||
|
let scan_config = ScanConfig::default().with_scan_type(ScanTypeConfig::Active {
|
||||||
|
min: esp_hal::time::Duration::from_millis(0),
|
||||||
|
max: esp_hal::time::Duration::from_millis(0),
|
||||||
|
});
|
||||||
|
let rv = lock.scan_async(&scan_config).await?;
|
||||||
|
info!("end wifi scan lock");
|
||||||
|
Ok(rv)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn last_pump_time(&self, plant: usize) -> Option<DateTime<Utc>> {
|
||||||
|
let ts = unsafe { LAST_WATERING_TIMESTAMP }[plant];
|
||||||
|
DateTime::from_timestamp_millis(ts)
|
||||||
|
}
|
||||||
|
pub(crate) fn store_last_pump_time(&mut self, plant: usize, time: DateTime<Utc>) {
|
||||||
|
unsafe {
|
||||||
|
LAST_WATERING_TIMESTAMP[plant] = time.timestamp_millis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub(crate) fn set_low_voltage_in_cycle(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
LOW_VOLTAGE_DETECTED = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub(crate) fn clear_low_voltage_in_cycle(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
LOW_VOLTAGE_DETECTED = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn low_voltage_in_cycle(&mut self) -> bool {
|
||||||
|
unsafe { LOW_VOLTAGE_DETECTED == 1 }
|
||||||
|
}
|
||||||
|
pub(crate) fn store_consecutive_pump_count(&mut self, plant: usize, count: u32) {
|
||||||
|
unsafe {
|
||||||
|
CONSECUTIVE_WATERING_PLANT[plant] = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub(crate) fn consecutive_pump_count(&mut self, plant: usize) -> u32 {
|
||||||
|
unsafe { CONSECUTIVE_WATERING_PLANT[plant] }
|
||||||
|
}
|
||||||
|
pub(crate) fn get_restart_to_conf(&mut self) -> bool {
|
||||||
|
unsafe { RESTART_TO_CONF == 1 }
|
||||||
|
}
|
||||||
|
pub(crate) fn set_restart_to_conf(&mut self, to_conf: bool) {
|
||||||
|
unsafe {
|
||||||
|
if to_conf {
|
||||||
|
RESTART_TO_CONF = 1;
|
||||||
|
} else {
|
||||||
|
RESTART_TO_CONF = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deep_sleep_ms(&mut self, duration_in_ms: u64) -> ! {
|
||||||
|
// Mark the current OTA image as valid if we reached here while in pending verify.
|
||||||
|
if let Ok(cur) = self.ota.current_ota_state() {
|
||||||
|
if cur == OtaImageState::PendingVerify {
|
||||||
|
info!("Marking OTA image as valid");
|
||||||
|
if let Err(err) = self.ota.set_current_ota_state(Valid) {
|
||||||
|
error!("Could not set image to valid: {:?}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
info!("No OTA image to mark as valid");
|
||||||
|
}
|
||||||
|
|
||||||
|
if duration_in_ms == 0 {
|
||||||
|
software_reset();
|
||||||
|
} else {
|
||||||
|
let timer = TimerWakeupSource::new(core::time::Duration::from_millis(duration_in_ms));
|
||||||
|
let mut wake_pins: [(&mut dyn RtcPinWithResistors, WakeupLevel); 1] =
|
||||||
|
[(&mut self.wake_gpio1, WakeupLevel::Low)];
|
||||||
|
let ext1 = esp_hal::rtc_cntl::sleep::Ext1WakeupSource::new(&mut wake_pins);
|
||||||
|
self.rtc.sleep_deep(&[&timer, &ext1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn load_config(&mut self) -> FatResult<PlantControllerConfig> {
|
||||||
|
let cfg = PathBuf::try_from(CONFIG_FILE).unwrap();
|
||||||
|
let data = self.fs.lock().await.read::<4096>(&cfg)?;
|
||||||
|
let config: PlantControllerConfig = serde_json::from_slice(&data)?;
|
||||||
|
return Ok(config);
|
||||||
|
}
|
||||||
|
pub(crate) async fn save_config(&mut self, config: Vec<u8>) -> FatResult<()> {
|
||||||
|
let filesystem = self.fs.lock().await;
|
||||||
|
let cfg = PathBuf::try_from(CONFIG_FILE)?;
|
||||||
|
filesystem.write(&cfg, &*config)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
pub(crate) async fn list_files(&self) -> FatResult<FileList> {
|
||||||
|
let path = PathBuf::new();
|
||||||
|
|
||||||
|
let fs = self.fs.lock().await;
|
||||||
|
let free_size = fs.available_space()?;
|
||||||
|
let total_size = fs.total_space();
|
||||||
|
|
||||||
|
let mut result = FileList {
|
||||||
|
total: total_size,
|
||||||
|
used: total_size - free_size,
|
||||||
|
files: Vec::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
fs.read_dir_and_then(&path, |dir| {
|
||||||
|
for entry in dir {
|
||||||
|
let e = entry?;
|
||||||
|
if e.file_type() == FileType::File {
|
||||||
|
result.files.push(FileInfo {
|
||||||
|
filename: e.path().to_string(),
|
||||||
|
size: e.metadata().len(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn init_rtc_deepsleep_memory(
|
||||||
|
&self,
|
||||||
|
init_rtc_store: bool,
|
||||||
|
to_config_mode: bool,
|
||||||
|
) {
|
||||||
|
if init_rtc_store {
|
||||||
|
unsafe {
|
||||||
|
LAST_WATERING_TIMESTAMP = [0; PLANT_COUNT];
|
||||||
|
CONSECUTIVE_WATERING_PLANT = [0; PLANT_COUNT];
|
||||||
|
LOW_VOLTAGE_DETECTED = 0;
|
||||||
|
if to_config_mode {
|
||||||
|
RESTART_TO_CONF = 1
|
||||||
|
} else {
|
||||||
|
RESTART_TO_CONF = 0;
|
||||||
|
}
|
||||||
|
LAST_CORROSION_PROTECTION_CHECK_DAY = -1;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
unsafe {
|
||||||
|
if to_config_mode {
|
||||||
|
RESTART_TO_CONF = 1;
|
||||||
|
}
|
||||||
|
log(
|
||||||
|
LogMessage::RestartToConfig,
|
||||||
|
RESTART_TO_CONF as u32,
|
||||||
|
0,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
log(
|
||||||
|
LogMessage::LowVoltage,
|
||||||
|
LOW_VOLTAGE_DETECTED as u32,
|
||||||
|
0,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
// is executed before main, no other code will alter these values during printing
|
||||||
|
#[allow(static_mut_refs)]
|
||||||
|
for (i, time) in LAST_WATERING_TIMESTAMP.iter().enumerate() {
|
||||||
|
info!("LAST_WATERING_TIMESTAMP[{i}] = UTC {time}");
|
||||||
|
}
|
||||||
|
// is executed before main, no other code will alter these values during printing
|
||||||
|
#[allow(static_mut_refs)]
|
||||||
|
for (i, item) in CONSECUTIVE_WATERING_PLANT.iter().enumerate() {
|
||||||
|
info!("CONSECUTIVE_WATERING_PLANT[{i}] = {item}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
156
rust/src/hal/initial_hal.rs
Normal file
156
rust/src/hal/initial_hal.rs
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
use crate::alloc::boxed::Box;
|
||||||
|
use crate::fat_error::{FatError, FatResult};
|
||||||
|
use crate::hal::esp::Esp;
|
||||||
|
use crate::hal::rtc::{BackupHeader, RTCModuleInteraction};
|
||||||
|
use crate::hal::water::TankSensor;
|
||||||
|
use crate::hal::{BoardInteraction, FreePeripherals, Sensor};
|
||||||
|
use crate::{
|
||||||
|
bail,
|
||||||
|
config::PlantControllerConfig,
|
||||||
|
hal::battery::{BatteryInteraction, NoBatteryMonitor},
|
||||||
|
};
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use chrono::{DateTime, FixedOffset, Utc};
|
||||||
|
use esp_hal::gpio::{Level, Output, OutputConfig};
|
||||||
|
use measurements::{Current, Voltage};
|
||||||
|
|
||||||
|
pub struct Initial<'a> {
|
||||||
|
pub(crate) general_fault: Output<'a>,
|
||||||
|
pub(crate) esp: Esp<'a>,
|
||||||
|
pub(crate) config: PlantControllerConfig,
|
||||||
|
pub(crate) battery: Box<dyn BatteryInteraction + Send>,
|
||||||
|
pub rtc: Box<dyn RTCModuleInteraction + Send>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) struct NoRTC {}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl RTCModuleInteraction for NoRTC {
|
||||||
|
async fn get_backup_info(&mut self) -> Result<BackupHeader, FatError> {
|
||||||
|
bail!("Please configure board revision")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_backup_config(&mut self, _chunk: usize) -> FatResult<([u8; 32], usize, u16)> {
|
||||||
|
bail!("Please configure board revision")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn backup_config(&mut self, _offset: usize, _bytes: &[u8]) -> FatResult<()> {
|
||||||
|
bail!("Please configure board revision")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn backup_config_finalize(&mut self, _crc: u16, _length: usize) -> FatResult<()> {
|
||||||
|
bail!("Please configure board revision")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_rtc_time(&mut self) -> Result<DateTime<Utc>, FatError> {
|
||||||
|
bail!("Please configure board revision")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_rtc_time(&mut self, _time: &DateTime<Utc>) -> Result<(), FatError> {
|
||||||
|
bail!("Please configure board revision")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn create_initial_board(
|
||||||
|
free_pins: FreePeripherals<'static>,
|
||||||
|
config: PlantControllerConfig,
|
||||||
|
esp: Esp<'static>,
|
||||||
|
) -> Result<Box<dyn BoardInteraction<'static> + Send>, FatError> {
|
||||||
|
log::info!("Start initial");
|
||||||
|
let general_fault = Output::new(free_pins.gpio23, Level::Low, OutputConfig::default());
|
||||||
|
let v = Initial {
|
||||||
|
general_fault,
|
||||||
|
config,
|
||||||
|
esp,
|
||||||
|
battery: Box::new(NoBatteryMonitor {}),
|
||||||
|
rtc: Box::new(NoRTC {}),
|
||||||
|
};
|
||||||
|
Ok(Box::new(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl<'a> BoardInteraction<'a> for Initial<'a> {
|
||||||
|
fn get_tank_sensor(&mut self) -> Result<&mut TankSensor<'a>, FatError> {
|
||||||
|
bail!("Please configure board revision")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_esp(&mut self) -> &mut Esp<'a> {
|
||||||
|
&mut self.esp
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_config(&mut self) -> &PlantControllerConfig {
|
||||||
|
&self.config
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_battery_monitor(&mut self) -> &mut Box<dyn BatteryInteraction + Send> {
|
||||||
|
&mut self.battery
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_rtc_module(&mut self) -> &mut Box<dyn RTCModuleInteraction + Send> {
|
||||||
|
&mut self.rtc
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_time(&mut self) -> DateTime<Utc> {
|
||||||
|
self.esp.get_time()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_time(&mut self, time: &DateTime<FixedOffset>) -> FatResult<()> {
|
||||||
|
self.rtc.set_rtc_time(&time.to_utc()).await?;
|
||||||
|
self.esp.set_time(time.to_utc());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_charge_indicator(&mut self, _charging: bool) -> Result<(), FatError> {
|
||||||
|
bail!("Please configure board revision")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn deep_sleep_ms(&mut self, duration_in_ms: u64) -> ! {
|
||||||
|
self.esp.deep_sleep_ms(duration_in_ms);
|
||||||
|
}
|
||||||
|
fn is_day(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
async fn light(&mut self, _enable: bool) -> Result<(), FatError> {
|
||||||
|
bail!("Please configure board revision")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn pump(&mut self, _plant: usize, _enable: bool) -> Result<(), FatError> {
|
||||||
|
bail!("Please configure board revision")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn pump_current(&mut self, _plant: usize) -> Result<Current, FatError> {
|
||||||
|
bail!("Please configure board revision")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn fault(&mut self, _plant: usize, _enable: bool) -> Result<(), FatError> {
|
||||||
|
bail!("Please configure board revision")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn measure_moisture_hz(
|
||||||
|
&mut self,
|
||||||
|
_plant: usize,
|
||||||
|
_sensor: Sensor,
|
||||||
|
) -> Result<f32, FatError> {
|
||||||
|
bail!("Please configure board revision")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn general_fault(&mut self, enable: bool) {
|
||||||
|
self.general_fault.set_level(enable.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn test(&mut self) -> Result<(), FatError> {
|
||||||
|
bail!("Please configure board revision")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_config(&mut self, config: PlantControllerConfig) {
|
||||||
|
self.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_mptt_voltage(&mut self) -> Result<Voltage, FatError> {
|
||||||
|
bail!("Please configure board revision")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_mptt_current(&mut self) -> Result<Current, FatError> {
|
||||||
|
bail!("Please configure board revision")
|
||||||
|
}
|
||||||
|
}
|
||||||
88
rust/src/hal/little_fs2storage_adapter.rs
Normal file
88
rust/src/hal/little_fs2storage_adapter.rs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
use crate::hal::shared_flash::MutexFlashStorage;
|
||||||
|
use embedded_storage::nor_flash::{check_erase, NorFlash, ReadNorFlash};
|
||||||
|
use esp_bootloader_esp_idf::partitions::FlashRegion;
|
||||||
|
use littlefs2::consts::U4096 as lfsCache;
|
||||||
|
use littlefs2::consts::U512 as lfsLookahead;
|
||||||
|
use littlefs2::driver::Storage as lfs2Storage;
|
||||||
|
use littlefs2::io::Error as lfs2Error;
|
||||||
|
use littlefs2::io::Result as lfs2Result;
|
||||||
|
use log::error;
|
||||||
|
|
||||||
|
pub struct LittleFs2Filesystem {
|
||||||
|
pub(crate) storage: &'static mut FlashRegion<'static, MutexFlashStorage>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl lfs2Storage for LittleFs2Filesystem {
|
||||||
|
const READ_SIZE: usize = 4096;
|
||||||
|
const WRITE_SIZE: usize = 4096;
|
||||||
|
const BLOCK_SIZE: usize = 4096; //usually optimal for flash access
|
||||||
|
const BLOCK_COUNT: usize = 8 * 1000 * 1000 / 4096; //8Mb in 4k blocks + a little space for stupid calculation errors
|
||||||
|
const BLOCK_CYCLES: isize = 100;
|
||||||
|
type CACHE_SIZE = lfsCache;
|
||||||
|
type LOOKAHEAD_SIZE = lfsLookahead;
|
||||||
|
|
||||||
|
fn read(&mut self, off: usize, buf: &mut [u8]) -> lfs2Result<usize> {
|
||||||
|
let read_size: usize = Self::READ_SIZE;
|
||||||
|
if off % read_size != 0 {
|
||||||
|
error!("Littlefs2Filesystem read error: offset not aligned to read size offset: {off} read_size: {read_size}");
|
||||||
|
return Err(lfs2Error::IO);
|
||||||
|
}
|
||||||
|
if buf.len() % read_size != 0 {
|
||||||
|
error!("Littlefs2Filesystem read error: length not aligned to read size length: {} read_size: {}", buf.len(), read_size);
|
||||||
|
return Err(lfs2Error::IO);
|
||||||
|
}
|
||||||
|
match self.storage.read(off as u32, buf) {
|
||||||
|
Ok(..) => Ok(buf.len()),
|
||||||
|
Err(err) => {
|
||||||
|
error!("Littlefs2Filesystem read error: {err:?}");
|
||||||
|
Err(lfs2Error::IO)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&mut self, off: usize, data: &[u8]) -> lfs2Result<usize> {
|
||||||
|
let write_size: usize = Self::WRITE_SIZE;
|
||||||
|
if off % write_size != 0 {
|
||||||
|
error!("Littlefs2Filesystem write error: offset not aligned to write size offset: {off} write_size: {write_size}");
|
||||||
|
return Err(lfs2Error::IO);
|
||||||
|
}
|
||||||
|
if data.len() % write_size != 0 {
|
||||||
|
error!("Littlefs2Filesystem write error: length not aligned to write size length: {} write_size: {}", data.len(), write_size);
|
||||||
|
return Err(lfs2Error::IO);
|
||||||
|
}
|
||||||
|
match self.storage.write(off as u32, data) {
|
||||||
|
Ok(..) => Ok(data.len()),
|
||||||
|
Err(err) => {
|
||||||
|
error!("Littlefs2Filesystem write error: {err:?}");
|
||||||
|
Err(lfs2Error::IO)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn erase(&mut self, off: usize, len: usize) -> lfs2Result<usize> {
|
||||||
|
let block_size: usize = Self::BLOCK_SIZE;
|
||||||
|
if off % block_size != 0 {
|
||||||
|
error!("Littlefs2Filesystem erase error: offset not aligned to block size offset: {off} block_size: {block_size}");
|
||||||
|
return Err(lfs2Error::IO);
|
||||||
|
}
|
||||||
|
if len % block_size != 0 {
|
||||||
|
error!("Littlefs2Filesystem erase error: length not aligned to block size length: {len} block_size: {block_size}");
|
||||||
|
return Err(lfs2Error::IO);
|
||||||
|
}
|
||||||
|
|
||||||
|
match check_erase(self.storage, off as u32, (off + len) as u32) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(err) => {
|
||||||
|
error!("Littlefs2Filesystem check erase error: {err:?}");
|
||||||
|
return Err(lfs2Error::IO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match self.storage.erase(off as u32, (off + len) as u32) {
|
||||||
|
Ok(..) => Ok(len),
|
||||||
|
Err(err) => {
|
||||||
|
error!("Littlefs2Filesystem erase error: {err:?}");
|
||||||
|
Err(lfs2Error::IO)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
629
rust/src/hal/mod.rs
Normal file
629
rust/src/hal/mod.rs
Normal file
@@ -0,0 +1,629 @@
|
|||||||
|
pub(crate) mod battery;
|
||||||
|
pub mod esp;
|
||||||
|
mod initial_hal;
|
||||||
|
mod little_fs2storage_adapter;
|
||||||
|
pub(crate) mod rtc;
|
||||||
|
mod shared_flash;
|
||||||
|
mod v3_hal;
|
||||||
|
mod v3_shift_register;
|
||||||
|
mod v4_hal;
|
||||||
|
mod v4_sensor;
|
||||||
|
mod water;
|
||||||
|
|
||||||
|
use crate::alloc::string::ToString;
|
||||||
|
use crate::hal::rtc::{DS3231Module, RTCModuleInteraction};
|
||||||
|
use esp_hal::interrupt::software::SoftwareInterruptControl;
|
||||||
|
use esp_hal::peripherals::Peripherals;
|
||||||
|
use esp_hal::peripherals::ADC1;
|
||||||
|
use esp_hal::peripherals::APB_SARADC;
|
||||||
|
use esp_hal::peripherals::GPIO0;
|
||||||
|
use esp_hal::peripherals::GPIO10;
|
||||||
|
use esp_hal::peripherals::GPIO11;
|
||||||
|
use esp_hal::peripherals::GPIO12;
|
||||||
|
use esp_hal::peripherals::GPIO13;
|
||||||
|
use esp_hal::peripherals::GPIO14;
|
||||||
|
use esp_hal::peripherals::GPIO15;
|
||||||
|
use esp_hal::peripherals::GPIO16;
|
||||||
|
use esp_hal::peripherals::GPIO17;
|
||||||
|
use esp_hal::peripherals::GPIO18;
|
||||||
|
use esp_hal::peripherals::GPIO2;
|
||||||
|
use esp_hal::peripherals::GPIO21;
|
||||||
|
use esp_hal::peripherals::GPIO22;
|
||||||
|
use esp_hal::peripherals::GPIO23;
|
||||||
|
use esp_hal::peripherals::GPIO24;
|
||||||
|
use esp_hal::peripherals::GPIO25;
|
||||||
|
use esp_hal::peripherals::GPIO26;
|
||||||
|
use esp_hal::peripherals::GPIO27;
|
||||||
|
use esp_hal::peripherals::GPIO28;
|
||||||
|
use esp_hal::peripherals::GPIO29;
|
||||||
|
use esp_hal::peripherals::GPIO3;
|
||||||
|
use esp_hal::peripherals::GPIO30;
|
||||||
|
use esp_hal::peripherals::GPIO4;
|
||||||
|
use esp_hal::peripherals::GPIO5;
|
||||||
|
use esp_hal::peripherals::GPIO6;
|
||||||
|
use esp_hal::peripherals::GPIO7;
|
||||||
|
use esp_hal::peripherals::GPIO8;
|
||||||
|
use esp_hal::peripherals::PCNT;
|
||||||
|
use esp_hal::peripherals::TWAI0;
|
||||||
|
use portable_atomic::AtomicBool;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
bail,
|
||||||
|
config::{BatteryBoardVersion, BoardVersion, PlantControllerConfig},
|
||||||
|
hal::{
|
||||||
|
battery::{BatteryInteraction, NoBatteryMonitor},
|
||||||
|
esp::Esp,
|
||||||
|
},
|
||||||
|
log::LogMessage,
|
||||||
|
BOARD_ACCESS,
|
||||||
|
};
|
||||||
|
use alloc::boxed::Box;
|
||||||
|
use alloc::format;
|
||||||
|
use alloc::sync::Arc;
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use bq34z100::Bq34z100g1Driver;
|
||||||
|
use chrono::{DateTime, FixedOffset, Utc};
|
||||||
|
use core::cell::RefCell;
|
||||||
|
use ds323x::ic::DS3231;
|
||||||
|
use ds323x::interface::I2cInterface;
|
||||||
|
use ds323x::{DateTimeAccess, Ds323x};
|
||||||
|
use eeprom24x::addr_size::TwoBytes;
|
||||||
|
use eeprom24x::page_size::B32;
|
||||||
|
use eeprom24x::unique_serial::No;
|
||||||
|
use eeprom24x::{Eeprom24x, SlaveAddr, Storage};
|
||||||
|
use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
|
||||||
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
|
use embassy_sync::blocking_mutex::CriticalSectionMutex;
|
||||||
|
use embedded_storage::nor_flash::RmwNorFlashStorage;
|
||||||
|
use embedded_storage::ReadStorage;
|
||||||
|
use esp_bootloader_esp_idf::partitions::{
|
||||||
|
AppPartitionSubType, DataPartitionSubType, FlashRegion, PartitionEntry, PartitionTable,
|
||||||
|
PartitionType,
|
||||||
|
};
|
||||||
|
use esp_hal::clock::CpuClock;
|
||||||
|
use esp_hal::gpio::{Input, InputConfig, Pull};
|
||||||
|
use esp_hal::uart::{Config as UartConfig, Uart};
|
||||||
|
use esp_storage::FlashStorage;
|
||||||
|
use lib_bms_protocol::{BmsReadable, ProtocolVersion};
|
||||||
|
use measurements::{Current, Voltage};
|
||||||
|
|
||||||
|
use crate::fat_error::{ContextExt, FatError, FatResult};
|
||||||
|
use crate::hal::battery::{print_battery_bq34z100, BQ34Z100G1};
|
||||||
|
use crate::hal::little_fs2storage_adapter::LittleFs2Filesystem;
|
||||||
|
use crate::hal::water::TankSensor;
|
||||||
|
use crate::log::log;
|
||||||
|
use embassy_sync::mutex::Mutex;
|
||||||
|
use embassy_sync::once_lock::OnceLock;
|
||||||
|
use esp_alloc as _;
|
||||||
|
use esp_backtrace as _;
|
||||||
|
use esp_bootloader_esp_idf::ota::{OtaImageState, Ota};
|
||||||
|
use esp_hal::delay::Delay;
|
||||||
|
use esp_hal::i2c::master::{BusTimeout, Config, I2c};
|
||||||
|
use esp_hal::pcnt::unit::Unit;
|
||||||
|
use esp_hal::pcnt::Pcnt;
|
||||||
|
use esp_hal::rng::Rng;
|
||||||
|
use esp_hal::rtc_cntl::{Rtc, SocResetReason};
|
||||||
|
use esp_hal::system::reset_reason;
|
||||||
|
use esp_hal::time::Rate;
|
||||||
|
use esp_hal::timer::timg::{TimerGroup, Wdt};
|
||||||
|
use esp_hal::Blocking;
|
||||||
|
use littlefs2::fs::{Allocation, Filesystem as lfs2Filesystem};
|
||||||
|
use littlefs2::object_safe::DynStorage;
|
||||||
|
use log::{error, info, warn};
|
||||||
|
use shared_flash::MutexFlashStorage;
|
||||||
|
|
||||||
|
pub static PROGRESS_ACTIVE: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
|
//Only support for 8 right now!
|
||||||
|
pub const PLANT_COUNT: usize = 8;
|
||||||
|
|
||||||
|
pub static WATCHDOG: OnceLock<
|
||||||
|
embassy_sync::blocking_mutex::Mutex<
|
||||||
|
CriticalSectionRawMutex,
|
||||||
|
RefCell<Wdt<esp_hal::peripherals::TIMG0>>,
|
||||||
|
>,
|
||||||
|
> = OnceLock::new();
|
||||||
|
|
||||||
|
const TANK_MULTI_SAMPLE: usize = 11;
|
||||||
|
pub static I2C_DRIVER: OnceLock<
|
||||||
|
embassy_sync::blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<I2c<Blocking>>>,
|
||||||
|
> = OnceLock::new();
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum Sensor {
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PlantHal {}
|
||||||
|
|
||||||
|
pub struct HAL<'a> {
|
||||||
|
pub board_hal: Box<dyn BoardInteraction<'a> + Send>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ota_state(
|
||||||
|
slot: AppPartitionSubType,
|
||||||
|
ota_data: &mut FlashRegion<RmwNorFlashStorage<&mut MutexFlashStorage>>,
|
||||||
|
) -> OtaImageState {
|
||||||
|
// Read and log OTA states for both slots before constructing Ota
|
||||||
|
// Each OTA select entry is 32 bytes: [seq:4][label:20][state:4][crc:4]
|
||||||
|
// Offsets within the OTA data partition: slot0 @ 0x0000, slot1 @ 0x1000
|
||||||
|
let mut slot_buf = [0u8; 32];
|
||||||
|
if slot == AppPartitionSubType::Ota0 {
|
||||||
|
let _ = ReadStorage::read(ota_data, 0x0000, &mut slot_buf);
|
||||||
|
} else {
|
||||||
|
let _ = ReadStorage::read(ota_data, 0x1000, &mut slot_buf);
|
||||||
|
}
|
||||||
|
let raw_state = u32::from_le_bytes(slot_buf[24..28].try_into().unwrap_or([0xff; 4]));
|
||||||
|
|
||||||
|
OtaImageState::try_from(raw_state).unwrap_or(OtaImageState::Undefined)
|
||||||
|
}
|
||||||
|
fn get_current_slot(
|
||||||
|
pt: &PartitionTable,
|
||||||
|
ota: &mut Ota<RmwNorFlashStorage<&mut MutexFlashStorage>>,
|
||||||
|
) -> Result<AppPartitionSubType, FatError> {
|
||||||
|
let booted = pt.booted_partition()?.ok_or(FatError::OTAError)?;
|
||||||
|
let booted_type = booted.partition_type();
|
||||||
|
let booted_ota_type = match booted_type {
|
||||||
|
PartitionType::App(subtype) => subtype,
|
||||||
|
_ => {
|
||||||
|
bail!("Booted partition is not an app partition");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected_partition = ota.current_app_partition()?;
|
||||||
|
if expected_partition == booted_ota_type {
|
||||||
|
info!("Booted partition matches expected partition");
|
||||||
|
} else {
|
||||||
|
info!("Booted partition does not match expected partition, fixing ota entry");
|
||||||
|
ota.set_current_app_partition(booted_ota_type)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let fixed = ota.current_app_partition()?;
|
||||||
|
let state = ota.current_ota_state();
|
||||||
|
info!("Expected partition: {expected_partition:?}, current partition: {booted_ota_type:?}, state: {state:?}");
|
||||||
|
|
||||||
|
if fixed != booted_ota_type {
|
||||||
|
bail!(
|
||||||
|
"Could not fix ota entry, booted partition is still not correct: {:?} != {:?}",
|
||||||
|
booted_ota_type,
|
||||||
|
fixed
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(booted_ota_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next_partition(current: AppPartitionSubType) -> FatResult<AppPartitionSubType> {
|
||||||
|
let next = match current {
|
||||||
|
AppPartitionSubType::Ota0 => AppPartitionSubType::Ota1,
|
||||||
|
AppPartitionSubType::Ota1 => AppPartitionSubType::Ota0,
|
||||||
|
_ => {
|
||||||
|
bail!("Current slot is not ota0 or ota1");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(next)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
pub trait BoardInteraction<'a> {
|
||||||
|
fn get_tank_sensor(&mut self) -> Result<&mut TankSensor<'a>, FatError>;
|
||||||
|
fn get_esp(&mut self) -> &mut Esp<'a>;
|
||||||
|
fn get_config(&mut self) -> &PlantControllerConfig;
|
||||||
|
fn get_battery_monitor(&mut self) -> &mut Box<dyn BatteryInteraction + Send>;
|
||||||
|
fn get_rtc_module(&mut self) -> &mut Box<dyn RTCModuleInteraction + Send>;
|
||||||
|
async fn get_time(&mut self) -> DateTime<Utc>;
|
||||||
|
async fn set_time(&mut self, time: &DateTime<FixedOffset>) -> FatResult<()>;
|
||||||
|
async fn set_charge_indicator(&mut self, charging: bool) -> Result<(), FatError>;
|
||||||
|
async fn deep_sleep_ms(&mut self, duration_in_ms: u64) -> !;
|
||||||
|
|
||||||
|
fn is_day(&self) -> bool;
|
||||||
|
//should be multsampled
|
||||||
|
async fn light(&mut self, enable: bool) -> Result<(), FatError>;
|
||||||
|
async fn pump(&mut self, plant: usize, enable: bool) -> Result<(), FatError>;
|
||||||
|
async fn pump_current(&mut self, plant: usize) -> Result<Current, FatError>;
|
||||||
|
async fn fault(&mut self, plant: usize, enable: bool) -> Result<(), FatError>;
|
||||||
|
async fn measure_moisture_hz(&mut self, plant: usize, sensor: Sensor) -> Result<f32, FatError>;
|
||||||
|
async fn general_fault(&mut self, enable: bool);
|
||||||
|
async fn test(&mut self) -> Result<(), FatError>;
|
||||||
|
fn set_config(&mut self, config: PlantControllerConfig);
|
||||||
|
async fn get_mptt_voltage(&mut self) -> Result<Voltage, FatError>;
|
||||||
|
async fn get_mptt_current(&mut self) -> Result<Current, FatError>;
|
||||||
|
|
||||||
|
async fn progress(&mut self, counter: u32) {
|
||||||
|
let current = counter % PLANT_COUNT as u32;
|
||||||
|
for led in 0..PLANT_COUNT {
|
||||||
|
if let Err(err) = self.fault(led, current == led as u32).await {
|
||||||
|
warn!("Fault on plant {}: {:?}", led, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let even = counter % 2 == 0;
|
||||||
|
let _ = self.general_fault(even.into()).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn clear_progress(&mut self) {
|
||||||
|
for led in 0..PLANT_COUNT {
|
||||||
|
if let Err(err) = self.fault(led, false).await {
|
||||||
|
warn!("Fault on plant {}: {:?}", led, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let _ = self.general_fault(false).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct FreePeripherals<'a> {
|
||||||
|
pub gpio0: GPIO0<'a>,
|
||||||
|
pub gpio2: GPIO2<'a>,
|
||||||
|
pub gpio3: GPIO3<'a>,
|
||||||
|
pub gpio4: GPIO4<'a>,
|
||||||
|
pub gpio5: GPIO5<'a>,
|
||||||
|
pub gpio6: GPIO6<'a>,
|
||||||
|
pub gpio7: GPIO7<'a>,
|
||||||
|
pub gpio8: GPIO8<'a>,
|
||||||
|
// //config button here
|
||||||
|
pub gpio10: GPIO10<'a>,
|
||||||
|
pub gpio11: GPIO11<'a>,
|
||||||
|
pub gpio12: GPIO12<'a>,
|
||||||
|
pub gpio13: GPIO13<'a>,
|
||||||
|
pub gpio14: GPIO14<'a>,
|
||||||
|
pub gpio15: GPIO15<'a>,
|
||||||
|
pub gpio16: GPIO16<'a>,
|
||||||
|
pub gpio17: GPIO17<'a>,
|
||||||
|
pub gpio18: GPIO18<'a>,
|
||||||
|
// //i2c here
|
||||||
|
pub gpio21: GPIO21<'a>,
|
||||||
|
pub gpio22: GPIO22<'a>,
|
||||||
|
pub gpio23: GPIO23<'a>,
|
||||||
|
pub gpio27: GPIO27<'a>,
|
||||||
|
pub twai: TWAI0<'a>,
|
||||||
|
pub pcnt0: Unit<'a, 0>,
|
||||||
|
pub pcnt1: Unit<'a, 1>,
|
||||||
|
pub adc1: ADC1<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
use crate::util::mk_static;
|
||||||
|
|
||||||
|
impl PlantHal {
|
||||||
|
pub async fn create() -> Result<Mutex<CriticalSectionRawMutex, HAL<'static>>, FatError> {
|
||||||
|
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
|
||||||
|
let peripherals: Peripherals = esp_hal::init(config);
|
||||||
|
|
||||||
|
esp_alloc::heap_allocator!(size: 64 * 1024);
|
||||||
|
esp_alloc::heap_allocator!(#[link_section = ".dram2_uninit"] size: 64000);
|
||||||
|
|
||||||
|
let mut rtc_peripheral: Rtc = Rtc::new(peripherals.LPWR);
|
||||||
|
rtc_peripheral.rwdt.disable();
|
||||||
|
|
||||||
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
|
let sw_int = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
|
||||||
|
esp_rtos::start(timg0.timer0, sw_int.software_interrupt0);
|
||||||
|
|
||||||
|
let boot_button = Input::new(
|
||||||
|
peripherals.GPIO9,
|
||||||
|
InputConfig::default().with_pull(Pull::None),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Reserve GPIO1 for deep sleep wake (configured just before entering sleep)
|
||||||
|
let wake_gpio1 = peripherals.GPIO1;
|
||||||
|
|
||||||
|
let rng = Rng::new();
|
||||||
|
let (controller, interfaces) = esp_radio::wifi::new(peripherals.WIFI, Default::default())
|
||||||
|
.expect("Could not init wifi");
|
||||||
|
|
||||||
|
let pcnt_module = Pcnt::new(peripherals.PCNT);
|
||||||
|
|
||||||
|
let free_pins = FreePeripherals {
|
||||||
|
gpio0: peripherals.GPIO0,
|
||||||
|
gpio2: peripherals.GPIO2,
|
||||||
|
gpio3: peripherals.GPIO3,
|
||||||
|
gpio4: peripherals.GPIO4,
|
||||||
|
gpio5: peripherals.GPIO5,
|
||||||
|
gpio6: peripherals.GPIO6,
|
||||||
|
gpio7: peripherals.GPIO7,
|
||||||
|
gpio8: peripherals.GPIO8,
|
||||||
|
gpio10: peripherals.GPIO10,
|
||||||
|
gpio11: peripherals.GPIO11,
|
||||||
|
gpio12: peripherals.GPIO12,
|
||||||
|
gpio13: peripherals.GPIO13,
|
||||||
|
gpio14: peripherals.GPIO14,
|
||||||
|
gpio15: peripherals.GPIO15,
|
||||||
|
gpio16: peripherals.GPIO16,
|
||||||
|
gpio17: peripherals.GPIO17,
|
||||||
|
gpio18: peripherals.GPIO18,
|
||||||
|
gpio21: peripherals.GPIO21,
|
||||||
|
gpio22: peripherals.GPIO22,
|
||||||
|
gpio23: peripherals.GPIO23,
|
||||||
|
gpio27: peripherals.GPIO27,
|
||||||
|
twai: peripherals.TWAI0,
|
||||||
|
pcnt0: pcnt_module.unit0,
|
||||||
|
pcnt1: pcnt_module.unit1,
|
||||||
|
adc1: peripherals.ADC1,
|
||||||
|
};
|
||||||
|
|
||||||
|
let tablebuffer = mk_static!(
|
||||||
|
[u8; esp_bootloader_esp_idf::partitions::PARTITION_TABLE_MAX_LEN],
|
||||||
|
[0u8; esp_bootloader_esp_idf::partitions::PARTITION_TABLE_MAX_LEN]
|
||||||
|
);
|
||||||
|
|
||||||
|
let bullshit = MutexFlashStorage {
|
||||||
|
inner: Arc::new(CriticalSectionMutex::new(RefCell::new(FlashStorage::new(
|
||||||
|
peripherals.FLASH,
|
||||||
|
)))),
|
||||||
|
};
|
||||||
|
let flash_storage = mk_static!(MutexFlashStorage, bullshit.clone());
|
||||||
|
let flash_storage_2 = mk_static!(MutexFlashStorage, bullshit.clone());
|
||||||
|
let flash_storage_3 = mk_static!(MutexFlashStorage, bullshit.clone());
|
||||||
|
|
||||||
|
let pt =
|
||||||
|
esp_bootloader_esp_idf::partitions::read_partition_table(flash_storage, tablebuffer)?;
|
||||||
|
|
||||||
|
let ota_data = mk_static!(
|
||||||
|
PartitionEntry,
|
||||||
|
pt.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::Data(
|
||||||
|
DataPartitionSubType::Ota,
|
||||||
|
))?
|
||||||
|
.expect("No OTA data partition found")
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut ota_data = ota_data.as_embedded_storage(mk_static!(
|
||||||
|
RmwNorFlashStorage<&mut MutexFlashStorage>,
|
||||||
|
RmwNorFlashStorage::new(flash_storage_2, mk_static!([u8; 4096], [0_u8; 4096]))
|
||||||
|
));
|
||||||
|
|
||||||
|
let state_0 = ota_state(AppPartitionSubType::Ota0, &mut ota_data);
|
||||||
|
let state_1 = ota_state(AppPartitionSubType::Ota1, &mut ota_data);
|
||||||
|
let mut ota = Ota::new(ota_data, 2)?;
|
||||||
|
let running = get_current_slot(&pt, &mut ota)?;
|
||||||
|
let target = next_partition(running)?;
|
||||||
|
|
||||||
|
info!("Currently running OTA slot: {running:?}");
|
||||||
|
info!("Updates will be stored in OTA slot: {target:?}");
|
||||||
|
info!("Slot0 state: {state_0:?}");
|
||||||
|
info!("Slot1 state: {state_1:?}");
|
||||||
|
|
||||||
|
//get current_state and next_state here!
|
||||||
|
let ota_target = match target {
|
||||||
|
AppPartitionSubType::Ota0 => pt
|
||||||
|
.find_partition(PartitionType::App(AppPartitionSubType::Ota0))?
|
||||||
|
.context("Partition table invalid no ota0")?,
|
||||||
|
AppPartitionSubType::Ota1 => pt
|
||||||
|
.find_partition(PartitionType::App(AppPartitionSubType::Ota1))?
|
||||||
|
.context("Partition table invalid no ota1")?,
|
||||||
|
_ => {
|
||||||
|
bail!("Invalid target partition");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let ota_target = mk_static!(PartitionEntry, ota_target);
|
||||||
|
let ota_target = mk_static!(
|
||||||
|
FlashRegion<MutexFlashStorage>,
|
||||||
|
ota_target.as_embedded_storage(flash_storage)
|
||||||
|
);
|
||||||
|
|
||||||
|
let data_partition = pt
|
||||||
|
.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::Data(
|
||||||
|
DataPartitionSubType::LittleFs,
|
||||||
|
))?
|
||||||
|
.expect("Data partition with littlefs not found");
|
||||||
|
let data_partition = mk_static!(PartitionEntry, data_partition);
|
||||||
|
|
||||||
|
let data = mk_static!(
|
||||||
|
FlashRegion<MutexFlashStorage>,
|
||||||
|
data_partition.as_embedded_storage(flash_storage_3)
|
||||||
|
);
|
||||||
|
let lfs2filesystem = mk_static!(LittleFs2Filesystem, LittleFs2Filesystem { storage: data });
|
||||||
|
let alloc = mk_static!(Allocation<LittleFs2Filesystem>, lfs2Filesystem::allocate());
|
||||||
|
if lfs2filesystem.is_mountable() {
|
||||||
|
info!("Littlefs2 filesystem is mountable");
|
||||||
|
} else {
|
||||||
|
match lfs2filesystem.format() {
|
||||||
|
Ok(..) => {
|
||||||
|
info!("Littlefs2 filesystem is formatted");
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
error!("Littlefs2 filesystem could not be formatted: {err:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::arc_with_non_send_sync)]
|
||||||
|
let fs = Arc::new(Mutex::new(
|
||||||
|
lfs2Filesystem::mount(alloc, lfs2filesystem).expect("Could not mount lfs2 filesystem"),
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
let uart0 =
|
||||||
|
Uart::new(peripherals.UART0, UartConfig::default()).map_err(|_| FatError::String {
|
||||||
|
error: "Uart creation failed".to_string(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let ap = interfaces.access_point;
|
||||||
|
let sta = interfaces.station;
|
||||||
|
let mut esp = Esp {
|
||||||
|
fs,
|
||||||
|
rng,
|
||||||
|
controller: Arc::new(Mutex::new(controller)),
|
||||||
|
interface_sta: Some(sta),
|
||||||
|
interface_ap: Some(ap),
|
||||||
|
boot_button,
|
||||||
|
wake_gpio1,
|
||||||
|
ota,
|
||||||
|
ota_target,
|
||||||
|
current: running,
|
||||||
|
slot0_state: state_0,
|
||||||
|
slot1_state: state_1,
|
||||||
|
uart0,
|
||||||
|
rtc: rtc_peripheral,
|
||||||
|
};
|
||||||
|
|
||||||
|
//init,reset rtc memory depending on cause
|
||||||
|
let mut init_rtc_store: bool = false;
|
||||||
|
let mut to_config_mode: bool = false;
|
||||||
|
let reasons = match reset_reason() {
|
||||||
|
None => "unknown",
|
||||||
|
Some(reason) => match reason {
|
||||||
|
SocResetReason::ChipPowerOn => "power on",
|
||||||
|
SocResetReason::CoreSDIO => "sdio reset",
|
||||||
|
SocResetReason::CoreMwdt0 => "Watchdog Main",
|
||||||
|
SocResetReason::CoreMwdt1 => "Watchdog 1",
|
||||||
|
SocResetReason::CoreRtcWdt => "Watchdog RTC",
|
||||||
|
SocResetReason::Cpu0Mwdt0 => "Watchdog MCpu0",
|
||||||
|
SocResetReason::Cpu0Sw => "software reset cpu0",
|
||||||
|
SocResetReason::SysRtcWdt => "Watchdog Sys rtc",
|
||||||
|
SocResetReason::Cpu0Mwdt1 => "cpu0 mwdt1",
|
||||||
|
SocResetReason::SysSuperWdt => "Watchdog Super",
|
||||||
|
SocResetReason::Cpu0RtcWdt => {
|
||||||
|
init_rtc_store = true;
|
||||||
|
"Watchdog RTC cpu0"
|
||||||
|
}
|
||||||
|
SocResetReason::CoreSw => "software reset",
|
||||||
|
SocResetReason::CoreDeepSleep => "deep sleep",
|
||||||
|
SocResetReason::SysBrownOut => "sys brown out",
|
||||||
|
SocResetReason::CoreEfuseCrc => "core efuse crc",
|
||||||
|
SocResetReason::CoreUsbUart => {
|
||||||
|
//TODO still required? or via button ignore? to_config_mode = true;
|
||||||
|
to_config_mode = true;
|
||||||
|
"core usb uart"
|
||||||
|
}
|
||||||
|
SocResetReason::CoreUsbJtag => "core usb jtag",
|
||||||
|
SocResetReason::Cpu0JtagCpu => "cpu0 jtag cpu",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
log(
|
||||||
|
LogMessage::ResetReason,
|
||||||
|
init_rtc_store as u32,
|
||||||
|
to_config_mode as u32,
|
||||||
|
"",
|
||||||
|
&format!("{reasons:?}"),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
esp.init_rtc_deepsleep_memory(init_rtc_store, to_config_mode)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let config = esp.load_config().await;
|
||||||
|
|
||||||
|
info!("Init rtc driver");
|
||||||
|
|
||||||
|
let sda = peripherals.GPIO20;
|
||||||
|
let scl = peripherals.GPIO19;
|
||||||
|
|
||||||
|
let i2c = I2c::new(
|
||||||
|
peripherals.I2C0,
|
||||||
|
Config::default()
|
||||||
|
.with_frequency(Rate::from_hz(100))
|
||||||
|
.with_timeout(BusTimeout::Maximum),
|
||||||
|
)?
|
||||||
|
.with_scl(scl)
|
||||||
|
.with_sda(sda);
|
||||||
|
let i2c_bus: embassy_sync::blocking_mutex::Mutex<
|
||||||
|
CriticalSectionRawMutex,
|
||||||
|
RefCell<I2c<Blocking>>,
|
||||||
|
> = CriticalSectionMutex::new(RefCell::new(i2c));
|
||||||
|
|
||||||
|
|
||||||
|
I2C_DRIVER.init(i2c_bus).expect("Could not init i2c driver");
|
||||||
|
|
||||||
|
let i2c_bus = I2C_DRIVER.get().await;
|
||||||
|
let rtc_device = I2cDevice::new(i2c_bus);
|
||||||
|
let mut bms_device = I2cDevice::new(i2c_bus);
|
||||||
|
let eeprom_device = I2cDevice::new(i2c_bus);
|
||||||
|
|
||||||
|
|
||||||
|
let mut rtc: Ds323x<
|
||||||
|
I2cInterface<I2cDevice<CriticalSectionRawMutex, I2c<Blocking>>>,
|
||||||
|
DS3231,
|
||||||
|
> = Ds323x::new_ds3231(rtc_device);
|
||||||
|
|
||||||
|
|
||||||
|
info!("Init rtc eeprom driver");
|
||||||
|
let eeprom = Eeprom24x::new_24x32(eeprom_device, SlaveAddr::Alternative(true, true, true));
|
||||||
|
let rtc_time = rtc.datetime();
|
||||||
|
match rtc_time {
|
||||||
|
Ok(tt) => {
|
||||||
|
info!("Rtc Module reports time at UTC {tt}");
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
info!("Rtc Module could not be read {err:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let storage: Storage<
|
||||||
|
I2cDevice<'static, CriticalSectionRawMutex, I2c<Blocking>>,
|
||||||
|
B32,
|
||||||
|
TwoBytes,
|
||||||
|
No,
|
||||||
|
Delay,
|
||||||
|
> = Storage::new(eeprom, Delay::new());
|
||||||
|
let rtc_module: Box<dyn RTCModuleInteraction + Send> =
|
||||||
|
Box::new(DS3231Module { rtc, storage }) as Box<dyn RTCModuleInteraction + Send>;
|
||||||
|
|
||||||
|
let hal = match config {
|
||||||
|
Ok(config) => {
|
||||||
|
let battery_interaction: Box<dyn BatteryInteraction + Send> =
|
||||||
|
match config.hardware.battery {
|
||||||
|
BatteryBoardVersion::Disabled => Box::new(NoBatteryMonitor {}),
|
||||||
|
BatteryBoardVersion::WchI2cSlave => {
|
||||||
|
let version = ProtocolVersion::read_from_i2c(&mut bms_device);
|
||||||
|
let version_val = match version {
|
||||||
|
Ok(v) => unsafe { core::mem::transmute::<ProtocolVersion, u32>(v) },
|
||||||
|
Err(_) => 0,
|
||||||
|
};
|
||||||
|
if version_val == 1 {
|
||||||
|
//Box::new(WCHI2CSlave { i2c: bms_device })
|
||||||
|
// todo fix the type above
|
||||||
|
Box::new(NoBatteryMonitor {})
|
||||||
|
} else {
|
||||||
|
//todo should be an error variant instead?
|
||||||
|
Box::new(NoBatteryMonitor {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BatteryBoardVersion::BQ34Z100G1 => Box::new(NoBatteryMonitor {}),
|
||||||
|
};
|
||||||
|
|
||||||
|
let board_hal: Box<dyn BoardInteraction + Send> = match config.hardware.board {
|
||||||
|
BoardVersion::INITIAL => {
|
||||||
|
initial_hal::create_initial_board(free_pins, config, esp)?
|
||||||
|
}
|
||||||
|
BoardVersion::V3 => {
|
||||||
|
v3_hal::create_v3(free_pins, esp, config, battery_interaction, rtc_module)?
|
||||||
|
}
|
||||||
|
BoardVersion::V4 => {
|
||||||
|
v4_hal::create_v4(free_pins, esp, config, battery_interaction, rtc_module)
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
HAL { board_hal }
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
log(
|
||||||
|
LogMessage::ConfigModeMissingConfig,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
"",
|
||||||
|
&err.to_string(),
|
||||||
|
);
|
||||||
|
HAL {
|
||||||
|
board_hal: initial_hal::create_initial_board(
|
||||||
|
free_pins,
|
||||||
|
PlantControllerConfig::default(),
|
||||||
|
esp,
|
||||||
|
)?,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Mutex::new(hal))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Feed the watchdog timer to prevent system reset
|
||||||
|
pub fn feed_watchdog() {
|
||||||
|
if let Some(wdt_mutex) = WATCHDOG.try_get() {
|
||||||
|
wdt_mutex.lock(|cell| {
|
||||||
|
cell.borrow_mut().feed();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
133
rust/src/hal/rtc.rs
Normal file
133
rust/src/hal/rtc.rs
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
use crate::hal::Box;
|
||||||
|
use crate::fat_error::FatResult;
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use bincode::config::Configuration;
|
||||||
|
use bincode::{config, Decode, Encode};
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use ds323x::ic::DS3231;
|
||||||
|
use ds323x::interface::I2cInterface;
|
||||||
|
use ds323x::{DateTimeAccess, Ds323x};
|
||||||
|
use eeprom24x::addr_size::TwoBytes;
|
||||||
|
use eeprom24x::page_size::B32;
|
||||||
|
use eeprom24x::unique_serial::No;
|
||||||
|
use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
|
||||||
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
|
use embedded_storage::{ReadStorage, Storage};
|
||||||
|
use esp_hal::delay::Delay;
|
||||||
|
use esp_hal::i2c::master::I2c;
|
||||||
|
use esp_hal::Blocking;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub const X25: crc::Crc<u16> = crc::Crc::<u16>::new(&crc::CRC_16_IBM_SDLC);
|
||||||
|
const CONFIG: Configuration = config::standard();
|
||||||
|
//
|
||||||
|
#[async_trait]
|
||||||
|
pub trait RTCModuleInteraction {
|
||||||
|
async fn get_backup_info(&mut self) -> FatResult<BackupHeader>;
|
||||||
|
async fn get_backup_config(&mut self, chunk: usize) -> FatResult<([u8; 32], usize, u16)>;
|
||||||
|
async fn backup_config(&mut self, offset: usize, bytes: &[u8]) -> FatResult<()>;
|
||||||
|
async fn backup_config_finalize(&mut self, crc: u16, length: usize) -> FatResult<()>;
|
||||||
|
async fn get_rtc_time(&mut self) -> FatResult<DateTime<Utc>>;
|
||||||
|
async fn set_rtc_time(&mut self, time: &DateTime<Utc>) -> FatResult<()>;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
const BACKUP_HEADER_MAX_SIZE: usize = 64;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Encode, Decode)]
|
||||||
|
pub struct BackupHeader {
|
||||||
|
pub timestamp: i64,
|
||||||
|
crc16: u16,
|
||||||
|
pub size: u16,
|
||||||
|
}
|
||||||
|
//
|
||||||
|
pub struct DS3231Module {
|
||||||
|
pub(crate) rtc: Ds323x<
|
||||||
|
I2cInterface<I2cDevice<'static, CriticalSectionRawMutex, I2c<'static, Blocking>>>,
|
||||||
|
DS3231,
|
||||||
|
>,
|
||||||
|
|
||||||
|
pub(crate) storage: eeprom24x::Storage<
|
||||||
|
I2cDevice<'static, CriticalSectionRawMutex, I2c<'static, Blocking>>,
|
||||||
|
B32,
|
||||||
|
TwoBytes,
|
||||||
|
No,
|
||||||
|
Delay,
|
||||||
|
>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl RTCModuleInteraction for DS3231Module {
|
||||||
|
async fn get_backup_info(&mut self) -> FatResult<BackupHeader> {
|
||||||
|
let mut header_page_buffer = [0_u8; BACKUP_HEADER_MAX_SIZE];
|
||||||
|
|
||||||
|
self.storage.read(0, &mut header_page_buffer)?;
|
||||||
|
|
||||||
|
let (header, len): (BackupHeader, usize) =
|
||||||
|
bincode::decode_from_slice(&header_page_buffer[..], CONFIG)?;
|
||||||
|
|
||||||
|
log::info!("Raw header is {:?} with size {}", header_page_buffer, len);
|
||||||
|
Ok(header)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_backup_config(&mut self, chunk: usize) -> FatResult<([u8; 32], usize, u16)> {
|
||||||
|
let mut header_page_buffer = [0_u8; BACKUP_HEADER_MAX_SIZE];
|
||||||
|
|
||||||
|
self.storage.read(0, &mut header_page_buffer)?;
|
||||||
|
let (header, _header_size): (BackupHeader, usize) =
|
||||||
|
bincode::decode_from_slice(&header_page_buffer[..], CONFIG)?;
|
||||||
|
|
||||||
|
let mut buf = [0_u8; 32];
|
||||||
|
let offset = chunk * buf.len() + BACKUP_HEADER_MAX_SIZE;
|
||||||
|
|
||||||
|
let end: usize = header.size as usize + BACKUP_HEADER_MAX_SIZE;
|
||||||
|
let current_end = offset + buf.len();
|
||||||
|
let chunk_size = if current_end > end {
|
||||||
|
end - offset
|
||||||
|
} else {
|
||||||
|
buf.len()
|
||||||
|
};
|
||||||
|
if chunk_size == 0 {
|
||||||
|
Ok((buf, 0, header.crc16))
|
||||||
|
} else {
|
||||||
|
self.storage.read(offset as u32, &mut buf)?;
|
||||||
|
//&buf[..chunk_size];
|
||||||
|
Ok((buf, chunk_size, header.crc16))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async fn backup_config(&mut self, offset: usize, bytes: &[u8]) -> FatResult<()> {
|
||||||
|
//skip header and write after
|
||||||
|
self.storage
|
||||||
|
.write((BACKUP_HEADER_MAX_SIZE + offset) as u32, &bytes)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn backup_config_finalize(&mut self, crc: u16, length: usize) -> FatResult<()> {
|
||||||
|
let mut header_page_buffer = [0_u8; BACKUP_HEADER_MAX_SIZE];
|
||||||
|
|
||||||
|
let time = self.get_rtc_time().await?.timestamp_millis();
|
||||||
|
let header = BackupHeader {
|
||||||
|
crc16: crc,
|
||||||
|
timestamp: time,
|
||||||
|
size: length as u16,
|
||||||
|
};
|
||||||
|
let config = config::standard();
|
||||||
|
let encoded = bincode::encode_into_slice(&header, &mut header_page_buffer, config)?;
|
||||||
|
log::info!(
|
||||||
|
"Raw header is {:?} with size {}",
|
||||||
|
header_page_buffer,
|
||||||
|
encoded
|
||||||
|
);
|
||||||
|
self.storage.write(0, &header_page_buffer)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_rtc_time(&mut self) -> FatResult<DateTime<Utc>> {
|
||||||
|
Ok(self.rtc.datetime()?.and_utc())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_rtc_time(&mut self, time: &DateTime<Utc>) -> FatResult<()> {
|
||||||
|
let naive_time = time.naive_utc();
|
||||||
|
Ok(self.rtc.set_datetime(&naive_time)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
65
rust/src/hal/shared_flash.rs
Normal file
65
rust/src/hal/shared_flash.rs
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
use alloc::sync::Arc;
|
||||||
|
use core::cell::RefCell;
|
||||||
|
use core::ops::{Deref, DerefMut};
|
||||||
|
use embassy_sync::blocking_mutex::CriticalSectionMutex;
|
||||||
|
use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash};
|
||||||
|
use embedded_storage::ReadStorage;
|
||||||
|
use esp_storage::{FlashStorage, FlashStorageError};
|
||||||
|
use log::info;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct MutexFlashStorage {
|
||||||
|
pub(crate) inner: Arc<CriticalSectionMutex<RefCell<FlashStorage<'static>>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ReadStorage for MutexFlashStorage {
|
||||||
|
type Error = FlashStorageError;
|
||||||
|
|
||||||
|
fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), FlashStorageError> {
|
||||||
|
self.inner
|
||||||
|
.lock(|f| ReadStorage::read(f.borrow_mut().deref_mut(), offset, bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn capacity(&self) -> usize {
|
||||||
|
self.inner
|
||||||
|
.lock(|f| ReadStorage::capacity(f.borrow().deref()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl embedded_storage::Storage for MutexFlashStorage {
|
||||||
|
fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
|
||||||
|
NorFlash::write(self, offset, bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ErrorType for MutexFlashStorage {
|
||||||
|
type Error = FlashStorageError;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ReadNorFlash for MutexFlashStorage {
|
||||||
|
const READ_SIZE: usize = 1;
|
||||||
|
|
||||||
|
fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
|
||||||
|
ReadStorage::read(self, offset, bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn capacity(&self) -> usize {
|
||||||
|
ReadStorage::capacity(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NorFlash for MutexFlashStorage {
|
||||||
|
const WRITE_SIZE: usize = 1;
|
||||||
|
const ERASE_SIZE: usize = 4096;
|
||||||
|
|
||||||
|
fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
|
||||||
|
info!("Erasing flash from 0x{:x} to 0x{:x}", from, to);
|
||||||
|
self.inner
|
||||||
|
.lock(|f| NorFlash::erase(f.borrow_mut().deref_mut(), from, to))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
|
||||||
|
self.inner
|
||||||
|
.lock(|f| NorFlash::write(f.borrow_mut().deref_mut(), offset, bytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
451
rust/src/hal/v3_hal.rs
Normal file
451
rust/src/hal/v3_hal.rs
Normal file
@@ -0,0 +1,451 @@
|
|||||||
|
use crate::bail;
|
||||||
|
use crate::fat_error::{FatError, FatResult};
|
||||||
|
use crate::hal::esp::{hold_disable, hold_enable};
|
||||||
|
use crate::hal::rtc::RTCModuleInteraction;
|
||||||
|
use crate::hal::v3_shift_register::ShiftRegister40;
|
||||||
|
use crate::hal::water::TankSensor;
|
||||||
|
use crate::hal::{BoardInteraction, FreePeripherals, Sensor, PLANT_COUNT};
|
||||||
|
use crate::log::{log, LogMessage, LOG_ACCESS};
|
||||||
|
use crate::{
|
||||||
|
config::PlantControllerConfig,
|
||||||
|
hal::{battery::BatteryInteraction, esp::Esp},
|
||||||
|
};
|
||||||
|
use alloc::boxed::Box;
|
||||||
|
use alloc::format;
|
||||||
|
use alloc::string::ToString;
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use chrono::{DateTime, FixedOffset, Utc};
|
||||||
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
|
use embassy_sync::mutex::Mutex;
|
||||||
|
use embassy_time::Timer;
|
||||||
|
use embedded_hal::digital::OutputPin as _;
|
||||||
|
use esp_hal::gpio::{Flex, Input, InputConfig, Level, Output, OutputConfig, Pull};
|
||||||
|
use esp_hal::pcnt::channel::CtrlMode::Keep;
|
||||||
|
use esp_hal::pcnt::channel::EdgeMode;
|
||||||
|
use esp_hal::pcnt::channel::EdgeMode::{Hold, Increment};
|
||||||
|
use esp_hal::pcnt::unit::Unit;
|
||||||
|
use measurements::{Current, Voltage};
|
||||||
|
|
||||||
|
const PUMP8_BIT: usize = 0;
|
||||||
|
const PUMP1_BIT: usize = 1;
|
||||||
|
const PUMP2_BIT: usize = 2;
|
||||||
|
const PUMP3_BIT: usize = 3;
|
||||||
|
const PUMP4_BIT: usize = 4;
|
||||||
|
const PUMP5_BIT: usize = 5;
|
||||||
|
const PUMP6_BIT: usize = 6;
|
||||||
|
const PUMP7_BIT: usize = 7;
|
||||||
|
const MS_0: usize = 8;
|
||||||
|
const MS_4: usize = 9;
|
||||||
|
const MS_2: usize = 10;
|
||||||
|
const MS_3: usize = 11;
|
||||||
|
const MS_1: usize = 13;
|
||||||
|
const SENSOR_ON: usize = 12;
|
||||||
|
|
||||||
|
const SENSOR_A_1: u8 = 7;
|
||||||
|
const SENSOR_A_2: u8 = 6;
|
||||||
|
const SENSOR_A_3: u8 = 5;
|
||||||
|
const SENSOR_A_4: u8 = 4;
|
||||||
|
const SENSOR_A_5: u8 = 3;
|
||||||
|
const SENSOR_A_6: u8 = 2;
|
||||||
|
const SENSOR_A_7: u8 = 1;
|
||||||
|
const SENSOR_A_8: u8 = 0;
|
||||||
|
|
||||||
|
const SENSOR_B_1: u8 = 8;
|
||||||
|
const SENSOR_B_2: u8 = 9;
|
||||||
|
const SENSOR_B_3: u8 = 10;
|
||||||
|
const SENSOR_B_4: u8 = 11;
|
||||||
|
const SENSOR_B_5: u8 = 12;
|
||||||
|
const SENSOR_B_6: u8 = 13;
|
||||||
|
const SENSOR_B_7: u8 = 14;
|
||||||
|
const SENSOR_B_8: u8 = 15;
|
||||||
|
|
||||||
|
const CHARGING: usize = 14;
|
||||||
|
const AWAKE: usize = 15;
|
||||||
|
|
||||||
|
const FAULT_3: usize = 16;
|
||||||
|
const FAULT_8: usize = 17;
|
||||||
|
const FAULT_7: usize = 18;
|
||||||
|
const FAULT_6: usize = 19;
|
||||||
|
const FAULT_5: usize = 20;
|
||||||
|
const FAULT_4: usize = 21;
|
||||||
|
const FAULT_1: usize = 22;
|
||||||
|
const FAULT_2: usize = 23;
|
||||||
|
|
||||||
|
const REPEAT_MOIST_MEASURE: usize = 1;
|
||||||
|
|
||||||
|
pub struct V3<'a> {
|
||||||
|
config: PlantControllerConfig,
|
||||||
|
battery_monitor: Box<dyn BatteryInteraction + Send>,
|
||||||
|
rtc_module: Box<dyn RTCModuleInteraction + Send>,
|
||||||
|
esp: Esp<'a>,
|
||||||
|
shift_register:
|
||||||
|
Mutex<CriticalSectionRawMutex, ShiftRegister40<Output<'a>, Output<'a>, Output<'a>>>,
|
||||||
|
_shift_register_enable_invert: Output<'a>,
|
||||||
|
tank_sensor: TankSensor<'a>,
|
||||||
|
solar_is_day: Input<'a>,
|
||||||
|
light: Output<'a>,
|
||||||
|
main_pump: Output<'a>,
|
||||||
|
general_fault: Output<'a>,
|
||||||
|
pub signal_counter: Unit<'static, 0>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn create_v3(
|
||||||
|
peripherals: FreePeripherals<'static>,
|
||||||
|
esp: Esp<'static>,
|
||||||
|
config: PlantControllerConfig,
|
||||||
|
battery_monitor: Box<dyn BatteryInteraction + Send>,
|
||||||
|
rtc_module: Box<dyn RTCModuleInteraction + Send>,
|
||||||
|
) -> Result<Box<dyn BoardInteraction<'static> + Send + 'static>, FatError> {
|
||||||
|
log::info!("Start v3");
|
||||||
|
let clock = Output::new(peripherals.gpio15, Level::Low, OutputConfig::default());
|
||||||
|
let latch = Output::new(peripherals.gpio3, Level::Low, OutputConfig::default());
|
||||||
|
let data = Output::new(peripherals.gpio23, Level::Low, OutputConfig::default());
|
||||||
|
let shift_register = ShiftRegister40::new(clock, latch, data);
|
||||||
|
//disable all
|
||||||
|
for mut pin in shift_register.decompose() {
|
||||||
|
let _ = pin.set_low();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set always-on status bits
|
||||||
|
let _ = shift_register.decompose()[AWAKE].set_high();
|
||||||
|
let _ = shift_register.decompose()[CHARGING].set_high();
|
||||||
|
|
||||||
|
// Multiplexer defaults: ms0..ms3 low, ms4 high (disabled)
|
||||||
|
let _ = shift_register.decompose()[MS_0].set_low();
|
||||||
|
let _ = shift_register.decompose()[MS_1].set_low();
|
||||||
|
let _ = shift_register.decompose()[MS_2].set_low();
|
||||||
|
let _ = shift_register.decompose()[MS_3].set_low();
|
||||||
|
let _ = shift_register.decompose()[MS_4].set_high();
|
||||||
|
|
||||||
|
let one_wire_pin = Flex::new(peripherals.gpio18);
|
||||||
|
let tank_power_pin = Output::new(peripherals.gpio11, Level::Low, OutputConfig::default());
|
||||||
|
|
||||||
|
let flow_sensor_pin = Input::new(
|
||||||
|
peripherals.gpio4,
|
||||||
|
InputConfig::default().with_pull(Pull::Up),
|
||||||
|
);
|
||||||
|
|
||||||
|
let tank_sensor = TankSensor::create(
|
||||||
|
one_wire_pin,
|
||||||
|
peripherals.adc1,
|
||||||
|
peripherals.gpio5,
|
||||||
|
tank_power_pin,
|
||||||
|
flow_sensor_pin,
|
||||||
|
peripherals.pcnt1,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let solar_is_day = Input::new(peripherals.gpio7, InputConfig::default());
|
||||||
|
let light = Output::new(peripherals.gpio10, Level::Low, OutputConfig::default());
|
||||||
|
let mut main_pump = Output::new(peripherals.gpio2, Level::Low, OutputConfig::default());
|
||||||
|
main_pump.set_low();
|
||||||
|
let mut general_fault = Output::new(peripherals.gpio6, Level::Low, OutputConfig::default());
|
||||||
|
general_fault.set_low();
|
||||||
|
|
||||||
|
hold_disable(21);
|
||||||
|
let mut shift_register_enable_invert =
|
||||||
|
Output::new(peripherals.gpio21, Level::Low, OutputConfig::default());
|
||||||
|
shift_register_enable_invert.set_low();
|
||||||
|
hold_enable(21);
|
||||||
|
|
||||||
|
let signal_counter = peripherals.pcnt0;
|
||||||
|
|
||||||
|
signal_counter.set_low_limit(None)?;
|
||||||
|
signal_counter.set_high_limit(Some(i16::MAX))?;
|
||||||
|
|
||||||
|
let ch0 = &signal_counter.channel0;
|
||||||
|
let edge_pin = Input::new(peripherals.gpio22, InputConfig::default());
|
||||||
|
ch0.set_edge_signal(edge_pin.peripheral_input());
|
||||||
|
ch0.set_input_mode(Hold, Increment);
|
||||||
|
ch0.set_ctrl_mode(Keep, Keep);
|
||||||
|
signal_counter.listen();
|
||||||
|
|
||||||
|
Ok(Box::new(V3 {
|
||||||
|
config,
|
||||||
|
battery_monitor,
|
||||||
|
rtc_module,
|
||||||
|
esp,
|
||||||
|
shift_register: Mutex::new(shift_register),
|
||||||
|
_shift_register_enable_invert: shift_register_enable_invert,
|
||||||
|
tank_sensor,
|
||||||
|
solar_is_day,
|
||||||
|
light,
|
||||||
|
main_pump,
|
||||||
|
general_fault,
|
||||||
|
signal_counter,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl<'a> BoardInteraction<'a> for V3<'a> {
|
||||||
|
fn get_tank_sensor(&mut self) -> Result<&mut TankSensor<'a>, FatError> {
|
||||||
|
Ok(&mut self.tank_sensor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_esp(&mut self) -> &mut Esp<'a> {
|
||||||
|
&mut self.esp
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_config(&mut self) -> &PlantControllerConfig {
|
||||||
|
&self.config
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_battery_monitor(&mut self) -> &mut Box<dyn BatteryInteraction + Send> {
|
||||||
|
&mut self.battery_monitor
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_rtc_module(&mut self) -> &mut Box<dyn RTCModuleInteraction + Send> {
|
||||||
|
&mut self.rtc_module
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_time(&mut self) -> DateTime<Utc> {
|
||||||
|
self.esp.get_time()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_time(&mut self, time: &DateTime<FixedOffset>) -> FatResult<()> {
|
||||||
|
self.rtc_module.set_rtc_time(&time.to_utc()).await?;
|
||||||
|
self.esp.set_time(time.to_utc());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_charge_indicator(&mut self, charging: bool) -> Result<(), FatError> {
|
||||||
|
let shift_register = self.shift_register.lock().await;
|
||||||
|
if charging {
|
||||||
|
let _ = shift_register.decompose()[CHARGING].set_high();
|
||||||
|
} else {
|
||||||
|
let _ = shift_register.decompose()[CHARGING].set_low();
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn deep_sleep_ms(&mut self, duration_in_ms: u64) -> ! {
|
||||||
|
let _ = self.shift_register.lock().await.decompose()[AWAKE].set_low();
|
||||||
|
self.esp.deep_sleep_ms(duration_in_ms)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_day(&self) -> bool {
|
||||||
|
self.solar_is_day.is_high()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn light(&mut self, enable: bool) -> Result<(), FatError> {
|
||||||
|
hold_disable(10);
|
||||||
|
if enable {
|
||||||
|
self.light.set_high();
|
||||||
|
} else {
|
||||||
|
self.light.set_low();
|
||||||
|
}
|
||||||
|
hold_enable(10);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
async fn pump(&mut self, plant: usize, enable: bool) -> Result<(), FatError> {
|
||||||
|
if enable {
|
||||||
|
self.main_pump.set_high();
|
||||||
|
}
|
||||||
|
|
||||||
|
let index = match plant {
|
||||||
|
0 => PUMP1_BIT,
|
||||||
|
1 => PUMP2_BIT,
|
||||||
|
2 => PUMP3_BIT,
|
||||||
|
3 => PUMP4_BIT,
|
||||||
|
4 => PUMP5_BIT,
|
||||||
|
5 => PUMP6_BIT,
|
||||||
|
6 => PUMP7_BIT,
|
||||||
|
7 => PUMP8_BIT,
|
||||||
|
_ => bail!("Invalid pump {plant}"),
|
||||||
|
};
|
||||||
|
let shift_register = self.shift_register.lock().await;
|
||||||
|
if enable {
|
||||||
|
let _ = shift_register.decompose()[index].set_high();
|
||||||
|
} else {
|
||||||
|
let _ = shift_register.decompose()[index].set_low();
|
||||||
|
}
|
||||||
|
|
||||||
|
if !enable {
|
||||||
|
self.main_pump.set_low();
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn pump_current(&mut self, _plant: usize) -> Result<Current, FatError> {
|
||||||
|
bail!("Not implemented in v3")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn fault(&mut self, plant: usize, enable: bool) -> Result<(), FatError> {
|
||||||
|
let index = match plant {
|
||||||
|
0 => FAULT_1,
|
||||||
|
1 => FAULT_2,
|
||||||
|
2 => FAULT_3,
|
||||||
|
3 => FAULT_4,
|
||||||
|
4 => FAULT_5,
|
||||||
|
5 => FAULT_6,
|
||||||
|
6 => FAULT_7,
|
||||||
|
7 => FAULT_8,
|
||||||
|
_ => panic!("Invalid plant id {}", plant),
|
||||||
|
};
|
||||||
|
let shift_register = self.shift_register.lock().await;
|
||||||
|
if enable {
|
||||||
|
let _ = shift_register.decompose()[index].set_high();
|
||||||
|
} else {
|
||||||
|
let _ = shift_register.decompose()[index].set_low();
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn measure_moisture_hz(&mut self, plant: usize, sensor: Sensor) -> Result<f32, FatError> {
|
||||||
|
let mut results = [0_f32; REPEAT_MOIST_MEASURE];
|
||||||
|
for repeat in 0..REPEAT_MOIST_MEASURE {
|
||||||
|
self.signal_counter.pause();
|
||||||
|
self.signal_counter.clear();
|
||||||
|
//Disable all
|
||||||
|
{
|
||||||
|
let shift_register = self.shift_register.lock().await;
|
||||||
|
shift_register.decompose()[MS_4].set_high()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let sensor_channel = match sensor {
|
||||||
|
Sensor::A => match plant {
|
||||||
|
0 => SENSOR_A_1,
|
||||||
|
1 => SENSOR_A_2,
|
||||||
|
2 => SENSOR_A_3,
|
||||||
|
3 => SENSOR_A_4,
|
||||||
|
4 => SENSOR_A_5,
|
||||||
|
5 => SENSOR_A_6,
|
||||||
|
6 => SENSOR_A_7,
|
||||||
|
7 => SENSOR_A_8,
|
||||||
|
_ => bail!("Invalid plant id {}", plant),
|
||||||
|
},
|
||||||
|
Sensor::B => match plant {
|
||||||
|
0 => SENSOR_B_1,
|
||||||
|
1 => SENSOR_B_2,
|
||||||
|
2 => SENSOR_B_3,
|
||||||
|
3 => SENSOR_B_4,
|
||||||
|
4 => SENSOR_B_5,
|
||||||
|
5 => SENSOR_B_6,
|
||||||
|
6 => SENSOR_B_7,
|
||||||
|
7 => SENSOR_B_8,
|
||||||
|
_ => bail!("Invalid plant id {}", plant),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let is_bit_set = |b: u8| -> bool { sensor_channel & (1 << b) != 0 };
|
||||||
|
{
|
||||||
|
let shift_register = self.shift_register.lock().await;
|
||||||
|
let pin_0 = &mut shift_register.decompose()[MS_0];
|
||||||
|
let pin_1 = &mut shift_register.decompose()[MS_1];
|
||||||
|
let pin_2 = &mut shift_register.decompose()[MS_2];
|
||||||
|
let pin_3 = &mut shift_register.decompose()[MS_3];
|
||||||
|
if is_bit_set(0) {
|
||||||
|
pin_0.set_high()?;
|
||||||
|
} else {
|
||||||
|
pin_0.set_low()?;
|
||||||
|
}
|
||||||
|
if is_bit_set(1) {
|
||||||
|
pin_1.set_high()?;
|
||||||
|
} else {
|
||||||
|
pin_1.set_low()?;
|
||||||
|
}
|
||||||
|
if is_bit_set(2) {
|
||||||
|
pin_2.set_high()?;
|
||||||
|
} else {
|
||||||
|
pin_2.set_low()?;
|
||||||
|
}
|
||||||
|
if is_bit_set(3) {
|
||||||
|
pin_3.set_high()?;
|
||||||
|
} else {
|
||||||
|
pin_3.set_low()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
shift_register.decompose()[MS_4].set_low()?;
|
||||||
|
shift_register.decompose()[SENSOR_ON].set_high()?;
|
||||||
|
}
|
||||||
|
let measurement = 100; //how long to measure and then extrapolate to hz
|
||||||
|
let factor = 1000f32 / measurement as f32; //scale raw cound by this number to get hz
|
||||||
|
|
||||||
|
//give some time to stabilize
|
||||||
|
Timer::after_millis(10).await;
|
||||||
|
self.signal_counter.resume();
|
||||||
|
Timer::after_millis(measurement).await;
|
||||||
|
self.signal_counter.pause();
|
||||||
|
{
|
||||||
|
let shift_register = self.shift_register.lock().await;
|
||||||
|
shift_register.decompose()[MS_4].set_high()?;
|
||||||
|
shift_register.decompose()[SENSOR_ON].set_low()?;
|
||||||
|
}
|
||||||
|
Timer::after_millis(10).await;
|
||||||
|
let unscaled = self.signal_counter.value();
|
||||||
|
let hz = unscaled as f32 * factor;
|
||||||
|
log(
|
||||||
|
LogMessage::RawMeasure,
|
||||||
|
unscaled as u32,
|
||||||
|
hz as u32,
|
||||||
|
&plant.to_string(),
|
||||||
|
&format!("{sensor:?}"),
|
||||||
|
);
|
||||||
|
results[repeat] = hz;
|
||||||
|
}
|
||||||
|
results.sort_by(|a, b| a.partial_cmp(b).unwrap()); // floats don't seem to implement total_ord
|
||||||
|
|
||||||
|
let mid = results.len() / 2;
|
||||||
|
let median = results[mid];
|
||||||
|
Ok(median)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn general_fault(&mut self, enable: bool) {
|
||||||
|
hold_disable(6);
|
||||||
|
if enable {
|
||||||
|
self.general_fault.set_high();
|
||||||
|
} else {
|
||||||
|
self.general_fault.set_low();
|
||||||
|
}
|
||||||
|
hold_enable(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn test(&mut self) -> Result<(), FatError> {
|
||||||
|
self.general_fault(true).await;
|
||||||
|
Timer::after_millis(100).await;
|
||||||
|
self.general_fault(false).await;
|
||||||
|
Timer::after_millis(100).await;
|
||||||
|
self.light(true).await?;
|
||||||
|
Timer::after_millis(500).await;
|
||||||
|
|
||||||
|
self.light(false).await?;
|
||||||
|
Timer::after_millis(500).await;
|
||||||
|
for i in 0..PLANT_COUNT {
|
||||||
|
self.fault(i, true).await?;
|
||||||
|
Timer::after_millis(500).await;
|
||||||
|
self.fault(i, false).await?;
|
||||||
|
Timer::after_millis(500).await;
|
||||||
|
}
|
||||||
|
for i in 0..PLANT_COUNT {
|
||||||
|
self.pump(i, true).await?;
|
||||||
|
Timer::after_millis(100).await;
|
||||||
|
self.pump(i, false).await?;
|
||||||
|
Timer::after_millis(100).await;
|
||||||
|
}
|
||||||
|
for plant in 0..PLANT_COUNT {
|
||||||
|
let a = self.measure_moisture_hz(plant, Sensor::A).await;
|
||||||
|
let b = self.measure_moisture_hz(plant, Sensor::B).await;
|
||||||
|
let aa = match a {
|
||||||
|
Ok(a) => a as u32,
|
||||||
|
Err(_) => u32::MAX,
|
||||||
|
};
|
||||||
|
let bb = match b {
|
||||||
|
Ok(b) => b as u32,
|
||||||
|
Err(_) => u32::MAX,
|
||||||
|
};
|
||||||
|
log(LogMessage::TestSensor, aa, bb, &plant.to_string(), "");
|
||||||
|
}
|
||||||
|
Timer::after_millis(10).await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_config(&mut self, config: PlantControllerConfig) {
|
||||||
|
self.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_mptt_voltage(&mut self) -> Result<Voltage, FatError> {
|
||||||
|
bail!("Not implemented in v3")
|
||||||
|
}
|
||||||
|
async fn get_mptt_current(&mut self) -> Result<Current, FatError> {
|
||||||
|
bail!("Not implemented in v3")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
//! Serial-in parallel-out shift register
|
//! Serial-in parallel-out shift register
|
||||||
|
#![allow(warnings)]
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
|
use core::convert::Infallible;
|
||||||
|
use core::iter::Iterator;
|
||||||
use core::mem::{self, MaybeUninit};
|
use core::mem::{self, MaybeUninit};
|
||||||
use std::convert::Infallible;
|
use core::result::{Result, Result::Ok};
|
||||||
|
use embedded_hal::digital::OutputPin;
|
||||||
|
|
||||||
use hal::digital::OutputPin;
|
trait ShiftRegisterInternal: Send {
|
||||||
|
|
||||||
trait ShiftRegisterInternal {
|
|
||||||
fn update(&self, index: usize, command: bool) -> Result<(), ()>;
|
fn update(&self, index: usize, command: bool) -> Result<(), ()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,9 +47,9 @@ macro_rules! ShiftRegisterBuilder {
|
|||||||
/// Serial-in parallel-out shift register
|
/// Serial-in parallel-out shift register
|
||||||
pub struct $name<Pin1, Pin2, Pin3>
|
pub struct $name<Pin1, Pin2, Pin3>
|
||||||
where
|
where
|
||||||
Pin1: OutputPin,
|
Pin1: OutputPin + Send,
|
||||||
Pin2: OutputPin,
|
Pin2: OutputPin + Send,
|
||||||
Pin3: OutputPin,
|
Pin3: OutputPin + Send,
|
||||||
{
|
{
|
||||||
clock: RefCell<Pin1>,
|
clock: RefCell<Pin1>,
|
||||||
latch: RefCell<Pin2>,
|
latch: RefCell<Pin2>,
|
||||||
@@ -58,9 +59,9 @@ macro_rules! ShiftRegisterBuilder {
|
|||||||
|
|
||||||
impl<Pin1, Pin2, Pin3> ShiftRegisterInternal for $name<Pin1, Pin2, Pin3>
|
impl<Pin1, Pin2, Pin3> ShiftRegisterInternal for $name<Pin1, Pin2, Pin3>
|
||||||
where
|
where
|
||||||
Pin1: OutputPin,
|
Pin1: OutputPin + Send,
|
||||||
Pin2: OutputPin,
|
Pin2: OutputPin + Send,
|
||||||
Pin3: OutputPin,
|
Pin3: OutputPin + Send,
|
||||||
{
|
{
|
||||||
/// Sets the value of the shift register output at `index` to value `command`
|
/// Sets the value of the shift register output at `index` to value `command`
|
||||||
fn update(&self, index: usize, command: bool) -> Result<(), ()> {
|
fn update(&self, index: usize, command: bool) -> Result<(), ()> {
|
||||||
@@ -85,9 +86,9 @@ macro_rules! ShiftRegisterBuilder {
|
|||||||
|
|
||||||
impl<Pin1, Pin2, Pin3> $name<Pin1, Pin2, Pin3>
|
impl<Pin1, Pin2, Pin3> $name<Pin1, Pin2, Pin3>
|
||||||
where
|
where
|
||||||
Pin1: OutputPin,
|
Pin1: OutputPin + Send,
|
||||||
Pin2: OutputPin,
|
Pin2: OutputPin + Send,
|
||||||
Pin3: OutputPin,
|
Pin3: OutputPin + Send,
|
||||||
{
|
{
|
||||||
/// Creates a new SIPO shift register from clock, latch, and data output pins
|
/// Creates a new SIPO shift register from clock, latch, and data output pins
|
||||||
pub fn new(clock: Pin1, latch: Pin2, data: Pin3) -> Self {
|
pub fn new(clock: Pin1, latch: Pin2, data: Pin3) -> Self {
|
||||||
@@ -100,7 +101,7 @@ macro_rules! ShiftRegisterBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get embedded-hal output pins to control the shift register outputs
|
/// Get embedded-hal output pins to control the shift register outputs
|
||||||
pub fn decompose(&self) -> [ShiftRegisterPin; $size] {
|
pub fn decompose(&self) -> [ShiftRegisterPin<'_>; $size] {
|
||||||
// Create an uninitialized array of `MaybeUninit`. The `assume_init` is
|
// Create an uninitialized array of `MaybeUninit`. The `assume_init` is
|
||||||
// safe because the type we are claiming to have initialized here is a
|
// safe because the type we are claiming to have initialized here is a
|
||||||
// bunch of `MaybeUninit`s, which do not require initialization.
|
// bunch of `MaybeUninit`s, which do not require initialization.
|
||||||
470
rust/src/hal/v4_hal.rs
Normal file
470
rust/src/hal/v4_hal.rs
Normal file
@@ -0,0 +1,470 @@
|
|||||||
|
use crate::config::PlantControllerConfig;
|
||||||
|
use crate::hal::battery::BatteryInteraction;
|
||||||
|
use crate::hal::esp::{hold_disable, hold_enable, Esp};
|
||||||
|
use crate::hal::rtc::RTCModuleInteraction;
|
||||||
|
use crate::hal::water::TankSensor;
|
||||||
|
use crate::hal::{BoardInteraction, FreePeripherals, Sensor, I2C_DRIVER, PLANT_COUNT};
|
||||||
|
use alloc::boxed::Box;
|
||||||
|
use alloc::string::ToString;
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use chrono::{DateTime, FixedOffset, Utc};
|
||||||
|
use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
|
||||||
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
|
use embassy_time::Timer;
|
||||||
|
use esp_hal::{twai, Blocking};
|
||||||
|
//use embedded_hal_bus::i2c::MutexDevice;
|
||||||
|
use crate::bail;
|
||||||
|
use crate::fat_error::{FatError, FatResult};
|
||||||
|
use crate::hal::v4_sensor::{SensorImpl, SensorInteraction};
|
||||||
|
use crate::log::{LogMessage, LOG_ACCESS};
|
||||||
|
use esp_hal::gpio::{Flex, Input, InputConfig, Level, Output, OutputConfig, Pull};
|
||||||
|
use esp_hal::i2c::master::I2c;
|
||||||
|
use esp_hal::pcnt::channel::CtrlMode::Keep;
|
||||||
|
use esp_hal::pcnt::channel::EdgeMode::{Hold, Increment};
|
||||||
|
use esp_hal::pcnt::Pcnt;
|
||||||
|
use esp_hal::twai::{EspTwaiFrame, StandardId, TwaiMode};
|
||||||
|
use esp_println::println;
|
||||||
|
use ina219::address::{Address, Pin};
|
||||||
|
use ina219::calibration::UnCalibrated;
|
||||||
|
use ina219::configuration::{Configuration, OperatingMode, Resolution};
|
||||||
|
use ina219::SyncIna219;
|
||||||
|
use measurements::Resistance;
|
||||||
|
use measurements::{Current, Voltage};
|
||||||
|
use pca9535::{GPIOBank, Pca9535Immediate, StandardExpanderInterface};
|
||||||
|
|
||||||
|
const MPPT_CURRENT_SHUNT_OHMS: f64 = 0.05_f64;
|
||||||
|
const TWAI_BAUDRATE: twai::BaudRate = twai::BaudRate::B125K;
|
||||||
|
|
||||||
|
pub enum Charger<'a> {
|
||||||
|
SolarMpptV1 {
|
||||||
|
mppt_ina: SyncIna219<
|
||||||
|
I2cDevice<'a, CriticalSectionRawMutex, I2c<'static, Blocking>>,
|
||||||
|
UnCalibrated,
|
||||||
|
>,
|
||||||
|
solar_is_day: Input<'a>,
|
||||||
|
charge_indicator: Output<'a>,
|
||||||
|
},
|
||||||
|
ErrorInit {},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Charger<'a> {
|
||||||
|
pub(crate) fn get_mppt_current(&mut self) -> FatResult<Current> {
|
||||||
|
match self {
|
||||||
|
Charger::SolarMpptV1 { mppt_ina, .. } => {
|
||||||
|
let v = mppt_ina.shunt_voltage()?;
|
||||||
|
let shunt_voltage = Voltage::from_microvolts(v.shunt_voltage_uv().abs() as f64);
|
||||||
|
let shut_value = Resistance::from_ohms(MPPT_CURRENT_SHUNT_OHMS);
|
||||||
|
let current = shunt_voltage.as_volts() / shut_value.as_ohms();
|
||||||
|
Ok(Current::from_amperes(current))
|
||||||
|
}
|
||||||
|
Charger::ErrorInit { .. } => {
|
||||||
|
bail!("hardware error during init");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_mptt_voltage(&mut self) -> FatResult<Voltage> {
|
||||||
|
match self {
|
||||||
|
Charger::SolarMpptV1 { mppt_ina, .. } => {
|
||||||
|
let v = mppt_ina.bus_voltage()?;
|
||||||
|
Ok(Voltage::from_millivolts(v.voltage_mv() as f64))
|
||||||
|
}
|
||||||
|
Charger::ErrorInit { .. } => {
|
||||||
|
bail!("hardware error during init");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Charger<'_> {
|
||||||
|
pub(crate) fn power_save(&mut self) {
|
||||||
|
match self {
|
||||||
|
Charger::SolarMpptV1 { mppt_ina, .. } => {
|
||||||
|
let _ = mppt_ina
|
||||||
|
.set_configuration(Configuration {
|
||||||
|
reset: Default::default(),
|
||||||
|
bus_voltage_range: Default::default(),
|
||||||
|
shunt_voltage_range: Default::default(),
|
||||||
|
bus_resolution: Default::default(),
|
||||||
|
shunt_resolution: Default::default(),
|
||||||
|
operating_mode: OperatingMode::PowerDown,
|
||||||
|
})
|
||||||
|
.map_err(|e| {
|
||||||
|
log::info!(
|
||||||
|
"Error setting ina mppt configuration during deep sleep preparation{:?}",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn set_charge_indicator(&mut self, charging: bool) -> FatResult<()> {
|
||||||
|
match self {
|
||||||
|
Self::SolarMpptV1 {
|
||||||
|
charge_indicator, ..
|
||||||
|
} => {
|
||||||
|
charge_indicator.set_level(charging.into());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_day(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Charger::SolarMpptV1 { solar_is_day, .. } => solar_is_day.is_high(),
|
||||||
|
_ => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct V4<'a> {
|
||||||
|
esp: Esp<'a>,
|
||||||
|
tank_sensor: TankSensor<'a>,
|
||||||
|
charger: Charger<'a>,
|
||||||
|
rtc_module: Box<dyn RTCModuleInteraction + Send>,
|
||||||
|
battery_monitor: Box<dyn BatteryInteraction + Send>,
|
||||||
|
config: PlantControllerConfig,
|
||||||
|
|
||||||
|
awake: Output<'a>,
|
||||||
|
light: Output<'a>,
|
||||||
|
general_fault: Output<'a>,
|
||||||
|
pump_expander: Pca9535Immediate<I2cDevice<'a, CriticalSectionRawMutex, I2c<'static, Blocking>>>,
|
||||||
|
pump_ina: Option<
|
||||||
|
SyncIna219<I2cDevice<'a, CriticalSectionRawMutex, I2c<'static, Blocking>>, UnCalibrated>,
|
||||||
|
>,
|
||||||
|
sensor: SensorImpl,
|
||||||
|
extra1: Output<'a>,
|
||||||
|
extra2: Output<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn create_v4(
|
||||||
|
peripherals: FreePeripherals<'static>,
|
||||||
|
esp: Esp<'static>,
|
||||||
|
config: PlantControllerConfig,
|
||||||
|
battery_monitor: Box<dyn BatteryInteraction + Send>,
|
||||||
|
rtc_module: Box<dyn RTCModuleInteraction + Send>,
|
||||||
|
) -> Result<Box<dyn BoardInteraction<'static> + Send + 'static>, FatError> {
|
||||||
|
log::info!("Start v4");
|
||||||
|
let mut awake = Output::new(peripherals.gpio21, Level::High, OutputConfig::default());
|
||||||
|
awake.set_high();
|
||||||
|
|
||||||
|
let mut general_fault = Output::new(peripherals.gpio23, Level::Low, OutputConfig::default());
|
||||||
|
general_fault.set_low();
|
||||||
|
|
||||||
|
let extra1 = Output::new(peripherals.gpio6, Level::Low, OutputConfig::default());
|
||||||
|
let extra2 = Output::new(peripherals.gpio15, Level::Low, OutputConfig::default());
|
||||||
|
|
||||||
|
let one_wire_pin = Flex::new(peripherals.gpio18);
|
||||||
|
let tank_power_pin = Output::new(peripherals.gpio11, Level::Low, OutputConfig::default());
|
||||||
|
let flow_sensor_pin = Input::new(
|
||||||
|
peripherals.gpio4,
|
||||||
|
InputConfig::default().with_pull(Pull::Up),
|
||||||
|
);
|
||||||
|
|
||||||
|
let tank_sensor = TankSensor::create(
|
||||||
|
one_wire_pin,
|
||||||
|
peripherals.adc1,
|
||||||
|
peripherals.gpio5,
|
||||||
|
tank_power_pin,
|
||||||
|
flow_sensor_pin,
|
||||||
|
peripherals.pcnt1,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let sensor_expander_device = I2cDevice::new(I2C_DRIVER.get().await);
|
||||||
|
let mut sensor_expander = Pca9535Immediate::new(sensor_expander_device, 34);
|
||||||
|
let sensor = match sensor_expander.pin_into_output(GPIOBank::Bank0, 0) {
|
||||||
|
Ok(_) => {
|
||||||
|
log::info!("SensorExpander answered");
|
||||||
|
|
||||||
|
let signal_counter = peripherals.pcnt0;
|
||||||
|
|
||||||
|
signal_counter.set_low_limit(Some(0))?;
|
||||||
|
signal_counter.set_high_limit(Some(i16::MAX))?;
|
||||||
|
|
||||||
|
let ch0 = &signal_counter.channel0;
|
||||||
|
let edge_pin = Input::new(peripherals.gpio22, InputConfig::default());
|
||||||
|
ch0.set_edge_signal(edge_pin.peripheral_input());
|
||||||
|
ch0.set_input_mode(Hold, Increment);
|
||||||
|
ch0.set_ctrl_mode(Keep, Keep);
|
||||||
|
signal_counter.listen();
|
||||||
|
|
||||||
|
for pin in 0..8 {
|
||||||
|
let _ = sensor_expander.pin_into_output(GPIOBank::Bank0, pin);
|
||||||
|
let _ = sensor_expander.pin_into_output(GPIOBank::Bank1, pin);
|
||||||
|
let _ = sensor_expander.pin_set_low(GPIOBank::Bank0, pin);
|
||||||
|
let _ = sensor_expander.pin_set_low(GPIOBank::Bank1, pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
SensorImpl::PulseCounter {
|
||||||
|
signal_counter,
|
||||||
|
sensor_expander,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
log::info!("Can bus mode ");
|
||||||
|
let twai_config = twai::TwaiConfiguration::new(
|
||||||
|
peripherals.twai,
|
||||||
|
peripherals.gpio0,
|
||||||
|
peripherals.gpio2,
|
||||||
|
TWAI_BAUDRATE,
|
||||||
|
TwaiMode::Normal,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut twai = twai_config.start();
|
||||||
|
let frame = EspTwaiFrame::new(StandardId::ZERO, &[1, 2, 3]).unwrap();
|
||||||
|
|
||||||
|
twai.transmit(&frame).unwrap();
|
||||||
|
|
||||||
|
// let frame = twai.receive().unwrap();
|
||||||
|
println!("Received a frame: {frame:?}");
|
||||||
|
//can bus version
|
||||||
|
SensorImpl::CanBus { twai }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let solar_is_day = Input::new(peripherals.gpio7, InputConfig::default());
|
||||||
|
let light = Output::new(peripherals.gpio10, Level::Low, Default::default());
|
||||||
|
let charge_indicator = Output::new(peripherals.gpio3, Level::Low, Default::default());
|
||||||
|
|
||||||
|
let pump_device = I2cDevice::new(I2C_DRIVER.get().await);
|
||||||
|
let mut pump_expander = Pca9535Immediate::new(pump_device, 32);
|
||||||
|
for pin in 0..8 {
|
||||||
|
let _ = pump_expander.pin_into_output(GPIOBank::Bank0, pin);
|
||||||
|
let _ = pump_expander.pin_into_output(GPIOBank::Bank1, pin);
|
||||||
|
let _ = pump_expander.pin_set_low(GPIOBank::Bank0, pin);
|
||||||
|
let _ = pump_expander.pin_set_low(GPIOBank::Bank1, pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mppt_current = I2cDevice::new(I2C_DRIVER.get().await);
|
||||||
|
let mppt_ina = match SyncIna219::new(mppt_current, Address::from_pins(Pin::Vcc, Pin::Gnd)) {
|
||||||
|
Ok(mut ina) => {
|
||||||
|
// Prefer higher averaging for more stable readings
|
||||||
|
let _ = ina.set_configuration(Configuration {
|
||||||
|
reset: Default::default(),
|
||||||
|
bus_voltage_range: Default::default(),
|
||||||
|
shunt_voltage_range: Default::default(),
|
||||||
|
bus_resolution: Default::default(),
|
||||||
|
shunt_resolution: Resolution::Avg128,
|
||||||
|
operating_mode: Default::default(),
|
||||||
|
});
|
||||||
|
Some(ina)
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
log::info!("Error creating mppt ina: {:?}", err);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let pump_current_dev = I2cDevice::new(I2C_DRIVER.get().await);
|
||||||
|
let pump_ina = match SyncIna219::new(pump_current_dev, Address::from_pins(Pin::Gnd, Pin::Sda)) {
|
||||||
|
Ok(ina) => Some(ina),
|
||||||
|
Err(err) => {
|
||||||
|
log::info!("Error creating pump ina: {:?}", err);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let charger = match mppt_ina {
|
||||||
|
Some(mut mppt_ina) => {
|
||||||
|
mppt_ina.set_configuration(Configuration {
|
||||||
|
reset: Default::default(),
|
||||||
|
bus_voltage_range: Default::default(),
|
||||||
|
shunt_voltage_range: Default::default(),
|
||||||
|
bus_resolution: Default::default(),
|
||||||
|
shunt_resolution: ina219::configuration::Resolution::Avg128,
|
||||||
|
operating_mode: Default::default(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Charger::SolarMpptV1 {
|
||||||
|
mppt_ina,
|
||||||
|
solar_is_day,
|
||||||
|
charge_indicator,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => Charger::ErrorInit {},
|
||||||
|
};
|
||||||
|
|
||||||
|
let v = V4 {
|
||||||
|
rtc_module,
|
||||||
|
esp,
|
||||||
|
awake,
|
||||||
|
tank_sensor,
|
||||||
|
light,
|
||||||
|
general_fault,
|
||||||
|
pump_expander,
|
||||||
|
config,
|
||||||
|
battery_monitor,
|
||||||
|
pump_ina,
|
||||||
|
charger,
|
||||||
|
extra1,
|
||||||
|
extra2,
|
||||||
|
sensor,
|
||||||
|
};
|
||||||
|
Ok(Box::new(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl<'a> BoardInteraction<'a> for V4<'a> {
|
||||||
|
fn get_tank_sensor(&mut self) -> Result<&mut TankSensor<'a>, FatError> {
|
||||||
|
Ok(&mut self.tank_sensor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_esp(&mut self) -> &mut Esp<'a> {
|
||||||
|
&mut self.esp
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_config(&mut self) -> &PlantControllerConfig {
|
||||||
|
&self.config
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_battery_monitor(&mut self) -> &mut Box<dyn BatteryInteraction + Send> {
|
||||||
|
&mut self.battery_monitor
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_rtc_module(&mut self) -> &mut Box<dyn RTCModuleInteraction + Send> {
|
||||||
|
&mut self.rtc_module
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_time(&mut self) -> DateTime<Utc> {
|
||||||
|
self.esp.get_time()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_time(&mut self, time: &DateTime<FixedOffset>) -> FatResult<()> {
|
||||||
|
self.rtc_module.set_rtc_time(&time.to_utc()).await?;
|
||||||
|
self.esp.set_time(time.to_utc());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_charge_indicator(&mut self, charging: bool) -> Result<(), FatError> {
|
||||||
|
self.charger.set_charge_indicator(charging)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn deep_sleep_ms(&mut self, duration_in_ms: u64) -> ! {
|
||||||
|
self.awake.set_low();
|
||||||
|
self.charger.power_save();
|
||||||
|
self.esp.deep_sleep_ms(duration_in_ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_day(&self) -> bool {
|
||||||
|
self.charger.is_day()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn light(&mut self, enable: bool) -> Result<(), FatError> {
|
||||||
|
hold_disable(10);
|
||||||
|
self.light.set_level(enable.into());
|
||||||
|
hold_enable(10);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn pump(&mut self, plant: usize, enable: bool) -> FatResult<()> {
|
||||||
|
if enable {
|
||||||
|
self.pump_expander
|
||||||
|
.pin_set_high(GPIOBank::Bank0, plant as u8)?;
|
||||||
|
} else {
|
||||||
|
self.pump_expander
|
||||||
|
.pin_set_low(GPIOBank::Bank0, plant as u8)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn pump_current(&mut self, _plant: usize) -> Result<Current, FatError> {
|
||||||
|
// sensor is shared for all pumps, ignore plant id
|
||||||
|
match self.pump_ina.as_mut() {
|
||||||
|
None => {
|
||||||
|
bail!("pump current sensor not available");
|
||||||
|
}
|
||||||
|
Some(pump_ina) => {
|
||||||
|
let v = pump_ina
|
||||||
|
.shunt_voltage()
|
||||||
|
.map_err(|e| FatError::String {
|
||||||
|
error: alloc::format!("{:?}", e),
|
||||||
|
})
|
||||||
|
.map(|v| {
|
||||||
|
let shunt_voltage =
|
||||||
|
Voltage::from_microvolts(v.shunt_voltage_uv().abs() as f64);
|
||||||
|
let shut_value = Resistance::from_ohms(0.05_f64);
|
||||||
|
let current = shunt_voltage.as_volts() / shut_value.as_ohms();
|
||||||
|
Current::from_amperes(current)
|
||||||
|
})?;
|
||||||
|
Ok(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn fault(&mut self, plant: usize, enable: bool) -> FatResult<()> {
|
||||||
|
if enable {
|
||||||
|
self.pump_expander
|
||||||
|
.pin_set_high(GPIOBank::Bank1, plant as u8)?;
|
||||||
|
} else {
|
||||||
|
self.pump_expander
|
||||||
|
.pin_set_low(GPIOBank::Bank1, plant as u8)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn measure_moisture_hz(&mut self, plant: usize, sensor: Sensor) -> Result<f32, FatError> {
|
||||||
|
self.sensor.measure_moisture_hz(plant, sensor).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn general_fault(&mut self, enable: bool) {
|
||||||
|
hold_disable(23);
|
||||||
|
self.general_fault.set_level(enable.into());
|
||||||
|
hold_enable(23);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn test(&mut self) -> Result<(), FatError> {
|
||||||
|
self.general_fault(true).await;
|
||||||
|
Timer::after_millis(100).await;
|
||||||
|
self.general_fault(false).await;
|
||||||
|
Timer::after_millis(500).await;
|
||||||
|
self.light(true).await?;
|
||||||
|
Timer::after_millis(500).await;
|
||||||
|
self.light(false).await?;
|
||||||
|
Timer::after_millis(500).await;
|
||||||
|
for i in 0..PLANT_COUNT {
|
||||||
|
self.fault(i, true).await?;
|
||||||
|
Timer::after_millis(500).await;
|
||||||
|
self.fault(i, false).await?;
|
||||||
|
Timer::after_millis(500).await;
|
||||||
|
}
|
||||||
|
for i in 0..PLANT_COUNT {
|
||||||
|
self.pump(i, true).await?;
|
||||||
|
Timer::after_millis(100).await;
|
||||||
|
self.pump(i, false).await?;
|
||||||
|
Timer::after_millis(100).await;
|
||||||
|
}
|
||||||
|
for plant in 0..PLANT_COUNT {
|
||||||
|
let a = self.measure_moisture_hz(plant, Sensor::A).await;
|
||||||
|
let b = self.measure_moisture_hz(plant, Sensor::B).await;
|
||||||
|
let aa = match a {
|
||||||
|
Ok(a) => a as u32,
|
||||||
|
Err(_) => u32::MAX,
|
||||||
|
};
|
||||||
|
let bb = match b {
|
||||||
|
Ok(b) => b as u32,
|
||||||
|
Err(_) => u32::MAX,
|
||||||
|
};
|
||||||
|
LOG_ACCESS
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.log(LogMessage::TestSensor, aa, bb, &plant.to_string(), "")
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
Timer::after_millis(10).await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_config(&mut self, config: PlantControllerConfig) {
|
||||||
|
self.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_mptt_voltage(&mut self) -> Result<Voltage, FatError> {
|
||||||
|
self.charger.get_mptt_voltage()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_mptt_current(&mut self) -> Result<Current, FatError> {
|
||||||
|
self.charger.get_mppt_current()
|
||||||
|
}
|
||||||
|
}
|
||||||
130
rust/src/hal/v4_sensor.rs
Normal file
130
rust/src/hal/v4_sensor.rs
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
use crate::fat_error::{FatError, FatResult};
|
||||||
|
use crate::hal::Box;
|
||||||
|
use crate::hal::Sensor;
|
||||||
|
use crate::log::{LogMessage, LOG_ACCESS};
|
||||||
|
use alloc::format;
|
||||||
|
use alloc::string::ToString;
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
|
||||||
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
|
use embassy_time::Timer;
|
||||||
|
use esp_hal::i2c::master::I2c;
|
||||||
|
use esp_hal::pcnt::unit::Unit;
|
||||||
|
use esp_hal::twai::Twai;
|
||||||
|
use esp_hal::Blocking;
|
||||||
|
use pca9535::{GPIOBank, Pca9535Immediate, StandardExpanderInterface};
|
||||||
|
|
||||||
|
const REPEAT_MOIST_MEASURE: usize = 10;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
pub trait SensorInteraction {
|
||||||
|
async fn measure_moisture_hz(&mut self, plant: usize, sensor: Sensor) -> FatResult<f32>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MS0: u8 = 1_u8;
|
||||||
|
const MS1: u8 = 0_u8;
|
||||||
|
const MS2: u8 = 3_u8;
|
||||||
|
const MS3: u8 = 4_u8;
|
||||||
|
const MS4: u8 = 2_u8;
|
||||||
|
const SENSOR_ON: u8 = 5_u8;
|
||||||
|
|
||||||
|
pub enum SensorImpl {
|
||||||
|
PulseCounter {
|
||||||
|
signal_counter: Unit<'static, 0>,
|
||||||
|
sensor_expander:
|
||||||
|
Pca9535Immediate<I2cDevice<'static, CriticalSectionRawMutex, I2c<'static, Blocking>>>,
|
||||||
|
},
|
||||||
|
CanBus {
|
||||||
|
twai: Twai<'static, Blocking>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl SensorInteraction for SensorImpl {
|
||||||
|
async fn measure_moisture_hz(&mut self, plant: usize, sensor: Sensor) -> FatResult<f32> {
|
||||||
|
match self {
|
||||||
|
SensorImpl::PulseCounter {
|
||||||
|
signal_counter,
|
||||||
|
sensor_expander,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let mut results = [0_f32; REPEAT_MOIST_MEASURE];
|
||||||
|
for repeat in 0..REPEAT_MOIST_MEASURE {
|
||||||
|
signal_counter.pause();
|
||||||
|
signal_counter.clear();
|
||||||
|
|
||||||
|
//Disable all
|
||||||
|
sensor_expander.pin_set_high(GPIOBank::Bank0, MS4)?;
|
||||||
|
|
||||||
|
let sensor_channel = match sensor {
|
||||||
|
Sensor::A => plant as u32,
|
||||||
|
Sensor::B => (15 - plant) as u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
let is_bit_set = |b: u8| -> bool { sensor_channel & (1 << b) != 0 };
|
||||||
|
if is_bit_set(0) {
|
||||||
|
sensor_expander.pin_set_high(GPIOBank::Bank0, MS0)?;
|
||||||
|
} else {
|
||||||
|
sensor_expander.pin_set_low(GPIOBank::Bank0, MS0)?;
|
||||||
|
}
|
||||||
|
if is_bit_set(1) {
|
||||||
|
sensor_expander.pin_set_high(GPIOBank::Bank0, MS1)?;
|
||||||
|
} else {
|
||||||
|
sensor_expander.pin_set_low(GPIOBank::Bank0, MS1)?;
|
||||||
|
}
|
||||||
|
if is_bit_set(2) {
|
||||||
|
sensor_expander.pin_set_high(GPIOBank::Bank0, MS2)?;
|
||||||
|
} else {
|
||||||
|
sensor_expander.pin_set_low(GPIOBank::Bank0, MS2)?;
|
||||||
|
}
|
||||||
|
if is_bit_set(3) {
|
||||||
|
sensor_expander.pin_set_high(GPIOBank::Bank0, MS3)?;
|
||||||
|
} else {
|
||||||
|
sensor_expander.pin_set_low(GPIOBank::Bank0, MS3)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
sensor_expander.pin_set_low(GPIOBank::Bank0, MS4)?;
|
||||||
|
sensor_expander.pin_set_high(GPIOBank::Bank0, SENSOR_ON)?;
|
||||||
|
|
||||||
|
let measurement = 100; // TODO what is this scaling factor? what is its purpose?
|
||||||
|
let factor = 1000f32 / measurement as f32;
|
||||||
|
|
||||||
|
//give some time to stabilize
|
||||||
|
Timer::after_millis(10).await;
|
||||||
|
signal_counter.resume();
|
||||||
|
Timer::after_millis(measurement).await;
|
||||||
|
signal_counter.pause();
|
||||||
|
sensor_expander.pin_set_high(GPIOBank::Bank0, MS4)?;
|
||||||
|
sensor_expander.pin_set_low(GPIOBank::Bank0, SENSOR_ON)?;
|
||||||
|
sensor_expander.pin_set_low(GPIOBank::Bank0, MS0)?;
|
||||||
|
sensor_expander.pin_set_low(GPIOBank::Bank0, MS1)?;
|
||||||
|
sensor_expander.pin_set_low(GPIOBank::Bank0, MS2)?;
|
||||||
|
sensor_expander.pin_set_low(GPIOBank::Bank0, MS3)?;
|
||||||
|
Timer::after_millis(10).await;
|
||||||
|
let unscaled = 1337; //signal_counter.get_counter_value()? as i32;
|
||||||
|
let hz = unscaled as f32 * factor;
|
||||||
|
LOG_ACCESS
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.log(
|
||||||
|
LogMessage::RawMeasure,
|
||||||
|
unscaled as u32,
|
||||||
|
hz as u32,
|
||||||
|
&plant.to_string(),
|
||||||
|
&format!("{sensor:?}"),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
results[repeat] = hz;
|
||||||
|
}
|
||||||
|
results.sort_by(|a, b| a.partial_cmp(b).unwrap()); // floats don't seem to implement total_ord
|
||||||
|
|
||||||
|
let mid = results.len() / 2;
|
||||||
|
let median = results[mid];
|
||||||
|
Ok(median)
|
||||||
|
}
|
||||||
|
SensorImpl::CanBus { twai } => Err(FatError::String {
|
||||||
|
error: "Not yet implemented".to_string(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
180
rust/src/hal/water.rs
Normal file
180
rust/src/hal/water.rs
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
use crate::bail;
|
||||||
|
use crate::fat_error::FatError;
|
||||||
|
use crate::hal::{ADC1, TANK_MULTI_SAMPLE};
|
||||||
|
use embassy_time::Timer;
|
||||||
|
use esp_hal::analog::adc::{Adc, AdcCalLine, AdcConfig, AdcPin, Attenuation};
|
||||||
|
use esp_hal::delay::Delay;
|
||||||
|
use esp_hal::gpio::{DriveMode, Flex, Input, InputConfig, Output, OutputConfig, Pull};
|
||||||
|
use esp_hal::pcnt::channel::CtrlMode::Keep;
|
||||||
|
use esp_hal::pcnt::channel::EdgeMode::{Hold, Increment};
|
||||||
|
use esp_hal::pcnt::unit::Unit;
|
||||||
|
use esp_hal::peripherals::GPIO5;
|
||||||
|
use esp_hal::Async;
|
||||||
|
use esp_println::println;
|
||||||
|
use onewire::{ds18b20, Device, DeviceSearch, OneWire, DS18B20};
|
||||||
|
|
||||||
|
unsafe impl Send for TankSensor<'_> {}
|
||||||
|
|
||||||
|
pub struct TankSensor<'a> {
|
||||||
|
one_wire_bus: OneWire<Flex<'a>>,
|
||||||
|
tank_channel: Adc<'a, ADC1<'a>, Async>,
|
||||||
|
tank_power: Output<'a>,
|
||||||
|
tank_pin: AdcPin<GPIO5<'a>, ADC1<'a>, AdcCalLine<ADC1<'a>>>,
|
||||||
|
flow_counter: Unit<'a, 1>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TankSensor<'a> {
|
||||||
|
pub(crate) fn create(
|
||||||
|
mut one_wire_pin: Flex<'a>,
|
||||||
|
adc1: ADC1<'a>,
|
||||||
|
gpio5: GPIO5<'a>,
|
||||||
|
tank_power: Output<'a>,
|
||||||
|
flow_sensor: Input,
|
||||||
|
pcnt1: Unit<'a, 1>,
|
||||||
|
) -> Result<TankSensor<'a>, FatError> {
|
||||||
|
one_wire_pin.apply_output_config(
|
||||||
|
&OutputConfig::default()
|
||||||
|
.with_drive_mode(DriveMode::OpenDrain)
|
||||||
|
.with_pull(Pull::None),
|
||||||
|
);
|
||||||
|
one_wire_pin.apply_input_config(&InputConfig::default().with_pull(Pull::None));
|
||||||
|
one_wire_pin.set_high();
|
||||||
|
one_wire_pin.set_input_enable(true);
|
||||||
|
one_wire_pin.set_output_enable(true);
|
||||||
|
|
||||||
|
let mut adc1_config = AdcConfig::new();
|
||||||
|
let tank_pin =
|
||||||
|
adc1_config.enable_pin_with_cal::<_, AdcCalLine<_>>(gpio5, Attenuation::_11dB);
|
||||||
|
let tank_channel = Adc::new(adc1, adc1_config).into_async();
|
||||||
|
|
||||||
|
let one_wire_bus = OneWire::new(one_wire_pin, false);
|
||||||
|
|
||||||
|
pcnt1.set_high_limit(Some(i16::MAX))?;
|
||||||
|
|
||||||
|
let ch0 = &pcnt1.channel0;
|
||||||
|
ch0.set_edge_signal(flow_sensor.peripheral_input());
|
||||||
|
ch0.set_input_mode(Hold, Increment);
|
||||||
|
ch0.set_ctrl_mode(Keep, Keep);
|
||||||
|
pcnt1.listen();
|
||||||
|
|
||||||
|
Ok(TankSensor {
|
||||||
|
one_wire_bus,
|
||||||
|
tank_channel,
|
||||||
|
tank_power,
|
||||||
|
tank_pin,
|
||||||
|
flow_counter: pcnt1,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset_flow_meter(&mut self) {
|
||||||
|
self.flow_counter.pause();
|
||||||
|
self.flow_counter.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start_flow_meter(&mut self) {
|
||||||
|
self.flow_counter.resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_flow_meter_value(&mut self) -> i16 {
|
||||||
|
self.flow_counter.value()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stop_flow_meter(&mut self) -> i16 {
|
||||||
|
self.flow_counter.pause();
|
||||||
|
self.get_flow_meter_value()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn water_temperature_c(&mut self) -> Result<f32, FatError> {
|
||||||
|
//multisample should be moved to water_temperature_c
|
||||||
|
let mut attempt = 1;
|
||||||
|
let mut delay = Delay::new();
|
||||||
|
|
||||||
|
let presence = self.one_wire_bus.reset(&mut delay)?;
|
||||||
|
println!("OneWire: reset presence pulse = {}", presence);
|
||||||
|
if !presence {
|
||||||
|
println!("OneWire: no device responded to reset — check pull-up resistor and wiring");
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut search = DeviceSearch::new();
|
||||||
|
let mut water_temp_sensor: Option<Device> = None;
|
||||||
|
let mut devices_found = 0u8;
|
||||||
|
while let Some(device) = self.one_wire_bus.search_next(&mut search, &mut delay)? {
|
||||||
|
devices_found += 1;
|
||||||
|
println!(
|
||||||
|
"OneWire: found device #{} family=0x{:02X} addr={:02X?}",
|
||||||
|
devices_found, device.address[0], device.address
|
||||||
|
);
|
||||||
|
if device.address[0] == ds18b20::FAMILY_CODE {
|
||||||
|
water_temp_sensor = Some(device);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
println!("OneWire: skipping device — not a DS18B20 (family 0x{:02X} != 0x{:02X})", device.address[0], ds18b20::FAMILY_CODE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if devices_found == 0 {
|
||||||
|
println!("OneWire: search found zero devices on the bus");
|
||||||
|
}
|
||||||
|
|
||||||
|
match water_temp_sensor {
|
||||||
|
Some(device) => {
|
||||||
|
println!("Found one wire device: {:?}", device);
|
||||||
|
let mut water_temp_sensor = DS18B20::new(device)?;
|
||||||
|
|
||||||
|
let water_temp: Result<f32, FatError> = loop {
|
||||||
|
let temp = self
|
||||||
|
.single_temperature_c(&mut water_temp_sensor, &mut delay)
|
||||||
|
.await;
|
||||||
|
match &temp {
|
||||||
|
Ok(res) => {
|
||||||
|
println!("Water temp is {}", res);
|
||||||
|
break temp;
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
println!("Could not get water temp {} attempt {}", err, attempt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if attempt == 5 {
|
||||||
|
break temp;
|
||||||
|
}
|
||||||
|
attempt += 1;
|
||||||
|
};
|
||||||
|
water_temp
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
bail!("Not found any one wire Ds18b20");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn single_temperature_c(
|
||||||
|
&mut self,
|
||||||
|
sensor: &mut DS18B20,
|
||||||
|
delay: &mut Delay,
|
||||||
|
) -> Result<f32, FatError> {
|
||||||
|
let resolution = sensor.measure_temperature(&mut self.one_wire_bus, delay)?;
|
||||||
|
Timer::after_millis(resolution.time_ms() as u64).await;
|
||||||
|
let temperature = sensor.read_temperature(&mut self.one_wire_bus, delay)? as f32;
|
||||||
|
if temperature == 85_f32 {
|
||||||
|
bail!("Ds18b20 dummy temperature returned");
|
||||||
|
}
|
||||||
|
Ok(temperature / 10_f32)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn tank_sensor_voltage(&mut self) -> Result<f32, FatError> {
|
||||||
|
self.tank_power.set_high();
|
||||||
|
//let stabilize
|
||||||
|
Timer::after_millis(100).await;
|
||||||
|
|
||||||
|
let mut store = [0_u16; TANK_MULTI_SAMPLE];
|
||||||
|
for sample in store.iter_mut() {
|
||||||
|
*sample = self.tank_channel.read_oneshot(&mut self.tank_pin).await;
|
||||||
|
//force yield between successful samples
|
||||||
|
Timer::after_millis(10).await;
|
||||||
|
}
|
||||||
|
self.tank_power.set_low();
|
||||||
|
|
||||||
|
store.sort();
|
||||||
|
let median_mv = store[TANK_MULTI_SAMPLE / 2] as f32;
|
||||||
|
Ok(median_mv / 1000.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
extern crate embedded_hal as hal;
|
|
||||||
|
|
||||||
pub mod sipo;
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user