Compare commits

..

11 Commits

14 changed files with 1067 additions and 342 deletions

311
Cargo.lock generated
View File

@ -2,371 +2,362 @@
# It is not intended for manual editing. # It is not intended for manual editing.
[[package]] [[package]]
name = "aligned" name = "aligned"
version = "0.3.1" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb1ce8b3382016136ab1d31a1b5ce807144f8b7eb2d5f16b2108f0f07edceb94"
dependencies = [ dependencies = [
"as-slice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "as-slice",
] ]
[[package]] [[package]]
name = "as-slice" name = "as-slice"
version = "0.1.0" version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37dfb65bc03b2bc85ee827004f14a6817e04160e3b1a28931986a666a9290e70"
dependencies = [ dependencies = [
"generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "generic-array 0.12.3",
"stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "generic-array 0.13.2",
"stable_deref_trait",
] ]
[[package]] [[package]]
name = "bare-metal" name = "bare-metal"
version = "0.2.4" version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
dependencies = [ dependencies = [
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version",
] ]
[[package]] [[package]]
name = "bitflags" name = "bit_field"
version = "1.0.4" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a165d606cf084741d4ac3a28fb6e9b1eb0bd31f6cd999098cfddb0b2ab381dc0"
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.3.1" version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
[[package]] [[package]]
name = "cast" name = "cast"
version = "0.2.2" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0"
dependencies = [
"rustc_version",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "0.1.7" version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]] [[package]]
name = "cortex-m" name = "cortex-m"
version = "0.6.0" version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2954942fbbdd49996704e6f048ce57567c3e1a4e2dc59b41ae9fde06a01fc763"
dependencies = [ dependencies = [
"aligned 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "aligned",
"bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "bare-metal",
"volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "volatile-register",
] ]
[[package]] [[package]]
name = "cortex-m-log" name = "cortex-m-log"
version = "0.5.0" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "978caafe65d1023d38b00c76b83564788fc351d954a5005fb72cf992c0d61458"
dependencies = [ dependencies = [
"cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m",
"cortex-m-semihosting 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m-semihosting",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log",
] ]
[[package]] [[package]]
name = "cortex-m-rt" name = "cortex-m-rt"
version = "0.6.10" version = "0.6.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00d518da72bba39496024b62607c1d8e37bcece44b2536664f1132a73a499a28"
dependencies = [ dependencies = [
"cortex-m-rt-macros 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m-rt-macros",
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "r0",
] ]
[[package]] [[package]]
name = "cortex-m-rt-macros" name = "cortex-m-rt-macros"
version = "0.1.5" version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4717562afbba06e760d34451919f5c3bf3ac15c7bb897e8b04862a7428378647"
dependencies = [ dependencies = [
"proc-macro2 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2",
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "quote",
"rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "syn",
"syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "cortex-m-semihosting" name = "cortex-m-semihosting"
version = "0.3.3" version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "113ef0ecffee2b62b58f9380f4469099b30e9f9cbee2804771b4203ba1762cfa"
dependencies = [ dependencies = [
"cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m",
] ]
[[package]] [[package]]
name = "embedded-hal" name = "embedded-hal"
version = "0.2.2" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee4908a155094da7723c2d60d617b820061e3b4efcc3d9e293d206a5a76c170b"
dependencies = [ dependencies = [
"nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "nb",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "void",
] ]
[[package]] [[package]]
name = "generic-array" name = "generic-array"
version = "0.12.0" version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
dependencies = [ dependencies = [
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "typenum",
]
[[package]]
name = "generic-array"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd"
dependencies = [
"typenum",
] ]
[[package]] [[package]]
name = "hash2hwaddr" name = "hash2hwaddr"
version = "0.0.1" version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "857afb5ee9e767c3a73b2ad7212b6deea0c3761a27db1e20ea0ed57ee352cfef"
[[package]] [[package]]
name = "log" name = "log"
version = "0.3.9" version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
dependencies = [ dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if",
]
[[package]]
name = "log"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "managed" name = "managed"
version = "0.7.1" version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdcec5e97041c7f0f1c5b7d93f12e57293c831c646f4cc7a5db59460c7ea8de6"
[[package]] [[package]]
name = "nb" name = "nb"
version = "0.1.2" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1411551beb3c11dedfb0a90a0fa256b47d28b9ec2cdff34c25a2fa59e45dbdc"
[[package]] [[package]]
name = "panic-abort" name = "panic-abort"
version = "0.3.1" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e20e6499bbbc412f280b04a42346b356c6fa0753d5fd22b7bd752ff34c778ee"
[[package]] [[package]]
name = "panic-semihosting" name = "panic-semihosting"
version = "0.5.2" version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c03864ac862876c16a308f5286f4aa217f1a69ac45df87ad3cd2847f818a642c"
dependencies = [ dependencies = [
"cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m",
"cortex-m-semihosting 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m-semihosting",
] ]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "0.4.28" version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435"
dependencies = [ dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "0.6.12" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
dependencies = [ dependencies = [
"proc-macro2 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2",
] ]
[[package]] [[package]]
name = "r0" name = "r0"
version = "0.2.2" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
[[package]]
name = "rand"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "rand_core" name = "rand_core"
version = "0.3.1" version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
[[package]] [[package]]
name = "rustc_version" name = "rustc_version"
version = "0.2.3" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [ dependencies = [
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver",
] ]
[[package]] [[package]]
name = "semver" name = "semver"
version = "0.9.0" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [ dependencies = [
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver-parser",
] ]
[[package]] [[package]]
name = "semver-parser" name = "semver-parser"
version = "0.7.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]] [[package]]
name = "smoltcp" name = "smoltcp"
version = "0.5.0" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fe46639fd2ec79eadf8fe719f237a7a0bd4dac5d957f1ca5bbdbc1c3c39e53a"
dependencies = [ dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags",
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "log",
"managed 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "managed",
] ]
[[package]] [[package]]
name = "stable_deref_trait" name = "stable_deref_trait"
version = "1.1.1" version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
[[package]] [[package]]
name = "stm32-eth" name = "stm32-eth"
version = "0.1.2" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/stm32-rs/stm32-eth.git#2c5dce379b85a31fb0b9c58a028b6454be1727aa"
dependencies = [ dependencies = [
"aligned 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "aligned",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log",
"smoltcp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "smoltcp",
"stm32f4xx-hal 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "stm32f4xx-hal",
"volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "volatile-register",
] ]
[[package]] [[package]]
name = "stm32f4" name = "stm32f4"
version = "0.7.0" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44a3d6c58b14e63926273694e7dd644894513c5e35ce6928c4657ddb62cae976"
dependencies = [ dependencies = [
"bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "bare-metal",
"cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m",
"cortex-m-rt 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m-rt",
"vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "vcell",
] ]
[[package]] [[package]]
name = "stm32f4xx-hal" name = "stm32f4xx-hal"
version = "0.5.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54abcca9b4abfb0d0518591ea39c2e14a0b07b9791548d4516ab5e61a83067cc"
dependencies = [ dependencies = [
"bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "bare-metal",
"cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "cast",
"cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m",
"cortex-m-rt 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m-rt",
"embedded-hal 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "embedded-hal",
"nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "nb",
"stm32f4 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "stm32f4",
"void",
] ]
[[package]] [[package]]
name = "syn" name = "syn"
version = "0.15.33" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859"
dependencies = [ dependencies = [
"proc-macro2 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2",
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "quote",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid",
] ]
[[package]] [[package]]
name = "thermostat" name = "thermostat"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "bare-metal",
"cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "bit_field",
"cortex-m-log 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder",
"cortex-m-rt 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m",
"embedded-hal 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m-log",
"hash2hwaddr 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m-rt",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "embedded-hal",
"panic-abort 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "hash2hwaddr",
"panic-semihosting 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "log",
"smoltcp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "panic-abort",
"stm32-eth 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "panic-semihosting",
"stm32f4xx-hal 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "smoltcp",
"stm32-eth",
"stm32f4xx-hal",
] ]
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.10.0" version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.1.0" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
[[package]] [[package]]
name = "vcell" name = "vcell"
version = "0.1.0" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "876e32dcadfe563a4289e994f7cb391197f362b6315dc45e8ba4aa6f564a4b3c"
[[package]] [[package]]
name = "void" name = "void"
version = "1.0.2" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]] [[package]]
name = "volatile-register" name = "volatile-register"
version = "0.2.0" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286"
dependencies = [ dependencies = [
"vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "vcell",
] ]
[metadata]
"checksum aligned 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a316c7ea8e1e9ece54862c992def5a7ac14de9f5832b69d71760680efeeefa"
"checksum as-slice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "293dac66b274fab06f95e7efb05ec439a6b70136081ea522d270bc351ae5bb27"
"checksum bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a3caf393d93b2d453e80638d0674597020cef3382ada454faacd43d1a55a735a"
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427"
"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4"
"checksum cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f3c18719fdc57db65668bfc977db9a0fa1a41d718c5d9cd4f652c9d4b0e0956a"
"checksum cortex-m-log 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "584a62cf37ddd834b8bfc21317bf3396915844298bf346dd1f4ca0572180ac7f"
"checksum cortex-m-rt 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "17805910e3ecf029bdbfcc42b7384d9e3d9e5626153fa810002c1ef9839338ac"
"checksum cortex-m-rt-macros 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d7ae692573e0acccb1579fef1abf5a5bf1d2f3f0149a22b16870ec9309aee25f"
"checksum cortex-m-semihosting 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "165f3f86f4d1031351a6c9dc8d5a3f8fae2050f9dd6ef925e3d675c232cc0e46"
"checksum embedded-hal 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9880e55238830314d41d88f1ac7a819d495799c3cc3bc392cc172bab26428c33"
"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592"
"checksum hash2hwaddr 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "857afb5ee9e767c3a73b2ad7212b6deea0c3761a27db1e20ea0ed57ee352cfef"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
"checksum managed 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcec5e97041c7f0f1c5b7d93f12e57293c831c646f4cc7a5db59460c7ea8de6"
"checksum nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1411551beb3c11dedfb0a90a0fa256b47d28b9ec2cdff34c25a2fa59e45dbdc"
"checksum panic-abort 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c14a66511ed17b6a8b4256b868d7fd207836d891db15eea5195dbcaf87e630f"
"checksum panic-semihosting 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "97cfb37c1d3b5f0cc18bf14485018cccd13bdd24f7b5bfd456c1d8760afef824"
"checksum proc-macro2 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)" = "ba92c84f814b3f9a44c5cfca7d2ad77fa10710867d2bbb1b3d175ab5f47daa12"
"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db"
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9"
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum smoltcp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fef582369edb298c6c41319a544ca9c4e83622f226055ccfcb35974fbb55ed34"
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
"checksum stm32-eth 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2e803668651a7e869501785e3ee11adf3e90ad2f9a55583f0ab45db9d994abca"
"checksum stm32f4 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e05bde3dc8cc36152bead69637e531ddb5654852e71425c0cdfdf656b749743"
"checksum stm32f4xx-hal 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdee466aa95237fec6962f3709cff5478e6de70de8c758271ec612c7a65fe42"
"checksum syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)" = "ec52cd796e5f01d0067225a5392e70084acc4c0013fa71d55166d38a8b307836"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45c297f0afb6928cd08ab1ff9d95e99392595ea25ae1b5ecf822ff8764e57a0d"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286"

