diff --git a/Cargo.lock b/Cargo.lock index c6f11f8..7b47d33 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,6 +41,14 @@ name = "byteorder" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "cast" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cfg-if" version = "0.1.10" @@ -80,7 +88,7 @@ name = "cortex-m-rt-macros" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -93,7 +101,7 @@ dependencies = [ "cortex-m 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m-rt 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m-rtfm-macros 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "heapless 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "heapless 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "rtfm-core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -102,7 +110,7 @@ name = "cortex-m-rtfm-macros" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "rtfm-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -116,12 +124,21 @@ dependencies = [ "cortex-m 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "embedded-hal" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "generic-array" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -129,7 +146,7 @@ name = "generic-array" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -142,12 +159,13 @@ dependencies = [ [[package]] name = "heapless" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "as-slice 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "generic-array 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", "hash32 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -171,6 +189,11 @@ name = "managed" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "nb" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "panic-halt" version = "0.2.0" @@ -187,7 +210,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -198,7 +221,7 @@ name = "quote" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -217,7 +240,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -244,10 +267,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -255,16 +278,16 @@ name = "serde-json-core" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "heapless 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", + "heapless 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -287,14 +310,15 @@ dependencies = [ "cortex-m-log 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m-rt 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m-rtfm 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "heapless 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "heapless 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "panic-halt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "panic-semihosting 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", "serde-json-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "smoltcp 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "stm32h7 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "stm32h7xx-hal 0.4.0 (git+https://github.com/quartiq/stm32h7xx-hal.git?branch=feature/quad-spi)", ] [[package]] @@ -313,19 +337,34 @@ dependencies = [ "vcell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "stm32h7xx-hal" +version = "0.4.0" +source = "git+https://github.com/quartiq/stm32h7xx-hal.git?branch=feature/quad-spi#a65de87263d87d5a730d21b5ebeea4bb1886233a" +dependencies = [ + "bare-metal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m-rt 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "stm32h7 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "syn" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "typenum" -version = "1.11.2" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -338,6 +377,11 @@ name = "vcell" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "volatile-register" version = "0.2.0" @@ -353,6 +397,7 @@ dependencies = [ "checksum bare-metal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" "checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +"checksum cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum cortex-m 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2954942fbbdd49996704e6f048ce57567c3e1a4e2dc59b41ae9fde06a01fc763" "checksum cortex-m-log 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "978caafe65d1023d38b00c76b83564788fc351d954a5005fb72cf992c0d61458" @@ -361,16 +406,18 @@ dependencies = [ "checksum cortex-m-rtfm 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eaf0b9fd3f042cb3793d15daf3cea201b2f25c99b0b5b936a551bb6909c3ae5b" "checksum cortex-m-rtfm-macros 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c62092f6ff344e9b0adb748f0302ed69889ba2fae1fce446e3788d4726ea73bb" "checksum cortex-m-semihosting 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "113ef0ecffee2b62b58f9380f4469099b30e9f9cbee2804771b4203ba1762cfa" +"checksum embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ee4908a155094da7723c2d60d617b820061e3b4efcc3d9e293d206a5a76c170b" "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" "checksum generic-array 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd" "checksum hash32 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d4041af86e63ac4298ce40e5cca669066e75b6f1aa3390fe2561ffa5e1d9f4cc" -"checksum heapless 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10b591a0032f114b7a77d4fbfab452660c553055515b7d7ece355db080d19087" +"checksum heapless 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8ffa511365b12346c5fbe759d82f80d3aa70d9f1ba01955594f84a1a6bbab985" "checksum indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "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-halt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812" "checksum panic-semihosting 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c03864ac862876c16a308f5286f4aa217f1a69ac45df87ad3cd2847f818a642c" -"checksum proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" +"checksum proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" "checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" "checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f" "checksum rtfm-core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec893edb2aa5b70320b94896ffea22a7ebb1cf3f942bb67cd5b60a865a63493" @@ -378,14 +425,16 @@ dependencies = [ "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 serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)" = "e707fbbf255b8fc8c3b99abb91e7257a622caeb20a9818cbadbeeede4e0932ff" +"checksum serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)" = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399" "checksum serde-json-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf406405ada9ef326ca78677324ac66994ff348fc48a16030be08caeed29825" -"checksum serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)" = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8" +"checksum serde_derive 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)" = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" "checksum smoltcp 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0fe46639fd2ec79eadf8fe719f237a7a0bd4dac5d957f1ca5bbdbc1c3c39e53a" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum stm32h7 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b0045066e082648e8a7ab1dd45c92efa8d7bec2beedf72ac7b62563911f82a" +"checksum stm32h7xx-hal 0.4.0 (git+https://github.com/quartiq/stm32h7xx-hal.git?branch=feature/quad-spi)" = "" "checksum syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" -"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" +"checksum typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum vcell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "876e32dcadfe563a4289e994f7cb391197f362b6315dc45e8ba4aa6f564a4b3c" +"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" diff --git a/Cargo.toml b/Cargo.toml index 66e5451..87e1ffe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,9 +35,14 @@ panic-halt = "0.2" serde = { version = "1.0", features = ["derive"], default-features = false } heapless = "0.5" serde-json-core = "0.1" -stm32h7 = { version = "0.10", features = ["stm32h743v", "rt"] } cortex-m-rtfm = "0.5" smoltcp = { version = "0.6", features = ["ethernet", "proto-ipv4", "socket-tcp"], default-features = false } +embedded-hal = "0.2.3" + +[dependencies.stm32h7xx-hal] +git = "https://github.com/quartiq/stm32h7xx-hal.git" +branch = "feature/quad-spi" +features = ["stm32h743v", "rt"] [features] semihosting = ["panic-semihosting", "cortex-m-log/semihosting"] diff --git a/src/board.rs b/src/board.rs index 572b1c2..eb72b54 100644 --- a/src/board.rs +++ b/src/board.rs @@ -1,460 +1,6 @@ -use super::eth; -use super::i2c; use super::pac; -fn pwr_setup(pwr: &pac::PWR) { - // go to VOS1 voltage scale for high perf - pwr.cr3 - .write(|w| w.scuen().set_bit().ldoen().set_bit().bypass().clear_bit()); - while pwr.csr1.read().actvosrdy().bit_is_clear() {} - pwr.d3cr.write(|w| unsafe { w.vos().bits(0b11) }); // vos1 - while pwr.d3cr.read().vosrdy().bit_is_clear() {} -} - -fn rcc_reset(rcc: &pac::RCC) { - // Reset all peripherals - rcc.ahb1rstr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - rcc.ahb1rstr.write(|w| unsafe { w.bits(0) }); - rcc.apb1lrstr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - rcc.apb1lrstr.write(|w| unsafe { w.bits(0) }); - rcc.apb1hrstr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - rcc.apb1hrstr.write(|w| unsafe { w.bits(0) }); - - rcc.ahb2rstr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - rcc.ahb2rstr.write(|w| unsafe { w.bits(0) }); - rcc.apb2rstr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - rcc.apb2rstr.write(|w| unsafe { w.bits(0) }); - - // do not reset the cpu - rcc.ahb3rstr.write(|w| unsafe { w.bits(0x7FFF_FFFF) }); - rcc.ahb3rstr.write(|w| unsafe { w.bits(0) }); - rcc.apb3rstr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - rcc.apb3rstr.write(|w| unsafe { w.bits(0) }); - - rcc.ahb4rstr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - rcc.ahb4rstr.write(|w| unsafe { w.bits(0) }); - rcc.apb4rstr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - rcc.apb4rstr.write(|w| unsafe { w.bits(0) }); -} - -fn rcc_pll_setup(rcc: &pac::RCC, flash: &pac::FLASH) { - // Switch to HSI to mess with HSE - rcc.cr.modify(|_, w| w.hsion().on()); - while rcc.cr.read().hsirdy().is_not_ready() {} - rcc.cfgr.modify(|_, w| w.sw().hsi()); - while !rcc.cfgr.read().sws().is_hsi() {} - rcc.cr.write(|w| w.hsion().on()); - rcc.cfgr.reset(); - - // Ensure HSE is on and stable - rcc.cr.modify(|_, w| w.hseon().on().hsebyp().not_bypassed()); - while !rcc.cr.read().hserdy().is_ready() {} - - rcc.pllckselr.modify( - |_, w| { - w.pllsrc() - .hse() - .divm1() - .bits(1) // ref prescaler - .divm2() - .bits(1) - }, // ref prescaler - ); - // Configure PLL1: 8MHz /1 *100 /2 = 400 MHz - rcc.pllcfgr.modify(|_, w| { - w.pll1vcosel() - .wide_vco() // 192-836 MHz VCO - .pll1rge() - .range8() // 8-16 MHz PFD - .pll1fracen() - .reset() - .divp1en() - .enabled() - .pll2vcosel() - .medium_vco() // 150-420 MHz VCO - .pll2rge() - .range8() // 8-16 MHz PFD - .pll2fracen() - .reset() - .divp2en() - .enabled() - .divq2en() - .enabled() - }); - rcc.pll1divr.write(|w| unsafe { - w.divn1() - .bits(100 - 1) // feebdack divider - .divp1() - .div2() // p output divider - }); - rcc.cr.modify(|_, w| w.pll1on().on()); - while !rcc.cr.read().pll1rdy().is_ready() {} - - // Configure PLL2: 8MHz /1 *25 / 2 = 100 MHz - rcc.pll2divr.write(|w| unsafe { - w.divn2() - .bits(25 - 1) // feebdack divider - .divp2() - .bits(2 - 1) // p output divider - .divq2() - .bits(2 - 1) // q output divider - }); - rcc.cr.modify(|_, w| w.pll2on().on()); - while !rcc.cr.read().pll2rdy().is_ready() {} - - // hclk 200 MHz, pclk 100 MHz - rcc.d1cfgr.write( - |w| { - w.d1cpre() - .div1() // sys_ck not divided - .hpre() - .div2() // rcc_hclk3 = sys_d1cpre_ck / 2 - .d1ppre() - .div2() - }, // rcc_pclk3 = rcc_hclk3 / 2 - ); - rcc.d2cfgr.write( - |w| { - w.d2ppre1() - .div2() // rcc_pclk1 = rcc_hclk3 / 2 - .d2ppre2() - .div2() - }, // rcc_pclk2 = rcc_hclk3 / 2 - ); - rcc.d3cfgr.write( - |w| w.d3ppre().div2(), // rcc_pclk4 = rcc_hclk3 / 2 - ); - - // 2 wait states, 0b10 programming delay - // 185-210 MHz - flash - .acr - .write(|w| unsafe { w.wrhighfreq().bits(2).latency().bits(2) }); - while flash.acr.read().latency().bits() != 2 {} - - // CSI for I/O compensationc ell - rcc.cr.modify(|_, w| w.csion().on()); - while !rcc.cr.read().csirdy().is_ready() {} - - // Set system clock to pll1_p - rcc.cfgr.modify(|_, w| w.sw().pll1()); - while !rcc.cfgr.read().sws().is_pll1() {} - - rcc.d1ccipr.write(|w| w.ckpersel().hse()); - rcc.d2ccip1r - .modify(|_, w| w.spi123sel().pll2_p().spi45sel().pll2_q()); - rcc.d3ccipr.modify(|_, w| w.spi6sel().pll2_q()); -} - -fn io_compensation_setup(syscfg: &pac::SYSCFG) { - syscfg - .cccsr - .modify(|_, w| w.en().set_bit().cs().clear_bit().hslv().clear_bit()); - while syscfg.cccsr.read().ready().bit_is_clear() {} -} - -fn gpio_setup( - gpioa: &pac::GPIOA, - gpiob: &pac::GPIOB, - gpiod: &pac::GPIOD, - gpioe: &pac::GPIOE, - gpiof: &pac::GPIOF, - gpiog: &pac::GPIOG, -) { - // FP_LED0 - gpiod.otyper.modify(|_, w| w.ot5().push_pull()); - gpiod.moder.modify(|_, w| w.moder5().output()); - gpiod.odr.modify(|_, w| w.odr5().low()); - - // FP_LED1 - gpiod.otyper.modify(|_, w| w.ot6().push_pull()); - gpiod.moder.modify(|_, w| w.moder6().output()); - gpiod.odr.modify(|_, w| w.odr6().low()); - - // LED_FP2 - gpiog.otyper.modify(|_, w| w.ot4().push_pull()); - gpiog.moder.modify(|_, w| w.moder4().output()); - gpiog.odr.modify(|_, w| w.odr4().low()); - - // LED_FP3 - gpiod.otyper.modify(|_, w| w.ot12().push_pull()); - gpiod.moder.modify(|_, w| w.moder12().output()); - gpiod.odr.modify(|_, w| w.odr12().low()); - - // AFE0_A0,1: PG2,PG3 - gpiog - .otyper - .modify(|_, w| w.ot2().push_pull().ot3().push_pull()); - gpiog - .moder - .modify(|_, w| w.moder2().output().moder3().output()); - gpiog.odr.modify(|_, w| w.odr2().low().odr3().low()); - - // ADC0 - // SCK: PG11 - gpiog.moder.modify(|_, w| w.moder11().alternate()); - gpiog.otyper.modify(|_, w| w.ot11().push_pull()); - gpiog.ospeedr.modify(|_, w| w.ospeedr11().very_high_speed()); - gpiog.afrh.modify(|_, w| w.afr11().af5()); - // MOSI: PD7 - // MISO: PA6 - gpioa.moder.modify(|_, w| w.moder6().alternate()); - gpioa.afrl.modify(|_, w| w.afr6().af5()); - // NSS: PG10 - gpiog.moder.modify(|_, w| w.moder10().alternate()); - gpiog.otyper.modify(|_, w| w.ot10().push_pull()); - gpiog.ospeedr.modify(|_, w| w.ospeedr10().very_high_speed()); - gpiog.afrh.modify(|_, w| w.afr10().af5()); - - // DAC0 - // SCK: PB10 - gpiob.moder.modify(|_, w| w.moder10().alternate()); - gpiob.otyper.modify(|_, w| w.ot10().push_pull()); - gpiob.ospeedr.modify(|_, w| w.ospeedr10().very_high_speed()); - gpiob.afrh.modify(|_, w| w.afr10().af5()); - // MOSI: PB15 - gpiob.moder.modify(|_, w| w.moder15().alternate()); - gpiob.otyper.modify(|_, w| w.ot15().push_pull()); - gpiob.ospeedr.modify(|_, w| w.ospeedr15().very_high_speed()); - gpiob.afrh.modify(|_, w| w.afr15().af5()); - // MISO: PB14 - // NSS: PB9 - gpiob.moder.modify(|_, w| w.moder9().alternate()); - gpiob.otyper.modify(|_, w| w.ot9().push_pull()); - gpiob.ospeedr.modify(|_, w| w.ospeedr9().very_high_speed()); - gpiob.afrh.modify(|_, w| w.afr9().af5()); - - // DAC0_LDAC: PE11 - gpioe.moder.modify(|_, w| w.moder11().output()); - gpioe.otyper.modify(|_, w| w.ot11().push_pull()); - gpioe.odr.modify(|_, w| w.odr11().low()); - - // DAC_CLR: PE12 - gpioe.moder.modify(|_, w| w.moder12().output()); - gpioe.otyper.modify(|_, w| w.ot12().push_pull()); - gpioe.odr.modify(|_, w| w.odr12().high()); - - // AFE1_A0,1: PD14,PD15 - gpiod - .otyper - .modify(|_, w| w.ot14().push_pull().ot15().push_pull()); - gpiod - .moder - .modify(|_, w| w.moder14().output().moder15().output()); - gpiod.odr.modify(|_, w| w.odr14().low().odr15().low()); - - // I2C2: SDA,SCL: PF0,PF1 - gpiof - .moder - .modify(|_, w| w.moder0().alternate().moder1().alternate()); - gpiof.afrl.modify(|_, w| w.afr0().af4().afr1().af4()); - gpiof - .otyper - .modify(|_, w| w.ot0().open_drain().ot1().open_drain()); - - // ADC1 - // SCK: PF6 - gpiof.moder.modify(|_, w| w.moder7().alternate()); - gpiof.otyper.modify(|_, w| w.ot7().push_pull()); - gpiof.ospeedr.modify(|_, w| w.ospeedr7().very_high_speed()); - gpiof.afrl.modify(|_, w| w.afr7().af5()); - // MOSI: PF9 - // MISO: PF7 - gpiof.moder.modify(|_, w| w.moder8().alternate()); - gpiof.afrh.modify(|_, w| w.afr8().af5()); - // NSS: PF8 - gpiof.moder.modify(|_, w| w.moder6().alternate()); - gpiof.otyper.modify(|_, w| w.ot6().push_pull()); - gpiof.ospeedr.modify(|_, w| w.ospeedr6().very_high_speed()); - gpiof.afrl.modify(|_, w| w.afr6().af5()); - - // DAC1 - // SCK: PE2 - gpioe.moder.modify(|_, w| w.moder2().alternate()); - gpioe.otyper.modify(|_, w| w.ot2().push_pull()); - gpioe.ospeedr.modify(|_, w| w.ospeedr2().very_high_speed()); - gpioe.afrl.modify(|_, w| w.afr2().af5()); - // MOSI: PE6 - gpioe.moder.modify(|_, w| w.moder6().alternate()); - gpioe.otyper.modify(|_, w| w.ot6().push_pull()); - gpioe.ospeedr.modify(|_, w| w.ospeedr6().very_high_speed()); - gpioe.afrl.modify(|_, w| w.afr6().af5()); - // MISO: PE5 - // NSS: PE4 - gpioe.moder.modify(|_, w| w.moder4().alternate()); - gpioe.otyper.modify(|_, w| w.ot4().push_pull()); - gpioe.ospeedr.modify(|_, w| w.ospeedr4().very_high_speed()); - gpioe.afrl.modify(|_, w| w.afr4().af5()); - - // DAC1_LDAC: PE15 - gpioe.moder.modify(|_, w| w.moder15().output()); - gpioe.otyper.modify(|_, w| w.ot15().push_pull()); - gpioe.odr.modify(|_, w| w.odr15().low()); -} - -// ADC0 -fn spi1_setup(spi1: &pac::SPI1) { - spi1.cfg1 - .modify(|_, w| w.mbr().div4().dsize().bits(16 - 1).fthlv().one_frame()); - spi1.cfg2.modify(|_, w| { - w.afcntr() - .controlled() - .ssom() - .not_asserted() - .ssoe() - .enabled() - .ssiop() - .active_low() - .ssm() - .disabled() - .cpol() - .idle_high() - .cpha() - .second_edge() - .lsbfrst() - .msbfirst() - .master() - .master() - .sp() - .motorola() - .comm() - .receiver() - .ioswp() - .disabled() - .midi() - .bits(0) - .mssi() - .bits(6) - }); - spi1.cr2.modify(|_, w| w.tsize().bits(1)); - spi1.cr1.write(|w| w.spe().enabled()); -} - -// ADC1 -fn spi5_setup(spi5: &pac::SPI5) { - spi5.cfg1 - .modify(|_, w| w.mbr().div4().dsize().bits(16 - 1).fthlv().one_frame()); - spi5.cfg2.modify(|_, w| { - w.afcntr() - .controlled() - .ssom() - .not_asserted() - .ssoe() - .enabled() - .ssiop() - .active_low() - .ssm() - .disabled() - .cpol() - .idle_high() - .cpha() - .second_edge() - .lsbfrst() - .msbfirst() - .master() - .master() - .sp() - .motorola() - .comm() - .receiver() - .ioswp() - .disabled() - .midi() - .bits(0) - .mssi() - .bits(6) - }); - spi5.cr2.modify(|_, w| w.tsize().bits(1)); - spi5.cr1.write(|w| w.spe().enabled()); -} - -// DAC0 -fn spi2_setup(spi2: &pac::SPI2) { - spi2.cfg1 - .modify(|_, w| w.mbr().div2().dsize().bits(16 - 1).fthlv().one_frame()); - spi2.cfg2.modify(|_, w| { - w.afcntr() - .controlled() - .ssom() - .not_asserted() - .ssoe() - .enabled() - .ssiop() - .active_low() - .ssm() - .disabled() - .cpol() - .idle_low() - .cpha() - .first_edge() - .lsbfrst() - .msbfirst() - .master() - .master() - .sp() - .motorola() - .comm() - .transmitter() - .ioswp() - .disabled() - .midi() - .bits(0) - .mssi() - .bits(0) - }); - spi2.cr2.modify(|_, w| w.tsize().bits(0)); - spi2.cr1.write(|w| w.spe().enabled()); - spi2.cr1.modify(|_, w| w.cstart().started()); -} - -// DAC1 -fn spi4_setup(spi4: &pac::SPI4) { - spi4.cfg1 - .modify(|_, w| w.mbr().div2().dsize().bits(16 - 1).fthlv().one_frame()); - spi4.cfg2.modify(|_, w| { - w.afcntr() - .controlled() - .ssom() - .not_asserted() - .ssoe() - .enabled() - .ssiop() - .active_low() - .ssm() - .disabled() - .cpol() - .idle_low() - .cpha() - .first_edge() - .lsbfrst() - .msbfirst() - .master() - .master() - .sp() - .motorola() - .comm() - .transmitter() - .ioswp() - .disabled() - .midi() - .bits(0) - .mssi() - .bits(0) - }); - spi4.cr2.modify(|_, w| w.tsize().bits(0)); - spi4.cr1.write(|w| w.spe().enabled()); - spi4.cr1.modify(|_, w| w.cstart().started()); -} - -fn tim2_setup(tim2: &pac::TIM2) { - tim2.psc.write(|w| w.psc().bits(200 - 1)); // from 200 MHz - tim2.arr.write(|w| unsafe { w.bits(2 - 1) }); // 2 µs - tim2.dier.write(|w| w.ude().set_bit()); - tim2.egr.write(|w| w.ug().set_bit()); - tim2.cr1.modify(|_, w| w.dir().clear_bit()); // up -} - -fn dma1_setup( +pub fn dma1_setup( dma1: &pac::DMA1, dmamux1: &pac::DMAMUX1, ma: usize, @@ -529,113 +75,3 @@ fn dma1_setup( dma1.st[1].fcr.modify(|_, w| w.dmdis().clear_bit()); dma1.st[1].cr.modify(|_, w| w.en().set_bit()); } - -#[link_section = ".sram1.datspi"] -static mut DAT: u32 = 0x201; // EN | CSTART - -pub fn init() { - let mut cp = unsafe { cortex_m::Peripherals::steal() }; - let dp = unsafe { pac::Peripherals::steal() }; - - let rcc = dp.RCC; - rcc_reset(&rcc); - pwr_setup(&dp.PWR); - rcc_pll_setup(&rcc, &dp.FLASH); - rcc.apb4enr.modify(|_, w| w.syscfgen().set_bit()); - io_compensation_setup(&dp.SYSCFG); - - cp.SCB.enable_icache(); - // TODO: ETH DMA coherence issues - // cp.SCB.enable_dcache(&mut cp.CPUID); - cp.DWT.enable_cycle_counter(); // japaric/cortex-m-rtfm#184 - - rcc.ahb4enr.modify(|_, w| { - w.gpioaen() - .set_bit() - .gpioben() - .set_bit() - .gpiocen() - .set_bit() - .gpioden() - .set_bit() - .gpioeen() - .set_bit() - .gpiofen() - .set_bit() - .gpiogen() - .set_bit() - }); - gpio_setup( - &dp.GPIOA, &dp.GPIOB, &dp.GPIOD, &dp.GPIOE, &dp.GPIOF, &dp.GPIOG, - ); - - rcc.apb1lenr.modify(|_, w| w.spi2en().set_bit()); - let spi2 = dp.SPI2; - spi2_setup(&spi2); - - rcc.apb2enr.modify(|_, w| w.spi4en().set_bit()); - let spi4 = dp.SPI4; - spi4_setup(&spi4); - - rcc.apb2enr.modify(|_, w| w.spi1en().set_bit()); - let spi1 = dp.SPI1; - spi1_setup(&spi1); - spi1.ier.write(|w| w.eotie().set_bit()); - - rcc.apb2enr.modify(|_, w| w.spi5en().set_bit()); - let spi5 = dp.SPI5; - spi5_setup(&spi5); - // spi5.ier.write(|w| w.eotie().set_bit()); - - rcc.ahb2enr.modify(|_, w| { - w.sram1en() - .set_bit() - .sram2en() - .set_bit() - .sram3en() - .set_bit() - }); - rcc.ahb1enr.modify(|_, w| w.dma1en().set_bit()); - // init SRAM1 rodata can't load with sram1 disabled - unsafe { DAT = 0x201 }; // EN | CSTART - cortex_m::asm::dsb(); - let dat_addr = unsafe { &DAT as *const _ } as usize; - cp.SCB.clean_dcache_by_address(dat_addr, 4); - - dma1_setup( - &dp.DMA1, - &dp.DMAMUX1, - dat_addr, - &spi1.cr1 as *const _ as usize, - &spi5.cr1 as *const _ as usize, - ); - - rcc.apb1lenr.modify(|_, w| w.tim2en().set_bit()); - - // work around the SPI stall erratum - let dbgmcu = dp.DBGMCU; - dbgmcu.apb1lfz1.modify(|_, w| w.tim2().set_bit()); - - tim2_setup(&dp.TIM2); - - rcc.apb1lenr.modify(|_, w| w.i2c2en().set_bit()); - i2c::setup(&dp.I2C2); - - rcc.apb4enr.modify(|_, w| w.syscfgen().set_bit()); - rcc.ahb1enr.modify(|_, w| { - w.eth1macen() - .set_bit() - .eth1txen() - .set_bit() - .eth1rxen() - .set_bit() - }); - dp.SYSCFG - .pmcr - .modify(|_, w| unsafe { w.epis().bits(0b100) }); // RMII - eth::setup_pins(&dp.GPIOA, &dp.GPIOB, &dp.GPIOC, &dp.GPIOG); - - // enable TIM2 this must be late to be able to handle the first ADC SPI - // interrupt in time - dp.TIM2.cr1.modify(|_, w| w.cen().set_bit()); -} diff --git a/src/eeprom.rs b/src/eeprom.rs index a50dd69..784c0b6 100644 --- a/src/eeprom.rs +++ b/src/eeprom.rs @@ -1,10 +1,11 @@ -use super::i2c; -use stm32h7::stm32h743v as pac; +use embedded_hal::blocking::i2c::WriteRead; -const I2C_ADDR: u8 = 0xa0; +const I2C_ADDR: u8 = 0x50; -pub fn read_eui48(i2c: &pac::I2C2) -> Result<[u8; 6], i2c::Error> { +pub fn read_eui48(i2c: &mut T) -> Result<[u8; 6], T::Error> +where T: WriteRead +{ let mut buffer = [0u8; 6]; - i2c::write_read(i2c, I2C_ADDR, &[0xFAu8], &mut buffer)?; + i2c.write_read(I2C_ADDR, &[0xFA_u8], &mut buffer)?; Ok(buffer) } diff --git a/src/eth.rs b/src/eth.rs index d108982..267a098 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -3,7 +3,7 @@ use smoltcp::phy; use smoltcp::time::Instant; use smoltcp::wire::EthernetAddress; use smoltcp::Result; -use stm32h7::stm32h743v as pac; +use super::{pac}; #[allow(dead_code)] mod phy_consts { @@ -85,50 +85,6 @@ use self::cr_consts::*; // 200 MHz AHB clock = eth_hclk const CLOCK_RANGE: u8 = ETH_MACMIIAR_CR_HCLK_DIV_102; -pub fn setup_pins( - gpioa: &pac::GPIOA, - gpiob: &pac::GPIOB, - gpioc: &pac::GPIOC, - gpiog: &pac::GPIOG, -) { - // PA1 RMII_REF_CLK - gpioa.moder.modify(|_, w| w.moder1().alternate()); - gpioa.afrl.modify(|_, w| w.afr1().af11()); - gpioa.ospeedr.modify(|_, w| w.ospeedr1().very_high_speed()); - // PA2 RMII_MDIO - gpioa.moder.modify(|_, w| w.moder2().alternate()); - gpioa.afrl.modify(|_, w| w.afr2().af11()); - gpioa.ospeedr.modify(|_, w| w.ospeedr2().very_high_speed()); - // PC1 RMII_MDC - gpioc.moder.modify(|_, w| w.moder1().alternate()); - gpioc.afrl.modify(|_, w| w.afr1().af11()); - gpioc.ospeedr.modify(|_, w| w.ospeedr1().very_high_speed()); - // PA7 RMII_CRS_DV - gpioa.moder.modify(|_, w| w.moder7().alternate()); - gpioa.afrl.modify(|_, w| w.afr7().af11()); - gpioa.ospeedr.modify(|_, w| w.ospeedr7().very_high_speed()); - // PC4 RMII_RXD0 - gpioc.moder.modify(|_, w| w.moder4().alternate()); - gpioc.afrl.modify(|_, w| w.afr4().af11()); - gpioc.ospeedr.modify(|_, w| w.ospeedr4().very_high_speed()); - // PC5 RMII_RXD1 - gpioc.moder.modify(|_, w| w.moder5().alternate()); - gpioc.afrl.modify(|_, w| w.afr5().af11()); - gpioc.ospeedr.modify(|_, w| w.ospeedr5().very_high_speed()); - // PB11 RMII_TX_EN - gpiob.moder.modify(|_, w| w.moder11().alternate()); - gpiob.afrh.modify(|_, w| w.afr11().af11()); - gpiob.ospeedr.modify(|_, w| w.ospeedr11().very_high_speed()); - // PB12 RXII_TXD0 - gpiob.moder.modify(|_, w| w.moder12().alternate()); - gpiob.afrh.modify(|_, w| w.afr12().af11()); - gpiob.ospeedr.modify(|_, w| w.ospeedr12().very_high_speed()); - // PG14 RMII TXD1 - gpiog.moder.modify(|_, w| w.moder14().alternate()); - gpiog.afrh.modify(|_, w| w.afr14().af11()); - gpiog.ospeedr.modify(|_, w| w.ospeedr14().very_high_speed()); -} - const PHY_ADDR: u8 = 0; fn phy_read(reg_addr: u8, mac: &pac::ETHERNET_MAC) -> u16 { diff --git a/src/i2c.rs b/src/i2c.rs deleted file mode 100644 index 2118194..0000000 --- a/src/i2c.rs +++ /dev/null @@ -1,145 +0,0 @@ -use stm32h7::stm32h743v as pac; - -// Adapted from stm32h7xx embedded-hal - -// I2C error -#[derive(Debug)] -pub enum Error { - // Bus error - Bus, - // Arbitration loss - Arbitration, - // Address not ACKd within a reasonable time (no device present?) - Timeout, - // Unexpected NACK during transfer - NAck, -} - -// Maximum number of times to retry NACKed address phase before timing out -// Note that many devices indicate a busy condition by NACKing (e.g. 24xx -// EEPROMs during write) -const N_RETRY: usize = 100; // ~ 10ms @ 100 kHz bus clock - -pub fn setup(i2c: &pac::I2C2) { - // Disable the peripheral before setting timings - i2c.cr1.modify(|_, w| w.pe().clear_bit()); - - // Values from STM32MXCube for 100 kHz I2C clock with 100 MHz peripheral clock - i2c.timingr.modify(|_, w| { - w.presc() - .bits(1) - .scldel() - .bits(0x12) - .sdadel() - .bits(0) - .sclh() - .bits(0xec) - .scll() - .bits(0xff) - }); - - // Enable the peripheral - i2c.cr1.write(|w| w.pe().set_bit()); -} - -// Busy-wait for a flag to be asserted, erroring out on unrecoverable problems -macro_rules! busy_wait_errors { - ($i2c:expr, $flag:ident) => { - loop { - let isr = $i2c.isr.read(); - - if isr.berr().bit_is_set() { - return Err(Error::Bus); - } else if isr.arlo().bit_is_set() { - return Err(Error::Arbitration); - } else if isr.nackf().bit_is_set() { - return Err(Error::NAck); - } else if isr.$flag().bit_is_set() { - break; - } - } - }; -} - -fn poll_for_start_ack( - i2c: &pac::I2C2, - addr: u8, - r_wn: bool, - data_len: usize, - autoend: bool, - start: bool, -) -> Result<(), Error> { - for _i in 0..N_RETRY { - // START and prepare to send `data_len` - i2c.cr2.write(|w| { - w.start() - .bit(start) - .sadd() - .bits(addr as u16) - .add10() - .clear_bit() - .rd_wrn() - .bit(r_wn) - .nbytes() - .bits(data_len as u8) - .autoend() - .bit(autoend) - }); - - loop { - let isr = i2c.isr.read(); - - if isr.berr().bit_is_set() { - return Err(Error::Bus); - } else if isr.arlo().bit_is_set() { - return Err(Error::Arbitration); - } else if isr.nackf().bit_is_set() { - i2c.icr.write(|w| w.nackcf().set_bit()); - // Wait to finish handling NACK-STOP - loop { - if i2c.isr.read().busy().bit_is_clear() { - break; - } - } - break; - } else if isr.txis().bit_is_set() || isr.rxne().bit_is_set() { - return Ok(()); - } - } - } - - Err(Error::Timeout) -} - -pub fn write_read( - i2c: &pac::I2C2, - addr: u8, - bytes: &[u8], - buffer: &mut [u8], -) -> Result<(), Error> { - assert!(bytes.len() < 256 && !bytes.is_empty()); - assert!(buffer.len() < 256 && !buffer.is_empty()); - - poll_for_start_ack(i2c, addr, false, bytes.len(), false, true)?; - - for byte in bytes { - // Wait until we are allowed to send data (START has been ACKed or last - // byte when through) - busy_wait_errors!(i2c, txis); - i2c.txdr.write(|w| w.txdata().bits(*byte)); - } - - // Wait until the last transmission is finished - busy_wait_errors!(i2c, tc); - - poll_for_start_ack(i2c, addr | 1, true, buffer.len(), true, true)?; - - for byte in buffer { - // Wait until we have received something - busy_wait_errors!(i2c, rxne); - *byte = i2c.rxdr.read().rxdata().bits(); - } - - // automatic STOP - Ok(()) -} diff --git a/src/main.rs b/src/main.rs index 5cc2497..1050e2d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,13 +27,20 @@ extern crate panic_halt; #[macro_use] extern crate log; -use core::ptr; // use core::sync::atomic::{AtomicU32, AtomicBool, Ordering}; use core::fmt::Write; use cortex_m_rt::exception; use heapless::{consts::*, String, Vec}; use rtfm::cyccnt::{Instant, U32Ext as _}; -use stm32h7::stm32h743v as pac; +use stm32h7xx_hal as hal; +use stm32h7xx_hal::{ + prelude::*, + stm32 as pac, +}; + +use embedded_hal::{ + digital::v2::OutputPin, +}; use smoltcp as net; @@ -47,7 +54,6 @@ use iir::*; mod board; mod eeprom; -mod i2c; #[cfg(not(feature = "semihosting"))] fn init_log() {} @@ -94,11 +100,69 @@ macro_rules! create_socket { }; } -#[rtfm::app(device = stm32h7::stm32h743v, peripherals = true, monotonic = rtfm::cyccnt::CYCCNT)] +type Adc1Spi = hal::spi::Spi< + hal::stm32::SPI2, + ( + hal::gpio::gpiob::PB10>, + hal::gpio::gpiob::PB14>, + hal::spi::NoMosi, + //hal::gpio::gpiob::PB9>, + ) +>; + +type Adc2Spi = hal::spi::Spi< + hal::stm32::SPI3, + ( + hal::gpio::gpioc::PC10>, + hal::gpio::gpiob::PB4>, + hal::spi::NoMosi, + //hal::gpio::gpioa::PA15>, + ) +>; + +type Dac1Spi = hal::spi::Spi< + hal::stm32::SPI4, + ( + hal::gpio::gpioe::PE2>, + hal::gpio::gpioe::PE5>, + hal::spi::NoMosi, + //hal::gpio::gpioe::PE4>, + ) +>; + +type Dac2Spi = hal::spi::Spi< + hal::stm32::SPI5, + ( + hal::gpio::gpiof::PF7>, + hal::gpio::gpiof::PF8>, + hal::spi::NoMosi, + //hal::gpio::gpiof::PF6>, + ) +>; + +type EepromI2c = hal::i2c::I2c< + hal::stm32::I2C2, + ( + hal::gpio::gpiof::PF1>, + hal::gpio::gpiof::PF0>, + ) +>; + +static DAT: u32 = 0x30; // EN | CSTART + +#[rtfm::app(device = stm32h7xx_hal::stm32, peripherals = true, monotonic = rtfm::cyccnt::CYCCNT)] const APP: () = { struct Resources { - spi: (pac::SPI1, pac::SPI2, pac::SPI4, pac::SPI5), - i2c: pac::I2C2, + adc1: Adc1Spi, + dac1: Dac1Spi, + + adc2: Adc2Spi, + dac2: Dac2Spi, + + i2c: EepromI2c, + + // TODO: Add in pounder hardware resources. + ethernet_periph: (pac::ETHERNET_MAC, pac::ETHERNET_DMA, pac::ETHERNET_MTL), #[init([[0.; 5]; 2])] @@ -112,7 +176,213 @@ const APP: () = { #[init(schedule = [tick])] fn init(c: init::Context) -> init::LateResources { - board::init(); + let dp = c.device; + let mut cp = cortex_m::Peripherals::take().unwrap(); + + let pwr = dp.PWR.constrain(); + let vos = pwr.freeze(); + + let rcc = dp.RCC.constrain(); + let mut clocks = rcc + .use_hse(8.mhz()) + .sysclk(400.mhz()) + .hclk(200.mhz()) + .per_ck(100.mhz()) + .pll2_p_ck(100.mhz()) + .pll2_q_ck(100.mhz()) + .freeze(vos, &dp.SYSCFG); + + clocks.rb.d2ccip1r.modify(|_, w| w.spi123sel().pll2_p().spi45sel().pll2_q()); + + let gpioa = dp.GPIOA.split(&mut clocks.ahb4); + let gpiob = dp.GPIOB.split(&mut clocks.ahb4); + let gpioc = dp.GPIOC.split(&mut clocks.ahb4); + let gpiod = dp.GPIOD.split(&mut clocks.ahb4); + let gpioe = dp.GPIOE.split(&mut clocks.ahb4); + let gpiof = dp.GPIOF.split(&mut clocks.ahb4); + let gpiog = dp.GPIOG.split(&mut clocks.ahb4); + + // Configure the SPI interfaces to the ADCs and DACs. + let adc1_spi = { + let spi_miso = gpiob.pb14.into_alternate_af5(); + let spi_sck = gpiob.pb10.into_alternate_af5(); + let _spi_nss = gpiob.pb9.into_alternate_af5(); + + let config = hal::spi::Config::new() + .set_mode(hal::spi::Mode{ + polarity: hal::spi::Polarity::IdleHigh, + phase: hal::spi::Phase::CaptureOnSecondTransition}) + .cs_delay(220e-9) + .frame_size(16) + .freeze(); + + let spi = hal::spi::Spi::spi2( + dp.SPI2, + (spi_sck, spi_miso, hal::spi::NoMosi), + config, + 25.mhz(), + &clocks); + + //spi.listen(hal::spi::Event::Rxp); + + spi + }; + + let adc2_spi = { + let spi_miso = gpiob.pb4.into_alternate_af6(); + let spi_sck = gpioc.pc10.into_alternate_af6(); + let _spi_nss = gpioa.pa15.into_alternate_af6(); + + let config = hal::spi::Config::new() + .set_mode(hal::spi::Mode{ + polarity: hal::spi::Polarity::IdleHigh, + phase: hal::spi::Phase::CaptureOnSecondTransition}) + .frame_size(16) + .cs_delay(220e-9) + .freeze(); + + let spi = hal::spi::Spi::spi3( + dp.SPI3, + (spi_sck, spi_miso, hal::spi::NoMosi), + config, + 25.mhz(), + &clocks); + + //spi.listen(hal::spi::Event::Rxp); + + spi + }; + + let dac1_spi = { + let spi_miso = gpioe.pe5.into_alternate_af5(); + let spi_sck = gpioe.pe2.into_alternate_af5(); + let _spi_nss = gpioe.pe4.into_alternate_af5(); + + let config = hal::spi::Config::new() + .set_mode(hal::spi::Mode{ + polarity: hal::spi::Polarity::IdleHigh, + phase: hal::spi::Phase::CaptureOnSecondTransition}) + .frame_size(16) + .swap_mosi_miso() + .freeze(); + + let spi = hal::spi::Spi::spi4( + dp.SPI4, + (spi_sck, spi_miso, hal::spi::NoMosi), + config, + 25.mhz(), + &clocks); + + spi + }; + + let dac2_spi = { + let spi_miso = gpiof.pf8.into_alternate_af5(); + let spi_sck = gpiof.pf7.into_alternate_af5(); + let _spi_nss = gpiof.pf6.into_alternate_af5(); + + let config = hal::spi::Config::new() + .set_mode(hal::spi::Mode{ + polarity: hal::spi::Polarity::IdleHigh, + phase: hal::spi::Phase::CaptureOnSecondTransition}) + .frame_size(16) + .swap_mosi_miso() + .freeze(); + + let spi = hal::spi::Spi::spi5( + dp.SPI5, + (spi_sck, spi_miso, hal::spi::NoMosi), + config, + 25.mhz(), + &clocks); + + spi + }; + + // TODO: Configure the DMA + //let mut dma = Dma::new(dp.DMA1, dp.DMAMUX1); + //dma.configure_transfer(DmaTransfer::MemoryToPeripheral, DmaSource::Timer2, trigger_word, + // &adc1_spi.spi.ptr().cr1.register) + //dma.configure_transfer(DmaTransfer::MemoryToPeripheral, DmaSource::Timer2, trigger_word, + // &adc2_spi.spi.ptr().cr1.register) + + // TODO: Configure timer 2 to trigger conversions for the ADC + let _timer2 = hal::timer::Timer::tim2(dp.TIM2, 500.khz(), &mut clocks); + + cortex_m::asm::dsb(); + let dat_addr = &DAT as *const _ as usize; + cp.SCB.clean_dcache_by_address(dat_addr, 4); + + board::dma1_setup( + &dp.DMA1, + &dp.DMAMUX1, + dat_addr, + &adc1_spi.spi.cr1 as *const _ as usize, + &adc2_spi.spi.cr1 as *const _ as usize, + ); + //timer2.enable_event(hal::timer::Event::DmaTransfer); + + // TODO: Configure the ethernet controller + + // Instantiate the QUADSPI pins and peripheral interface. + + // TODO: Place these into a pins structure that is provided to the QSPI constructor. + let _qspi_clk = gpiob.pb2.into_alternate_af9(); + let _qspi_ncs = gpioc.pc11.into_alternate_af9(); + let _qspi_io0 = gpioe.pe7.into_alternate_af10(); + let _qspi_io1 = gpioe.pe8.into_alternate_af10(); + let _qspi_io2 = gpioe.pe9.into_alternate_af10(); + let _qspi_io3 = gpioe.pe10.into_alternate_af10(); + + let mut fp_led_0 = gpiod.pd5.into_push_pull_output(); + let mut fp_led_1 = gpiod.pd6.into_push_pull_output(); + let mut fp_led_2 = gpiod.pd12.into_push_pull_output(); + let mut fp_led_3 = gpiog.pg4.into_push_pull_output(); + + fp_led_0.set_low().unwrap(); + fp_led_1.set_low().unwrap(); + fp_led_2.set_low().unwrap(); + fp_led_3.set_low().unwrap(); + + let _i2c1 = { + let sda = gpiob.pb7.into_alternate_af4().set_open_drain(); + let scl = gpiob.pb8.into_alternate_af4().set_open_drain(); + hal::i2c::I2c::i2c1(dp.I2C1, (scl, sda), 100.khz(), &clocks) + }; + + let i2c2 = { + let sda = gpiof.pf0.into_alternate_af4().set_open_drain(); + let scl = gpiof.pf1.into_alternate_af4().set_open_drain(); + hal::i2c::I2c::i2c2(dp.I2C2, (scl, sda), 100.khz(), &clocks) + }; + + // Configure ethernet pins. + let _rmii_ref_clk = gpioa.pa1.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh); + let _rmii_mdio = gpioa.pa2.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh); + let _rmii_mdc = gpioc.pc1.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh); + let _rmii_crs_dv = gpioa.pa7.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh); + let _rmii_rxd0 = gpioc.pc4.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh); + let _rmii_rxd1 = gpioc.pc5.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh); + let _rmii_tx_en = gpiob.pb11.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh); + let _rmii_txd0 = gpiob.pb12.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh); + + // TODO: This configuration seems to cause a system reset? + //let _rmii_txd1 = gpiog.pg14.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh); + + // Enable the ethernet peripheral. + clocks.apb4.enr().modify(|_, w| w.syscfgen().set_bit()); + clocks.ahb1.enr().modify(|_, w| { + w.eth1macen().set_bit() + .eth1txen().set_bit() + .eth1rxen().set_bit() + }); + + dp.SYSCFG.pmcr.modify(|_, w| unsafe { w.epis().bits(0b100) }); // RMII + + cp.SCB.enable_icache(); + + // The cycle counter is used for RTFM scheduling. + cp.DWT.enable_cycle_counter(); init_log(); // info!("Version {} {}", build_info::PKG_VERSION, build_info::GIT_VERSION.unwrap()); @@ -121,10 +391,13 @@ const APP: () = { // c.schedule.tick(Instant::now()).unwrap(); - let dp = c.device; init::LateResources { - spi: (dp.SPI1, dp.SPI2, dp.SPI4, dp.SPI5), - i2c: dp.I2C2, + adc1: adc1_spi, + dac1: dac1_spi, + adc2: adc2_spi, + dac2: dac2_spi, + + i2c: i2c2, ethernet_periph: ( dp.ETHERNET_MAC, dp.ETHERNET_DMA, @@ -244,40 +517,49 @@ const APP: () = { // seems to slow it down // #[link_section = ".data.spi1"] - #[task(binds = SPI1, resources = [spi, iir_state, iir_ch], priority = 2)] - fn spi1(c: spi1::Context) { + #[task(binds = SPI2, resources = [adc1, dac1, iir_state, iir_ch], priority = 2)] + fn spi2(c: spi2::Context) { #[cfg(feature = "bkpt")] cortex_m::asm::bkpt(); - let (spi1, spi2, spi4, spi5) = c.resources.spi; + let adc = c.resources.adc1; + let dac = c.resources.dac1; let iir_ch = c.resources.iir_ch; let iir_state = c.resources.iir_state; - let sr = spi1.sr.read(); - if sr.eot().bit_is_set() { - spi1.ifcr.write(|w| w.eotc().set_bit()); - } - if sr.rxp().bit_is_set() { - let rxdr = &spi1.rxdr as *const _ as *const u16; - let a = unsafe { ptr::read_volatile(rxdr) }; + // TODO: Doesn't make sense if RXP is unset. + if adc.is_rxp() { + let a: u16 = adc.read().unwrap(); + let x0 = f32::from(a as i16); let y0 = iir_ch[0].update(&mut iir_state[0], x0); let d = y0 as i16 as u16 ^ 0x8000; - let txdr = &spi2.txdr as *const _ as *mut u16; - unsafe { ptr::write_volatile(txdr, d) }; - } - let sr = spi5.sr.read(); - if sr.eot().bit_is_set() { - spi5.ifcr.write(|w| w.eotc().set_bit()); + // TODO: Handle errors. + dac.send(d).unwrap(); } - if sr.rxp().bit_is_set() { - let rxdr = &spi5.rxdr as *const _ as *const u16; - let a = unsafe { ptr::read_volatile(rxdr) }; + #[cfg(feature = "bkpt")] + cortex_m::asm::bkpt(); + } + + #[task(binds = SPI3, resources = [adc2, dac2, iir_state, iir_ch], priority = 2)] + fn spi3(c: spi3::Context) { + #[cfg(feature = "bkpt")] + cortex_m::asm::bkpt(); + let adc = c.resources.adc2; + let dac = c.resources.dac2; + let iir_ch = c.resources.iir_ch; + let iir_state = c.resources.iir_state; + + // TODO: Doesn't make sense if RXP is unset. + if adc.is_rxp() { + let a: u16 = adc.read().unwrap(); + let x0 = f32::from(a as i16); let y0 = iir_ch[1].update(&mut iir_state[1], x0); let d = y0 as i16 as u16 ^ 0x8000; - let txdr = &spi4.txdr as *const _ as *mut u16; - unsafe { ptr::write_volatile(txdr, d) }; + + // TODO: Handle errors. + dac.send(d).unwrap(); } #[cfg(feature = "bkpt")] cortex_m::asm::bkpt();