eth: sketch
eth: rework ethernet: wip eth: simplify cargo: bump stm32h7 ethmac: rework ethmac: fixup cargo: semihosting version bump ethmac: fixup eth: tweak eth: cleanup eth: tweaks eth: more debug eth: tweak memory: rename for clarity eth: tweak eth: pings eth: cleanup eth: cleanup, use interrupts, tighten filter
This commit is contained in:
parent
8ff8a4ce31
commit
0fafd7aa42
|
@ -2,8 +2,20 @@
|
|||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "aligned"
|
||||
version = "0.2.0"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"as-slice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "as-slice"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"generic-array 0.12.0 (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]]
|
||||
name = "bare-metal"
|
||||
|
@ -46,21 +58,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "cortex-m"
|
||||
version = "0.5.8"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aligned 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"aligned 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cortex-m-log"
|
||||
version = "0.4.0"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cortex-m 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m-semihosting 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m-semihosting 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -78,18 +90,26 @@ name = "cortex-m-rt-macros"
|
|||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cortex-m-semihosting"
|
||||
version = "0.3.2"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cortex-m 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -141,14 +161,6 @@ dependencies = [
|
|||
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.6"
|
||||
|
@ -175,10 +187,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
[[package]]
|
||||
name = "panic-semihosting"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
source = "git+https://github.com/rust-embedded/panic-semihosting?rev=aef8231a521aa4197cdb5c3b0bc2b435ed663e2b#aef8231a521aa4197cdb5c3b0bc2b435ed663e2b"
|
||||
dependencies = [
|
||||
"cortex-m 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m-semihosting 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m-semihosting 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -193,7 +205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.27"
|
||||
version = "0.4.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -204,7 +216,7 @@ name = "quote"
|
|||
version = "0.6.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -276,7 +288,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"managed 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -284,34 +295,40 @@ dependencies = [
|
|||
name = "stabilizer"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aligned 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"built 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m-log 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m-log 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m-rt 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"panic-abort 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"panic-semihosting 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"panic-semihosting 0.5.1 (git+https://github.com/rust-embedded/panic-semihosting?rev=aef8231a521aa4197cdb5c3b0bc2b435ed663e2b)",
|
||||
"smoltcp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stm32h7 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stm32h7 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "stm32h7"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m-rt 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.15.31"
|
||||
version = "0.15.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -334,6 +351,11 @@ dependencies = [
|
|||
"serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.4"
|
||||
|
@ -403,32 +425,33 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum aligned 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d39da9b88ae1a81c03c9c082b8db83f1d0e93914126041962af61034ab44c4a5"
|
||||
"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 built 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "61f5aae2fa15b68fbcf0cbab64e659a55d10e9bacc55d3470ef77ae73030d755"
|
||||
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
|
||||
"checksum cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5f3fee5eeb60324c2781f1e41286bdee933850fff9b3c672587fed5ec58c83"
|
||||
"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4"
|
||||
"checksum cortex-m 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dab2164a0fc216781a47fc343347365112ae6917421d3fa4bac6faf0fbaaaec7"
|
||||
"checksum cortex-m-log 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "62d666a7362a29620140c5a0a8149dd31f06bd6a804240f32359a83ded1e210a"
|
||||
"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.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7e1ccc9052352415ec4e3f762f4541098d012016f9354a1a5b2dede39b67f426"
|
||||
"checksum cortex-m-rt-macros 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d7ae692573e0acccb1579fef1abf5a5bf1d2f3f0149a22b16870ec9309aee25f"
|
||||
"checksum cortex-m-semihosting 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d1dc2abec1a772e8bb697cad17d5710f180043caf8939820f0f6ba4b7ae2a4b5"
|
||||
"checksum cortex-m-semihosting 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "165f3f86f4d1031351a6c9dc8d5a3f8fae2050f9dd6ef925e3d675c232cc0e46"
|
||||
"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592"
|
||||
"checksum git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "591f8be1674b421644b6c030969520bc3fa12114d2eb467471982ed3e9584e71"
|
||||
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
|
||||
"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917"
|
||||
"checksum libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "48441cb35dc255da8ae72825689a95368bf510659ae1ad55dc4aa88cb1789bf1"
|
||||
"checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe"
|
||||
"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 matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||
"checksum panic-abort 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c14a66511ed17b6a8b4256b868d7fd207836d891db15eea5195dbcaf87e630f"
|
||||
"checksum panic-semihosting 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a647d81e7b00f69deac766cd96d69fc11c95c18657d2448b539ae93e4c558689"
|
||||
"checksum panic-semihosting 0.5.1 (git+https://github.com/rust-embedded/panic-semihosting?rev=aef8231a521aa4197cdb5c3b0bc2b435ed663e2b)" = "<none>"
|
||||
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
|
||||
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
|
||||
"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915"
|
||||
"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"
|
||||
|
@ -441,10 +464,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "aa5f7c20820475babd2c077c3ab5f8c77a31c15e16ea38687b4c02d3e48680f4"
|
||||
"checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be"
|
||||
"checksum smoltcp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fef582369edb298c6c41319a544ca9c4e83622f226055ccfcb35974fbb55ed34"
|
||||
"checksum stm32h7 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2756cb97ac50836393814072493107a42701fecd11a6d228527292479bb1f25"
|
||||
"checksum syn 0.15.31 (registry+https://github.com/rust-lang/crates.io-index)" = "d2b4cfac95805274c6afdb12d8f770fa2d27c045953e7b630a81801953699a9a"
|
||||
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
|
||||
"checksum stm32h7 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64173a3f8edb1bf9e17b14861695da2a7e6ca98afc99e0f249b62e4962cc478d"
|
||||
"checksum syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)" = "846620ec526c1599c070eff393bfeeeb88a93afa2513fc3b49f1fea84cf7b0ed"
|
||||
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
|
||||
"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
|
||||
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
|
||||
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
||||
"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426"
|
||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
|
|
20
Cargo.toml
20
Cargo.toml
|
@ -27,15 +27,23 @@ features = []
|
|||
default-target = "thumbv7em-none-eabihf"
|
||||
|
||||
[dependencies]
|
||||
cortex-m = { version = "0.5", features = ["inline-asm", "const-fn"] }
|
||||
cortex-m = { version = "0.6", features = ["inline-asm", "const-fn"] }
|
||||
cortex-m-rt = { version = "0.6", features = ["device"] }
|
||||
cortex-m-log = { version = "0.4", features = ["log-integration"] }
|
||||
stm32h7 = { version = "0.6", features = ["stm32h7x3", "rt"] }
|
||||
# stm32h7 = { path = "../stm32-rs/stm32h7", features = ["stm32h7x3", "rt"] }
|
||||
cortex-m-log = { version = "0.5", features = ["log-integration"] }
|
||||
stm32h7 = { version = "0.7", features = ["stm32h7x3", "rt"] }
|
||||
log = "0.4"
|
||||
panic-abort = "0.3"
|
||||
panic-semihosting = { version = "0.5", optional = true }
|
||||
smoltcp = { version = "0.5", default-features = false, features = ["proto-ipv4", "socket-tcp", "log"] }
|
||||
# https://github.com/rust-embedded/panic-semihosting/issues/16
|
||||
# panic-semihosting = { version = "0.6", optional = true }
|
||||
panic-semihosting = { git = "https://github.com/rust-embedded/panic-semihosting", rev = "aef8231a521aa4197cdb5c3b0bc2b435ed663e2b", optional = true }
|
||||
aligned = "0.3"
|
||||
|
||||
[dependencies.smoltcp]
|
||||
#git = "https://github.com/m-labs/smoltcp"
|
||||
#rev = "cd893e6"
|
||||
version = "0.5"
|
||||
features = ["proto-ipv4", "socket-tcp"]
|
||||
default-features = false
|
||||
|
||||
[features]
|
||||
semihosting = ["panic-semihosting", "cortex-m-log/semihosting"]
|
||||
|
|
22
memory.x
22
memory.x
|
@ -2,9 +2,11 @@ MEMORY
|
|||
{
|
||||
ITCM (rwx) : ORIGIN = 0x00000000, LENGTH = 64K
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
|
||||
RAM_D1 (rwx) : ORIGIN = 0x24000000, LENGTH = 512K
|
||||
RAM_D2 (rwx) : ORIGIN = 0x30000000, LENGTH = 288K
|
||||
RAM_D3 (rwx) : ORIGIN = 0x38000000, LENGTH = 64K
|
||||
AXISRAM (rwx) : ORIGIN = 0x24000000, LENGTH = 512K
|
||||
SRAM1 (rwx) : ORIGIN = 0x30000000, LENGTH = 128K
|
||||
SRAM2 (rwx) : ORIGIN = 0x30020000, LENGTH = 128K
|
||||
SRAM3 (rwx) : ORIGIN = 0x30040000, LENGTH = 32K
|
||||
BACKUPSRAM (rwx) : ORIGIN = 0x38000000, LENGTH = 64K
|
||||
RAM_B (rwx) : ORIGIN = 0x38800000, LENGTH = 4K
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
|
||||
FLASH1 (rx) : ORIGIN = 0x08100000, LENGTH = 1024K
|
||||
|
@ -14,5 +16,17 @@ SECTIONS {
|
|||
.sram1 (NOLOAD) : ALIGN(4) {
|
||||
*(.sram1);
|
||||
. = ALIGN(4);
|
||||
} > RAM_D2
|
||||
} > SRAM1
|
||||
.sram2 (NOLOAD) : ALIGN(4) {
|
||||
*(.sram2);
|
||||
. = ALIGN(4);
|
||||
} > SRAM2
|
||||
.sram3 (NOLOAD) : ALIGN(4) {
|
||||
*(.sram3);
|
||||
. = ALIGN(4);
|
||||
} > SRAM3
|
||||
.axisram (NOLOAD) : ALIGN(8) {
|
||||
*(.axisram);
|
||||
. = ALIGN(8);
|
||||
} > AXISRAM
|
||||
} INSERT AFTER .bss;
|
||||
|
|
|
@ -0,0 +1,611 @@
|
|||
use core::{slice, cmp};
|
||||
use cortex_m;
|
||||
use stm32h7::stm32h7x3 as stm32;
|
||||
use smoltcp::Result;
|
||||
use smoltcp::time::Instant;
|
||||
use smoltcp::wire::EthernetAddress;
|
||||
use smoltcp::phy;
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod phy_consts {
|
||||
pub const PHY_REG_BCR: u8 = 0x00;
|
||||
pub const PHY_REG_BSR: u8 = 0x01;
|
||||
pub const PHY_REG_ID1: u8 = 0x02;
|
||||
pub const PHY_REG_ID2: u8 = 0x03;
|
||||
pub const PHY_REG_ANTX: u8 = 0x04;
|
||||
pub const PHY_REG_ANRX: u8 = 0x05;
|
||||
pub const PHY_REG_ANEXP: u8 = 0x06;
|
||||
pub const PHY_REG_ANNPTX: u8 = 0x07;
|
||||
pub const PHY_REG_ANNPRX: u8 = 0x08;
|
||||
pub const PHY_REG_SSR: u8 = 0x1F; // Special Status Register
|
||||
pub const PHY_REG_CTL: u8 = 0x0D; // Ethernet PHY Register Control
|
||||
pub const PHY_REG_ADDAR: u8 = 0x0E; // Ethernet PHY Address or Data
|
||||
|
||||
pub const PHY_REG_WUCSR: u16 = 08010;
|
||||
|
||||
pub const PHY_REG_BCR_COLTEST: u16 = 1 << 7;
|
||||
pub const PHY_REG_BCR_FD: u16 = 1 << 8;
|
||||
pub const PHY_REG_BCR_ANRST: u16 = 1 << 9;
|
||||
pub const PHY_REG_BCR_ISOLATE: u16 = 1 << 10;
|
||||
pub const PHY_REG_BCR_POWERDN: u16 = 1 << 11;
|
||||
pub const PHY_REG_BCR_AN: u16 = 1 << 12;
|
||||
pub const PHY_REG_BCR_100M: u16 = 1 << 13;
|
||||
pub const PHY_REG_BCR_LOOPBACK: u16 = 1 << 14;
|
||||
pub const PHY_REG_BCR_RESET: u16 = 1 << 15;
|
||||
|
||||
pub const PHY_REG_BSR_JABBER: u16 = 1 << 1;
|
||||
pub const PHY_REG_BSR_UP: u16 = 1 << 2;
|
||||
pub const PHY_REG_BSR_FAULT: u16 = 1 << 4;
|
||||
pub const PHY_REG_BSR_ANDONE: u16 = 1 << 5;
|
||||
|
||||
pub const PHY_REG_SSR_ANDONE: u16 = 1 << 12;
|
||||
pub const PHY_REG_SSR_SPEED: u16 = 0b111 << 2;
|
||||
pub const PHY_REG_SSR_10BASE_HD: u16 = 0b001 << 2;
|
||||
pub const PHY_REG_SSR_10BASE_FD: u16 = 0b101 << 2;
|
||||
pub const PHY_REG_SSR_100BASE_HD: u16 = 0b010 << 2;
|
||||
pub const PHY_REG_SSR_100BASE_FD: u16 = 0b110 << 2;
|
||||
}
|
||||
use self::phy_consts::*;
|
||||
|
||||
pub const MTU: usize = 1522;
|
||||
|
||||
const EMAC_DES3_OWN: u32 = 0x80000000;
|
||||
const EMAC_DES3_CTXT: u32 = 0x40000000;
|
||||
const EMAC_DES3_FD: u32 = 0x20000000;
|
||||
const EMAC_DES3_LD: u32 = 0x10000000;
|
||||
const EMAC_DES3_ES: u32 = 0x00008000;
|
||||
const EMAC_TDES2_IOC: u32 = 0x80000000;
|
||||
const EMAC_RDES3_IOC: u32 = 0x40000000;
|
||||
const EMAC_RDES3_PL: u32 = 0x00007FFF;
|
||||
const EMAC_RDES3_BUF1V: u32 = 0x01000000;
|
||||
const EMAC_TDES2_B1L: u32 = 0x00003FFF;
|
||||
const EMAC_DES0_BUF1AP: u32 = 0xFFFFFFFF;
|
||||
|
||||
const ETH_DESC_U32_SIZE: usize = 4;
|
||||
const ETH_TX_BUFFER_COUNT: usize = 4;
|
||||
const ETH_TX_BUFFER_SIZE: usize = 1536;
|
||||
const ETH_RX_BUFFER_COUNT: usize = 4;
|
||||
const ETH_RX_BUFFER_SIZE: usize = 1536;
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod cr_consts {
|
||||
/* For HCLK 60-100 MHz */
|
||||
pub const ETH_MACMIIAR_CR_HCLK_DIV_42: u8 = 0;
|
||||
/* For HCLK 100-150 MHz */
|
||||
pub const ETH_MACMIIAR_CR_HCLK_DIV_62: u8 = 1;
|
||||
/* For HCLK 20-35 MHz */
|
||||
pub const ETH_MACMIIAR_CR_HCLK_DIV_16: u8 = 2;
|
||||
/* For HCLK 35-60 MHz */
|
||||
pub const ETH_MACMIIAR_CR_HCLK_DIV_26: u8 = 3;
|
||||
/* For HCLK 150-250 MHz */
|
||||
pub const ETH_MACMIIAR_CR_HCLK_DIV_102: u8 = 4;
|
||||
/* For HCLK 250-300 MHz */
|
||||
pub const ETH_MACMIIAR_CR_HCLK_DIV_124: u8 = 5;
|
||||
}
|
||||
use self::cr_consts::*;
|
||||
|
||||
// set clock range in MAC MII address register
|
||||
// 200 MHz AHB clock = eth_hclk
|
||||
const CLOCK_RANGE: u8 = ETH_MACMIIAR_CR_HCLK_DIV_102;
|
||||
|
||||
|
||||
pub fn setup(rcc: &stm32::RCC, syscfg: &stm32::SYSCFG) {
|
||||
rcc.apb4enr.modify(|_, w| w.syscfgen().set_bit());
|
||||
rcc.ahb1enr.modify(|_, w| {
|
||||
w.eth1macen().set_bit()
|
||||
.eth1txen().set_bit()
|
||||
.eth1rxen().set_bit()
|
||||
});
|
||||
syscfg.pmcr.modify(|_, w| unsafe { w.epis().bits(0b100) }); // RMII
|
||||
//rcc.ahb1rstr.modify(|_, w| w.eth1macrst().set_bit());
|
||||
//rcc.ahb1rstr.modify(|_, w| w.eth1macrst().clear_bit());
|
||||
}
|
||||
|
||||
pub fn setup_pins(gpioa: &stm32::GPIOA, gpiob: &stm32::GPIOB,
|
||||
gpioc: &stm32::GPIOC, gpiog: &stm32::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) -> u16 {
|
||||
cortex_m::interrupt::free(|_cs| {
|
||||
let mac = unsafe { &*stm32::ETHERNET_MAC::ptr() };
|
||||
|
||||
while mac.macmdioar.read().mb().bit_is_set() {}
|
||||
mac.macmdioar.modify(|_, w| unsafe {
|
||||
w
|
||||
.pa().bits(PHY_ADDR)
|
||||
.rda().bits(reg_addr)
|
||||
.goc().bits(0b11) // read
|
||||
.cr().bits(CLOCK_RANGE)
|
||||
.mb().set_bit()
|
||||
});
|
||||
while mac.macmdioar.read().mb().bit_is_set() {}
|
||||
mac.macmdiodr.read().md().bits()
|
||||
})
|
||||
}
|
||||
|
||||
fn phy_write(reg_addr: u8, reg_data: u16) {
|
||||
cortex_m::interrupt::free(|_cs| {
|
||||
let mac = unsafe { &*stm32::ETHERNET_MAC::ptr() };
|
||||
|
||||
while mac.macmdioar.read().mb().bit_is_set() {}
|
||||
mac.macmdiodr.write(|w| unsafe { w.md().bits(reg_data) });
|
||||
mac.macmdioar.modify(|_, w| unsafe {
|
||||
w
|
||||
.pa().bits(PHY_ADDR)
|
||||
.rda().bits(reg_addr)
|
||||
.goc().bits(0b01) // read
|
||||
.cr().bits(CLOCK_RANGE)
|
||||
.mb().set_bit()
|
||||
});
|
||||
while mac.macmdioar.read().mb().bit_is_set() {}
|
||||
})
|
||||
}
|
||||
|
||||
// Writes a value to an extended PHY register in MMD address space
|
||||
fn phy_write_ext(reg_addr: u16, reg_data: u16) {
|
||||
phy_write(PHY_REG_CTL, 0x0003); // set address
|
||||
phy_write(PHY_REG_ADDAR, reg_addr);
|
||||
phy_write(PHY_REG_CTL, 0x4003); // set data
|
||||
phy_write(PHY_REG_ADDAR, reg_data);
|
||||
}
|
||||
|
||||
#[repr(align(4))]
|
||||
struct RxRing {
|
||||
desc_buf: [[u32; ETH_DESC_U32_SIZE]; ETH_RX_BUFFER_COUNT],
|
||||
pkt_buf: [[u8; ETH_RX_BUFFER_SIZE]; ETH_RX_BUFFER_COUNT],
|
||||
cur_desc: usize,
|
||||
counter: u32,
|
||||
}
|
||||
|
||||
impl RxRing {
|
||||
const fn new() -> Self {
|
||||
Self {
|
||||
desc_buf: [[0; ETH_DESC_U32_SIZE]; ETH_RX_BUFFER_COUNT],
|
||||
pkt_buf: [[0; ETH_RX_BUFFER_SIZE]; ETH_RX_BUFFER_COUNT],
|
||||
cur_desc: 0,
|
||||
counter: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn init(&mut self) {
|
||||
for i in 0..self.desc_buf.len() {
|
||||
for j in 0..self.desc_buf[0].len() {
|
||||
self.desc_buf[i][j] = 0;
|
||||
}
|
||||
for j in 0..self.pkt_buf[0].len() {
|
||||
self.pkt_buf[i][j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cortex_m::interrupt::free(|_cs| unsafe {
|
||||
let dma = &*stm32::ETHERNET_DMA::ptr();
|
||||
|
||||
dma.dmacrx_dlar.write(|w| {
|
||||
w.bits(&self.desc_buf as *const _ as u32)
|
||||
});
|
||||
|
||||
dma.dmacrx_rlr.write(|w| {
|
||||
w.rdrl().bits(self.desc_buf.len() as u16 - 1) // FIXME: unclear
|
||||
});
|
||||
});
|
||||
|
||||
self.cur_desc = 0;
|
||||
for _ in 0..self.desc_buf.len() {
|
||||
self.buf_release()
|
||||
}
|
||||
self.counter = 0;
|
||||
}
|
||||
|
||||
fn next_desc(&self) -> usize {
|
||||
(self.cur_desc + 1) % self.desc_buf.len()
|
||||
}
|
||||
|
||||
// not owned by DMA
|
||||
fn buf_owned(&self) -> bool {
|
||||
self.desc_buf[self.cur_desc][3] & EMAC_DES3_OWN == 0
|
||||
}
|
||||
|
||||
fn buf_valid(&self) -> bool {
|
||||
self.desc_buf[self.cur_desc][3] &
|
||||
(EMAC_DES3_FD | EMAC_DES3_LD | EMAC_DES3_ES | EMAC_DES3_CTXT) ==
|
||||
(EMAC_DES3_FD | EMAC_DES3_LD)
|
||||
}
|
||||
|
||||
unsafe fn buf_as_slice<'a>(&self) -> &'a [u8] {
|
||||
let len = (self.desc_buf[self.cur_desc][3] & EMAC_RDES3_PL) as usize;
|
||||
let len = cmp::min(len, ETH_RX_BUFFER_SIZE);
|
||||
let addr = &self.pkt_buf[self.cur_desc] as *const u8;
|
||||
slice::from_raw_parts(addr, len)
|
||||
}
|
||||
|
||||
fn buf_release(&mut self) {
|
||||
let addr = &self.pkt_buf[self.cur_desc] as *const _;
|
||||
self.desc_buf[self.cur_desc][0] = addr as u32 & EMAC_DES0_BUF1AP;
|
||||
self.desc_buf[self.cur_desc][3] = EMAC_RDES3_BUF1V | EMAC_RDES3_IOC | EMAC_DES3_OWN;
|
||||
|
||||
let addr = &self.desc_buf[self.cur_desc] as *const _;
|
||||
cortex_m::interrupt::free(|_cs| {
|
||||
let dma = unsafe { &*stm32::ETHERNET_DMA::ptr() };
|
||||
dma.dmacrx_dtpr.write(|w| unsafe { w.bits(addr as u32) });
|
||||
});
|
||||
|
||||
self.cur_desc = self.next_desc();
|
||||
self.counter += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(align(4))]
|
||||
struct TxRing {
|
||||
desc_buf: [[u32; ETH_DESC_U32_SIZE]; ETH_TX_BUFFER_COUNT],
|
||||
pkt_buf: [[u8; ETH_TX_BUFFER_SIZE]; ETH_TX_BUFFER_COUNT],
|
||||
cur_desc: usize,
|
||||
counter: u32,
|
||||
}
|
||||
|
||||
impl TxRing {
|
||||
const fn new() -> Self {
|
||||
Self {
|
||||
desc_buf: [[0; ETH_DESC_U32_SIZE]; ETH_TX_BUFFER_COUNT],
|
||||
pkt_buf: [[0; ETH_TX_BUFFER_SIZE]; ETH_TX_BUFFER_COUNT],
|
||||
cur_desc: 0,
|
||||
counter: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn init(&mut self) {
|
||||
for i in 0..self.desc_buf.len() {
|
||||
for j in 0..self.desc_buf[0].len() {
|
||||
self.desc_buf[i][j] = 0;
|
||||
}
|
||||
for j in 0..self.pkt_buf[0].len() {
|
||||
self.pkt_buf[i][j] = 0;
|
||||
}
|
||||
}
|
||||
self.cur_desc = 0;
|
||||
self.counter = 0;
|
||||
|
||||
cortex_m::interrupt::free(|_cs| unsafe {
|
||||
let dma = &*stm32::ETHERNET_DMA::ptr();
|
||||
|
||||
dma.dmactx_dlar.write(|w| {
|
||||
w.bits(&self.desc_buf as *const _ as u32)
|
||||
});
|
||||
|
||||
dma.dmactx_rlr.write(|w| {
|
||||
w.tdrl().bits(self.desc_buf.len() as u16 - 1) // FIXME: unclear
|
||||
});
|
||||
|
||||
dma.dmactx_dtpr.write(|w| {
|
||||
w.bits(&self.desc_buf[0] as *const _ as u32)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn next_desc(&self) -> usize {
|
||||
(self.cur_desc + 1) % self.desc_buf.len()
|
||||
}
|
||||
|
||||
// not owned by DMA
|
||||
fn buf_owned(&self) -> bool {
|
||||
self.desc_buf[self.cur_desc][3] & EMAC_DES3_OWN == 0
|
||||
}
|
||||
|
||||
unsafe fn buf_as_slice_mut<'a>(&mut self, len: usize) -> &'a mut [u8] {
|
||||
let len = cmp::min(len, ETH_TX_BUFFER_SIZE);
|
||||
self.desc_buf[self.cur_desc][2] = EMAC_TDES2_IOC | (len as u32 & EMAC_TDES2_B1L);
|
||||
let addr = &self.pkt_buf[self.cur_desc] as *const _ as *mut u8;
|
||||
self.desc_buf[self.cur_desc][0] = addr as u32 & EMAC_DES0_BUF1AP;
|
||||
slice::from_raw_parts_mut(addr, len)
|
||||
}
|
||||
|
||||
fn buf_release(&mut self) {
|
||||
self.desc_buf[self.cur_desc][3] = EMAC_DES3_OWN | EMAC_DES3_FD | EMAC_DES3_LD;
|
||||
self.cur_desc = self.next_desc();
|
||||
self.counter += 1;
|
||||
|
||||
let addr = &self.desc_buf[self.cur_desc] as *const _;
|
||||
cortex_m::interrupt::free(|_cs| {
|
||||
let dma = unsafe { &*stm32::ETHERNET_DMA::ptr() };
|
||||
dma.dmactx_dtpr.write(|w| unsafe { w.bits(addr as u32) });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Device {
|
||||
rx: RxRing,
|
||||
tx: TxRing,
|
||||
}
|
||||
|
||||
impl Device {
|
||||
pub const fn new() -> Self {
|
||||
Self{ rx: RxRing::new(), tx: TxRing::new() }
|
||||
}
|
||||
|
||||
// After `init` is called, `Device` shall not be moved.
|
||||
pub unsafe fn init(&mut self, mac: EthernetAddress) {
|
||||
cortex_m::interrupt::free(|_cs| {
|
||||
let eth_mac = &*stm32::ETHERNET_MAC::ptr();
|
||||
let eth_dma = &*stm32::ETHERNET_DMA::ptr();
|
||||
let _eth_mmc = &*stm32::ETHERNET_MMC::ptr();
|
||||
let eth_mtl = &*stm32::ETHERNET_MTL::ptr();
|
||||
|
||||
eth_dma.dmamr.modify(|_, w| w.swr().set_bit());
|
||||
while eth_dma.dmamr.read().swr().bit_is_set() {}
|
||||
|
||||
// 200 MHz
|
||||
eth_mac.mac1ustcr.modify(|_, w| w.tic_1us_cntr().bits(200 - 1));
|
||||
|
||||
// Configuration Register
|
||||
eth_mac.maccr.modify(|_, w| {
|
||||
w
|
||||
.arpen().clear_bit()
|
||||
.ipc().set_bit()
|
||||
.ipg().bits(0b000) // 96 bit
|
||||
.ecrsfd().clear_bit()
|
||||
.dcrs().clear_bit()
|
||||
.bl().bits(0b00) // 19
|
||||
.prelen().bits(0b00) // 7
|
||||
// CRC stripping for Type frames
|
||||
.cst().set_bit()
|
||||
// Fast Ethernet speed
|
||||
.fes().set_bit()
|
||||
// Duplex mode
|
||||
.dm().set_bit()
|
||||
// Automatic pad/CRC stripping
|
||||
.acs().set_bit()
|
||||
// Retry disable in half-duplex mode
|
||||
.dr().set_bit()
|
||||
});
|
||||
eth_mac.macecr.modify(|_, w| {
|
||||
w
|
||||
.eipgen().clear_bit()
|
||||
.usp().clear_bit()
|
||||
.spen().clear_bit()
|
||||
.dcrcc().clear_bit()
|
||||
});
|
||||
// Set the MAC address
|
||||
eth_mac.maca0lr.write(|w|
|
||||
w.addrlo().bits( mac.0[0] as u32 |
|
||||
((mac.0[1] as u32) << 8) |
|
||||
((mac.0[2] as u32) << 16) |
|
||||
((mac.0[3] as u32) << 24))
|
||||
);
|
||||
eth_mac.maca0hr.write(|w|
|
||||
w.addrhi().bits( mac.0[4] as u16 |
|
||||
((mac.0[5] as u16) << 8))
|
||||
//.ae().set_bit()
|
||||
//.sa().clear_bit()
|
||||
//.mbc().bits(0b000000)
|
||||
);
|
||||
// frame filter register
|
||||
eth_mac.macpfr.modify(|_, w| {
|
||||
w
|
||||
.dntu().clear_bit()
|
||||
.ipfe().clear_bit()
|
||||
.vtfe().clear_bit()
|
||||
.hpf().clear_bit()
|
||||
.saf().clear_bit()
|
||||
.saif().clear_bit()
|
||||
.pcf().bits(0b00)
|
||||
.dbf().clear_bit()
|
||||
.pm().clear_bit()
|
||||
.daif().clear_bit()
|
||||
.hmc().clear_bit()
|
||||
.huc().clear_bit()
|
||||
// Receive All
|
||||
.ra().clear_bit()
|
||||
// Promiscuous mode
|
||||
.pr().clear_bit()
|
||||
});
|
||||
eth_mac.macwtr.write(|w| w.pwe().clear_bit());
|
||||
// Flow Control Register
|
||||
eth_mac.macqtxfcr.modify(|_, w| {
|
||||
// Pause time
|
||||
w.pt().bits(0x100)
|
||||
});
|
||||
eth_mac.macrxfcr.modify(|_, w| w);
|
||||
eth_mtl.mtlrxqomr.modify(|_, w|
|
||||
w
|
||||
// Receive store and forward
|
||||
.rsf().set_bit()
|
||||
// Dropping of TCP/IP checksum error frames disable
|
||||
.dis_tcp_ef().clear_bit()
|
||||
// Forward error frames
|
||||
.fep().clear_bit()
|
||||
// Forward undersized good packets
|
||||
.fup().clear_bit()
|
||||
);
|
||||
eth_mtl.mtltxqomr.modify(|_, w| {
|
||||
w
|
||||
// Transmit store and forward
|
||||
.tsf().set_bit()
|
||||
});
|
||||
|
||||
if (phy_read(PHY_REG_ID1) != 0x0007) | (phy_read(PHY_REG_ID2) != 0xC131) {
|
||||
error!("PHY ID error!");
|
||||
}
|
||||
|
||||
phy_write(PHY_REG_BCR, PHY_REG_BCR_RESET);
|
||||
while phy_read(PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {};
|
||||
phy_write_ext(PHY_REG_WUCSR, 0);
|
||||
phy_write(PHY_REG_BCR, PHY_REG_BCR_AN | PHY_REG_BCR_ANRST | PHY_REG_BCR_100M);
|
||||
/*
|
||||
while phy_read(PHY_REG_BSR) & PHY_REG_BSR_UP == 0 {};
|
||||
while phy_read(PHY_REG_BSR) & PHY_REG_BSR_ANDONE == 0 {};
|
||||
while phy_read(PHY_REG_SSR) & (PHY_REG_SSR_ANDONE | PHY_REG_SSR_SPEED)
|
||||
!= PHY_REG_SSR_ANDONE | PHY_REG_SSR_100BASE_FD {};
|
||||
*/
|
||||
|
||||
// operation mode register
|
||||
eth_dma.dmamr.modify(|_, w| {
|
||||
w
|
||||
.intm().clear_bit() // FIXME: bits(0b00)
|
||||
// Rx Tx priority ratio 1:1
|
||||
.pr().bits(0b000)
|
||||
.txpr().clear_bit()
|
||||
.da().clear_bit()
|
||||
});
|
||||
// bus mode register
|
||||
eth_dma.dmasbmr.modify(|_, w| {
|
||||
// Address-aligned beats
|
||||
w.aal().set_bit()
|
||||
// Fixed burst
|
||||
.fb().set_bit()
|
||||
});
|
||||
eth_dma.dmaccr.modify(|_, w| {
|
||||
w
|
||||
.dsl().bits(0)
|
||||
.pblx8().clear_bit()
|
||||
.mss().bits(536)
|
||||
});
|
||||
eth_dma.dmactx_cr.modify(|_, w| {
|
||||
w
|
||||
// Tx DMA PBL
|
||||
.txpbl().bits(32)
|
||||
.tse().clear_bit()
|
||||
// Operate on second frame
|
||||
.osf().clear_bit()
|
||||
});
|
||||
|
||||
eth_dma.dmacrx_cr.modify(|_, w| {
|
||||
w
|
||||
// receive buffer size
|
||||
.rbsz().bits(MTU as u16)
|
||||
// Rx DMA PBL
|
||||
.rxpbl().bits(32)
|
||||
// Disable flushing of received frames
|
||||
.rpf().clear_bit()
|
||||
});
|
||||
|
||||
self.rx.init();
|
||||
self.tx.init();
|
||||
|
||||
// Manage MAC transmission and reception
|
||||
eth_mac.maccr.modify(|_, w| {
|
||||
w.re().bit(true) // Receiver Enable
|
||||
.te().bit(true) // Transmiter Enable
|
||||
});
|
||||
eth_mtl.mtltxqomr.modify(|_, w| w.ftq().set_bit());
|
||||
|
||||
// Manage DMA transmission and reception
|
||||
eth_dma.dmactx_cr.modify(|_, w| w.st().set_bit());
|
||||
eth_dma.dmacrx_cr.modify(|_, w| w.sr().set_bit());
|
||||
|
||||
eth_dma.dmacsr.modify(|_, w|
|
||||
w.tps().set_bit()
|
||||
.rps().set_bit()
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> phy::Device<'a> for &'b mut Device {
|
||||
type RxToken = RxToken<'a>;
|
||||
type TxToken = TxToken<'a>;
|
||||
|
||||
fn capabilities(&self) -> phy::DeviceCapabilities {
|
||||
let mut capabilities = phy::DeviceCapabilities::default();
|
||||
capabilities.max_transmission_unit = 1500;
|
||||
capabilities.max_burst_size = Some(self.tx.desc_buf.len());
|
||||
capabilities
|
||||
}
|
||||
|
||||
fn receive(&mut self) -> Option<(RxToken, TxToken)> {
|
||||
// Skip all queued packets with errors.
|
||||
while self.rx.buf_owned() && !self.rx.buf_valid() {
|
||||
self.rx.buf_release()
|
||||
}
|
||||
|
||||
if !(self.rx.buf_owned() && self.tx.buf_owned()) {
|
||||
return None
|
||||
}
|
||||
|
||||
Some((RxToken(&mut self.rx), TxToken(&mut self.tx)))
|
||||
}
|
||||
|
||||
fn transmit(&mut self) -> Option<TxToken> {
|
||||
if !self.tx.buf_owned() {
|
||||
return None
|
||||
}
|
||||
|
||||
Some(TxToken(&mut self.tx))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RxToken<'a>(&'a mut RxRing);
|
||||
|
||||
impl<'a> phy::RxToken for RxToken<'a> {
|
||||
fn consume<R, F>(self, _timestamp: Instant, f: F) -> Result<R>
|
||||
where F: FnOnce(&[u8]) -> Result<R> {
|
||||
let result = f(unsafe { self.0.buf_as_slice() });
|
||||
self.0.buf_release();
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TxToken<'a>(&'a mut TxRing);
|
||||
|
||||
impl<'a> phy::TxToken for TxToken<'a> {
|
||||
fn consume<R, F>(self, _timestamp: Instant, len: usize, f: F) -> Result<R>
|
||||
where F: FnOnce(&mut [u8]) -> Result<R> {
|
||||
let result = f(unsafe { self.0.buf_as_slice_mut(len) });
|
||||
self.0.buf_release();
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eth_interrupt_handler(eth_dma: &stm32::ETHERNET_DMA) {
|
||||
eth_dma.dmacsr.write(|w|
|
||||
w
|
||||
.nis().set_bit()
|
||||
.ri().set_bit()
|
||||
.ti().set_bit()
|
||||
);
|
||||
}
|
||||
|
||||
pub fn enable_interrupt(dma: &stm32::ETHERNET_DMA) {
|
||||
dma.dmacier.modify(|_, w|
|
||||
w
|
||||
.nie().set_bit()
|
||||
.rie().set_bit()
|
||||
.tie().set_bit()
|
||||
);
|
||||
}
|
133
src/main.rs
133
src/main.rs
|
@ -14,10 +14,15 @@ extern crate log;
|
|||
|
||||
use core::ptr;
|
||||
use core::cell::RefCell;
|
||||
use core::fmt::Write;
|
||||
use cortex_m_rt::{entry, exception};
|
||||
use stm32h7::stm32h7x3::{self as stm32, Peripherals, CorePeripherals, interrupt};
|
||||
use cortex_m::interrupt::Mutex;
|
||||
|
||||
use smoltcp as net;
|
||||
|
||||
mod eth;
|
||||
|
||||
mod iir;
|
||||
use iir::*;
|
||||
|
||||
|
@ -49,14 +54,14 @@ mod build_info {
|
|||
|
||||
fn pwr_setup(pwr: &stm32::PWR) {
|
||||
// go to VOS1 voltage scale for high perf
|
||||
pwr.pwr_cr3.write(|w|
|
||||
pwr.cr3.write(|w|
|
||||
w.sden().set_bit()
|
||||
.ldoen().set_bit()
|
||||
.bypass().clear_bit()
|
||||
);
|
||||
while pwr.pwr_csr1.read().actvosrdy().bit_is_clear() {}
|
||||
pwr.pwr_d3cr.write(|w| unsafe { w.vos().bits(0b11) }); // vos1
|
||||
while pwr.pwr_d3cr.read().vosrdy().bit_is_clear() {}
|
||||
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: &stm32::RCC) {
|
||||
|
@ -327,7 +332,7 @@ fn gpio_setup(gpioa: &stm32::GPIOA, gpiob: &stm32::GPIOB, gpiod: &stm32::GPIOD,
|
|||
|
||||
// ADC0
|
||||
fn spi1_setup(spi1: &stm32::SPI1) {
|
||||
spi1.cfg1.modify(|_, w| unsafe {
|
||||
spi1.cfg1.modify(|_, w| {
|
||||
w.mbr().bits(1) // clk/4
|
||||
.dsize().bits(16 - 1)
|
||||
.fthvl().bits(1 - 1) // one data
|
||||
|
@ -348,7 +353,7 @@ fn spi1_setup(spi1: &stm32::SPI1) {
|
|||
.midi().bits(0) // master inter data idle
|
||||
.mssi().bits(6) // master SS idle
|
||||
});
|
||||
spi1.cr2.modify(|_, w| unsafe {
|
||||
spi1.cr2.modify(|_, w| {
|
||||
w.tsize().bits(1)
|
||||
});
|
||||
spi1.cr1.write(|w| w.spe().set_bit());
|
||||
|
@ -356,7 +361,7 @@ fn spi1_setup(spi1: &stm32::SPI1) {
|
|||
|
||||
// ADC1
|
||||
fn spi5_setup(spi5: &stm32::SPI5) {
|
||||
spi5.cfg1.modify(|_, w| unsafe {
|
||||
spi5.cfg1.modify(|_, w| {
|
||||
w.mbr().bits(1) // clk/4
|
||||
.dsize().bits(16 - 1)
|
||||
.fthvl().bits(1 - 1) // one data
|
||||
|
@ -377,7 +382,7 @@ fn spi5_setup(spi5: &stm32::SPI5) {
|
|||
.midi().bits(0) // master inter data idle
|
||||
.mssi().bits(6) // master SS idle
|
||||
});
|
||||
spi5.cr2.modify(|_, w| unsafe {
|
||||
spi5.cr2.modify(|_, w| {
|
||||
w.tsize().bits(1)
|
||||
});
|
||||
spi5.cr1.write(|w| w.spe().set_bit());
|
||||
|
@ -385,7 +390,7 @@ fn spi5_setup(spi5: &stm32::SPI5) {
|
|||
|
||||
// DAC0
|
||||
fn spi2_setup(spi2: &stm32::SPI2) {
|
||||
spi2.cfg1.modify(|_, w| unsafe {
|
||||
spi2.cfg1.modify(|_, w| {
|
||||
w.mbr().bits(0) // clk/2
|
||||
.dsize().bits(16 - 1)
|
||||
.fthvl().bits(1 - 1) // one data
|
||||
|
@ -406,7 +411,7 @@ fn spi2_setup(spi2: &stm32::SPI2) {
|
|||
.midi().bits(0) // master inter data idle
|
||||
.mssi().bits(0) // master SS idle
|
||||
});
|
||||
spi2.cr2.modify(|_, w| unsafe {
|
||||
spi2.cr2.modify(|_, w| {
|
||||
w.tsize().bits(0)
|
||||
});
|
||||
spi2.cr1.write(|w| w.spe().set_bit());
|
||||
|
@ -415,7 +420,7 @@ fn spi2_setup(spi2: &stm32::SPI2) {
|
|||
|
||||
// DAC1
|
||||
fn spi4_setup(spi4: &stm32::SPI4) {
|
||||
spi4.cfg1.modify(|_, w| unsafe {
|
||||
spi4.cfg1.modify(|_, w| {
|
||||
w.mbr().bits(0) // clk/2
|
||||
.dsize().bits(16 - 1)
|
||||
.fthvl().bits(1 - 1) // one data
|
||||
|
@ -436,7 +441,7 @@ fn spi4_setup(spi4: &stm32::SPI4) {
|
|||
.midi().bits(0) // master inter data idle
|
||||
.mssi().bits(0) // master SS idle
|
||||
});
|
||||
spi4.cr2.modify(|_, w| unsafe {
|
||||
spi4.cr2.modify(|_, w| {
|
||||
w.tsize().bits(0)
|
||||
});
|
||||
spi4.cr1.write(|w| w.spe().set_bit());
|
||||
|
@ -460,7 +465,7 @@ fn dma1_setup(dma1: &stm32::DMA1, dmamux1: &stm32::DMAMUX1, ma: usize, pa0: usiz
|
|||
dma1.s0par.write(|w| unsafe { w.pa().bits(pa0 as u32) });
|
||||
dma1.s0m0ar.write(|w| unsafe { w.m0a().bits(ma as u32) });
|
||||
dma1.s0ndtr.write(|w| unsafe { w.ndt().bits(1) });
|
||||
dmamux1.dmamux1_c0cr.modify(|_, w| unsafe { w.dmareq_id().bits(22) }); // tim2_up
|
||||
dmamux1.ccr[0].modify(|_, w| unsafe { w.dmareq_id().bits(22) }); // tim2_up
|
||||
dma1.s0cr.modify(|_, w| unsafe {
|
||||
w.pl().bits(0b01) // medium
|
||||
.circ().set_bit() // reload ndtr
|
||||
|
@ -483,7 +488,7 @@ fn dma1_setup(dma1: &stm32::DMA1, dmamux1: &stm32::DMAMUX1, ma: usize, pa0: usiz
|
|||
dma1.s1par.write(|w| unsafe { w.pa().bits(pa1 as u32) });
|
||||
dma1.s1m0ar.write(|w| unsafe { w.m0a().bits(ma as u32) });
|
||||
dma1.s1ndtr.write(|w| unsafe { w.ndt().bits(1) });
|
||||
dmamux1.dmamux1_c1cr.modify(|_, w| unsafe { w.dmareq_id().bits(22) }); // tim2_up
|
||||
dmamux1.ccr[1].modify(|_, w| unsafe { w.dmareq_id().bits(22) }); // tim2_up
|
||||
dma1.s1cr.modify(|_, w| unsafe {
|
||||
w.pl().bits(0b01) // medium
|
||||
.circ().set_bit() // reload ndtr
|
||||
|
@ -499,7 +504,6 @@ fn dma1_setup(dma1: &stm32::DMA1, dmamux1: &stm32::DMAMUX1, ma: usize, pa0: usiz
|
|||
});
|
||||
dma1.s1fcr.modify(|_, w| w.dmdis().clear_bit());
|
||||
dma1.s1cr.modify(|_, w| w.en().set_bit());
|
||||
|
||||
}
|
||||
|
||||
static SPIP: Mutex<RefCell<Option<(
|
||||
|
@ -509,6 +513,26 @@ static SPIP: Mutex<RefCell<Option<(
|
|||
#[link_section = ".sram1"]
|
||||
static mut DAT: u32 = (1 << 9) | (1 << 0);
|
||||
|
||||
static TIME: Mutex<RefCell<i64>> = Mutex::new(RefCell::new(0));
|
||||
|
||||
#[link_section = ".sram3"]
|
||||
static mut ETH: eth::Device = eth::Device::new();
|
||||
|
||||
const TCP_RX_BUFFER_SIZE: usize = 4096;
|
||||
const TCP_TX_BUFFER_SIZE: usize = 4096;
|
||||
|
||||
macro_rules! create_socket {
|
||||
($set:ident, $rx_storage:ident, $tx_storage:ident, $target:ident) => (
|
||||
let mut $rx_storage = [0; TCP_RX_BUFFER_SIZE];
|
||||
let mut $tx_storage = [0; TCP_TX_BUFFER_SIZE];
|
||||
let tcp_rx_buffer = net::socket::TcpSocketBuffer::new(&mut $rx_storage[..]);
|
||||
let tcp_tx_buffer = net::socket::TcpSocketBuffer::new(&mut $tx_storage[..]);
|
||||
let tcp_socket = net::socket::TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer);
|
||||
let $target = $set.add(tcp_socket);
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let mut cp = CorePeripherals::take().unwrap();
|
||||
|
@ -527,13 +551,22 @@ fn main() -> ! {
|
|||
rcc.apb4enr.modify(|_, w| w.syscfgen().set_bit());
|
||||
io_compensation_setup(&dp.SYSCFG);
|
||||
|
||||
// 100 MHz
|
||||
cp.SYST.set_clock_source(cortex_m::peripheral::syst::SystClkSource::Core);
|
||||
cp.SYST.set_reload(cortex_m::peripheral::SYST::get_ticks_per_10ms()*200/10);
|
||||
cp.SYST.enable_counter();
|
||||
cp.SYST.enable_interrupt();
|
||||
unsafe { cp.SCB.shpr[11].write(128); } // systick exception priority
|
||||
|
||||
cp.SCB.enable_icache();
|
||||
cp.SCB.enable_dcache(&mut cp.CPUID);
|
||||
// TODO: ETH DMA coherence issues
|
||||
// cp.SCB.enable_dcache(&mut cp.CPUID);
|
||||
cp.DWT.enable_cycle_counter();
|
||||
|
||||
rcc.ahb4enr.modify(|_, w|
|
||||
w.gpioaen().set_bit()
|
||||
.gpioben().set_bit()
|
||||
.gpiocen().set_bit()
|
||||
.gpioden().set_bit()
|
||||
.gpioeen().set_bit()
|
||||
.gpiofen().set_bit()
|
||||
|
@ -559,7 +592,12 @@ fn main() -> ! {
|
|||
spi5_setup(&spi5);
|
||||
// spi5.ier.write(|w| w.eotie().set_bit());
|
||||
|
||||
rcc.ahb2enr.modify(|_, w| w.sram1en().set_bit());
|
||||
rcc.ahb2enr.modify(|_, w|
|
||||
w
|
||||
.sram1en().set_bit()
|
||||
.sram2en().set_bit()
|
||||
.sram3en().set_bit()
|
||||
);
|
||||
rcc.ahb1enr.modify(|_, w| w.dma1en().set_bit());
|
||||
unsafe { DAT = (1 << 9) | (1 << 0) }; // init SRAM1 rodata can't load with sram1 disabled
|
||||
cortex_m::asm::dsb();
|
||||
|
@ -589,16 +627,62 @@ fn main() -> ! {
|
|||
IIR_CH[1].get_x_offset().unwrap();
|
||||
}
|
||||
|
||||
unsafe { cp.NVIC.set_priority(stm32::Interrupt::SPI1, 0); } // highest prio
|
||||
cortex_m::interrupt::free(|cs| {
|
||||
cp.NVIC.enable(stm32::Interrupt::SPI1);
|
||||
SPIP.borrow(cs).replace(Some((spi1, spi2, spi4, spi5)));
|
||||
});
|
||||
|
||||
eth::setup(&rcc, &dp.SYSCFG);
|
||||
eth::setup_pins(&dp.GPIOA, &dp.GPIOB, &dp.GPIOC, &dp.GPIOG);
|
||||
|
||||
let device = unsafe { &mut ETH };
|
||||
let hardware_addr = net::wire::EthernetAddress([0x10, 0xE2, 0xD5, 0x00, 0x03, 0x00]);
|
||||
unsafe { device.init(hardware_addr) };
|
||||
let mut neighbor_cache_storage = [None; 8];
|
||||
let neighbor_cache = net::iface::NeighborCache::new(&mut neighbor_cache_storage[..]);
|
||||
let local_addr = net::wire::IpAddress::v4(10, 0, 16, 99);
|
||||
let mut ip_addrs = [net::wire::IpCidr::new(local_addr, 24)];
|
||||
let mut iface = net::iface::EthernetInterfaceBuilder::new(device)
|
||||
.ethernet_addr(hardware_addr)
|
||||
.neighbor_cache(neighbor_cache)
|
||||
.ip_addrs(&mut ip_addrs[..])
|
||||
.finalize();
|
||||
let mut socket_set_entries: [_; 8] = Default::default();
|
||||
let mut sockets = net::socket::SocketSet::new(&mut socket_set_entries[..]);
|
||||
create_socket!(sockets, tcp_rx_storage0, tcp_tx_storage0, tcp_handle0);
|
||||
|
||||
eth::enable_interrupt(&dp.ETHERNET_DMA);
|
||||
unsafe { cp.NVIC.set_priority(stm32::Interrupt::ETH, 196); } // mid prio
|
||||
cp.NVIC.enable(stm32::Interrupt::ETH);
|
||||
|
||||
loop {
|
||||
for _ in 0..1_000_000 { cortex_m::asm::wfi(); }
|
||||
let time = cortex_m::interrupt::free(|cs| *TIME.borrow(cs).borrow());
|
||||
|
||||
{
|
||||
let socket = &mut *sockets.get::<net::socket::TcpSocket>(tcp_handle0);
|
||||
if !socket.is_open() {
|
||||
socket.listen(80).unwrap_or_else(|e| warn!("TCP listen error: {:?}", e));
|
||||
}
|
||||
if socket.can_send() {
|
||||
write!(socket, "hello\n")
|
||||
.map(|_| socket.close())
|
||||
.unwrap_or_else(|e| warn!("TCP send error: {:?}", e));
|
||||
}
|
||||
}
|
||||
|
||||
match iface.poll(&mut sockets, net::time::Instant::from_millis(time)) {
|
||||
Ok(_) => (),
|
||||
Err(e) => info!("iface poll error: {:?}", e)
|
||||
}
|
||||
|
||||
if time % 1000 == 0 {
|
||||
let (x0, y0, x1, y1) = unsafe {
|
||||
(IIR_STATE[0][0], IIR_STATE[0][2], IIR_STATE[1][0], IIR_STATE[1][2]) };
|
||||
info!("x0={} y0={} x1={} y1={}", x0, y0, x1, y1);
|
||||
info!("x0={:.1} y0={:.1} x1={:.1} y1={:.1}", x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
cortex_m::asm::wfi();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -648,6 +732,17 @@ fn SPI1() {
|
|||
cortex_m::asm::bkpt();
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn ETH() {
|
||||
let p = unsafe { Peripherals::steal() };
|
||||
eth::eth_interrupt_handler(&p.ETHERNET_DMA);
|
||||
}
|
||||
|
||||
#[exception]
|
||||
fn SysTick() {
|
||||
cortex_m::interrupt::free(|cs| *TIME.borrow(cs).borrow_mut() += 1);
|
||||
}
|
||||
|
||||
#[exception]
|
||||
fn HardFault(ef: &cortex_m_rt::ExceptionFrame) -> ! {
|
||||
panic!("HardFault at {:#?}", ef);
|
||||
|
|
Loading…
Reference in New Issue