View File

@ -20,12 +20,14 @@ log = "0.4"
bare-metal = "0.2" bare-metal = "0.2"
cortex-m = "0.6" cortex-m = "0.6"
cortex-m-rt = { version = "0.6", features = ["device"] } cortex-m-rt = { version = "0.6", features = ["device"] }
cortex-m-log = { version = "0.5", features = ["log-integration"] } cortex-m-log = { version = "0.6", features = ["log-integration"] }
embedded-hal = "0.2" embedded-hal = "0.2"
stm32f4xx-hal = { version = "0.5", features = ["rt", "stm32f429"] } stm32f4xx-hal = { version = "0.7", features = ["rt", "stm32f427"] }
stm32-eth = { version = "0.1.2", features = ["smoltcp-phy", "nucleo-f429zi"] } stm32-eth = { version = "0.1.2", features = ["smoltcp-phy"], git = "https://github.com/stm32-rs/stm32-eth.git" }
smoltcp = { version = "0.5.0", default-features = false, features = ["proto-ipv4", "socket-tcp", "log"] } smoltcp = { version = "0.6.0", default-features = false, features = ["proto-ipv4", "socket-tcp", "log"] }
hash2hwaddr = { version = "0.0", optional = true } hash2hwaddr = { version = "0.0", optional = true }
bit_field = "0.10"
byteorder = { version = "1", default-features = false }
[features] [features]
semihosting = ["panic-semihosting", "cortex-m-log/semihosting"] semihosting = ["panic-semihosting", "cortex-m-log/semihosting"]

View File

@ -1 +1 @@
"08kk6ja9g4j4apa02n02gxpjm62s27aabx33lg0dmzxgr1v5xlr1" "0yqq7z4qz29vxxc40cp2pjaifvnhacz6hm3v1s839n1q4qlkcjm5"

214
src/ad7172/adc.rs Normal file
View File

