diff --git a/Cargo.lock b/Cargo.lock index 753f995287..3f50e8bd9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -659,9 +659,9 @@ checksum = "f9236877021b66ad90f833d8a73a7acb702b985b64c5986682d9f1f1a184f0fb" [[package]] name = "cortex-m" -version = "0.7.5" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd20d4ac4aa86f4f75f239d59e542ef67de87cce2c282818dc6e84155d3ea126" +checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" dependencies = [ "bare-metal 0.2.5", "bitfield 0.13.2", @@ -671,23 +671,22 @@ dependencies = [ [[package]] name = "cortex-m-rt" -version = "0.6.15" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "454f278bf469e2de0a4d22ea019d169d8944f86957c8207a39e3f66c32be2fc6" +checksum = "801d4dec46b34c299ccf6b036717ae0fce602faa4f4fe816d9013b9a7c9f5ba6" dependencies = [ "cortex-m-rt-macros", - "r0", ] [[package]] name = "cortex-m-rt-macros" -version = "0.6.15" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3aa52243e26f5922fa522b0814019e0c98fc567e2756d715dce7ad7a81f49" +checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" dependencies = [ "proc-macro2", "quote", - "syn 1.0.94", + "syn 2.0.98", ] [[package]] @@ -2257,7 +2256,6 @@ dependencies = [ "derive_more", "drv-caboose", "drv-lpc55-update-api", - "drv-spi-api", "drv-update-api", "dumper-api", "gateway-messages", @@ -3641,9 +3639,9 @@ dependencies = [ [[package]] name = "lpc55-pac" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1b5b32d313af526145882f5115a55177f479e9328ca667a84aaaa1ae6d65d3" +checksum = "3a4952baed9d9e7e82a6bbc87333f939b90eb41df3e6c0be5e35d0ec61005f91" dependencies = [ "cortex-m", "cortex-m-rt", @@ -4449,12 +4447,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "r0" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f" - [[package]] name = "radium" version = "0.7.0" @@ -5131,11 +5123,11 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stm32f3" -version = "0.13.2" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "081e808e6b2114ced6a83437081ed9816c92017eda7722a7c22f80984fb5476a" +checksum = "b28b37228ef3fa47956af38c6abd756e912f244c1657f14e66d42fc8d74ea96f" dependencies = [ - "bare-metal 0.2.5", + "bare-metal 1.0.0", "cortex-m", "cortex-m-rt", "vcell", @@ -5143,11 +5135,11 @@ dependencies = [ [[package]] name = "stm32f4" -version = "0.13.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3d56009c8f32e4f208dbea17df72484154d1040a8969b75d8c73eb7b18fe8f" +checksum = "fb94729242cd1aebe6dab42a2ca0131985ae93bc3ab2751b680df724bb35528d" dependencies = [ - "bare-metal 0.2.5", + "bare-metal 1.0.0", "cortex-m", "cortex-m-rt", "vcell", @@ -5167,9 +5159,9 @@ dependencies = [ [[package]] name = "stm32h7" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0faa648e03579befdd7267ab5c669624729028001fcf3c973832f53e310a06" +checksum = "362f288cd8341e9209587b889c385f323e82fc237b60c272868965bb879bb9b1" dependencies = [ "bare-metal 1.0.0", "cortex-m", diff --git a/Cargo.toml b/Cargo.toml index 9a739c2308..37f790a6fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,7 +63,7 @@ colored = { version = "2.0", default-features = false } convert_case = { version = "0.4", default-features = false } corncobs = { version = "0.1.1", default-features = false } cortex-m = { version = "0.7", default-features = false, features = ["inline-asm"]} -cortex-m-rt = { version = "0.6.12", default-features = false } +cortex-m-rt = { version = "0.7.5", default-features = false } cortex-m-semihosting = { version = "0.5.0", default-features = false } crc = { version = "3.0.0", default-features = false } critical-section = { version = "1.1.2" } @@ -89,7 +89,7 @@ indexmap = { version = "1.4.0", default-features = false, features = ["serde-1"] indoc = { version = "2.0.3", default-features = false } itertools = { version = "0.10.5", default-features = false } leb128 = { version = "0.2.5", default-features = false } -lpc55-pac = { version = "0.4", default-features = false } +lpc55-pac = { version = "0.5", default-features = false } memchr = { version = "2.4", default-features = false } memoffset = { version = "0.6.5", default-features = false } minicbor = { version = "2.1.1", default-features = false } @@ -127,10 +127,10 @@ ssh-key = { version = "0.6.6", default-features = false, features = ["std", "p25 spin = { version = "0.9.4", default-features = false, features = ["mutex", "spin_mutex"]} ssmarshal = { version = "1.0.0", default-features = false } static_assertions = { version = "1", default-features = false } -stm32f3 = { version = "0.13.0", default-features = false } -stm32f4 = { version = "0.13.0", default-features = false } -stm32h7 = { version = "0.14", default-features = false } -stm32g0 = { version = "0.15.1", default-features = false } +stm32f3 = { version = "0.15", default-features = false } +stm32f4 = { version = "0.15", default-features = false } +stm32h7 = { version = "0.15", default-features = false } +stm32g0 = { version = "0.15", default-features = false } strsim = { version = "0.10.0", default-features = false } syn = { version = "2", default-features = false, features = ["derive", "parsing", "proc-macro", "extra-traits", "full", "printing"] } toml = { version = "0.9.6", default-features = false, features = ["parse", "display", "serde", "preserve_order"] } diff --git a/app/cosmo/base.toml b/app/cosmo/base.toml index ccc8debaf9..c4b848861b 100644 --- a/app/cosmo/base.toml +++ b/app/cosmo/base.toml @@ -1389,7 +1389,7 @@ input = {port = "B", pin = 14, af = 5} [config.spi.spi2.devices.spartan7_fpga] mux = "port_b" cs = [] -clock_divider = "DIV8" # 12.5 MHz +clock_divider = "Div8" # 12.5 MHz # no CS pin; we're using the SPI peripheral to send synchronized CLK + DATA # SPI_SP_TO_KSZ8463_SCK @@ -1444,7 +1444,7 @@ input = {port = "J", pin = 11, af = 5} [config.spi.spi5.devices.rot] mux = "port_j" cs = [{port = "K", pin = 1}] -clock_divider = "DIV256" +clock_divider = "Div256" ################################################################################ diff --git a/app/demo-stm32h7-nucleo/app-h743.toml b/app/demo-stm32h7-nucleo/app-h743.toml index 88c9a0a4c6..302a276d1a 100644 --- a/app/demo-stm32h7-nucleo/app-h743.toml +++ b/app/demo-stm32h7-nucleo/app-h743.toml @@ -185,7 +185,7 @@ input = {port = "A", pin = 6, af = 5} # miso [config.spi.spi1.devices.pins] mux = "cn7_arduino" cs = [{port = "D", pin = 14}] -clock_divider = "DIV16" +clock_divider = "Div16" [config.net] diff --git a/app/demo-stm32h7-nucleo/app-h753.toml b/app/demo-stm32h7-nucleo/app-h753.toml index 2bce2264d3..096597c62c 100644 --- a/app/demo-stm32h7-nucleo/app-h753.toml +++ b/app/demo-stm32h7-nucleo/app-h753.toml @@ -233,7 +233,7 @@ input = {port = "A", pin = 6, af = 5} [config.spi.spi1.devices.pins] mux = "cn7_arduino" cs = [{port = "D", pin = 14}] -clock_divider = "DIV32" +clock_divider = "Div32" [config.net] # UDP ports in sockets below are assigned in oxidecomputer/oana diff --git a/app/gemini-bu/app.toml b/app/gemini-bu/app.toml index 39d86c1eef..1e24dbfe2f 100644 --- a/app/gemini-bu/app.toml +++ b/app/gemini-bu/app.toml @@ -321,4 +321,4 @@ input = {port = "E", pin = 5, af = 5} [config.spi.spi4.devices.rot] mux = "port_e" cs = [{port = "E", pin = 4}] -clock_divider = "DIV256" +clock_divider = "Div256" diff --git a/app/gimlet/base.toml b/app/gimlet/base.toml index b7133df17e..cda3165e6b 100644 --- a/app/gimlet/base.toml +++ b/app/gimlet/base.toml @@ -1288,7 +1288,7 @@ input = {port = "E", pin = 5, af = 5} [config.spi.spi4.devices.rot] mux = "rot" cs = [{port = "E", pin = 4}] -clock_divider = "DIV256" +clock_divider = "Div256" # VLAN configuration [config.net.vlans.sidecar1] diff --git a/app/gimlet/src/main.rs b/app/gimlet/src/main.rs index c8bc0380bb..e0fa082241 100644 --- a/app/gimlet/src/main.rs +++ b/app/gimlet/src/main.rs @@ -137,8 +137,8 @@ fn system_init() { // the prescaler. divm: 1, // VCO must tolerate an 8MHz input range: - vcosel: device::rcc::pllcfgr::PLL1VCOSEL_A::WIDEVCO, - pllrange: device::rcc::pllcfgr::PLL1RGE_A::RANGE8, + vcosel: device::rcc::pllcfgr::PLL1VCOSEL_A::WideVco, + pllrange: device::rcc::pllcfgr::PLL1RGE_A::Range8, // DIVN governs the multiplication of the VCO input frequency to produce // the intermediate frequency. We want an IF of 800MHz, or a // multiplication of 100x. @@ -148,23 +148,23 @@ fn system_init() { divn: 100 - 1, // P is the divisor from the VCO IF to the system frequency. We want // 400MHz, so: - divp: device::rcc::pll1divr::DIVP1_A::DIV2, + divp: device::rcc::pll1divr::DIVP1_A::Div2, // Q produces kernel clocks; we set it to 200MHz: divq: 4 - 1, // R is mostly used by the trace unit and we leave it fast: divr: 2 - 1, // We run the CPU at the full core rate of 400MHz: - cpu_div: device::rcc::d1cfgr::D1CPRE_A::DIV1, + cpu_div: device::rcc::d1cfgr::D1CPRE_A::Div1, // We down-shift the AHB by a factor of 2, to 200MHz, to meet its // constraints: - ahb_div: device::rcc::d1cfgr::HPRE_A::DIV2, + ahb_div: device::rcc::d1cfgr::HPRE_A::Div2, // We configure all APB for 100MHz. These are relative to the AHB // frequency. - apb1_div: device::rcc::d2cfgr::D2PPRE1_A::DIV2, - apb2_div: device::rcc::d2cfgr::D2PPRE2_A::DIV2, - apb3_div: device::rcc::d1cfgr::D1PPRE_A::DIV2, - apb4_div: device::rcc::d3cfgr::D3PPRE_A::DIV2, + apb1_div: device::rcc::d2cfgr::D2PPRE1_A::Div2, + apb2_div: device::rcc::d2cfgr::D2PPRE2_A::Div2, + apb3_div: device::rcc::d1cfgr::D1PPRE_A::Div2, + apb4_div: device::rcc::d3cfgr::D3PPRE_A::Div2, // Flash runs at 200MHz: 2WS, 2 programming cycles. See reference manual // Table 13. diff --git a/app/gimletlet/base-gimletlet2.toml b/app/gimletlet/base-gimletlet2.toml index f2d2faf176..6c8cb4057e 100644 --- a/app/gimletlet/base-gimletlet2.toml +++ b/app/gimletlet/base-gimletlet2.toml @@ -176,8 +176,8 @@ input = {port = "C", pin = 11, af = 6} [config.spi.spi3.devices.spi3_header] mux = "port_c" cs = [{port = "A", pin = 15}] -clock_divider = "DIV256" # 774 kHz, works with LPC55 clock at 48MHz -# clock_divider = "DIV128" # 1.5 MHz, fails unless LPC55 clock is at 96MHz +clock_divider = "Div256" # 774 kHz, works with LPC55 clock at 48MHz +# clock_divider = "Div128" # 1.5 MHz, fails unless LPC55 clock is at 96MHz [config.spi.spi4] controller = 4 diff --git a/app/grapefruit/base.toml b/app/grapefruit/base.toml index 5157d8466f..bd0d01c76a 100644 --- a/app/grapefruit/base.toml +++ b/app/grapefruit/base.toml @@ -428,7 +428,7 @@ input = {port = "B", pin = 14, af = 5} # not actually used in FPGA config [config.spi.spi2.devices.spartan7_fpga] mux = "port_b" cs = [] -clock_divider = "DIV8" # 12.5 MHz +clock_divider = "Div8" # 12.5 MHz # no CS pin; we're using the SPI peripheral to send synchronized CLK + DATA [config.spi.spi4] @@ -443,7 +443,7 @@ input = {port = "E", pin = 5, af = 5} [config.spi.spi4.devices.rot] mux = "port_e" cs = [{port = "E", pin = 4}] -clock_divider = "DIV256" +clock_divider = "Div256" ################################################################################ diff --git a/app/minibar/app.toml b/app/minibar/app.toml index 2f775b85af..23b5a1075f 100644 --- a/app/minibar/app.toml +++ b/app/minibar/app.toml @@ -315,7 +315,7 @@ controller = 4 [config.spi.spi4.devices.rot] mux = "rot" cs = [{port = "E", pin = 4}] -clock_divider = "DIV256" +clock_divider = "Div256" [config.spi.spi4.mux_options.rot] outputs = [ diff --git a/app/psc/base.toml b/app/psc/base.toml index cb69afe472..a06752cc4b 100644 --- a/app/psc/base.toml +++ b/app/psc/base.toml @@ -526,7 +526,7 @@ input = {port = "E", pin = 5, af = 5} [config.spi.spi4.devices.rot] mux = "rot" cs = [{port = "E", pin = 4}] -clock_divider = "DIV256" +clock_divider = "Div256" # VLAN configuration [config.net.vlans.sidecar1] diff --git a/app/sidecar/base.toml b/app/sidecar/base.toml index dde8b05eb4..cb5e628e72 100644 --- a/app/sidecar/base.toml +++ b/app/sidecar/base.toml @@ -1114,7 +1114,7 @@ controller = 4 [config.spi.spi4.devices.rot] mux = "rot" cs = [{port = "E", pin = 4}] -clock_divider = "DIV256" +clock_divider = "Div256" [config.spi.spi4.mux_options.rot] outputs = [ diff --git a/build/spi/src/lib.rs b/build/spi/src/lib.rs index 46ce8849f4..4a39a6fef4 100644 --- a/build/spi/src/lib.rs +++ b/build/spi/src/lib.rs @@ -85,23 +85,24 @@ pub struct DeviceDescriptorConfig { pub cs: Vec, } +// N.B. the names in this enum _must_ match those used in the PAC! #[derive(Copy, Clone, Debug, Deserialize)] pub enum ClockDivider { - DIV2, - DIV4, - DIV8, - DIV16, - DIV32, - DIV64, - DIV128, - DIV256, + Div2, + Div4, + Div8, + Div16, + Div32, + Div64, + Div128, + Div256, } impl Default for ClockDivider { fn default() -> ClockDivider { // When this config mechanism was introduced, we had everything set at - // DIV64 for a ~1.5625 MHz SCK rate. - Self::DIV64 + // Div64 for a ~1.5625 MHz SCK rate. + Self::Div64 } } diff --git a/drv/spi-api/build.rs b/drv/spi-api/build.rs index d0a757dd33..34ad5b2613 100644 --- a/drv/spi-api/build.rs +++ b/drv/spi-api/build.rs @@ -17,21 +17,17 @@ fn main() -> Result<()> { let dest_path = out_dir.join("spi_devices.rs"); let mut file = File::create(dest_path)?; - if let Ok(global_config) = build_util::config::() { - writeln!(&mut file, "pub mod devices {{")?; - for (periph, p) in global_config.spi { - writeln!( - &mut file, - " // {periph} ({} devices)", - p.devices.len() - )?; - for (i, name) in p.devices.keys().enumerate() { - let name = name.to_uppercase(); - writeln!(&mut file, " pub const {name}: u8 = {i};")?; - } + let global_config = build_util::config::()?; + + writeln!(&mut file, "pub mod devices {{")?; + for (periph, p) in global_config.spi { + writeln!(&mut file, " // {periph} ({} devices)", p.devices.len())?; + for (i, name) in p.devices.keys().enumerate() { + let name = name.to_uppercase(); + writeln!(&mut file, " pub const {name}: u8 = {i};")?; } - writeln!(&mut file, "}}")?; } + writeln!(&mut file, "}}")?; Ok(()) } diff --git a/drv/sprot-api/Cargo.toml b/drv/sprot-api/Cargo.toml index 3fa0d0e605..44fb1b9ea0 100644 --- a/drv/sprot-api/Cargo.toml +++ b/drv/sprot-api/Cargo.toml @@ -23,7 +23,6 @@ counters = { path = "../../lib/counters" } derive-idol-err = { path = "../../lib/derive-idol-err" } drv-caboose = { path = "../../drv/caboose" } drv-lpc55-update-api = { path = "../../drv/lpc55-update-api" } -drv-spi-api = { path = "../../drv/spi-api" } drv-update-api = { path = "../../drv/update-api" } dumper-api = { path = "../../task/dumper-api" } ringbuf = { path = "../../lib/ringbuf" } diff --git a/drv/sprot-api/src/error.rs b/drv/sprot-api/src/error.rs index b73ed7961b..ab508b874f 100644 --- a/drv/sprot-api/src/error.rs +++ b/drv/sprot-api/src/error.rs @@ -8,7 +8,6 @@ use attest_api::AttestError; use derive_more::From; use drv_caboose::CabooseError; use drv_lpc55_update_api::RawCabooseError; -use drv_spi_api::SpiError; use drv_update_api::UpdateError; use dumper_api::DumperError; use hubpack::SerializedSize; @@ -37,7 +36,6 @@ use idol_runtime::RequestError; )] pub enum SprotError { Protocol(#[count(children)] SprotProtocolError), - Spi(#[count(children)] SpiError), Update(#[count(children)] UpdateError), Sprockets(#[count(children)] SprocketsError), Watchdog(#[count(children)] WatchdogError), @@ -47,7 +45,6 @@ impl From for SpError { fn from(value: SprotError) -> Self { match value { SprotError::Protocol(e) => Self::Sprot(e.into()), - SprotError::Spi(e) => Self::Spi(e.into()), SprotError::Update(e) => Self::Update(e.into()), SprotError::Sprockets(e) => Self::Sprockets(e.into()), SprotError::Watchdog(e) => Self::Watchdog(e.into()), @@ -59,7 +56,6 @@ impl From for RotError { fn from(value: SprotError) -> Self { match value { SprotError::Protocol(e) => Self::Sprot(e.into()), - SprotError::Spi(e) => Self::Spi(e.into()), SprotError::Update(e) => Self::Update(e.into()), SprotError::Sprockets(e) => Self::Sprockets(e.into()), SprotError::Watchdog(e) => Self::Watchdog(e.into()), @@ -345,10 +341,6 @@ impl From for AttestDataSprotError { Self::ProtocolDesynchronized } }, - SprotError::Spi(e1) => match e1 { - SpiError::BadTransferSize => Self::SpiBadTransferSize, - SpiError::TaskRestarted => Self::SpiTaskRestarted, - }, // We should never return these but it's safer to return an // enum just in case these come up SprotError::Update(_) => Self::UpdateError, diff --git a/drv/stm32h7-hash/src/lib.rs b/drv/stm32h7-hash/src/lib.rs index fd0f59b262..083e0272f3 100644 --- a/drv/stm32h7-hash/src/lib.rs +++ b/drv/stm32h7-hash/src/lib.rs @@ -318,14 +318,14 @@ impl Hash { // The hash is read out as words into little endian ARM world. // Since the bit order needs to be maintained, read as B.E. let result = [ - u32::from_be(self.reg.hash_hr0.read().bits()), - u32::from_be(self.reg.hash_hr1.read().bits()), - u32::from_be(self.reg.hash_hr2.read().bits()), - u32::from_be(self.reg.hash_hr3.read().bits()), - u32::from_be(self.reg.hash_hr4.read().bits()), - u32::from_be(self.reg.hash_hr5.read().bits()), - u32::from_be(self.reg.hash_hr6.read().bits()), - u32::from_be(self.reg.hash_hr7.read().bits()), + u32::from_be(self.reg.hash_hr[0].read().bits()), + u32::from_be(self.reg.hash_hr[1].read().bits()), + u32::from_be(self.reg.hash_hr[2].read().bits()), + u32::from_be(self.reg.hash_hr[3].read().bits()), + u32::from_be(self.reg.hash_hr[4].read().bits()), + u32::from_be(self.reg.hash_hr[5].read().bits()), + u32::from_be(self.reg.hash_hr[6].read().bits()), + u32::from_be(self.reg.hash_hr[7].read().bits()), ]; out.clone_from_slice(result.as_bytes()); Ok(()) diff --git a/drv/stm32h7-spi-server-core/src/lib.rs b/drv/stm32h7-spi-server-core/src/lib.rs index 9d7448dc97..7d65e06806 100644 --- a/drv/stm32h7-spi-server-core/src/lib.rs +++ b/drv/stm32h7-spi-server-core/src/lib.rs @@ -136,13 +136,13 @@ impl SpiServerCore { // This should correspond to '0' in the standard SPI parlance spi.initialize( - device::spi1::cfg1::MBR_A::DIV64, + device::spi1::cfg1::MBR_A::Div64, 8, - device::spi1::cfg2::COMM_A::FULLDUPLEX, - device::spi1::cfg2::LSBFRST_A::MSBFIRST, - device::spi1::cfg2::CPHA_A::FIRSTEDGE, - device::spi1::cfg2::CPOL_A::IDLELOW, - device::spi1::cfg2::SSOM_A::ASSERTED, + device::spi1::cfg2::COMM_A::FullDuplex, + device::spi1::cfg2::LSBFRST_A::Msbfirst, + device::spi1::cfg2::CPHA_A::FirstEdge, + device::spi1::cfg2::CPOL_A::IdleLow, + device::spi1::cfg2::SSOM_A::Asserted, ); // Configure all devices' CS pins to be deasserted (set). diff --git a/drv/stm32h7-startup/src/lib.rs b/drv/stm32h7-startup/src/lib.rs index 03041e761b..3b85828b4b 100644 --- a/drv/stm32h7-startup/src/lib.rs +++ b/drv/stm32h7-startup/src/lib.rs @@ -4,64 +4,84 @@ #![no_std] -use cortex_m_rt::pre_init; - #[cfg(feature = "h743")] use stm32h7::stm32h743 as device; #[cfg(feature = "h753")] use stm32h7::stm32h753 as device; -#[cfg(any(feature = "h743", feature = "h753"))] -#[pre_init] -unsafe fn system_pre_init() { - // Configure the power supply to latch the LDO on and prevent further - // reconfiguration. - // - // Normally we would use Peripherals::take() to safely get a reference to - // the PWR block, but that function expects RAM to be initialized and - // writable. At this point, RAM is neither -- because the chip requires us - // to get the power supply configuration right _before it guarantees that - // RAM will work._ - // - // Another case of the cortex_m/stm32 crates being designed with simpler - // systems in mind. - - // Synthesize a pointer using a const fn (which won't hit RAM) and then - // convert it to a reference. We can have a reference to PWR because it's - // hardware, and is thus not uninitialized. - let pwr = &*device::PWR::ptr(); - // Poke CR3 to enable the LDO and prevent further writes. - pwr.cr3.modify(|_, w| w.ldoen().set_bit()); - - // Busy-wait until the ACTVOSRDY bit says that we've stabilized at VOS3. - while !pwr.csr1.read().actvosrdy().bit() { - // spin - } - - // Turn on the internal RAMs. - let rcc = &*device::RCC::ptr(); - rcc.ahb2enr.modify(|_, w| { - w.sram1en() - .set_bit() - .sram2en() - .set_bit() - .sram3en() - .set_bit() - }); - - // Okay, yay, we can use some RAMs now. - - #[cfg(any(feature = "h743", feature = "h753"))] - { - // Workaround for erratum 2.2.9 "Reading from AXI SRAM may lead to data - // read corruption" - limits AXI SRAM read concurrency. - let axi = &*device::AXI::ptr(); - axi.targ7_fn_mod - .modify(|_, w| w.read_iss_override().set_bit()); - } - - // We'll do the rest in system_init. +// System pre-init hook for establishing system properties required by Rust. +// +// This routine must run before anything touches RAM! The cortex-m-rt crate's +// Reset handler ensures this. As a result, we have to write this in raw +// assembly code, to avoid trying to push/pop a stack frame. +// +// Be very careful about reordering or removing things from this function. +core::arch::global_asm! { + ".global __pre_init", + ".type __pre_init_,%function", + ".thumb_func", + ".cfi_startproc", + "__pre_init:", + + // PWR.CR3 has a write-once feature on the LDO enable bit. The processor + // would like the power configuration to be stable before it guarantees that + // writes to RAM will succeed (reference manual 6.4.1 "System supply + // startup"). We're actually perfectly happy with the reset supply + // configuration, which is VOS3 on the LDO. So, we'll write PWR.CR3 just to + // lock it: + " movw r0, :lower16:{PWR_addr}", + " movt r0, :upper16:{PWR_addr}", + " ldr r1, [r0, #{PWR_CR3_offset}]", + " str r1, [r0, #{PWR_CR3_offset}]", + + // Technically we're supposed to ensure that we're stable at VOS3 before + // continuing; this should already be ensured before our code was allowed to + // run, but for safety's sake: + "1: ldr r1, [r0, #{PWR_CSR1_offset}]", + " tst r1, #(1 << {PWR_CSR1_ACTVOSRDY_bit})", + " beq 1b", + + // Turn on all of the smaller non-TCM non-AXI SRAMs, in case the program + // puts data there. + " movw r0, :lower16:{RCC_addr}", + " movt r0, :upper16:{RCC_addr}", + " ldr r1, [r0, #{RCC_AHB2ENR_offset}]", + " orrs r1, #((1 << {RCC_AHB2ENR_SRAM1EN_bit}) \ + | (1 << {RCC_AHB2ENR_SRAM2EN_bit}) \ + | (1 << {RCC_AHB2ENR_SRAM3EN_bit}))", + + // Apply workaround for ST erratum 2.2.9 "Reading from AXI SRAM may lead to + // data read corruption" - limits AXI SRAM read concurrency. + " movw r0, :lower16:{AXI_TARG7_FN_MOD_addr}", + " movt r0, :upper16:{AXI_TARG7_FN_MOD_addr}", + " ldr r1, [r0]", + " orrs r1, #(1 << {AXI_TARG7_FN_MOD_READ_ISS_OVERRIDE_bit})", + " str r1, [r0]", + + // Aaaaand we're done. + " bx lr", + ".cfi_endproc", + ".size __pre_init, . - __pre_init", + + PWR_addr = const 0x5802_4800, //device::PWR::ptr(), + PWR_CSR1_offset = const 0x4, // reference manual 6.8.2 + PWR_CSR1_ACTVOSRDY_bit = const 13, + PWR_CR3_offset = const 0xC, // reference manual 6.8.4 + + RCC_addr = const 0x5802_4400, //device::RCC::ptr(), + RCC_AHB2ENR_offset = const 0x0DC, // reference manual 8.7.42 + RCC_AHB2ENR_SRAM1EN_bit = const 29, // reference manual 8.7.42 + RCC_AHB2ENR_SRAM2EN_bit = const 30, // reference manual 8.7.42 + RCC_AHB2ENR_SRAM3EN_bit = const 31, // reference manual 8.7.42 + + + // The offset from the AXI block to this register is too large to do the + // same base/displacement thing as the other peripherals above, so this + // constant is the result of adding the base address from the reference + // manual (0x5100_0000) to the offset from table 6. + AXI_TARG7_FN_MOD_addr = const 0x5100_8108, + AXI_TARG7_FN_MOD_READ_ISS_OVERRIDE_bit = const 0, // same } pub struct ClockConfig { diff --git a/lib/endoscope/src/main.rs b/lib/endoscope/src/main.rs index 4b9b789386..4bd1af9e73 100644 --- a/lib/endoscope/src/main.rs +++ b/lib/endoscope/src/main.rs @@ -24,8 +24,8 @@ const CLOCK_CONFIG: ClockConfig = ClockConfig { // the prescaler. divm: 1, // VCO must tolerate an 8MHz input range: - vcosel: device::rcc::pllcfgr::PLL1VCOSEL_A::WIDEVCO, - pllrange: device::rcc::pllcfgr::PLL1RGE_A::RANGE8, + vcosel: device::rcc::pllcfgr::PLL1VCOSEL_A::WideVco, + pllrange: device::rcc::pllcfgr::PLL1RGE_A::Range8, // DIVN governs the multiplication of the VCO input frequency to produce // the intermediate frequency. We want an IF of 800MHz, or a // multiplication of 100x. @@ -35,23 +35,23 @@ const CLOCK_CONFIG: ClockConfig = ClockConfig { divn: 100 - 1, // P is the divisor from the VCO IF to the system frequency. We want // 400MHz, so: - divp: device::rcc::pll1divr::DIVP1_A::DIV2, + divp: device::rcc::pll1divr::DIVP1_A::Div2, // Q produces kernel clocks; we set it to 200MHz: divq: 4 - 1, // R is mostly used by the trace unit and we leave it fast: divr: 2 - 1, // We run the CPU at the full core rate of 400MHz: - cpu_div: device::rcc::d1cfgr::D1CPRE_A::DIV1, + cpu_div: device::rcc::d1cfgr::D1CPRE_A::Div1, // We down-shift the AHB by a factor of 2, to 200MHz, to meet its // constraints: - ahb_div: device::rcc::d1cfgr::HPRE_A::DIV2, + ahb_div: device::rcc::d1cfgr::HPRE_A::Div2, // We configure all APB for 100MHz. These are relative to the AHB // frequency. - apb1_div: device::rcc::d2cfgr::D2PPRE1_A::DIV2, - apb2_div: device::rcc::d2cfgr::D2PPRE2_A::DIV2, - apb3_div: device::rcc::d1cfgr::D1PPRE_A::DIV2, - apb4_div: device::rcc::d3cfgr::D3PPRE_A::DIV2, + apb1_div: device::rcc::d2cfgr::D2PPRE1_A::Div2, + apb2_div: device::rcc::d2cfgr::D2PPRE2_A::Div2, + apb3_div: device::rcc::d1cfgr::D1PPRE_A::Div2, + apb4_div: device::rcc::d3cfgr::D3PPRE_A::Div2, // Flash runs at 200MHz: 2WS, 2 programming cycles. See reference manual // Table 13. diff --git a/task/hiffy/Cargo.toml b/task/hiffy/Cargo.toml index 0efdbf4d3e..48ffc49462 100644 --- a/task/hiffy/Cargo.toml +++ b/task/hiffy/Cargo.toml @@ -10,7 +10,7 @@ drv-hash-api = { path = "../../drv/hash-api", optional = true } drv-i2c-api = { path = "../../drv/i2c-api" } drv-lpc55-gpio-api = { path = "../../drv/lpc55-gpio-api", optional = true } drv-sp-ctrl-api = { path = "../../drv/sp-ctrl-api", optional = true } -drv-spi-api = { path = "../../drv/spi-api" } +drv-spi-api = { path = "../../drv/spi-api", optional = true } drv-sprot-api = { path = "../../drv/sprot-api", optional = true } drv-stm32xx-i2c = { path = "../../drv/stm32xx-i2c", optional = true } drv-stm32xx-sys-api = { path = "../../drv/stm32xx-sys-api", optional = true } @@ -42,7 +42,7 @@ no-ipc-counters = ["idol/no-counters"] testsuite = [ "test-api" ] i2c = [] gpio = [] -spi = [] +spi = ["drv-spi-api"] send = [] send-rw = [] sprot = ["drv-sprot-api"]