@ -0,0 +1,214 @@
use core::fmt;
use embedded_hal::digital::v2::OutputPin;
use embedded_hal::blocking::spi::Transfer;
use log::{info, warn};
use super::checksum::{ChecksumMode, Checksum};
use super::AdcError;
use super::{
regs, regs::RegisterData,
Input, RefSource, PostFilter, DigitalFilterOrder,
};
/// AD7172-2 implementation
///
/// [Manual](https://www.analog.com/media/en/technical-documentation/data-sheets/AD7172-2.pdf)
pub struct Adc<SPI: Transfer<u8>, NSS: OutputPin> {
spi: SPI,
nss: NSS,
checksum_mode: ChecksumMode,
}
impl<SPI: Transfer<u8, Error = E>, NSS: OutputPin, E: fmt::Debug> Adc<SPI, NSS> {
pub fn new(spi: SPI, mut nss: NSS) -> Result<Self, AdcError<SPI::Error>> {
let _ = nss.set_high();
let mut adc = Adc {
spi, nss,
checksum_mode: ChecksumMode::Off,
};
adc.reset()?;
adc.set_checksum_mode(ChecksumMode::Crc).unwrap();
let mut retries = 0;
let mut adc_id;
loop {
adc_id = adc.identify()?;
if adc_id & 0xFFF0 == 0x00D0 {
break;
} else {
retries += 1;
}
}
info!("ADC id: {:04X} ({} retries)", adc_id, retries);
Ok(adc)
}
/// `0x00DX` for AD7172-2
pub fn identify(&mut self) -> Result<u16, AdcError<SPI::Error>> {
self.read_reg(&regs::Id)
.map(|id| id.id())
}
pub fn set_checksum_mode(&mut self, mode: ChecksumMode) -> Result<(), AdcError<SPI::Error>> {
// Cannot use update_reg() here because checksum_mode is
// updated between read_reg() and write_reg().
let mut ifmode = self.read_reg(&regs::IfMode)?;
ifmode.set_crc(mode);
self.checksum_mode = mode;
self.write_reg(&regs::IfMode, &mut ifmode)?;
Ok(())
}
pub fn set_sync_enable(&mut self, enable: bool) -> Result<(), AdcError<SPI::Error>> {
self.update_reg(&regs::GpioCon, |data| {
data.set_sync_en(enable);
})
}
pub fn setup_channel(
&mut self, index: u8, in_pos: Input, in_neg: Input
) -> Result<(), AdcError<SPI::Error>> {
self.update_reg(&regs::SetupCon { index }, |data| {
data.set_bipolar(false);
data.set_refbuf_pos(true);
data.set_refbuf_neg(true);
data.set_ainbuf_pos(true);
data.set_ainbuf_neg(true);
data.set_ref_sel(RefSource::External);
})?;
self.update_reg(&regs::FiltCon { index }, |data| {
data.set_enh_filt_en(true);
data.set_enh_filt(PostFilter::F16SPS);
data.set_order(DigitalFilterOrder::Sinc5Sinc1);
})?;
// let mut offset = <regs::Offset as regs::Register>::Data::empty();
// offset.set_offset(0);
// self.write_reg(&regs::Offset { index }, &mut offset);
self.update_reg(&regs::Channel { index }, |data| {
data.set_setup(index);
data.set_enabled(true);
data.set_a_in_pos(in_pos);
data.set_a_in_neg(in_neg);
})?;
Ok(())
}
pub fn get_postfilter(&mut self, index: u8) -> Result<Option<PostFilter>, AdcError<SPI::Error>> {
self.read_reg(&regs::FiltCon { index })
.map(|data| {
if data.enh_filt_en() {
Some(data.enh_filt())
} else {
None
}
})
}
pub fn set_postfilter(&mut self, index: u8, filter: Option<PostFilter>) -> Result<(), AdcError<SPI::Error>> {
self.update_reg(&regs::FiltCon { index }, |data| {
match filter {
None => data.set_enh_filt_en(false),
Some(filter) => {
data.set_enh_filt_en(true);
data.set_enh_filt(filter);
}
}
})
}
/// Returns the channel the data is from
pub fn data_ready(&mut self) -> Result<Option<u8>, AdcError<SPI::Error>> {
self.read_reg(&regs::Status)
.map(|status| {
if status.ready() {
Some(status.channel())
} else {
None
}
})
}
/// Get data
pub fn read_data(&mut self) -> Result<i32, AdcError<SPI::Error>> {
self.read_reg(&regs::Data)
.map(|data| data.data())
}
fn read_reg<R: regs::Register>(&mut self, reg: &R) -> Result<R::Data, AdcError<SPI::Error>> {
let mut reg_data = R::Data::empty();
let address = 0x40 | reg.address();
let mut checksum = Checksum::new(self.checksum_mode);
checksum.feed(&[address]);
let checksum_out = checksum.result();
let checksum_in = self.transfer(address, reg_data.as_mut(), checksum_out)?;
checksum.feed(&reg_data);
let checksum_expected = checksum.result();
if checksum_expected != checksum_in {
return Err(AdcError::ChecksumMismatch(checksum_expected, checksum_in));
}
Ok(reg_data)
}
fn write_reg<R: regs::Register>(&mut self, reg: &R, reg_data: &mut R::Data) -> Result<(), AdcError<SPI::Error>> {
let address = reg.address();
let mut checksum = Checksum::new(match self.checksum_mode {
ChecksumMode::Off => ChecksumMode::Off,
// write checksums are always crc
ChecksumMode::Xor => ChecksumMode::Crc,
ChecksumMode::Crc => ChecksumMode::Crc,
});
checksum.feed(&[address]);
checksum.feed(&reg_data);
let checksum_out = checksum.result();
self.transfer(address, reg_data.as_mut(), checksum_out)?;
Ok(())
}
fn update_reg<R, F, A>(&mut self, reg: &R, f: F) -> Result<A, AdcError<SPI::Error>>
where
R: regs::Register,
F: FnOnce(&mut R::Data) -> A,
{
let mut reg_data = self.read_reg(reg)?;
let result = f(&mut reg_data);
self.write_reg(reg, &mut reg_data)?;
Ok(result)
}
pub fn reset(&mut self) -> Result<(), SPI::Error> {
let mut buf = [0xFFu8; 8];
let _ = self.nss.set_low();
let result = self.spi.transfer(&mut buf);
let _ = self.nss.set_high();
result?;
Ok(())
}
fn transfer<'w>(&mut self, addr: u8, reg_data: &'w mut [u8], checksum: Option<u8>) -> Result<Option<u8>, SPI::Error> {
let mut addr_buf = [addr];
let _ = self.nss.set_low();
let result = match self.spi.transfer(&mut addr_buf) {
Ok(_) => self.spi.transfer(reg_data),
Err(e) => Err(e),
};
let result = match (result, checksum) {
(Ok(_),None) =>
Ok(None),
(Ok(_), Some(checksum_out)) => {
let mut checksum_buf = [checksum_out; 1];
match self.spi.transfer(&mut checksum_buf) {
Ok(_) => Ok(Some(checksum_buf[0])),
Err(e) => Err(e),
}
}
(Err(e), _) =>
Err(e),
};
let _ = self.nss.set_high();
result
}
}

60
src/ad7172/checksum.rs Normal file
View File

@ -0,0 +1,60 @@
#[derive(Clone, Copy, PartialEq)]
#[repr(u8)]
pub enum ChecksumMode {
Off = 0b00,
/// Seems much less reliable than `Crc`
Xor = 0b01,
Crc = 0b10,
}
impl From<u8> for ChecksumMode {
fn from(x: u8) -> Self {
match x {
0 => ChecksumMode::Off,
1 => ChecksumMode::Xor,
_ => ChecksumMode::Crc,
}
}
}
pub struct Checksum {
mode: ChecksumMode,
state: u8,
}
impl Checksum {
pub fn new(mode: ChecksumMode) -> Self {
Checksum { mode, state: 0 }
}
fn feed_byte(&mut self, input: u8) {
match self.mode {
ChecksumMode::Off => {},
ChecksumMode::Xor => self.state ^= input,
ChecksumMode::Crc => {
for i in 0..8 {
let input_mask = 0x80 >> i;
self.state = (self.state << 1) ^
if ((self.state & 0x80) != 0) != ((input & input_mask) != 0) {
0x07 /* x8 + x2 + x + 1 */
} else {
0
};
}
}
}
}
pub fn feed(&mut self, input: &[u8]) {
for &b in input {
self.feed_byte(b);
}
}
pub fn result(&self) -> Option<u8> {
match self.mode {
ChecksumMode::Off => None,
_ => Some(self.state)
}
}
}

210
src/ad7172/mod.rs Normal file
View File

@ -0,0 +1,210 @@
use core::fmt;
use stm32f4xx_hal::{
time::{MegaHertz, U32Ext},
spi,
};
pub mod regs;
mod checksum;
pub use checksum::ChecksumMode;
mod adc;
pub use adc::*;
/// SPI Mode 3
pub const SPI_MODE: spi::Mode = spi::Mode {
polarity: spi::Polarity::IdleHigh,
phase: spi::Phase::CaptureOnSecondTransition,
};
/// 2 MHz
pub const SPI_CLOCK: MegaHertz = MegaHertz(2);
#[derive(Clone, Debug, PartialEq)]
pub enum AdcError<SPI> {
SPI(SPI),
ChecksumMismatch(Option<u8>, Option<u8>),
}
impl<SPI> From<SPI> for AdcError<SPI> {
fn from(e: SPI) -> Self {
AdcError::SPI(e)
}
}
#[derive(Clone, Copy, Debug)]
#[repr(u8)]
pub enum Input {
Ain0 = 0,
Ain1 = 1,
Ain2 = 2,
Ain3 = 3,
Ain4 = 4,
TemperaturePos = 17,
TemperatureNeg = 18,
AnalogSupplyPos = 19,
AnalogSupplyNeg = 20,
RefPos = 21,
RefNeg = 22,
Invalid = 0b11111,
}
impl From<u8> for Input {
fn from(x: u8) -> Self {
match x {
0 => Input::Ain0,
1 => Input::Ain1,
2 => Input::Ain2,
3 => Input::Ain3,
4 => Input::Ain4,
17 => Input::TemperaturePos,
18 => Input::TemperatureNeg,
19 => Input::AnalogSupplyPos,
20 => Input::AnalogSupplyNeg,
21 => Input::RefPos,
22 => Input::RefNeg,
_ => Input::Invalid,
}
}
}
impl fmt::Display for Input {
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
use Input::*;
match self {
Ain0 => "ain0",
Ain1 => "ain1",
Ain2 => "ain2",
Ain3 => "ain3",
Ain4 => "ain4",
TemperaturePos => "temperature+",
TemperatureNeg => "temperature-",
AnalogSupplyPos => "analogsupply+",
AnalogSupplyNeg => "analogsupply-",
RefPos => "ref+",
RefNeg => "ref-",
_ => "<INVALID>",
}.fmt(fmt)
}
}
/// Reference source for ADC conversion
#[repr(u8)]
pub enum RefSource {
/// External reference
External = 0b00,
/// Internal 2.5V reference
Internal = 0b10,
/// AVDD1 AVSS
Avdd1MinusAvss = 0b11,
Invalid = 0b01,
}
impl From<u8> for RefSource {
fn from(x: u8) -> Self {
match x {
0 => RefSource::External,
1 => RefSource::Internal,
2 => RefSource::Avdd1MinusAvss,
_ => RefSource::Invalid,
}
}
}
impl fmt::Display for RefSource {
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
use RefSource::*;
match self {
External => "external",
Internal => "internal",
Avdd1MinusAvss => "avdd1-avss",
_ => "<INVALID>",
}.fmt(fmt)
}
}
#[derive(Clone, Copy)]
#[repr(u8)]
pub enum PostFilter {
/// 27 SPS, 47 dB rejection, 36.7 ms settling
F27SPS = 0b010,
/// 21.25 SPS, 62 dB rejection, 40 ms settling
F21SPS = 0b011,
/// 20 SPS, 86 dB rejection, 50 ms settling
F20SPS = 0b101,
/// 16.67 SPS, 92 dB rejection, 60 ms settling
F16SPS = 0b110,
Invalid = 0b111,
}
impl PostFilter {
pub const VALID_VALUES: &'static [Self] = &[
PostFilter::F27SPS,
PostFilter::F21SPS,
PostFilter::F20SPS,
PostFilter::F16SPS,
];
pub fn closest(rate: f32) -> Option<Self> {
/// (x - y).abs()
fn d(x: f32, y: f32) -> f32 {
if x >= y {
x - y
} else {
y - x
}
}
let mut best: Option<(f32, Self)> = None;
for value in Self::VALID_VALUES {
let error = d(rate, value.output_rate().unwrap());
let better = best
.map(|(best_error, _)| error < best_error)
.unwrap_or(true);
if better {
best = Some((error, *value));
}
}
best.map(|(_, best)| best)
}
/// Samples per Second
pub fn output_rate(&self) -> Option<f32> {
match self {
PostFilter::F27SPS => Some(27.0),
PostFilter::F21SPS => Some(21.25),
PostFilter::F20SPS => Some(20.0),
PostFilter::F16SPS => Some(16.67),
PostFilter::Invalid => None,
}
}
}
impl From<u8> for PostFilter {
fn from(x: u8) -> Self {
match x {
0b010 => PostFilter::F27SPS,
0b011 => PostFilter::F21SPS,
0b101 => PostFilter::F20SPS,
0b110 => PostFilter::F16SPS,
_ => PostFilter::Invalid,
}
}
}
#[repr(u8)]
pub enum DigitalFilterOrder {
Sinc5Sinc1 = 0b00,
Sinc3 = 0b11,
Invalid = 0b10,
}
impl From<u8> for DigitalFilterOrder {
fn from(x: u8) -> Self {
match x {
0b00 => DigitalFilterOrder::Sinc5Sinc1,
0b11 => DigitalFilterOrder::Sinc3,
_ => DigitalFilterOrder::Invalid,
}
}
}

275
src/ad7172/regs.rs Normal file
View File

@ -0,0 +1,275 @@
use core::ops::{Deref, DerefMut};
use byteorder::{BigEndian, ByteOrder};
use bit_field::BitField;
use super::*;
pub trait Register {
type Data: RegisterData;
fn address(&self) -> u8;
}
pub trait RegisterData: Deref<Target=[u8]> + DerefMut {
fn empty() -> Self;
}
macro_rules! def_reg {
($Reg: ident, $reg: ident, $addr: expr, $size: expr) => {
/// AD7172 register
pub struct $Reg;
impl Register for $Reg {
/// Register contents
type Data = $reg::Data;
/// Register address
fn address(&self) -> u8 {
$addr
}
}
mod $reg {
/// Register contents
pub struct Data(pub [u8; $size]);
impl super::RegisterData for Data {
/// Generate zeroed register contents
fn empty() -> Self {
Data([0; $size])
}
}
impl core::ops::Deref for Data {
type Target = [u8];
fn deref(&self) -> &[u8] {
&self.0
}
}
impl core::ops::DerefMut for Data {
fn deref_mut(&mut self) -> &mut [u8] {
&mut self.0
}
}
}
};
($Reg: ident, u8, $reg: ident, $addr: expr, $size: expr) => {
pub struct $Reg { pub index: u8, }
impl Register for $Reg {
type Data = $reg::Data;
fn address(&self) -> u8 {
$addr + self.index
}
}
mod $reg {
pub struct Data(pub [u8; $size]);
impl super::RegisterData for Data {
fn empty() -> Self {
Data([0; $size])
}
}
impl core::ops::Deref for Data {
type Target = [u8];
fn deref(&self) -> &[u8] {
&self.0
}
}
impl core::ops::DerefMut for Data {
fn deref_mut(&mut self) -> &mut [u8] {
&mut self.0
}
}
}
}
}
macro_rules! reg_bit {
($getter: ident, $byte: expr, $bit: expr, $doc: expr) => {
#[allow(unused)]
#[doc = $doc]
pub fn $getter(&self) -> bool {
self.0[$byte].get_bit($bit)
}
};
($getter: ident, $setter: ident, $byte: expr, $bit: expr, $doc: expr) => {
#[allow(unused)]
#[doc = $doc]
pub fn $getter(&self) -> bool {
self.0[$byte].get_bit($bit)
}
#[allow(unused)]
#[doc = $doc]
pub fn $setter(&mut self, value: bool) {
self.0[$byte].set_bit($bit, value);
}
};
}
macro_rules! reg_bits {
($getter: ident, $byte: expr, $bits: expr, $doc: expr) => {
#[allow(unused)]
#[doc = $doc]
pub fn $getter(&self) -> u8 {
self.0[$byte].get_bits($bits)
}
};
($getter: ident, $setter: ident, $byte: expr, $bits: expr, $doc: expr) => {
#[allow(unused)]
#[doc = $doc]
pub fn $getter(&self) -> u8 {
self.0[$byte].get_bits($bits)
}
#[allow(unused)]
#[doc = $doc]
pub fn $setter(&mut self, value: u8) {
self.0[$byte].set_bits($bits, value);
}
};
($getter: ident, $byte: expr, $bits: expr, $ty: ty, $doc: expr) => {
#[allow(unused)]
#[doc = $doc]
pub fn $getter(&self) -> $ty {
self.0[$byte].get_bits($bits) as $ty
}
};
($getter: ident, $setter: ident, $byte: expr, $bits: expr, $ty: ty, $doc: expr) => {
#[allow(unused)]
#[doc = $doc]
pub fn $getter(&self) -> $ty {
self.0[$byte].get_bits($bits).into()
}
#[allow(unused)]
#[doc = $doc]
pub fn $setter(&mut self, value: $ty) {
self.0[$byte].set_bits($bits, value as u8);
}
};
}
def_reg!(Status, status, 0x00, 1);
impl status::Data {
/// Is there new data to read?
pub fn ready(&self) -> bool {
! self.not_ready()
}
reg_bit!(not_ready, 0, 7, "No data ready indicator");
reg_bits!(channel, 0, 0..=1, "Channel for which data is ready");
reg_bit!(adc_error, 0, 6, "ADC error");
reg_bit!(crc_error, 0, 5, "SPI CRC error");
reg_bit!(reg_error, 0,4, "Register error");
}
def_reg!(IfMode, if_mode, 0x02, 2);
impl if_mode::Data {
reg_bits!(crc, set_crc, 1, 2..=3, ChecksumMode, "SPI checksum mode");
}
def_reg!(Data, data, 0x04, 3);
impl data::Data {
pub fn data(&self) -> i32 {
let raw =
(u32::from(self.0[0]) << 16) |
(u32::from(self.0[1]) << 8) |
u32::from(self.0[2]);
if raw & 0x80_0000 != 0 {
((raw & 0x7F_FFFF) | 0x8000_0000) as i32
} else {
raw as i32
}
}
}
def_reg!(GpioCon, gpio_con, 0x06, 2);
impl gpio_con::Data {
reg_bit!(sync_en, set_sync_en, 0, 3, "Enables the SYNC/ERROR pin as a sync input");
}
def_reg!(Id, id, 0x07, 2);
impl id::Data {
pub fn id(&self) -> u16 {
BigEndian::read_u16(&self.0)
}
}
def_reg!(Channel, u8, channel, 0x10, 2);
impl channel::Data {
reg_bit!(enabled, set_enabled, 0, 7, "Channel enabled");
reg_bits!(setup, set_setup, 0, 4..=5, "Setup number");
/// Which input is connected to positive input of this channel
#[allow(unused)]
pub fn a_in_pos(&self) -> Input {
((self.0[0].get_bits(0..=1) << 3) |
self.0[1].get_bits(5..=7)).into()
}
/// Set which input is connected to positive input of this channel
#[allow(unused)]
pub fn set_a_in_pos(&mut self, value: Input) {
let value = value as u8;
self.0[0].set_bits(0..=1, value >> 3);
self.0[1].set_bits(5..=7, value & 0x7);
}
reg_bits!(a_in_neg, set_a_in_neg, 1, 0..=4, Input,
"Which input is connected to negative input of this channel");
// const PROPS: &'static [Property<Self>] = &[
// Property::named("enable")
// .readable(&|self_: &Self| self_.enabled().into())
// .writebale(&|self_: &mut Self, value| self_.set_enabled(value != 0)),
// Property::named("setup")
// .readable(&|self_: &Self| self_.0[0].get_bits(4..=5).into())
// .writeable(&|self_: &mut Self, value| {
// self_.0[0].set_bits(4..=5, value as u8);
// }),
// ];
// pub fn props() -> &'static [Property<Self>] {
// Self::PROPS
// }
}
def_reg!(SetupCon, u8, setup_con, 0x20, 2);
impl setup_con::Data {
reg_bit!(bipolar, set_bipolar, 0, 4, "Unipolar (`false`) or bipolar (`true`) coded output");
reg_bit!(refbuf_pos, set_refbuf_pos, 0, 3, "Enable REF+ input buffer");
reg_bit!(refbuf_neg, set_refbuf_neg, 0, 2, "Enable REF- input buffer");
reg_bit!(ainbuf_pos, set_ainbuf_pos, 0, 1, "Enable AIN+ input buffer");
reg_bit!(ainbuf_neg, set_ainbuf_neg, 0, 0, "Enable AIN- input buffer");
reg_bit!(burnout_en, 1, 7, "enables a 10 µA current source on the positive analog input selected and a 10 µA current sink on the negative analog input selected");
reg_bits!(ref_sel, set_ref_sel, 1, 4..=5, RefSource, "Select reference source for conversion");
}
def_reg!(FiltCon, u8, filt_con, 0x28, 2);
impl filt_con::Data {
reg_bit!(sinc3_map, 0, 7, "If set, mapping of filter register changes to directly program the decimation rate of the sinc3 filter");
reg_bit!(enh_filt_en, set_enh_filt_en, 0, 3, "Enable postfilters for enhanced 50Hz and 60Hz rejection");
reg_bits!(enh_filt, set_enh_filt, 0, 0..=2, PostFilter, "Select postfilters for enhanced 50Hz and 60Hz rejection");
reg_bits!(order, set_order, 1, 5..=6, DigitalFilterOrder, "order of the digital filter that processes the modulator data");
reg_bits!(odr, set_odr, 1, 0..=4, "Output data rate");
}
def_reg!(Offset, u8, offset, 0x30, 3);
impl offset::Data {
#[allow(unused)]
pub fn offset(&self) -> u32 {
(u32::from(self.0[0]) << 16) |
(u32::from(self.0[1]) << 8) |
u32::from(self.0[2])
}
#[allow(unused)]
pub fn set_offset(&mut self, value: u32) {
self.0[0] = (value >> 16) as u8;
self.0[1] = (value >> 8) as u8;
self.0[2] = value as u8;
}
}
def_reg!(Gain, u8, gain, 0x38, 3);
impl gain::Data {
#[allow(unused)]
pub fn gain(&self) -> u32 {
(u32::from(self.0[0]) << 16) |
(u32::from(self.0[1]) << 8) |
u32::from(self.0[2])
}
#[allow(unused)]
pub fn set_gain(&mut self, value: u32) {
self.0[0] = (value >> 16) as u8;
self.0[1] = (value >> 8) as u8;
self.0[2] = value as u8;
}
}

View File

@ -1,46 +0,0 @@
use stm32f4xx_hal::{
adc::{
Adc,
config::*,
},
gpio::{Analog, gpioa::PA3 as Pin},
stm32::ADC1 as ADC,
};
/// ADC Input
pub struct AdcInput {
/// unused but consumed
_pin: Pin<Analog>,
adc: Adc<ADC>,
}
impl AdcInput {
/// Configure pin into analog mode
pub fn new<MODE>(adc: ADC, pin: Pin<MODE>) -> Self {
let pin = pin.into_analog();
let adc_config = AdcConfig::default()
.scan(Scan::Enabled)
.continuous(Continuous::Single)
.clock(Clock::Pclk2_div_2);
let mut adc = Adc::adc1(adc, true, adc_config);
adc.configure_channel(&pin, Sequence::One, SampleTime::Cycles_480);
AdcInput { _pin: pin, adc }
}
/// Enable the ADC,
/// run a conversion
/// disable the ADC
pub fn read(&mut self) -> u16 {
let adc = &mut self.adc;
adc.enable();
adc.clear_end_of_conversion_flag();
adc.start_conversion();
let sample = adc.current_sample();
let result = adc.sample_to_millivolts(sample);
adc.wait_for_conversion_sequence();
adc.disable();
result
}
}

19
src/init_log.rs Normal file
View File

@ -0,0 +1,19 @@
#[cfg(not(feature = "semihosting"))]
pub fn init_log() {}
#[cfg(feature = "semihosting")]
pub fn init_log() {
use log::LevelFilter;
use cortex_m_log::log::{Logger, init};
use cortex_m_log::printer::semihosting::{InterruptOk, hio::HStdout};
static mut LOGGER: Option<Logger<InterruptOk<HStdout>>> = None;
let logger = Logger {
inner: InterruptOk::<_>::stdout().expect("semihosting stdout"),
level: LevelFilter::Info,
};
let logger = unsafe {
LOGGER.get_or_insert(logger)
};
init(logger).expect("set logger");
}

View File

@ -1,46 +0,0 @@
use embedded_hal::digital::OutputPin;
use stm32f4xx_hal::gpio::{
Output, PushPull,
gpiob::{PB0, PB7, PB14},
};
type GreenPin = PB0<Output<PushPull>>;
type BluePin = PB7<Output<PushPull>>;
type RedPin = PB14<Output<PushPull>>;
pub struct Led<PIN> {
pin: PIN,
}
impl<PIN: OutputPin> Led<PIN> {
fn new(pin: PIN) -> Self {
Led { pin }
}
pub fn on(&mut self) {
self.pin.set_high();
}
pub fn off(&mut self) {
self.pin.set_low();
}
}
impl Led<GreenPin> {
pub fn green(pin: GreenPin) -> Self {
Self::new(pin)
}
}
impl Led<BluePin> {
pub fn blue(pin: BluePin) -> Self {
Self::new(pin)
}
}
impl Led<RedPin> {
pub fn red(pin: RedPin) -> Self {
Self::new(pin)
}
}

View File

@ -1,6 +1,6 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
#![deny(warnings, unused)] // TODO: #![deny(warnings, unused)]
#[cfg(not(feature = "semihosting"))] #[cfg(not(feature = "semihosting"))]
use panic_abort as _; use panic_abort as _;
@ -15,7 +15,6 @@ use cortex_m_rt::entry;
use embedded_hal::watchdog::{WatchdogEnable, Watchdog}; use embedded_hal::watchdog::{WatchdogEnable, Watchdog};
use stm32f4xx_hal::{ use stm32f4xx_hal::{
rcc::RccExt, rcc::RccExt,
gpio::GpioExt,
watchdog::IndependentWatchdog, watchdog::IndependentWatchdog,
time::U32Ext, time::U32Ext,
stm32::{CorePeripherals, Peripherals}, stm32::{CorePeripherals, Peripherals},
@ -25,14 +24,15 @@ use smoltcp::{
wire::EthernetAddress, wire::EthernetAddress,
}; };
mod adc_input; mod init_log;
use adc_input::AdcInput; use init_log::init_log;
mod pins;
use pins::Pins;
mod ad7172;
mod net; mod net;
mod server; mod server;
use server::Server; use server::Server;
mod timer; mod timer;
mod led;
use led::Led;
/// Interval at which to sample the ADC input and broadcast to all /// Interval at which to sample the ADC input and broadcast to all
/// clients. /// clients.
@ -40,28 +40,14 @@ use led::Led;
/// This should be a multiple of the `TIMER_RATE`. /// This should be a multiple of the `TIMER_RATE`.
const OUTPUT_INTERVAL: u32 = 1000; const OUTPUT_INTERVAL: u32 = 1000;
#[cfg(not(feature = "semihosting"))]
const WATCHDOG_INTERVAL: u32 = 100;
#[cfg(feature = "semihosting")]
const WATCHDOG_INTERVAL: u32 = 10_000;
#[cfg(not(feature = "generate-hwaddr"))] #[cfg(not(feature = "generate-hwaddr"))]
const NET_HWADDR: [u8; 6] = [0x02, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; const NET_HWADDR: [u8; 6] = [0x02, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
#[cfg(not(feature = "semihosting"))]
fn init_log() {}
#[cfg(feature = "semihosting")]
fn init_log() {
use log::LevelFilter;
use cortex_m_log::log::{Logger, init};
use cortex_m_log::printer::semihosting::{InterruptOk, hio::HStdout};
static mut LOGGER: Option<Logger<InterruptOk<HStdout>>> = None;
let logger = Logger {
inner: InterruptOk::<_>::stdout().expect("semihosting stdout"),
level: LevelFilter::Info,
};
let logger = unsafe {
LOGGER.get_or_insert(logger)
};
init(logger).expect("set logger");
}
/// Initialization and main loop /// Initialization and main loop
#[entry] #[entry]
@ -84,28 +70,13 @@ fn main() -> ! {
.freeze(); .freeze();
let mut wd = IndependentWatchdog::new(dp.IWDG); let mut wd = IndependentWatchdog::new(dp.IWDG);
wd.start(1000u32.ms()); wd.start(WATCHDOG_INTERVAL.ms());
wd.feed(); wd.feed();
let gpioa = dp.GPIOA.split(); let pins = Pins::setup(clocks, dp.GPIOA, dp.GPIOB, dp.GPIOC, dp.GPIOG, dp.SPI2);
let gpiob = dp.GPIOB.split();
let gpioc = dp.GPIOC.split();
let gpiog = dp.GPIOG.split();
let mut led_green = Led::green(gpiob.pb0.into_push_pull_output()); let mut adc = ad7172::Adc::new(pins.adc_spi, pins.adc_nss).unwrap();
let mut led_blue = Led::blue(gpiob.pb7.into_push_pull_output());
let mut led_red = Led::red(gpiob.pb14.into_push_pull_output());
info!("ADC init");
let mut adc_input = AdcInput::new(dp.ADC1, gpioa.pa3);
info!("Eth setup");
stm32_eth::setup_pins(
gpioa.pa1, gpioa.pa2, gpioa.pa7, gpiob.pb13, gpioc.pc1,
gpioc.pc4, gpioc.pc5, gpiog.pg11, gpiog.pg13
);
info!("Timer setup");
timer::setup(cp.SYST, clocks); timer::setup(cp.SYST, clocks);
#[cfg(not(feature = "generate-hwaddr"))] #[cfg(not(feature = "generate-hwaddr"))]
@ -118,40 +89,39 @@ fn main() -> ! {
info!("Net hwaddr: {}", hwaddr); info!("Net hwaddr: {}", hwaddr);
info!("Net startup"); info!("Net startup");
net::run(&mut cp.NVIC, dp.ETHERNET_MAC, dp.ETHERNET_DMA, hwaddr, |iface| { net::run(dp.ETHERNET_MAC, dp.ETHERNET_DMA, hwaddr, |iface| {
Server::run(iface, |server| { Server::run(iface, |server| {
let mut last_output = 0_u32; let mut last_output = 0_u32;
loop { loop {
let now = timer::now().0; let now = timer::now().0;
let instant = Instant::from_millis(i64::from(now)); let instant = Instant::from_millis(i64::from(now));
led_blue.on();
cortex_m::interrupt::free(net::clear_pending); cortex_m::interrupt::free(net::clear_pending);
server.poll(instant) server.poll(instant)
.unwrap_or_else(|e| { .unwrap_or_else(|e| {
warn!("poll: {:?}", e); warn!("poll: {:?}", e);
}); });
led_blue.off();
let now = timer::now().0; let now = timer::now().0;
if now - last_output >= OUTPUT_INTERVAL { if now - last_output >= OUTPUT_INTERVAL {
led_red.on(); // let adc_value = adc_input.read();
let adc_value = adc_input.read(); writeln!(server, "t={},pa3={}\r", now, 0.0 /*adc_value*/).unwrap();
writeln!(server, "t={},pa3={}\r", now, adc_value).unwrap();
last_output = now; last_output = now;
led_red.off(); }
if let Some(channel) = adc.data_ready().unwrap() {
let data = adc.read_data().unwrap();
info!("ADC {}: {:08X}", channel, data);
} }
// Update watchdog // Update watchdog
wd.feed(); wd.feed();
cortex_m::interrupt::free(|cs| { // cortex_m::interrupt::free(|cs| {
if !net::is_pending(cs) { // if !net::is_pending(cs) {
led_green.on(); // // Wait for interrupts
// Wait for interrupts // wfi();
wfi(); // }
led_green.off(); // });
}
});
} }
}); });
}); });

View File

@ -5,7 +5,7 @@ use core::cell::RefCell;
use cortex_m::interrupt::Mutex; use cortex_m::interrupt::Mutex;
use bare_metal::CriticalSection; use bare_metal::CriticalSection;
use stm32f4xx_hal::{ use stm32f4xx_hal::{
stm32::{interrupt, Peripherals, NVIC, ETHERNET_MAC, ETHERNET_DMA}, stm32::{interrupt, Peripherals, ETHERNET_MAC, ETHERNET_DMA},
}; };
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr}; use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr};
use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder, EthernetInterface}; use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder, EthernetInterface};
@ -24,7 +24,7 @@ static NET_PENDING: Mutex<RefCell<bool>> = Mutex::new(RefCell::new(false));
/// Run callback `f` with ethernet driver and TCP/IP stack /// Run callback `f` with ethernet driver and TCP/IP stack
pub fn run<F>( pub fn run<F>(
nvic: &mut NVIC, ethernet_mac: ETHERNET_MAC, ethernet_dma: ETHERNET_DMA, ethernet_mac: ETHERNET_MAC, ethernet_dma: ETHERNET_DMA,
ethernet_addr: EthernetAddress, f: F ethernet_addr: EthernetAddress, f: F
) where ) where
F: FnOnce(EthernetInterface<&mut stm32_eth::Eth<'static, 'static>>), F: FnOnce(EthernetInterface<&mut stm32_eth::Eth<'static, 'static>>),
@ -40,7 +40,7 @@ pub fn run<F>(
ethernet_mac, ethernet_dma, ethernet_mac, ethernet_dma,
&mut rx_ring[..], &mut tx_ring[..] &mut rx_ring[..], &mut tx_ring[..]
); );
eth_dev.enable_interrupt(nvic); eth_dev.enable_interrupt();
// IP stack // IP stack
let local_addr = IpAddress::v4(192, 168, 69, 3); let local_addr = IpAddress::v4(192, 168, 69, 3);

93
src/pins.rs Normal file
View File

@ -0,0 +1,93 @@
use stm32f4xx_hal::{
gpio::{
AF5, Alternate,
gpioa::{PA1, PA2, PA7},
gpiob::{PB10, PB11, PB12, PB13, PB14, PB15},
gpioc::{PC1, PC4, PC5},
gpiog::{PG13},
GpioExt,
Output, PushPull,
Speed::VeryHigh,
},
rcc::Clocks,
spi::Spi,
stm32::{GPIOA, GPIOB, GPIOC, GPIOG, SPI2},
};
/// SPI peripheral used for communication with the ADC
type AdcSpi = Spi<SPI2, (PB10<Alternate<AF5>>, PB14<Alternate<AF5>>, PB15<Alternate<AF5>>)>;
pub struct Pins {
pub adc_spi: AdcSpi,
pub adc_nss: PB12<Output<PushPull>>,
}
impl Pins {
/// Setup GPIO pins and configure MCU peripherals
pub fn setup(clocks: Clocks, gpioa: GPIOA, gpiob: GPIOB, gpioc: GPIOC, gpiog: GPIOG, spi2: SPI2) -> Self {
let gpioa = gpioa.split();
let gpiob = gpiob.split();
let gpioc = gpioc.split();
let gpiog = gpiog.split();
Self::setup_ethernet(
gpioa.pa1, gpioa.pa2, gpioc.pc1, gpioa.pa7,
gpioc.pc4, gpioc.pc5, gpiob.pb11, gpiog.pg13,
gpiob.pb13
);
let adc_spi = Self::setup_spi_adc(clocks, spi2, gpiob.pb10, gpiob.pb14, gpiob.pb15);
let adc_nss = gpiob.pb12.into_push_pull_output();
Pins {
adc_spi,
adc_nss,
}
}
/// Configure the GPIO pins for SPI operation, and initialize SPI
fn setup_spi_adc<M1, M2, M3>(
clocks: Clocks,
spi2: SPI2,
sck: PB10<M1>,
miso: PB14<M2>,
mosi: PB15<M3>,
) -> AdcSpi
{
let sck = sck.into_alternate_af5();
let miso = miso.into_alternate_af5();
let mosi = mosi.into_alternate_af5();
Spi::spi2(
spi2,
(sck, miso, mosi),
crate::ad7172::SPI_MODE,
crate::ad7172::SPI_CLOCK.into(),
clocks
)
}
/// Configure the GPIO pins for Ethernet operation
fn setup_ethernet<M1, M2, M3, M4, M5, M6, M7, M8, M9>(
pa1: PA1<M1>, pa2: PA2<M2>, pc1: PC1<M3>, pa7: PA7<M4>,
pc4: PC4<M5>, pc5: PC5<M6>, pb11: PB11<M7>, pg13: PG13<M8>,
pb13: PB13<M9>
) {
// PA1 RMII Reference Clock - SB13 ON
pa1.into_alternate_af11().set_speed(VeryHigh);
// PA2 RMII MDIO - SB160 ON
pa2.into_alternate_af11().set_speed(VeryHigh);
// PC1 RMII MDC - SB164 ON
pc1.into_alternate_af11().set_speed(VeryHigh);
// PA7 RMII RX Data Valid D11 JP6 ON
pa7.into_alternate_af11().set_speed(VeryHigh);
// PC4 RMII RXD0 - SB178 ON
pc4.into_alternate_af11().set_speed(VeryHigh);
// PC5 RMII RXD1 - SB181 ON
pc5.into_alternate_af11().set_speed(VeryHigh);
// PB11 RMII TX Enable - SB183 ON
pb11.into_alternate_af11().set_speed(VeryHigh);
// PG13 RXII TXD0 - SB182 ON
pg13.into_alternate_af11().set_speed(VeryHigh);
// PB13 RMII TXD1 I2S_A_CK JP7 ON
pb13.into_alternate_af11().set_speed(VeryHigh);
}
}

View File

@ -1,5 +1,5 @@
use core::fmt; use core::fmt;
use core::mem::uninitialized; use core::mem::MaybeUninit;
use smoltcp::{ use smoltcp::{
iface::EthernetInterface, iface::EthernetInterface,
socket::{SocketSet, SocketHandle, TcpSocket, TcpSocketBuffer}, socket::{SocketSet, SocketHandle, TcpSocket, TcpSocketBuffer},
@ -16,27 +16,22 @@ const SOCKET_COUNT: usize = 8;
const TCP_RX_BUFFER_SIZE: usize = 2048; const TCP_RX_BUFFER_SIZE: usize = 2048;
const TCP_TX_BUFFER_SIZE: usize = 2048; const TCP_TX_BUFFER_SIZE: usize = 2048;
macro_rules! create_socket_storage { macro_rules! create_socket {
($rx_storage:ident, $tx_storage:ident) => ( ($set:ident, $rx_storage:ident, $tx_storage:ident, $target:expr) => {
let mut $rx_storage = [0; TCP_RX_BUFFER_SIZE]; let mut $rx_storage = [0; TCP_RX_BUFFER_SIZE];
let mut $tx_storage = [0; TCP_TX_BUFFER_SIZE]; let mut $tx_storage = [0; TCP_TX_BUFFER_SIZE];
)
}
macro_rules! create_socket {
($set:ident, $rx_storage:ident, $tx_storage:ident, $target:expr) => (
let tcp_rx_buffer = TcpSocketBuffer::new(&mut $rx_storage[..]); let tcp_rx_buffer = TcpSocketBuffer::new(&mut $rx_storage[..]);
let tcp_tx_buffer = TcpSocketBuffer::new(&mut $tx_storage[..]); let tcp_tx_buffer = TcpSocketBuffer::new(&mut $tx_storage[..]);
let tcp_socket = TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer); let tcp_socket = TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer);
$target = $set.add(tcp_socket); $target = $set.add(tcp_socket);
) }
} }
/// Contains a number of server sockets that get all sent the same /// Contains a number of server sockets that get all sent the same
/// data (through `fmt::Write`). /// data (through `fmt::Write`).
pub struct Server<'a, 'b> { pub struct Server<'a, 'b> {
net: EthernetInterface<'a, 'a, 'a, &'a mut stm32_eth::Eth<'static, 'static>>, net: EthernetInterface<'a, 'a, 'a, &'a mut stm32_eth::Eth<'static, 'static>>,
sockets: SocketSet<'b, 'b, 'static>, sockets: SocketSet<'b, 'b, 'b>,
handles: [SocketHandle; SOCKET_COUNT], handles: [SocketHandle; SOCKET_COUNT],
} }
@ -46,21 +41,9 @@ impl<'a, 'b> Server<'a, 'b> {
where where
F: FnOnce(&mut Server<'a, '_>), F: FnOnce(&mut Server<'a, '_>),
{ {
create_socket_storage!(tcp_rx_storage0, tcp_tx_storage0); let mut sockets_storage: [_; SOCKET_COUNT] = Default::default();
create_socket_storage!(tcp_rx_storage1, tcp_tx_storage1);
create_socket_storage!(tcp_rx_storage2, tcp_tx_storage2);
create_socket_storage!(tcp_rx_storage3, tcp_tx_storage3);
create_socket_storage!(tcp_rx_storage4, tcp_tx_storage4);
create_socket_storage!(tcp_rx_storage5, tcp_tx_storage5);
create_socket_storage!(tcp_rx_storage6, tcp_tx_storage6);
create_socket_storage!(tcp_rx_storage7, tcp_tx_storage7);
let mut sockets_storage = [
None, None, None, None,
None, None, None, None
];
let mut sockets = SocketSet::new(&mut sockets_storage[..]); let mut sockets = SocketSet::new(&mut sockets_storage[..]);
let mut handles: [SocketHandle; SOCKET_COUNT] = unsafe { uninitialized() }; let mut handles: [SocketHandle; SOCKET_COUNT] = unsafe { MaybeUninit::uninit().assume_init() };
create_socket!(sockets, tcp_rx_storage0, tcp_tx_storage0, handles[0]); create_socket!(sockets, tcp_rx_storage0, tcp_tx_storage0, handles[0]);
create_socket!(sockets, tcp_rx_storage1, tcp_tx_storage1, handles[1]); create_socket!(sockets, tcp_rx_storage1, tcp_tx_storage1, handles[1]);
create_socket!(sockets, tcp_rx_storage2, tcp_tx_storage2, handles[2]); create_socket!(sockets, tcp_rx_storage2, tcp_tx_storage2, handles[2]);