aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-05-01 02:21:06 +0200
committerDario Nieuwenhuis <[email protected]>2024-05-01 02:24:45 +0200
commitfb67fe0a6c155191534955f1230dccaea0e11a94 (patch)
treeac01b69047aeee08983a5149409080d137f19cb1 /embassy-stm32
parentecc910b76dbfa2064f42e6917a7b5654a89b81ed (diff)
stm32: add support for STM32H7[RS] "bootflash line", add HIL tests.
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/Cargo.toml24
-rw-r--r--embassy-stm32/build.rs17
-rw-r--r--embassy-stm32/src/can/fd/peripheral.rs30
-rw-r--r--embassy-stm32/src/can/fdcan.rs4
-rw-r--r--embassy-stm32/src/cryp/mod.rs133
-rw-r--r--embassy-stm32/src/eth/v2/mod.rs36
-rw-r--r--embassy-stm32/src/lib.rs6
-rw-r--r--embassy-stm32/src/rcc/bd.rs13
-rw-r--r--embassy-stm32/src/rcc/h.rs215
-rw-r--r--embassy-stm32/src/rcc/hsi48.rs4
-rw-r--r--embassy-stm32/src/rcc/mco.rs26
-rw-r--r--embassy-stm32/src/rcc/mod.rs2
-rw-r--r--embassy-stm32/src/ucpd.rs2
-rw-r--r--embassy-stm32/src/usb/otg.rs4
14 files changed, 327 insertions, 189 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 6492d69f7..cc126b3af 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -72,7 +72,7 @@ rand_core = "0.6.3"
72sdio-host = "0.5.0" 72sdio-host = "0.5.0"
73critical-section = "1.1" 73critical-section = "1.1"
74#stm32-metapac = { version = "15" } 74#stm32-metapac = { version = "15" }
75stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-37a0941112fd16fee53aaa2005fd67b77adab59c" } 75stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-afee4331adc717f4cc52caab16838c95334535be" }
76 76
77vcell = "0.1.3" 77vcell = "0.1.3"
78nb = "1.0.0" 78nb = "1.0.0"
@@ -98,7 +98,7 @@ proc-macro2 = "1.0.36"
98quote = "1.0.15" 98quote = "1.0.15"
99 99
100#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} 100#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
101stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-37a0941112fd16fee53aaa2005fd67b77adab59c", default-features = false, features = ["metadata"]} 101stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-afee4331adc717f4cc52caab16838c95334535be", default-features = false, features = ["metadata"]}
102 102
103[features] 103[features]
104default = ["rt"] 104default = ["rt"]
@@ -1095,6 +1095,26 @@ stm32h7b3qi = [ "stm32-metapac/stm32h7b3qi" ]
1095stm32h7b3ri = [ "stm32-metapac/stm32h7b3ri" ] 1095stm32h7b3ri = [ "stm32-metapac/stm32h7b3ri" ]
1096stm32h7b3vi = [ "stm32-metapac/stm32h7b3vi" ] 1096stm32h7b3vi = [ "stm32-metapac/stm32h7b3vi" ]
1097stm32h7b3zi = [ "stm32-metapac/stm32h7b3zi" ] 1097stm32h7b3zi = [ "stm32-metapac/stm32h7b3zi" ]
1098stm32h7r3a8 = [ "stm32-metapac/stm32h7r3a8" ]
1099stm32h7r3i8 = [ "stm32-metapac/stm32h7r3i8" ]
1100stm32h7r3l8 = [ "stm32-metapac/stm32h7r3l8" ]
1101stm32h7r3r8 = [ "stm32-metapac/stm32h7r3r8" ]
1102stm32h7r3v8 = [ "stm32-metapac/stm32h7r3v8" ]
1103stm32h7r3z8 = [ "stm32-metapac/stm32h7r3z8" ]
1104stm32h7r7a8 = [ "stm32-metapac/stm32h7r7a8" ]
1105stm32h7r7i8 = [ "stm32-metapac/stm32h7r7i8" ]
1106stm32h7r7l8 = [ "stm32-metapac/stm32h7r7l8" ]
1107stm32h7r7z8 = [ "stm32-metapac/stm32h7r7z8" ]
1108stm32h7s3a8 = [ "stm32-metapac/stm32h7s3a8" ]
1109stm32h7s3i8 = [ "stm32-metapac/stm32h7s3i8" ]
1110stm32h7s3l8 = [ "stm32-metapac/stm32h7s3l8" ]
1111stm32h7s3r8 = [ "stm32-metapac/stm32h7s3r8" ]
1112stm32h7s3v8 = [ "stm32-metapac/stm32h7s3v8" ]
1113stm32h7s3z8 = [ "stm32-metapac/stm32h7s3z8" ]
1114stm32h7s7a8 = [ "stm32-metapac/stm32h7s7a8" ]
1115stm32h7s7i8 = [ "stm32-metapac/stm32h7s7i8" ]
1116stm32h7s7l8 = [ "stm32-metapac/stm32h7s7l8" ]
1117stm32h7s7z8 = [ "stm32-metapac/stm32h7s7z8" ]
1098stm32l010c6 = [ "stm32-metapac/stm32l010c6" ] 1118stm32l010c6 = [ "stm32-metapac/stm32l010c6" ]
1099stm32l010f4 = [ "stm32-metapac/stm32l010f4" ] 1119stm32l010f4 = [ "stm32-metapac/stm32l010f4" ]
1100stm32l010k4 = [ "stm32-metapac/stm32l010k4" ] 1120stm32l010k4 = [ "stm32-metapac/stm32l010k4" ]
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index ba3af2550..ba118f338 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -406,7 +406,16 @@ fn main() {
406 }, 406 },
407 ); 407 );
408 } 408 }
409 if chip_name.starts_with("stm32h7") { 409
410 if chip_name.starts_with("stm32h7r") || chip_name.starts_with("stm32h7s") {
411 clock_gen.chained_muxes.insert(
412 "PER",
413 &PeripheralRccRegister {
414 register: "AHBPERCKSELR",
415 field: "PERSEL",
416 },
417 );
418 } else if chip_name.starts_with("stm32h7") {
410 clock_gen.chained_muxes.insert( 419 clock_gen.chained_muxes.insert(
411 "PER", 420 "PER",
412 &PeripheralRccRegister { 421 &PeripheralRccRegister {
@@ -1585,7 +1594,11 @@ fn main() {
1585 println!("cargo:rustc-cfg=package_{}", &chip_name[10..11]); 1594 println!("cargo:rustc-cfg=package_{}", &chip_name[10..11]);
1586 println!("cargo:rustc-cfg=flashsize_{}", &chip_name[11..12]); 1595 println!("cargo:rustc-cfg=flashsize_{}", &chip_name[11..12]);
1587 } else { 1596 } else {
1588 println!("cargo:rustc-cfg={}", &chip_name[..7]); // stm32f4 1597 if &chip_name[..8] == "stm32h7r" || &chip_name[..8] == "stm32h7s" {
1598 println!("cargo:rustc-cfg=stm32h7rs");
1599 } else {
1600 println!("cargo:rustc-cfg={}", &chip_name[..7]); // stm32f4
1601 }
1589 println!("cargo:rustc-cfg={}", &chip_name[..9]); // stm32f429 1602 println!("cargo:rustc-cfg={}", &chip_name[..9]); // stm32f429
1590 println!("cargo:rustc-cfg={}x", &chip_name[..8]); // stm32f42x 1603 println!("cargo:rustc-cfg={}x", &chip_name[..8]); // stm32f42x
1591 println!("cargo:rustc-cfg={}x{}", &chip_name[..7], &chip_name[8..9]); // stm32f4x9 1604 println!("cargo:rustc-cfg={}x{}", &chip_name[..7], &chip_name[8..9]); // stm32f4x9
diff --git a/embassy-stm32/src/can/fd/peripheral.rs b/embassy-stm32/src/can/fd/peripheral.rs
index e5cfee528..9cd5f0785 100644
--- a/embassy-stm32/src/can/fd/peripheral.rs
+++ b/embassy-stm32/src/can/fd/peripheral.rs
@@ -30,10 +30,10 @@ impl Registers {
30 &mut self.msg_ram_mut().transmit.tbsa[bufidx] 30 &mut self.msg_ram_mut().transmit.tbsa[bufidx]
31 } 31 }
32 pub fn msg_ram_mut(&self) -> &mut RegisterBlock { 32 pub fn msg_ram_mut(&self) -> &mut RegisterBlock {
33 #[cfg(stm32h7)] 33 #[cfg(can_fdcan_h7)]
34 let ptr = self.msgram.ram(self.msg_ram_offset / 4).as_ptr() as *mut RegisterBlock; 34 let ptr = self.msgram.ram(self.msg_ram_offset / 4).as_ptr() as *mut RegisterBlock;
35 35
36 #[cfg(not(stm32h7))] 36 #[cfg(not(can_fdcan_h7))]
37 let ptr = self.msgram.as_ptr() as *mut RegisterBlock; 37 let ptr = self.msgram.as_ptr() as *mut RegisterBlock;
38 38
39 unsafe { &mut (*ptr) } 39 unsafe { &mut (*ptr) }
@@ -105,7 +105,7 @@ impl Registers {
105 return Some(BusError::BusWarning); 105 return Some(BusError::BusWarning);
106 } else { 106 } else {
107 cfg_if! { 107 cfg_if! {
108 if #[cfg(stm32h7)] { 108 if #[cfg(can_fdcan_h7)] {
109 let lec = err.lec(); 109 let lec = err.lec();
110 } else { 110 } else {
111 let lec = err.lec().to_bits(); 111 let lec = err.lec().to_bits();
@@ -334,14 +334,14 @@ impl Registers {
334 // set extended filters list size to 8 334 // set extended filters list size to 8
335 // REQUIRED: we use the memory map as if these settings are set 335 // REQUIRED: we use the memory map as if these settings are set
336 // instead of re-calculating them. 336 // instead of re-calculating them.
337 #[cfg(not(stm32h7))] 337 #[cfg(not(can_fdcan_h7))]
338 { 338 {
339 self.regs.rxgfc().modify(|w| { 339 self.regs.rxgfc().modify(|w| {
340 w.set_lss(crate::can::fd::message_ram::STANDARD_FILTER_MAX); 340 w.set_lss(crate::can::fd::message_ram::STANDARD_FILTER_MAX);
341 w.set_lse(crate::can::fd::message_ram::EXTENDED_FILTER_MAX); 341 w.set_lse(crate::can::fd::message_ram::EXTENDED_FILTER_MAX);
342 }); 342 });
343 } 343 }
344 #[cfg(stm32h7)] 344 #[cfg(can_fdcan_h7)]
345 { 345 {
346 self.regs 346 self.regs
347 .sidfc() 347 .sidfc()
@@ -354,11 +354,11 @@ impl Registers {
354 self.configure_msg_ram(); 354 self.configure_msg_ram();
355 355
356 // Enable timestamping 356 // Enable timestamping
357 #[cfg(not(stm32h7))] 357 #[cfg(not(can_fdcan_h7))]
358 self.regs 358 self.regs
359 .tscc() 359 .tscc()
360 .write(|w| w.set_tss(stm32_metapac::can::vals::Tss::INCREMENT)); 360 .write(|w| w.set_tss(stm32_metapac::can::vals::Tss::INCREMENT));
361 #[cfg(stm32h7)] 361 #[cfg(can_fdcan_h7)]
362 self.regs.tscc().write(|w| w.set_tss(0x01)); 362 self.regs.tscc().write(|w| w.set_tss(0x01));
363 363
364 // this isn't really documented in the reference manual 364 // this isn't really documented in the reference manual
@@ -491,9 +491,9 @@ impl Registers {
491 491
492 self.regs.cccr().modify(|w| { 492 self.regs.cccr().modify(|w| {
493 w.set_fdoe(fdoe); 493 w.set_fdoe(fdoe);
494 #[cfg(stm32h7)] 494 #[cfg(can_fdcan_h7)]
495 w.set_bse(brse); 495 w.set_bse(brse);
496 #[cfg(not(stm32h7))] 496 #[cfg(not(can_fdcan_h7))]
497 w.set_brse(brse); 497 w.set_brse(brse);
498 }); 498 });
499 } 499 }
@@ -508,14 +508,14 @@ impl Registers {
508 #[inline] 508 #[inline]
509 #[allow(unused)] 509 #[allow(unused)]
510 pub fn set_timestamp_counter_source(&mut self, select: TimestampSource) { 510 pub fn set_timestamp_counter_source(&mut self, select: TimestampSource) {
511 #[cfg(stm32h7)] 511 #[cfg(can_fdcan_h7)]
512 let (tcp, tss) = match select { 512 let (tcp, tss) = match select {
513 TimestampSource::None => (0, 0), 513 TimestampSource::None => (0, 0),
514 TimestampSource::Prescaler(p) => (p as u8, 1), 514 TimestampSource::Prescaler(p) => (p as u8, 1),
515 TimestampSource::FromTIM3 => (0, 2), 515 TimestampSource::FromTIM3 => (0, 2),
516 }; 516 };
517 517
518 #[cfg(not(stm32h7))] 518 #[cfg(not(can_fdcan_h7))]
519 let (tcp, tss) = match select { 519 let (tcp, tss) = match select {
520 TimestampSource::None => (0, stm32_metapac::can::vals::Tss::ZERO), 520 TimestampSource::None => (0, stm32_metapac::can::vals::Tss::ZERO),
521 TimestampSource::Prescaler(p) => (p as u8, stm32_metapac::can::vals::Tss::INCREMENT), 521 TimestampSource::Prescaler(p) => (p as u8, stm32_metapac::can::vals::Tss::INCREMENT),
@@ -528,7 +528,7 @@ impl Registers {
528 }); 528 });
529 } 529 }
530 530
531 #[cfg(not(stm32h7))] 531 #[cfg(not(can_fdcan_h7))]
532 /// Configures the global filter settings 532 /// Configures the global filter settings
533 #[inline] 533 #[inline]
534 pub fn set_global_filter(&mut self, filter: GlobalFilter) { 534 pub fn set_global_filter(&mut self, filter: GlobalFilter) {
@@ -551,7 +551,7 @@ impl Registers {
551 }); 551 });
552 } 552 }
553 553
554 #[cfg(stm32h7)] 554 #[cfg(can_fdcan_h7)]
555 /// Configures the global filter settings 555 /// Configures the global filter settings
556 #[inline] 556 #[inline]
557 pub fn set_global_filter(&mut self, filter: GlobalFilter) { 557 pub fn set_global_filter(&mut self, filter: GlobalFilter) {
@@ -575,10 +575,10 @@ impl Registers {
575 }); 575 });
576 } 576 }
577 577
578 #[cfg(not(stm32h7))] 578 #[cfg(not(can_fdcan_h7))]
579 fn configure_msg_ram(&mut self) {} 579 fn configure_msg_ram(&mut self) {}
580 580
581 #[cfg(stm32h7)] 581 #[cfg(can_fdcan_h7)]
582 fn configure_msg_ram(&mut self) { 582 fn configure_msg_ram(&mut self) {
583 let r = self.regs; 583 let r = self.regs;
584 584
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs
index 6144ba520..81ceb06aa 100644
--- a/embassy-stm32/src/can/fdcan.rs
+++ b/embassy-stm32/src/can/fdcan.rs
@@ -975,7 +975,7 @@ macro_rules! impl_fdcan {
975 }; 975 };
976} 976}
977 977
978#[cfg(not(stm32h7))] 978#[cfg(not(can_fdcan_h7))]
979foreach_peripheral!( 979foreach_peripheral!(
980 (can, FDCAN) => { impl_fdcan!(FDCAN, FDCANRAM); }; 980 (can, FDCAN) => { impl_fdcan!(FDCAN, FDCANRAM); };
981 (can, FDCAN1) => { impl_fdcan!(FDCAN1, FDCANRAM1); }; 981 (can, FDCAN1) => { impl_fdcan!(FDCAN1, FDCANRAM1); };
@@ -983,7 +983,7 @@ foreach_peripheral!(
983 (can, FDCAN3) => { impl_fdcan!(FDCAN3, FDCANRAM3); }; 983 (can, FDCAN3) => { impl_fdcan!(FDCAN3, FDCANRAM3); };
984); 984);
985 985
986#[cfg(stm32h7)] 986#[cfg(can_fdcan_h7)]
987foreach_peripheral!( 987foreach_peripheral!(
988 (can, FDCAN1) => { impl_fdcan!(FDCAN1, FDCANRAM, 0x0000); }; 988 (can, FDCAN1) => { impl_fdcan!(FDCAN1, FDCANRAM, 0x0000); };
989 (can, FDCAN2) => { impl_fdcan!(FDCAN2, FDCANRAM, 0x0C00); }; 989 (can, FDCAN2) => { impl_fdcan!(FDCAN2, FDCANRAM, 0x0C00); };
diff --git a/embassy-stm32/src/cryp/mod.rs b/embassy-stm32/src/cryp/mod.rs
index 18b5ec918..f19c94fda 100644
--- a/embassy-stm32/src/cryp/mod.rs
+++ b/embassy-stm32/src/cryp/mod.rs
@@ -1,5 +1,5 @@
1//! Crypto Accelerator (CRYP) 1//! Crypto Accelerator (CRYP)
2#[cfg(any(cryp_v2, cryp_v3))] 2#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
3use core::cmp::min; 3use core::cmp::min;
4use core::marker::PhantomData; 4use core::marker::PhantomData;
5use core::ptr; 5use core::ptr;
@@ -7,7 +7,7 @@ use core::ptr;
7use embassy_hal_internal::{into_ref, PeripheralRef}; 7use embassy_hal_internal::{into_ref, PeripheralRef};
8use embassy_sync::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
9 9
10use crate::dma::{NoDma, Priority, Transfer, TransferOptions}; 10use crate::dma::{NoDma, Transfer, TransferOptions};
11use crate::interrupt::typelevel::Interrupt; 11use crate::interrupt::typelevel::Interrupt;
12use crate::{interrupt, pac, peripherals, Peripheral}; 12use crate::{interrupt, pac, peripherals, Peripheral};
13 13
@@ -147,7 +147,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for TdesEcb<'c, KEY_SIZE> {
147 { 147 {
148 p.cr().modify(|w| w.set_algomode(0)); 148 p.cr().modify(|w| w.set_algomode(0));
149 } 149 }
150 #[cfg(any(cryp_v2, cryp_v3))] 150 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
151 { 151 {
152 p.cr().modify(|w| w.set_algomode0(0)); 152 p.cr().modify(|w| w.set_algomode0(0));
153 p.cr().modify(|w| w.set_algomode3(false)); 153 p.cr().modify(|w| w.set_algomode3(false));
@@ -189,7 +189,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for TdesCbc<'c, KEY_SIZE> {
189 { 189 {
190 p.cr().modify(|w| w.set_algomode(1)); 190 p.cr().modify(|w| w.set_algomode(1));
191 } 191 }
192 #[cfg(any(cryp_v2, cryp_v3))] 192 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
193 { 193 {
194 p.cr().modify(|w| w.set_algomode0(1)); 194 p.cr().modify(|w| w.set_algomode0(1));
195 p.cr().modify(|w| w.set_algomode3(false)); 195 p.cr().modify(|w| w.set_algomode3(false));
@@ -231,7 +231,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for DesEcb<'c, KEY_SIZE> {
231 { 231 {
232 p.cr().modify(|w| w.set_algomode(2)); 232 p.cr().modify(|w| w.set_algomode(2));
233 } 233 }
234 #[cfg(any(cryp_v2, cryp_v3))] 234 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
235 { 235 {
236 p.cr().modify(|w| w.set_algomode0(2)); 236 p.cr().modify(|w| w.set_algomode0(2));
237 p.cr().modify(|w| w.set_algomode3(false)); 237 p.cr().modify(|w| w.set_algomode3(false));
@@ -272,7 +272,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for DesCbc<'c, KEY_SIZE> {
272 { 272 {
273 p.cr().modify(|w| w.set_algomode(3)); 273 p.cr().modify(|w| w.set_algomode(3));
274 } 274 }
275 #[cfg(any(cryp_v2, cryp_v3))] 275 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
276 { 276 {
277 p.cr().modify(|w| w.set_algomode0(3)); 277 p.cr().modify(|w| w.set_algomode0(3));
278 p.cr().modify(|w| w.set_algomode3(false)); 278 p.cr().modify(|w| w.set_algomode3(false));
@@ -313,7 +313,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesEcb<'c, KEY_SIZE> {
313 { 313 {
314 p.cr().modify(|w| w.set_algomode(7)); 314 p.cr().modify(|w| w.set_algomode(7));
315 } 315 }
316 #[cfg(any(cryp_v2, cryp_v3))] 316 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
317 { 317 {
318 p.cr().modify(|w| w.set_algomode0(7)); 318 p.cr().modify(|w| w.set_algomode0(7));
319 p.cr().modify(|w| w.set_algomode3(false)); 319 p.cr().modify(|w| w.set_algomode3(false));
@@ -327,7 +327,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesEcb<'c, KEY_SIZE> {
327 { 327 {
328 p.cr().modify(|w| w.set_algomode(2)); 328 p.cr().modify(|w| w.set_algomode(2));
329 } 329 }
330 #[cfg(any(cryp_v2, cryp_v3))] 330 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
331 { 331 {
332 p.cr().modify(|w| w.set_algomode0(2)); 332 p.cr().modify(|w| w.set_algomode0(2));
333 p.cr().modify(|w| w.set_algomode3(false)); 333 p.cr().modify(|w| w.set_algomode3(false));
@@ -370,7 +370,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesCbc<'c, KEY_SIZE> {
370 { 370 {
371 p.cr().modify(|w| w.set_algomode(7)); 371 p.cr().modify(|w| w.set_algomode(7));
372 } 372 }
373 #[cfg(any(cryp_v2, cryp_v3))] 373 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
374 { 374 {
375 p.cr().modify(|w| w.set_algomode0(7)); 375 p.cr().modify(|w| w.set_algomode0(7));
376 p.cr().modify(|w| w.set_algomode3(false)); 376 p.cr().modify(|w| w.set_algomode3(false));
@@ -384,7 +384,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesCbc<'c, KEY_SIZE> {
384 { 384 {
385 p.cr().modify(|w| w.set_algomode(5)); 385 p.cr().modify(|w| w.set_algomode(5));
386 } 386 }
387 #[cfg(any(cryp_v2, cryp_v3))] 387 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
388 { 388 {
389 p.cr().modify(|w| w.set_algomode0(5)); 389 p.cr().modify(|w| w.set_algomode0(5));
390 p.cr().modify(|w| w.set_algomode3(false)); 390 p.cr().modify(|w| w.set_algomode3(false));
@@ -426,7 +426,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesCtr<'c, KEY_SIZE> {
426 { 426 {
427 p.cr().modify(|w| w.set_algomode(6)); 427 p.cr().modify(|w| w.set_algomode(6));
428 } 428 }
429 #[cfg(any(cryp_v2, cryp_v3))] 429 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
430 { 430 {
431 p.cr().modify(|w| w.set_algomode0(6)); 431 p.cr().modify(|w| w.set_algomode0(6));
432 p.cr().modify(|w| w.set_algomode3(false)); 432 p.cr().modify(|w| w.set_algomode3(false));
@@ -439,14 +439,14 @@ impl<'c> CipherSized for AesCtr<'c, { 192 / 8 }> {}
439impl<'c> CipherSized for AesCtr<'c, { 256 / 8 }> {} 439impl<'c> CipherSized for AesCtr<'c, { 256 / 8 }> {}
440impl<'c, const KEY_SIZE: usize> IVSized for AesCtr<'c, KEY_SIZE> {} 440impl<'c, const KEY_SIZE: usize> IVSized for AesCtr<'c, KEY_SIZE> {}
441 441
442#[cfg(any(cryp_v2, cryp_v3))] 442#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
443///AES-GCM Cipher Mode 443///AES-GCM Cipher Mode
444pub struct AesGcm<'c, const KEY_SIZE: usize> { 444pub struct AesGcm<'c, const KEY_SIZE: usize> {
445 iv: [u8; 16], 445 iv: [u8; 16],
446 key: &'c [u8; KEY_SIZE], 446 key: &'c [u8; KEY_SIZE],
447} 447}
448 448
449#[cfg(any(cryp_v2, cryp_v3))] 449#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
450impl<'c, const KEY_SIZE: usize> AesGcm<'c, KEY_SIZE> { 450impl<'c, const KEY_SIZE: usize> AesGcm<'c, KEY_SIZE> {
451 /// Constucts a new AES-GCM cipher for a cryptographic operation. 451 /// Constucts a new AES-GCM cipher for a cryptographic operation.
452 pub fn new(key: &'c [u8; KEY_SIZE], iv: &'c [u8; 12]) -> Self { 452 pub fn new(key: &'c [u8; KEY_SIZE], iv: &'c [u8; 12]) -> Self {
@@ -457,7 +457,7 @@ impl<'c, const KEY_SIZE: usize> AesGcm<'c, KEY_SIZE> {
457 } 457 }
458} 458}
459 459
460#[cfg(any(cryp_v2, cryp_v3))] 460#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
461impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> { 461impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> {
462 const BLOCK_SIZE: usize = AES_BLOCK_SIZE; 462 const BLOCK_SIZE: usize = AES_BLOCK_SIZE;
463 463
@@ -504,7 +504,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> {
504 [0; 4] 504 [0; 4]
505 } 505 }
506 506
507 #[cfg(cryp_v3)] 507 #[cfg(any(cryp_v3, cryp_v4))]
508 fn pre_final(&self, p: &pac::cryp::Cryp, _dir: Direction, padding_len: usize) -> [u32; 4] { 508 fn pre_final(&self, p: &pac::cryp::Cryp, _dir: Direction, padding_len: usize) -> [u32; 4] {
509 //Handle special GCM partial block process. 509 //Handle special GCM partial block process.
510 p.cr().modify(|w| w.set_npblb(padding_len as u8)); 510 p.cr().modify(|w| w.set_npblb(padding_len as u8));
@@ -573,25 +573,25 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> {
573 } 573 }
574} 574}
575 575
576#[cfg(any(cryp_v2, cryp_v3))] 576#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
577impl<'c> CipherSized for AesGcm<'c, { 128 / 8 }> {} 577impl<'c> CipherSized for AesGcm<'c, { 128 / 8 }> {}
578#[cfg(any(cryp_v2, cryp_v3))] 578#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
579impl<'c> CipherSized for AesGcm<'c, { 192 / 8 }> {} 579impl<'c> CipherSized for AesGcm<'c, { 192 / 8 }> {}
580#[cfg(any(cryp_v2, cryp_v3))] 580#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
581impl<'c> CipherSized for AesGcm<'c, { 256 / 8 }> {} 581impl<'c> CipherSized for AesGcm<'c, { 256 / 8 }> {}
582#[cfg(any(cryp_v2, cryp_v3))] 582#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
583impl<'c, const KEY_SIZE: usize> CipherAuthenticated<16> for AesGcm<'c, KEY_SIZE> {} 583impl<'c, const KEY_SIZE: usize> CipherAuthenticated<16> for AesGcm<'c, KEY_SIZE> {}
584#[cfg(any(cryp_v2, cryp_v3))] 584#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
585impl<'c, const KEY_SIZE: usize> IVSized for AesGcm<'c, KEY_SIZE> {} 585impl<'c, const KEY_SIZE: usize> IVSized for AesGcm<'c, KEY_SIZE> {}
586 586
587#[cfg(any(cryp_v2, cryp_v3))] 587#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
588/// AES-GMAC Cipher Mode 588/// AES-GMAC Cipher Mode
589pub struct AesGmac<'c, const KEY_SIZE: usize> { 589pub struct AesGmac<'c, const KEY_SIZE: usize> {
590 iv: [u8; 16], 590 iv: [u8; 16],
591 key: &'c [u8; KEY_SIZE], 591 key: &'c [u8; KEY_SIZE],
592} 592}
593 593
594#[cfg(any(cryp_v2, cryp_v3))] 594#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
595impl<'c, const KEY_SIZE: usize> AesGmac<'c, KEY_SIZE> { 595impl<'c, const KEY_SIZE: usize> AesGmac<'c, KEY_SIZE> {
596 /// Constructs a new AES-GMAC cipher for a cryptographic operation. 596 /// Constructs a new AES-GMAC cipher for a cryptographic operation.
597 pub fn new(key: &'c [u8; KEY_SIZE], iv: &'c [u8; 12]) -> Self { 597 pub fn new(key: &'c [u8; KEY_SIZE], iv: &'c [u8; 12]) -> Self {
@@ -602,7 +602,7 @@ impl<'c, const KEY_SIZE: usize> AesGmac<'c, KEY_SIZE> {
602 } 602 }
603} 603}
604 604
605#[cfg(any(cryp_v2, cryp_v3))] 605#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
606impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> { 606impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> {
607 const BLOCK_SIZE: usize = AES_BLOCK_SIZE; 607 const BLOCK_SIZE: usize = AES_BLOCK_SIZE;
608 608
@@ -649,7 +649,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> {
649 [0; 4] 649 [0; 4]
650 } 650 }
651 651
652 #[cfg(cryp_v3)] 652 #[cfg(any(cryp_v3, cryp_v4))]
653 fn pre_final(&self, p: &pac::cryp::Cryp, _dir: Direction, padding_len: usize) -> [u32; 4] { 653 fn pre_final(&self, p: &pac::cryp::Cryp, _dir: Direction, padding_len: usize) -> [u32; 4] {
654 //Handle special GCM partial block process. 654 //Handle special GCM partial block process.
655 p.cr().modify(|w| w.set_npblb(padding_len as u8)); 655 p.cr().modify(|w| w.set_npblb(padding_len as u8));
@@ -716,18 +716,18 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> {
716 } 716 }
717} 717}
718 718
719#[cfg(any(cryp_v2, cryp_v3))] 719#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
720impl<'c> CipherSized for AesGmac<'c, { 128 / 8 }> {} 720impl<'c> CipherSized for AesGmac<'c, { 128 / 8 }> {}
721#[cfg(any(cryp_v2, cryp_v3))] 721#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
722impl<'c> CipherSized for AesGmac<'c, { 192 / 8 }> {} 722impl<'c> CipherSized for AesGmac<'c, { 192 / 8 }> {}
723#[cfg(any(cryp_v2, cryp_v3))] 723#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
724impl<'c> CipherSized for AesGmac<'c, { 256 / 8 }> {} 724impl<'c> CipherSized for AesGmac<'c, { 256 / 8 }> {}
725#[cfg(any(cryp_v2, cryp_v3))] 725#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
726impl<'c, const KEY_SIZE: usize> CipherAuthenticated<16> for AesGmac<'c, KEY_SIZE> {} 726impl<'c, const KEY_SIZE: usize> CipherAuthenticated<16> for AesGmac<'c, KEY_SIZE> {}
727#[cfg(any(cryp_v2, cryp_v3))] 727#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
728impl<'c, const KEY_SIZE: usize> IVSized for AesGmac<'c, KEY_SIZE> {} 728impl<'c, const KEY_SIZE: usize> IVSized for AesGmac<'c, KEY_SIZE> {}
729 729
730#[cfg(any(cryp_v2, cryp_v3))] 730#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
731/// AES-CCM Cipher Mode 731/// AES-CCM Cipher Mode
732pub struct AesCcm<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> { 732pub struct AesCcm<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> {
733 key: &'c [u8; KEY_SIZE], 733 key: &'c [u8; KEY_SIZE],
@@ -737,7 +737,7 @@ pub struct AesCcm<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZ
737 ctr: [u8; 16], 737 ctr: [u8; 16],
738} 738}
739 739
740#[cfg(any(cryp_v2, cryp_v3))] 740#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
741impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> AesCcm<'c, KEY_SIZE, TAG_SIZE, IV_SIZE> { 741impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> AesCcm<'c, KEY_SIZE, TAG_SIZE, IV_SIZE> {
742 /// Constructs a new AES-CCM cipher for a cryptographic operation. 742 /// Constructs a new AES-CCM cipher for a cryptographic operation.
743 pub fn new(key: &'c [u8; KEY_SIZE], iv: &'c [u8; IV_SIZE], aad_len: usize, payload_len: usize) -> Self { 743 pub fn new(key: &'c [u8; KEY_SIZE], iv: &'c [u8; IV_SIZE], aad_len: usize, payload_len: usize) -> Self {
@@ -801,7 +801,7 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Aes
801 } 801 }
802} 802}
803 803
804#[cfg(any(cryp_v2, cryp_v3))] 804#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
805impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cipher<'c> 805impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cipher<'c>
806 for AesCcm<'c, KEY_SIZE, TAG_SIZE, IV_SIZE> 806 for AesCcm<'c, KEY_SIZE, TAG_SIZE, IV_SIZE>
807{ 807{
@@ -865,7 +865,7 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip
865 return temp1; 865 return temp1;
866 } 866 }
867 867
868 #[cfg(cryp_v3)] 868 #[cfg(any(cryp_v3, cryp_v4))]
869 fn pre_final(&self, p: &pac::cryp::Cryp, _dir: Direction, padding_len: usize) -> [u32; 4] { 869 fn pre_final(&self, p: &pac::cryp::Cryp, _dir: Direction, padding_len: usize) -> [u32; 4] {
870 //Handle special GCM partial block process. 870 //Handle special GCM partial block process.
871 p.cr().modify(|w| w.set_npblb(padding_len as u8)); 871 p.cr().modify(|w| w.set_npblb(padding_len as u8));
@@ -950,39 +950,39 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip
950 } 950 }
951} 951}
952 952
953#[cfg(any(cryp_v2, cryp_v3))] 953#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
954impl<'c, const TAG_SIZE: usize, const IV_SIZE: usize> CipherSized for AesCcm<'c, { 128 / 8 }, TAG_SIZE, IV_SIZE> {} 954impl<'c, const TAG_SIZE: usize, const IV_SIZE: usize> CipherSized for AesCcm<'c, { 128 / 8 }, TAG_SIZE, IV_SIZE> {}
955#[cfg(any(cryp_v2, cryp_v3))] 955#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
956impl<'c, const TAG_SIZE: usize, const IV_SIZE: usize> CipherSized for AesCcm<'c, { 192 / 8 }, TAG_SIZE, IV_SIZE> {} 956impl<'c, const TAG_SIZE: usize, const IV_SIZE: usize> CipherSized for AesCcm<'c, { 192 / 8 }, TAG_SIZE, IV_SIZE> {}
957#[cfg(any(cryp_v2, cryp_v3))] 957#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
958impl<'c, const TAG_SIZE: usize, const IV_SIZE: usize> CipherSized for AesCcm<'c, { 256 / 8 }, TAG_SIZE, IV_SIZE> {} 958impl<'c, const TAG_SIZE: usize, const IV_SIZE: usize> CipherSized for AesCcm<'c, { 256 / 8 }, TAG_SIZE, IV_SIZE> {}
959#[cfg(any(cryp_v2, cryp_v3))] 959#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
960impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<4> for AesCcm<'c, KEY_SIZE, 4, IV_SIZE> {} 960impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<4> for AesCcm<'c, KEY_SIZE, 4, IV_SIZE> {}
961#[cfg(any(cryp_v2, cryp_v3))] 961#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
962impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<6> for AesCcm<'c, KEY_SIZE, 6, IV_SIZE> {} 962impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<6> for AesCcm<'c, KEY_SIZE, 6, IV_SIZE> {}
963#[cfg(any(cryp_v2, cryp_v3))] 963#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
964impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<8> for AesCcm<'c, KEY_SIZE, 8, IV_SIZE> {} 964impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<8> for AesCcm<'c, KEY_SIZE, 8, IV_SIZE> {}
965#[cfg(any(cryp_v2, cryp_v3))] 965#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
966impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<10> for AesCcm<'c, KEY_SIZE, 10, IV_SIZE> {} 966impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<10> for AesCcm<'c, KEY_SIZE, 10, IV_SIZE> {}
967#[cfg(any(cryp_v2, cryp_v3))] 967#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
968impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<12> for AesCcm<'c, KEY_SIZE, 12, IV_SIZE> {} 968impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<12> for AesCcm<'c, KEY_SIZE, 12, IV_SIZE> {}
969#[cfg(any(cryp_v2, cryp_v3))] 969#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
970impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<14> for AesCcm<'c, KEY_SIZE, 14, IV_SIZE> {} 970impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<14> for AesCcm<'c, KEY_SIZE, 14, IV_SIZE> {}
971#[cfg(any(cryp_v2, cryp_v3))] 971#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
972impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<16> for AesCcm<'c, KEY_SIZE, 16, IV_SIZE> {} 972impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<16> for AesCcm<'c, KEY_SIZE, 16, IV_SIZE> {}
973#[cfg(any(cryp_v2, cryp_v3))] 973#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
974impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 7> {} 974impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 7> {}
975#[cfg(any(cryp_v2, cryp_v3))] 975#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
976impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 8> {} 976impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 8> {}
977#[cfg(any(cryp_v2, cryp_v3))] 977#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
978impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 9> {} 978impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 9> {}
979#[cfg(any(cryp_v2, cryp_v3))] 979#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
980impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 10> {} 980impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 10> {}
981#[cfg(any(cryp_v2, cryp_v3))] 981#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
982impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 11> {} 982impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 11> {}
983#[cfg(any(cryp_v2, cryp_v3))] 983#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
984impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 12> {} 984impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 12> {}
985#[cfg(any(cryp_v2, cryp_v3))] 985#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
986impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 13> {} 986impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 13> {}
987 987
988#[allow(dead_code)] 988#[allow(dead_code)]
@@ -1205,7 +1205,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1205 ctx 1205 ctx
1206 } 1206 }
1207 1207
1208 #[cfg(any(cryp_v2, cryp_v3))] 1208 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1209 /// Controls the header phase of cipher processing. 1209 /// Controls the header phase of cipher processing.
1210 /// This function is only valid for authenticated ciphers including GCM, CCM, and GMAC. 1210 /// This function is only valid for authenticated ciphers including GCM, CCM, and GMAC.
1211 /// All additional associated data (AAD) must be supplied to this function prior to starting the payload phase with `payload_blocking`. 1211 /// All additional associated data (AAD) must be supplied to this function prior to starting the payload phase with `payload_blocking`.
@@ -1302,7 +1302,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1302 self.store_context(ctx); 1302 self.store_context(ctx);
1303 } 1303 }
1304 1304
1305 #[cfg(any(cryp_v2, cryp_v3))] 1305 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1306 /// Controls the header phase of cipher processing. 1306 /// Controls the header phase of cipher processing.
1307 /// This function is only valid for authenticated ciphers including GCM, CCM, and GMAC. 1307 /// This function is only valid for authenticated ciphers including GCM, CCM, and GMAC.
1308 /// All additional associated data (AAD) must be supplied to this function prior to starting the payload phase with `payload`. 1308 /// All additional associated data (AAD) must be supplied to this function prior to starting the payload phase with `payload`.
@@ -1420,7 +1420,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1420 if !ctx.aad_complete && ctx.header_len > 0 { 1420 if !ctx.aad_complete && ctx.header_len > 0 {
1421 panic!("Additional associated data must be processed first!"); 1421 panic!("Additional associated data must be processed first!");
1422 } else if !ctx.aad_complete { 1422 } else if !ctx.aad_complete {
1423 #[cfg(any(cryp_v2, cryp_v3))] 1423 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1424 { 1424 {
1425 ctx.aad_complete = true; 1425 ctx.aad_complete = true;
1426 T::regs().cr().modify(|w| w.set_crypen(false)); 1426 T::regs().cr().modify(|w| w.set_crypen(false));
@@ -1512,7 +1512,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1512 if !ctx.aad_complete && ctx.header_len > 0 { 1512 if !ctx.aad_complete && ctx.header_len > 0 {
1513 panic!("Additional associated data must be processed first!"); 1513 panic!("Additional associated data must be processed first!");
1514 } else if !ctx.aad_complete { 1514 } else if !ctx.aad_complete {
1515 #[cfg(any(cryp_v2, cryp_v3))] 1515 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1516 { 1516 {
1517 ctx.aad_complete = true; 1517 ctx.aad_complete = true;
1518 T::regs().cr().modify(|w| w.set_crypen(false)); 1518 T::regs().cr().modify(|w| w.set_crypen(false));
@@ -1585,7 +1585,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1585 self.store_context(ctx); 1585 self.store_context(ctx);
1586 } 1586 }
1587 1587
1588 #[cfg(any(cryp_v2, cryp_v3))] 1588 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1589 /// Generates an authentication tag for authenticated ciphers including GCM, CCM, and GMAC. 1589 /// Generates an authentication tag for authenticated ciphers including GCM, CCM, and GMAC.
1590 /// Called after the all data has been encrypted/decrypted by `payload`. 1590 /// Called after the all data has been encrypted/decrypted by `payload`.
1591 pub fn finish_blocking< 1591 pub fn finish_blocking<
@@ -1614,7 +1614,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1614 payloadlen1.swap_bytes(), 1614 payloadlen1.swap_bytes(),
1615 payloadlen2.swap_bytes(), 1615 payloadlen2.swap_bytes(),
1616 ]; 1616 ];
1617 #[cfg(cryp_v3)] 1617 #[cfg(any(cryp_v3, cryp_v4))]
1618 let footer: [u32; 4] = [headerlen1, headerlen2, payloadlen1, payloadlen2]; 1618 let footer: [u32; 4] = [headerlen1, headerlen2, payloadlen1, payloadlen2];
1619 1619
1620 self.write_words_blocking(C::BLOCK_SIZE, &footer); 1620 self.write_words_blocking(C::BLOCK_SIZE, &footer);
@@ -1631,7 +1631,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1631 tag 1631 tag
1632 } 1632 }
1633 1633
1634 #[cfg(any(cryp_v2, cryp_v3))] 1634 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1635 // Generates an authentication tag for authenticated ciphers including GCM, CCM, and GMAC. 1635 // Generates an authentication tag for authenticated ciphers including GCM, CCM, and GMAC.
1636 /// Called after the all data has been encrypted/decrypted by `payload`. 1636 /// Called after the all data has been encrypted/decrypted by `payload`.
1637 pub async fn finish< 1637 pub async fn finish<
@@ -1664,7 +1664,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1664 payloadlen1.swap_bytes(), 1664 payloadlen1.swap_bytes(),
1665 payloadlen2.swap_bytes(), 1665 payloadlen2.swap_bytes(),
1666 ]; 1666 ];
1667 #[cfg(cryp_v3)] 1667 #[cfg(any(cryp_v3, cryp_v4))]
1668 let footer: [u32; 4] = [headerlen1, headerlen2, payloadlen1, payloadlen2]; 1668 let footer: [u32; 4] = [headerlen1, headerlen2, payloadlen1, payloadlen2];
1669 1669
1670 let write = Self::write_words(&mut self.indma, C::BLOCK_SIZE, &footer); 1670 let write = Self::write_words(&mut self.indma, C::BLOCK_SIZE, &footer);
@@ -1735,7 +1735,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1735 ctx.iv[2] = T::regs().init(1).ivlr().read(); 1735 ctx.iv[2] = T::regs().init(1).ivlr().read();
1736 ctx.iv[3] = T::regs().init(1).ivrr().read(); 1736 ctx.iv[3] = T::regs().init(1).ivrr().read();
1737 1737
1738 #[cfg(any(cryp_v2, cryp_v3))] 1738 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1739 for i in 0..8 { 1739 for i in 0..8 {
1740 ctx.csgcmccm[i] = T::regs().csgcmccmr(i).read(); 1740 ctx.csgcmccm[i] = T::regs().csgcmccmr(i).read();
1741 ctx.csgcm[i] = T::regs().csgcmr(i).read(); 1741 ctx.csgcm[i] = T::regs().csgcmr(i).read();
@@ -1750,7 +1750,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1750 T::regs().init(1).ivlr().write_value(ctx.iv[2]); 1750 T::regs().init(1).ivlr().write_value(ctx.iv[2]);
1751 T::regs().init(1).ivrr().write_value(ctx.iv[3]); 1751 T::regs().init(1).ivrr().write_value(ctx.iv[3]);
1752 1752
1753 #[cfg(any(cryp_v2, cryp_v3))] 1753 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1754 for i in 0..8 { 1754 for i in 0..8 {
1755 T::regs().csgcmccmr(i).write_value(ctx.csgcmccm[i]); 1755 T::regs().csgcmccmr(i).write_value(ctx.csgcmccm[i]);
1756 T::regs().csgcmr(i).write_value(ctx.csgcm[i]); 1756 T::regs().csgcmr(i).write_value(ctx.csgcm[i]);
@@ -1797,7 +1797,8 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1797 let num_words = blocks.len() / 4; 1797 let num_words = blocks.len() / 4;
1798 let src_ptr = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words); 1798 let src_ptr = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words);
1799 let options = TransferOptions { 1799 let options = TransferOptions {
1800 priority: Priority::High, 1800 #[cfg(not(gpdma))]
1801 priority: crate::dma::Priority::High,
1801 ..Default::default() 1802 ..Default::default()
1802 }; 1803 };
1803 let dma_transfer = unsafe { Transfer::new_write_raw(dma, dma_request, src_ptr, dst_ptr, options) }; 1804 let dma_transfer = unsafe { Transfer::new_write_raw(dma, dma_request, src_ptr, dst_ptr, options) };
@@ -1806,7 +1807,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1806 dma_transfer.await; 1807 dma_transfer.await;
1807 } 1808 }
1808 1809
1809 #[cfg(any(cryp_v2, cryp_v3))] 1810 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1810 fn write_words_blocking(&self, block_size: usize, blocks: &[u32]) { 1811 fn write_words_blocking(&self, block_size: usize, blocks: &[u32]) {
1811 assert_eq!((blocks.len() * 4) % block_size, 0); 1812 assert_eq!((blocks.len() * 4) % block_size, 0);
1812 let mut byte_counter: usize = 0; 1813 let mut byte_counter: usize = 0;
@@ -1820,7 +1821,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1820 } 1821 }
1821 } 1822 }
1822 1823
1823 #[cfg(any(cryp_v2, cryp_v3))] 1824 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1824 async fn write_words(dma: &mut PeripheralRef<'_, DmaIn>, block_size: usize, blocks: &[u32]) 1825 async fn write_words(dma: &mut PeripheralRef<'_, DmaIn>, block_size: usize, blocks: &[u32])
1825 where 1826 where
1826 DmaIn: crate::cryp::DmaIn<T>, 1827 DmaIn: crate::cryp::DmaIn<T>,
@@ -1836,7 +1837,8 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1836 let num_words = blocks.len(); 1837 let num_words = blocks.len();
1837 let src_ptr = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words); 1838 let src_ptr = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words);
1838 let options = TransferOptions { 1839 let options = TransferOptions {
1839 priority: Priority::High, 1840 #[cfg(not(gpdma))]
1841 priority: crate::dma::Priority::High,
1840 ..Default::default() 1842 ..Default::default()
1841 }; 1843 };
1842 let dma_transfer = unsafe { Transfer::new_write_raw(dma, dma_request, src_ptr, dst_ptr, options) }; 1844 let dma_transfer = unsafe { Transfer::new_write_raw(dma, dma_request, src_ptr, dst_ptr, options) };
@@ -1875,7 +1877,8 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1875 let num_words = blocks.len() / 4; 1877 let num_words = blocks.len() / 4;
1876 let dst_ptr = ptr::slice_from_raw_parts_mut(blocks.as_mut_ptr().cast(), num_words); 1878 let dst_ptr = ptr::slice_from_raw_parts_mut(blocks.as_mut_ptr().cast(), num_words);
1877 let options = TransferOptions { 1879 let options = TransferOptions {
1878 priority: Priority::VeryHigh, 1880 #[cfg(not(gpdma))]
1881 priority: crate::dma::Priority::VeryHigh,
1879 ..Default::default() 1882 ..Default::default()
1880 }; 1883 };
1881 let dma_transfer = unsafe { Transfer::new_read_raw(dma, dma_request, src_ptr, dst_ptr, options) }; 1884 let dma_transfer = unsafe { Transfer::new_read_raw(dma, dma_request, src_ptr, dst_ptr, options) };
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs
index 37f460574..a19aa42cf 100644
--- a/embassy-stm32/src/eth/v2/mod.rs
+++ b/embassy-stm32/src/eth/v2/mod.rs
@@ -4,6 +4,7 @@ use core::marker::PhantomData;
4use core::sync::atomic::{fence, Ordering}; 4use core::sync::atomic::{fence, Ordering};
5 5
6use embassy_hal_internal::{into_ref, PeripheralRef}; 6use embassy_hal_internal::{into_ref, PeripheralRef};
7use stm32_metapac::syscfg::vals::EthSelPhy;
7 8
8pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; 9pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing};
9use super::*; 10use super::*;
@@ -80,19 +81,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
80 phy: P, 81 phy: P,
81 mac_addr: [u8; 6], 82 mac_addr: [u8; 6],
82 ) -> Self { 83 ) -> Self {
83 // Enable the necessary Clocks 84 // Enable the necessary clocks
84 #[cfg(not(rcc_h5))]
85 critical_section::with(|_| {
86 crate::pac::RCC.ahb1enr().modify(|w| {
87 w.set_eth1macen(true);
88 w.set_eth1txen(true);
89 w.set_eth1rxen(true);
90 });
91
92 crate::pac::SYSCFG.pmcr().modify(|w| w.set_epis(0b100));
93 });
94
95 #[cfg(rcc_h5)]
96 critical_section::with(|_| { 85 critical_section::with(|_| {
97 crate::pac::RCC.ahb1enr().modify(|w| { 86 crate::pac::RCC.ahb1enr().modify(|w| {
98 w.set_ethen(true); 87 w.set_ethen(true);
@@ -100,9 +89,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
100 w.set_ethrxen(true); 89 w.set_ethrxen(true);
101 }); 90 });
102 91
103 crate::pac::SYSCFG 92 crate::pac::SYSCFG.pmcr().modify(|w| w.set_eth_sel_phy(EthSelPhy::RMII));
104 .pmcr()
105 .modify(|w| w.set_eth_sel_phy(crate::pac::syscfg::vals::EthSelPhy::B_0X4));
106 }); 93 });
107 94
108 into_ref!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); 95 into_ref!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
@@ -145,19 +132,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
145 phy: P, 132 phy: P,
146 mac_addr: [u8; 6], 133 mac_addr: [u8; 6],
147 ) -> Self { 134 ) -> Self {
148 // Enable necessary clocks. 135 // Enable the necessary clocks
149 #[cfg(not(rcc_h5))]
150 critical_section::with(|_| {
151 crate::pac::RCC.ahb1enr().modify(|w| {
152 w.set_eth1macen(true);
153 w.set_eth1txen(true);
154 w.set_eth1rxen(true);
155 });
156
157 crate::pac::SYSCFG.pmcr().modify(|w| w.set_epis(0b000));
158 });
159
160 #[cfg(rcc_h5)]
161 critical_section::with(|_| { 136 critical_section::with(|_| {
162 crate::pac::RCC.ahb1enr().modify(|w| { 137 crate::pac::RCC.ahb1enr().modify(|w| {
163 w.set_ethen(true); 138 w.set_ethen(true);
@@ -165,10 +140,9 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
165 w.set_ethrxen(true); 140 w.set_ethrxen(true);
166 }); 141 });
167 142
168 // TODO: This is for RMII - what would MII need here?
169 crate::pac::SYSCFG 143 crate::pac::SYSCFG
170 .pmcr() 144 .pmcr()
171 .modify(|w| w.set_eth_sel_phy(crate::pac::syscfg::vals::EthSelPhy::B_0X4)); 145 .modify(|w| w.set_eth_sel_phy(EthSelPhy::MII_GMII));
172 }); 146 });
173 147
174 into_ref!(rx_clk, tx_clk, mdio, mdc, rxdv, rx_d0, rx_d1, rx_d2, rx_d3, tx_d0, tx_d1, tx_d2, tx_d3, tx_en); 148 into_ref!(rx_clk, tx_clk, mdio, mdc, rxdv, rx_d0, rx_d1, rx_d2, rx_d3, tx_d0, tx_d1, tx_d2, tx_d3, tx_en);
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 7d2b49ff4..1f4e9ab1e 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -2,7 +2,7 @@
2#![allow(async_fn_in_trait)] 2#![allow(async_fn_in_trait)]
3#![cfg_attr( 3#![cfg_attr(
4 docsrs, 4 docsrs,
5 doc = "<div style='padding:30px;background:#810;color:#fff;text-align:center;'><p>You might want to <a href='https://docs.embassy.dev/embassy-stm32'>browse the `embassy-stm32` documentation on the Embassy website</a> instead.</p><p>The documentation here on `docs.rs` is built for a single chip only (STM32H755 in particular), while on the Embassy website you can pick your exact chip from the top menu. Available peripherals and their APIs change depending on the chip.</p></div>\n\n" 5 doc = "<div style='padding:30px;background:#810;color:#fff;text-align:center;'><p>You might want to <a href='https://docs.embassy.dev/embassy-stm32'>browse the `embassy-stm32` documentation on the Embassy website</a> instead.</p><p>The documentation here on `docs.rs` is built for a single chip only (stm32h7, stm32h7rs55 in particular), while on the Embassy website you can pick your exact chip from the top menu. Available peripherals and their APIs change depending on the chip.</p></div>\n\n"
6)] 6)]
7#![doc = include_str!("../README.md")] 7#![doc = include_str!("../README.md")]
8#![warn(missing_docs)] 8#![warn(missing_docs)]
@@ -303,9 +303,9 @@ pub fn init(config: Config) -> Peripherals {
303 303
304 #[cfg(not(any(stm32f1, stm32wb, stm32wl)))] 304 #[cfg(not(any(stm32f1, stm32wb, stm32wl)))]
305 peripherals::SYSCFG::enable_and_reset_with_cs(cs); 305 peripherals::SYSCFG::enable_and_reset_with_cs(cs);
306 #[cfg(not(any(stm32h5, stm32h7, stm32wb, stm32wl)))] 306 #[cfg(not(any(stm32h5, stm32h7, stm32h7rs, stm32wb, stm32wl)))]
307 peripherals::PWR::enable_and_reset_with_cs(cs); 307 peripherals::PWR::enable_and_reset_with_cs(cs);
308 #[cfg(not(any(stm32f2, stm32f4, stm32f7, stm32l0, stm32h5, stm32h7)))] 308 #[cfg(not(any(stm32f2, stm32f4, stm32f7, stm32l0, stm32h5, stm32h7, stm32h7rs)))]
309 peripherals::FLASH::enable_and_reset_with_cs(cs); 309 peripherals::FLASH::enable_and_reset_with_cs(cs);
310 310
311 // Enable the VDDIO2 power supply on chips that have it. 311 // Enable the VDDIO2 power supply on chips that have it.
diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs
index 54d3c662b..f3ac4fdbe 100644
--- a/embassy-stm32/src/rcc/bd.rs
+++ b/embassy-stm32/src/rcc/bd.rs
@@ -198,7 +198,7 @@ impl LsConfig {
198 } 198 }
199 199
200 // If not OK, reset backup domain and configure it. 200 // If not OK, reset backup domain and configure it.
201 #[cfg(not(any(rcc_l0, rcc_l0_v2, rcc_l1, stm32h5, stm32c0)))] 201 #[cfg(not(any(rcc_l0, rcc_l0_v2, rcc_l1, stm32h5, stm32h7rs, stm32c0)))]
202 { 202 {
203 bdcr().modify(|w| w.set_bdrst(true)); 203 bdcr().modify(|w| w.set_bdrst(true));
204 bdcr().modify(|w| w.set_bdrst(false)); 204 bdcr().modify(|w| w.set_bdrst(false));
@@ -210,11 +210,12 @@ impl LsConfig {
210 // letting half our RAM go magically *poof*. 210 // letting half our RAM go magically *poof*.
211 // STM32H503CB/EB/KB/RB device errata - 2.2.8 SRAM2 unduly erased upon a backup domain reset 211 // STM32H503CB/EB/KB/RB device errata - 2.2.8 SRAM2 unduly erased upon a backup domain reset
212 // STM32H562xx/563xx/573xx device errata - 2.2.14 SRAM2 is erased when the backup domain is reset 212 // STM32H562xx/563xx/573xx device errata - 2.2.14 SRAM2 is erased when the backup domain is reset
213 //#[cfg(any(stm32h5))] 213 //#[cfg(any(stm32h5, stm32h7rs))]
214 //{ 214 #[cfg(any(stm32h7rs))]
215 // bdcr().modify(|w| w.set_vswrst(true)); 215 {
216 // bdcr().modify(|w| w.set_vswrst(false)); 216 bdcr().modify(|w| w.set_vswrst(true));
217 //} 217 bdcr().modify(|w| w.set_vswrst(false));
218 }
218 #[cfg(any(stm32c0, stm32l0))] 219 #[cfg(any(stm32c0, stm32l0))]
219 { 220 {
220 bdcr().modify(|w| w.set_rtcrst(true)); 221 bdcr().modify(|w| w.set_rtcrst(true));
diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs
index aa8c4b1f7..5d47d400c 100644
--- a/embassy-stm32/src/rcc/h.rs
+++ b/embassy-stm32/src/rcc/h.rs
@@ -1,7 +1,6 @@
1use core::ops::RangeInclusive; 1use core::ops::RangeInclusive;
2 2
3use crate::pac; 3use crate::pac;
4use crate::pac::pwr::vals::Vos;
5pub use crate::pac::rcc::vals::{ 4pub use crate::pac::rcc::vals::{
6 Hsidiv as HSIPrescaler, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul, Pllsrc as PllSource, Sw as Sysclk, 5 Hsidiv as HSIPrescaler, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul, Pllsrc as PllSource, Sw as Sysclk,
7}; 6};
@@ -22,9 +21,12 @@ const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(128_000_000)..=Hertz(560_000
22const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(192_000_000)..=Hertz(836_000_000); 21const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(192_000_000)..=Hertz(836_000_000);
23#[cfg(any(pwr_h7rm0399, pwr_h7rm0433))] 22#[cfg(any(pwr_h7rm0399, pwr_h7rm0433))]
24const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(192_000_000)..=Hertz(960_000_000); 23const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(192_000_000)..=Hertz(960_000_000);
24#[cfg(any(stm32h7rs))]
25const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(384_000_000)..=Hertz(1672_000_000);
25 26
26pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; 27pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler};
27 28
29#[cfg(any(stm32h5, stm32h7))]
28#[derive(Clone, Copy, Eq, PartialEq)] 30#[derive(Clone, Copy, Eq, PartialEq)]
29pub enum VoltageScale { 31pub enum VoltageScale {
30 Scale0, 32 Scale0,
@@ -32,6 +34,8 @@ pub enum VoltageScale {
32 Scale2, 34 Scale2,
33 Scale3, 35 Scale3,
34} 36}
37#[cfg(any(stm32h7rs))]
38pub use crate::pac::pwr::vals::Vos as VoltageScale;
35 39
36#[derive(Clone, Copy, Eq, PartialEq)] 40#[derive(Clone, Copy, Eq, PartialEq)]
37pub enum HseMode { 41pub enum HseMode {
@@ -40,7 +44,7 @@ pub enum HseMode {
40 /// external analog clock (low swing) (HSEBYP=1, HSEEXT=0) 44 /// external analog clock (low swing) (HSEBYP=1, HSEEXT=0)
41 Bypass, 45 Bypass,
42 /// external digital clock (full swing) (HSEBYP=1, HSEEXT=1) 46 /// external digital clock (full swing) (HSEBYP=1, HSEEXT=1)
43 #[cfg(any(rcc_h5, rcc_h50))] 47 #[cfg(any(rcc_h5, rcc_h50, rcc_h7rs))]
44 BypassDigital, 48 BypassDigital,
45} 49}
46 50
@@ -65,8 +69,8 @@ pub struct Pll {
65 69
66 /// PLL P division factor. If None, PLL P output is disabled. 70 /// PLL P division factor. If None, PLL P output is disabled.
67 /// On PLL1, it must be even for most series (in particular, 71 /// On PLL1, it must be even for most series (in particular,
68 /// it cannot be 1 in series other than STM32H723/733, 72 /// it cannot be 1 in series other than stm32h7, stm32h7rs23/733,
69 /// STM32H725/735 and STM32H730.) 73 /// stm32h7, stm32h7rs25/735 and stm32h7, stm32h7rs30.)
70 pub divp: Option<PllDiv>, 74 pub divp: Option<PllDiv>,
71 /// PLL Q division factor. If None, PLL Q output is disabled. 75 /// PLL Q division factor. If None, PLL Q output is disabled.
72 pub divq: Option<PllDiv>, 76 pub divq: Option<PllDiv>,
@@ -115,7 +119,7 @@ impl From<TimerPrescaler> for Timpre {
115 119
116/// Power supply configuration 120/// Power supply configuration
117/// See RM0433 Rev 4 7.4 121/// See RM0433 Rev 4 7.4
118#[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))] 122#[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468, pwr_h7rs))]
119#[derive(PartialEq)] 123#[derive(PartialEq)]
120pub enum SupplyConfig { 124pub enum SupplyConfig {
121 /// Default power supply configuration. 125 /// Default power supply configuration.
@@ -164,8 +168,15 @@ pub enum SupplyConfig {
164/// SMPS step-down converter voltage output level. 168/// SMPS step-down converter voltage output level.
165/// This is only used in certain power supply configurations: 169/// This is only used in certain power supply configurations:
166/// SMPSLDO, SMPSExternalLDO, SMPSExternalLDOBypass. 170/// SMPSLDO, SMPSExternalLDO, SMPSExternalLDOBypass.
167#[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))] 171#[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468, pwr_h7rs))]
168pub use pac::pwr::vals::Sdlevel as SMPSSupplyVoltage; 172#[derive(Clone, Copy, Eq, PartialEq, Debug)]
173pub enum SMPSSupplyVoltage {
174 /// 1.8v
175 V1_8,
176 /// 2.5v
177 #[cfg(not(pwr_h7rs))]
178 V2_5,
179}
169 180
170/// Configuration of the core clocks 181/// Configuration of the core clocks
171#[non_exhaustive] 182#[non_exhaustive]
@@ -178,22 +189,26 @@ pub struct Config {
178 189
179 pub pll1: Option<Pll>, 190 pub pll1: Option<Pll>,
180 pub pll2: Option<Pll>, 191 pub pll2: Option<Pll>,
181 #[cfg(any(rcc_h5, stm32h7))] 192 #[cfg(any(rcc_h5, stm32h7, stm32h7rs))]
182 pub pll3: Option<Pll>, 193 pub pll3: Option<Pll>,
183 194
195 #[cfg(any(stm32h7, stm32h7rs))]
184 pub d1c_pre: AHBPrescaler, 196 pub d1c_pre: AHBPrescaler,
185 pub ahb_pre: AHBPrescaler, 197 pub ahb_pre: AHBPrescaler,
186 pub apb1_pre: APBPrescaler, 198 pub apb1_pre: APBPrescaler,
187 pub apb2_pre: APBPrescaler, 199 pub apb2_pre: APBPrescaler,
200 #[cfg(not(stm32h7rs))]
188 pub apb3_pre: APBPrescaler, 201 pub apb3_pre: APBPrescaler,
189 #[cfg(stm32h7)] 202 #[cfg(any(stm32h7, stm32h7rs))]
190 pub apb4_pre: APBPrescaler, 203 pub apb4_pre: APBPrescaler,
204 #[cfg(stm32h7rs)]
205 pub apb5_pre: APBPrescaler,
191 206
192 pub timer_prescaler: TimerPrescaler, 207 pub timer_prescaler: TimerPrescaler,
193 pub voltage_scale: VoltageScale, 208 pub voltage_scale: VoltageScale,
194 pub ls: super::LsConfig, 209 pub ls: super::LsConfig,
195 210
196 #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))] 211 #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468, pwr_h7rs))]
197 pub supply_config: SupplyConfig, 212 pub supply_config: SupplyConfig,
198 213
199 /// Per-peripheral kernel clock selection muxes 214 /// Per-peripheral kernel clock selection muxes
@@ -210,23 +225,30 @@ impl Default for Config {
210 sys: Sysclk::HSI, 225 sys: Sysclk::HSI,
211 pll1: None, 226 pll1: None,
212 pll2: None, 227 pll2: None,
213 #[cfg(any(rcc_h5, stm32h7))] 228 #[cfg(any(rcc_h5, stm32h7, stm32h7rs))]
214 pll3: None, 229 pll3: None,
215 230
231 #[cfg(any(stm32h7, stm32h7rs))]
216 d1c_pre: AHBPrescaler::DIV1, 232 d1c_pre: AHBPrescaler::DIV1,
217 ahb_pre: AHBPrescaler::DIV1, 233 ahb_pre: AHBPrescaler::DIV1,
218 apb1_pre: APBPrescaler::DIV1, 234 apb1_pre: APBPrescaler::DIV1,
219 apb2_pre: APBPrescaler::DIV1, 235 apb2_pre: APBPrescaler::DIV1,
236 #[cfg(not(stm32h7rs))]
220 apb3_pre: APBPrescaler::DIV1, 237 apb3_pre: APBPrescaler::DIV1,
221 #[cfg(stm32h7)] 238 #[cfg(any(stm32h7, stm32h7rs))]
222 apb4_pre: APBPrescaler::DIV1, 239 apb4_pre: APBPrescaler::DIV1,
240 #[cfg(stm32h7rs)]
241 apb5_pre: APBPrescaler::DIV1,
223 242
224 timer_prescaler: TimerPrescaler::DefaultX2, 243 timer_prescaler: TimerPrescaler::DefaultX2,
244 #[cfg(not(rcc_h7rs))]
225 voltage_scale: VoltageScale::Scale0, 245 voltage_scale: VoltageScale::Scale0,
246 #[cfg(rcc_h7rs)]
247 voltage_scale: VoltageScale::HIGH,
226 ls: Default::default(), 248 ls: Default::default(),
227 249
228 #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))] 250 #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468, pwr_h7rs))]
229 supply_config: SupplyConfig::Default, 251 supply_config: SupplyConfig::LDO,
230 252
231 mux: Default::default(), 253 mux: Default::default(),
232 } 254 }
@@ -234,24 +256,30 @@ impl Default for Config {
234} 256}
235 257
236pub(crate) unsafe fn init(config: Config) { 258pub(crate) unsafe fn init(config: Config) {
259 #[cfg(any(stm32h7))]
260 let pwr_reg = PWR.cr3();
261 #[cfg(any(stm32h7rs))]
262 let pwr_reg = PWR.csr2();
263
237 // NB. The lower bytes of CR3 can only be written once after 264 // NB. The lower bytes of CR3 can only be written once after
238 // POR, and must be written with a valid combination. Refer to 265 // POR, and must be written with a valid combination. Refer to
239 // RM0433 Rev 7 6.8.4. This is partially enforced by dropping 266 // RM0433 Rev 7 6.8.4. This is partially enforced by dropping
240 // `self` at the end of this method, but of course we cannot 267 // `self` at the end of this method, but of course we cannot
241 // know what happened between the previous POR and here. 268 // know what happened between the previous POR and here.
242 #[cfg(pwr_h7rm0433)] 269 #[cfg(pwr_h7rm0433)]
243 PWR.cr3().modify(|w| { 270 pwr_reg.modify(|w| {
244 w.set_scuen(true); 271 w.set_scuen(true);
245 w.set_ldoen(true); 272 w.set_ldoen(true);
246 w.set_bypass(false); 273 w.set_bypass(false);
247 }); 274 });
248 275
249 #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))] 276 #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468, pwr_h7rs))]
250 { 277 {
278 use pac::pwr::vals::Sdlevel;
251 match config.supply_config { 279 match config.supply_config {
252 SupplyConfig::Default => { 280 SupplyConfig::Default => {
253 PWR.cr3().modify(|w| { 281 pwr_reg.modify(|w| {
254 w.set_sdlevel(SMPSSupplyVoltage::RESET); 282 w.set_sdlevel(Sdlevel::RESET);
255 w.set_sdexthp(false); 283 w.set_sdexthp(false);
256 w.set_sden(true); 284 w.set_sden(true);
257 w.set_ldoen(true); 285 w.set_ldoen(true);
@@ -259,25 +287,30 @@ pub(crate) unsafe fn init(config: Config) {
259 }); 287 });
260 } 288 }
261 SupplyConfig::LDO => { 289 SupplyConfig::LDO => {
262 PWR.cr3().modify(|w| { 290 pwr_reg.modify(|w| {
263 w.set_sden(false); 291 w.set_sden(false);
264 w.set_ldoen(true); 292 w.set_ldoen(true);
265 w.set_bypass(false); 293 w.set_bypass(false);
266 }); 294 });
267 } 295 }
268 SupplyConfig::DirectSMPS => { 296 SupplyConfig::DirectSMPS => {
269 PWR.cr3().modify(|w| { 297 pwr_reg.modify(|w| {
270 w.set_sdexthp(false); 298 w.set_sdexthp(false);
271 w.set_sden(true); 299 w.set_sden(true);
272 w.set_ldoen(false); 300 w.set_ldoen(false);
273 w.set_bypass(false); 301 w.set_bypass(false);
274 }); 302 });
275 } 303 }
276 SupplyConfig::SMPSLDO(smps_supply_voltage) 304 SupplyConfig::SMPSLDO(sdlevel)
277 | SupplyConfig::SMPSExternalLDO(smps_supply_voltage) 305 | SupplyConfig::SMPSExternalLDO(sdlevel)
278 | SupplyConfig::SMPSExternalLDOBypass(smps_supply_voltage) => { 306 | SupplyConfig::SMPSExternalLDOBypass(sdlevel) => {
279 PWR.cr3().modify(|w| { 307 let sdlevel = match sdlevel {
280 w.set_sdlevel(smps_supply_voltage); 308 SMPSSupplyVoltage::V1_8 => Sdlevel::V1_8,
309 #[cfg(not(pwr_h7rs))]
310 SMPSSupplyVoltage::V2_5 => Sdlevel::V2_5,
311 };
312 pwr_reg.modify(|w| {
313 w.set_sdlevel(sdlevel);
281 w.set_sdexthp(matches!( 314 w.set_sdexthp(matches!(
282 config.supply_config, 315 config.supply_config,
283 SupplyConfig::SMPSExternalLDO(_) | SupplyConfig::SMPSExternalLDOBypass(_) 316 SupplyConfig::SMPSExternalLDO(_) | SupplyConfig::SMPSExternalLDOBypass(_)
@@ -291,7 +324,7 @@ pub(crate) unsafe fn init(config: Config) {
291 }); 324 });
292 } 325 }
293 SupplyConfig::SMPSDisabledLDOBypass => { 326 SupplyConfig::SMPSDisabledLDOBypass => {
294 PWR.cr3().modify(|w| { 327 pwr_reg.modify(|w| {
295 w.set_sden(false); 328 w.set_sden(false);
296 w.set_ldoen(false); 329 w.set_ldoen(false);
297 w.set_bypass(true); 330 w.set_bypass(true);
@@ -305,43 +338,49 @@ pub(crate) unsafe fn init(config: Config) {
305 // in the D3CR.VOS and CR3.SDLEVEL fields. By default after reset 338 // in the D3CR.VOS and CR3.SDLEVEL fields. By default after reset
306 // VOS = Scale 3, so check that the voltage on the VCAP pins = 339 // VOS = Scale 3, so check that the voltage on the VCAP pins =
307 // 1.0V. 340 // 1.0V.
308 #[cfg(any(pwr_h7rm0433, pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))] 341 #[cfg(any(stm32h7))]
309 while !PWR.csr1().read().actvosrdy() {} 342 while !PWR.csr1().read().actvosrdy() {}
343 #[cfg(any(stm32h7rs))]
344 while !PWR.sr1().read().actvosrdy() {}
310 345
311 // Configure voltage scale. 346 // Configure voltage scale.
312 #[cfg(any(pwr_h5, pwr_h50))] 347 #[cfg(any(pwr_h5, pwr_h50))]
313 { 348 {
314 PWR.voscr().modify(|w| { 349 PWR.voscr().modify(|w| {
315 w.set_vos(match config.voltage_scale { 350 w.set_vos(match config.voltage_scale {
316 VoltageScale::Scale0 => Vos::SCALE0, 351 VoltageScale::Scale0 => crate::pac::pwr::vals::Vos::SCALE0,
317 VoltageScale::Scale1 => Vos::SCALE1, 352 VoltageScale::Scale1 => crate::pac::pwr::vals::Vos::SCALE1,
318 VoltageScale::Scale2 => Vos::SCALE2, 353 VoltageScale::Scale2 => crate::pac::pwr::vals::Vos::SCALE2,
319 VoltageScale::Scale3 => Vos::SCALE3, 354 VoltageScale::Scale3 => crate::pac::pwr::vals::Vos::SCALE3,
320 }) 355 })
321 }); 356 });
322 while !PWR.vossr().read().vosrdy() {} 357 while !PWR.vossr().read().vosrdy() {}
323 } 358 }
324
325 #[cfg(syscfg_h7)] 359 #[cfg(syscfg_h7)]
326 { 360 {
327 // in chips without the overdrive bit, we can go from any scale to any scale directly. 361 // in chips without the overdrive bit, we can go from any scale to any scale directly.
328 PWR.d3cr().modify(|w| { 362 PWR.d3cr().modify(|w| {
329 w.set_vos(match config.voltage_scale { 363 w.set_vos(match config.voltage_scale {
330 VoltageScale::Scale0 => Vos::SCALE0, 364 VoltageScale::Scale0 => crate::pac::pwr::vals::Vos::SCALE0,
331 VoltageScale::Scale1 => Vos::SCALE1, 365 VoltageScale::Scale1 => crate::pac::pwr::vals::Vos::SCALE1,
332 VoltageScale::Scale2 => Vos::SCALE2, 366 VoltageScale::Scale2 => crate::pac::pwr::vals::Vos::SCALE2,
333 VoltageScale::Scale3 => Vos::SCALE3, 367 VoltageScale::Scale3 => crate::pac::pwr::vals::Vos::SCALE3,
334 }) 368 })
335 }); 369 });
336 while !PWR.d3cr().read().vosrdy() {} 370 while !PWR.d3cr().read().vosrdy() {}
337 } 371 }
372 #[cfg(pwr_h7rs)]
373 {
374 PWR.csr4().modify(|w| w.set_vos(config.voltage_scale));
375 while !PWR.csr4().read().vosrdy() {}
376 }
338 377
339 #[cfg(syscfg_h7od)] 378 #[cfg(syscfg_h7od)]
340 { 379 {
341 match config.voltage_scale { 380 match config.voltage_scale {
342 VoltageScale::Scale0 => { 381 VoltageScale::Scale0 => {
343 // to go to scale0, we must go to Scale1 first... 382 // to go to scale0, we must go to Scale1 first...
344 PWR.d3cr().modify(|w| w.set_vos(Vos::SCALE1)); 383 PWR.d3cr().modify(|w| w.set_vos(crate::pac::pwr::vals::Vos::SCALE1));
345 while !PWR.d3cr().read().vosrdy() {} 384 while !PWR.d3cr().read().vosrdy() {}
346 385
347 // Then enable overdrive. 386 // Then enable overdrive.
@@ -353,9 +392,9 @@ pub(crate) unsafe fn init(config: Config) {
353 PWR.d3cr().modify(|w| { 392 PWR.d3cr().modify(|w| {
354 w.set_vos(match config.voltage_scale { 393 w.set_vos(match config.voltage_scale {
355 VoltageScale::Scale0 => unreachable!(), 394 VoltageScale::Scale0 => unreachable!(),
356 VoltageScale::Scale1 => Vos::SCALE1, 395 VoltageScale::Scale1 => crate::pac::pwr::vals::Vos::SCALE1,
357 VoltageScale::Scale2 => Vos::SCALE2, 396 VoltageScale::Scale2 => crate::pac::pwr::vals::Vos::SCALE2,
358 VoltageScale::Scale3 => Vos::SCALE3, 397 VoltageScale::Scale3 => crate::pac::pwr::vals::Vos::SCALE3,
359 }) 398 })
360 }); 399 });
361 while !PWR.d3cr().read().vosrdy() {} 400 while !PWR.d3cr().read().vosrdy() {}
@@ -388,7 +427,7 @@ pub(crate) unsafe fn init(config: Config) {
388 Some(hse) => { 427 Some(hse) => {
389 RCC.cr().modify(|w| { 428 RCC.cr().modify(|w| {
390 w.set_hsebyp(hse.mode != HseMode::Oscillator); 429 w.set_hsebyp(hse.mode != HseMode::Oscillator);
391 #[cfg(any(rcc_h5, rcc_h50))] 430 #[cfg(any(rcc_h5, rcc_h50, rcc_h7rs))]
392 w.set_hseext(match hse.mode { 431 w.set_hseext(match hse.mode {
393 HseMode::Oscillator | HseMode::Bypass => pac::rcc::vals::Hseext::ANALOG, 432 HseMode::Oscillator | HseMode::Bypass => pac::rcc::vals::Hseext::ANALOG,
394 HseMode::BypassDigital => pac::rcc::vals::Hseext::DIGITAL, 433 HseMode::BypassDigital => pac::rcc::vals::Hseext::DIGITAL,
@@ -414,7 +453,7 @@ pub(crate) unsafe fn init(config: Config) {
414 }; 453 };
415 454
416 // H7 has shared PLLSRC, check it's equal in all PLLs. 455 // H7 has shared PLLSRC, check it's equal in all PLLs.
417 #[cfg(stm32h7)] 456 #[cfg(any(stm32h7, stm32h7rs))]
418 { 457 {
419 let plls = [&config.pll1, &config.pll2, &config.pll3]; 458 let plls = [&config.pll1, &config.pll2, &config.pll3];
420 if !super::util::all_equal(plls.into_iter().flatten().map(|p| p.source)) { 459 if !super::util::all_equal(plls.into_iter().flatten().map(|p| p.source)) {
@@ -426,7 +465,7 @@ pub(crate) unsafe fn init(config: Config) {
426 let pll_input = PllInput { csi, hse, hsi }; 465 let pll_input = PllInput { csi, hse, hsi };
427 let pll1 = init_pll(0, config.pll1, &pll_input); 466 let pll1 = init_pll(0, config.pll1, &pll_input);
428 let pll2 = init_pll(1, config.pll2, &pll_input); 467 let pll2 = init_pll(1, config.pll2, &pll_input);
429 #[cfg(any(rcc_h5, stm32h7))] 468 #[cfg(any(rcc_h5, stm32h7, stm32h7rs))]
430 let pll3 = init_pll(2, config.pll3, &pll_input); 469 let pll3 = init_pll(2, config.pll3, &pll_input);
431 470
432 // Configure sysclk 471 // Configure sysclk
@@ -474,8 +513,13 @@ pub(crate) unsafe fn init(config: Config) {
474 VoltageScale::Scale2 => (Hertz(300_000_000), Hertz(150_000_000), Hertz(75_000_000)), 513 VoltageScale::Scale2 => (Hertz(300_000_000), Hertz(150_000_000), Hertz(75_000_000)),
475 VoltageScale::Scale3 => (Hertz(200_000_000), Hertz(100_000_000), Hertz(50_000_000)), 514 VoltageScale::Scale3 => (Hertz(200_000_000), Hertz(100_000_000), Hertz(50_000_000)),
476 }; 515 };
516 #[cfg(stm32h7rs)]
517 let (d1cpre_clk_max, hclk_max, pclk_max) = match config.voltage_scale {
518 VoltageScale::HIGH => (Hertz(600_000_000), Hertz(300_000_000), Hertz(150_000_000)),
519 VoltageScale::LOW => (Hertz(400_000_000), Hertz(200_000_000), Hertz(100_000_000)),
520 };
477 521
478 #[cfg(stm32h7)] 522 #[cfg(any(stm32h7, stm32h7rs))]
479 let hclk = { 523 let hclk = {
480 let d1cpre_clk = sys / config.d1c_pre; 524 let d1cpre_clk = sys / config.d1c_pre;
481 assert!(d1cpre_clk <= d1cpre_clk_max); 525 assert!(d1cpre_clk <= d1cpre_clk_max);
@@ -491,12 +535,18 @@ pub(crate) unsafe fn init(config: Config) {
491 let apb2 = hclk / config.apb2_pre; 535 let apb2 = hclk / config.apb2_pre;
492 let apb2_tim = apb_div_tim(&config.apb2_pre, hclk, config.timer_prescaler); 536 let apb2_tim = apb_div_tim(&config.apb2_pre, hclk, config.timer_prescaler);
493 assert!(apb2 <= pclk_max); 537 assert!(apb2 <= pclk_max);
538 #[cfg(not(stm32h7rs))]
494 let apb3 = hclk / config.apb3_pre; 539 let apb3 = hclk / config.apb3_pre;
540 #[cfg(not(stm32h7rs))]
495 assert!(apb3 <= pclk_max); 541 assert!(apb3 <= pclk_max);
496 #[cfg(stm32h7)] 542 #[cfg(any(stm32h7, stm32h7rs))]
497 let apb4 = hclk / config.apb4_pre; 543 let apb4 = hclk / config.apb4_pre;
498 #[cfg(stm32h7)] 544 #[cfg(any(stm32h7, stm32h7rs))]
499 assert!(apb4 <= pclk_max); 545 assert!(apb4 <= pclk_max);
546 #[cfg(stm32h7rs)]
547 let apb5 = hclk / config.apb5_pre;
548 #[cfg(stm32h7rs)]
549 assert!(apb5 <= pclk_max);
500 550
501 flash_setup(hclk, config.voltage_scale); 551 flash_setup(hclk, config.voltage_scale);
502 552
@@ -520,6 +570,25 @@ pub(crate) unsafe fn init(config: Config) {
520 w.set_d3ppre(config.apb4_pre); 570 w.set_d3ppre(config.apb4_pre);
521 }); 571 });
522 } 572 }
573 #[cfg(stm32h7rs)]
574 {
575 RCC.cdcfgr().write(|w| {
576 w.set_cpre(config.d1c_pre);
577 });
578 while RCC.cdcfgr().read().cpre() != config.d1c_pre {}
579
580 RCC.bmcfgr().write(|w| {
581 w.set_bmpre(config.ahb_pre);
582 });
583 while RCC.bmcfgr().read().bmpre() != config.ahb_pre {}
584
585 RCC.apbcfgr().modify(|w| {
586 w.set_ppre1(config.apb1_pre);
587 w.set_ppre2(config.apb2_pre);
588 w.set_ppre4(config.apb4_pre);
589 w.set_ppre5(config.apb5_pre);
590 });
591 }
523 #[cfg(stm32h5)] 592 #[cfg(stm32h5)]
524 { 593 {
525 // Set hpre 594 // Set hpre
@@ -540,7 +609,7 @@ pub(crate) unsafe fn init(config: Config) {
540 while RCC.cfgr().read().sws() != config.sys {} 609 while RCC.cfgr().read().sws() != config.sys {}
541 610
542 // IO compensation cell - Requires CSI clock and SYSCFG 611 // IO compensation cell - Requires CSI clock and SYSCFG
543 #[cfg(stm32h7)] // TODO h5 612 #[cfg(any(stm32h7))] // TODO h5, h7rs
544 if csi.is_some() { 613 if csi.is_some() {
545 // Enable the compensation cell, using back-bias voltage code 614 // Enable the compensation cell, using back-bias voltage code
546 // provide by the cell. 615 // provide by the cell.
@@ -551,7 +620,7 @@ pub(crate) unsafe fn init(config: Config) {
551 w.set_hslv(false); 620 w.set_hslv(false);
552 }) 621 })
553 }); 622 });
554 while !pac::SYSCFG.cccsr().read().ready() {} 623 while !pac::SYSCFG.cccsr().read().rdy() {}
555 } 624 }
556 625
557 config.mux.init(); 626 config.mux.init();
@@ -562,11 +631,17 @@ pub(crate) unsafe fn init(config: Config) {
562 hclk2: Some(hclk), 631 hclk2: Some(hclk),
563 hclk3: Some(hclk), 632 hclk3: Some(hclk),
564 hclk4: Some(hclk), 633 hclk4: Some(hclk),
634 #[cfg(stm32h7rs)]
635 hclk5: Some(hclk),
565 pclk1: Some(apb1), 636 pclk1: Some(apb1),
566 pclk2: Some(apb2), 637 pclk2: Some(apb2),
638 #[cfg(not(stm32h7rs))]
567 pclk3: Some(apb3), 639 pclk3: Some(apb3),
568 #[cfg(stm32h7)] 640 #[cfg(any(stm32h7, stm32h7rs))]
569 pclk4: Some(apb4), 641 pclk4: Some(apb4),
642 #[cfg(stm32h7rs)]
643 pclk5: Some(apb5),
644
570 pclk1_tim: Some(apb1_tim), 645 pclk1_tim: Some(apb1_tim),
571 pclk2_tim: Some(apb2_tim), 646 pclk2_tim: Some(apb2_tim),
572 rtc: rtc, 647 rtc: rtc,
@@ -584,11 +659,15 @@ pub(crate) unsafe fn init(config: Config) {
584 pll2_p: pll2.p, 659 pll2_p: pll2.p,
585 pll2_q: pll2.q, 660 pll2_q: pll2.q,
586 pll2_r: pll2.r, 661 pll2_r: pll2.r,
587 #[cfg(any(rcc_h5, stm32h7))] 662 #[cfg(stm32h7rs)]
663 pll2_s: None, // TODO
664 #[cfg(stm32h7rs)]
665 pll2_t: None, // TODO
666 #[cfg(any(rcc_h5, stm32h7, stm32h7rs))]
588 pll3_p: pll3.p, 667 pll3_p: pll3.p,
589 #[cfg(any(rcc_h5, stm32h7))] 668 #[cfg(any(rcc_h5, stm32h7, stm32h7rs))]
590 pll3_q: pll3.q, 669 pll3_q: pll3.q,
591 #[cfg(any(rcc_h5, stm32h7))] 670 #[cfg(any(rcc_h5, stm32h7, stm32h7rs))]
592 pll3_r: pll3.r, 671 pll3_r: pll3.r,
593 672
594 #[cfg(rcc_h50)] 673 #[cfg(rcc_h50)]
@@ -601,8 +680,14 @@ pub(crate) unsafe fn init(config: Config) {
601 #[cfg(stm32h5)] 680 #[cfg(stm32h5)]
602 audioclk: None, 681 audioclk: None,
603 i2s_ckin: None, 682 i2s_ckin: None,
604 #[cfg(stm32h7)] 683 #[cfg(any(stm32h7, stm32h7rs))]
605 dsi_phy: None, // TODO 684 dsi_phy: None, // TODO
685 #[cfg(stm32h7rs)]
686 spdifrx_symb: None, // TODO
687 #[cfg(stm32h7rs)]
688 clk48mohci: None, // TODO
689 #[cfg(stm32h7rs)]
690 usb: None, // TODO
606 ); 691 );
607} 692}
608 693
@@ -627,7 +712,7 @@ fn init_pll(num: usize, config: Option<Pll>, input: &PllInput) -> PllOutput {
627 while RCC.cr().read().pllrdy(num) {} 712 while RCC.cr().read().pllrdy(num) {}
628 713
629 // "To save power when PLL1 is not used, the value of PLL1M must be set to 0."" 714 // "To save power when PLL1 is not used, the value of PLL1M must be set to 0.""
630 #[cfg(stm32h7)] 715 #[cfg(any(stm32h7, stm32h7rs))]
631 RCC.pllckselr().write(|w| w.set_divm(num, PllPreDiv::from_bits(0))); 716 RCC.pllckselr().write(|w| w.set_divm(num, PllPreDiv::from_bits(0)));
632 #[cfg(stm32h5)] 717 #[cfg(stm32h5)]
633 RCC.pllcfgr(num).write(|w| w.set_divm(PllPreDiv::from_bits(0))); 718 RCC.pllcfgr(num).write(|w| w.set_divm(PllPreDiv::from_bits(0)));
@@ -696,7 +781,7 @@ fn init_pll(num: usize, config: Option<Pll>, input: &PllInput) -> PllOutput {
696 w.set_pllren(r.is_some()); 781 w.set_pllren(r.is_some());
697 }); 782 });
698 783
699 #[cfg(stm32h7)] 784 #[cfg(any(stm32h7, stm32h7rs))]
700 { 785 {
701 RCC.pllckselr().modify(|w| { 786 RCC.pllckselr().modify(|w| {
702 w.set_divm(num, config.prediv); 787 w.set_divm(num, config.prediv);
@@ -850,6 +935,26 @@ fn flash_setup(clk: Hertz, vos: VoltageScale) {
850 (VoltageScale::Scale3, ..=88) => (3, 1), 935 (VoltageScale::Scale3, ..=88) => (3, 1),
851 _ => unreachable!(), 936 _ => unreachable!(),
852 }; 937 };
938 #[cfg(flash_h7rs)]
939 let (latency, wrhighfreq) = match (vos, clk.0) {
940 // VOS high range VCORE 1.30V - 1.40V
941 (VoltageScale::HIGH, ..=40_000_000) => (0, 0),
942 (VoltageScale::HIGH, ..=80_000_000) => (1, 0),
943 (VoltageScale::HIGH, ..=120_000_000) => (2, 1),
944 (VoltageScale::HIGH, ..=160_000_000) => (3, 1),
945 (VoltageScale::HIGH, ..=200_000_000) => (4, 2),
946 (VoltageScale::HIGH, ..=240_000_000) => (5, 2),
947 (VoltageScale::HIGH, ..=280_000_000) => (6, 3),
948 (VoltageScale::HIGH, ..=320_000_000) => (7, 3),
949 // VOS low range VCORE 1.15V - 1.26V
950 (VoltageScale::LOW, ..=36_000_000) => (0, 0),
951 (VoltageScale::LOW, ..=72_000_000) => (1, 0),
952 (VoltageScale::LOW, ..=108_000_000) => (2, 1),
953 (VoltageScale::LOW, ..=144_000_000) => (3, 1),
954 (VoltageScale::LOW, ..=180_000_000) => (4, 2),
955 (VoltageScale::LOW, ..=216_000_000) => (5, 2),
956 _ => unreachable!(),
957 };
853 958
854 debug!("flash: latency={} wrhighfreq={}", latency, wrhighfreq); 959 debug!("flash: latency={} wrhighfreq={}", latency, wrhighfreq);
855 960
diff --git a/embassy-stm32/src/rcc/hsi48.rs b/embassy-stm32/src/rcc/hsi48.rs
index 6f0d7b379..da81abc34 100644
--- a/embassy-stm32/src/rcc/hsi48.rs
+++ b/embassy-stm32/src/rcc/hsi48.rs
@@ -33,9 +33,9 @@ pub(crate) fn init_hsi48(config: Hsi48Config) -> Hertz {
33 }); 33 });
34 34
35 // Enable HSI48 35 // Enable HSI48
36 #[cfg(not(any(stm32u5, stm32g0, stm32h5, stm32h7, stm32u5, stm32wba, stm32f0)))] 36 #[cfg(not(any(stm32u5, stm32g0, stm32h5, stm32h7, stm32h7rs, stm32u5, stm32wba, stm32f0)))]
37 let r = RCC.crrcr(); 37 let r = RCC.crrcr();
38 #[cfg(any(stm32u5, stm32g0, stm32h5, stm32h7, stm32u5, stm32wba))] 38 #[cfg(any(stm32u5, stm32g0, stm32h5, stm32h7, stm32h7rs, stm32u5, stm32wba))]
39 let r = RCC.cr(); 39 let r = RCC.cr();
40 #[cfg(any(stm32f0))] 40 #[cfg(any(stm32f0))]
41 let r = RCC.cr2(); 41 let r = RCC.cr2();
diff --git a/embassy-stm32/src/rcc/mco.rs b/embassy-stm32/src/rcc/mco.rs
index 4b22a099d..40e963466 100644
--- a/embassy-stm32/src/rcc/mco.rs
+++ b/embassy-stm32/src/rcc/mco.rs
@@ -5,9 +5,31 @@ use embassy_hal_internal::into_ref;
5use crate::gpio::{AFType, Speed}; 5use crate::gpio::{AFType, Speed};
6#[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))] 6#[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))]
7pub use crate::pac::rcc::vals::Mcopre as McoPrescaler; 7pub use crate::pac::rcc::vals::Mcopre as McoPrescaler;
8#[cfg(not(any(rcc_f2, rcc_f410, rcc_f4, rcc_f7, rcc_h50, rcc_h5, rcc_h7ab, rcc_h7rm0433, rcc_h7)))] 8#[cfg(not(any(
9 rcc_f2,
10 rcc_f410,
11 rcc_f4,
12 rcc_f7,
13 rcc_h50,
14 rcc_h5,
15 rcc_h7ab,
16 rcc_h7rm0433,
17 rcc_h7,
18 rcc_h7rs
19)))]
9pub use crate::pac::rcc::vals::Mcosel as McoSource; 20pub use crate::pac::rcc::vals::Mcosel as McoSource;
10#[cfg(any(rcc_f2, rcc_f410, rcc_f4, rcc_f7, rcc_h50, rcc_h5, rcc_h7ab, rcc_h7rm0433, rcc_h7))] 21#[cfg(any(
22 rcc_f2,
23 rcc_f410,
24 rcc_f4,
25 rcc_f7,
26 rcc_h50,
27 rcc_h5,
28 rcc_h7ab,
29 rcc_h7rm0433,
30 rcc_h7,
31 rcc_h7rs
32))]
11pub use crate::pac::rcc::vals::{Mco1sel as Mco1Source, Mco2sel as Mco2Source}; 33pub use crate::pac::rcc::vals::{Mco1sel as Mco1Source, Mco2sel as Mco2Source};
12use crate::pac::RCC; 34use crate::pac::RCC;
13use crate::{peripherals, Peripheral}; 35use crate::{peripherals, Peripheral};
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index a4e497fe7..a585940bc 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -24,7 +24,7 @@ pub use hsi48::*;
24#[cfg_attr(stm32c0, path = "c0.rs")] 24#[cfg_attr(stm32c0, path = "c0.rs")]
25#[cfg_attr(stm32g0, path = "g0.rs")] 25#[cfg_attr(stm32g0, path = "g0.rs")]
26#[cfg_attr(stm32g4, path = "g4.rs")] 26#[cfg_attr(stm32g4, path = "g4.rs")]
27#[cfg_attr(any(stm32h5, stm32h7), path = "h.rs")] 27#[cfg_attr(any(stm32h5, stm32h7, stm32h7rs), path = "h.rs")]
28#[cfg_attr(any(stm32l0, stm32l1, stm32l4, stm32l5, stm32wb, stm32wl, stm32u0), path = "l.rs")] 28#[cfg_attr(any(stm32l0, stm32l1, stm32l4, stm32l5, stm32wb, stm32wl, stm32u0), path = "l.rs")]
29#[cfg_attr(stm32u5, path = "u5.rs")] 29#[cfg_attr(stm32u5, path = "u5.rs")]
30#[cfg_attr(stm32wba, path = "wba.rs")] 30#[cfg_attr(stm32wba, path = "wba.rs")]
diff --git a/embassy-stm32/src/ucpd.rs b/embassy-stm32/src/ucpd.rs
index fe614b811..63412f9b7 100644
--- a/embassy-stm32/src/ucpd.rs
+++ b/embassy-stm32/src/ucpd.rs
@@ -58,7 +58,7 @@ pub(crate) fn init(
58 }) 58 })
59 } 59 }
60 60
61 #[cfg(any(stm32h5, stm32u5))] 61 #[cfg(any(stm32h5, stm32u5, stm32h7rs))]
62 { 62 {
63 crate::pac::PWR.ucpdr().modify(|w| { 63 crate::pac::PWR.ucpdr().modify(|w| {
64 w.set_ucpd_dbdis(!ucpd1_db_enable); 64 w.set_ucpd_dbdis(!ucpd1_db_enable);
diff --git a/embassy-stm32/src/usb/otg.rs b/embassy-stm32/src/usb/otg.rs
index 5d0e1116e..3debd5079 100644
--- a/embassy-stm32/src/usb/otg.rs
+++ b/embassy-stm32/src/usb/otg.rs
@@ -371,7 +371,7 @@ foreach_interrupt!(
371 } else if #[cfg(stm32g0x1)] { 371 } else if #[cfg(stm32g0x1)] {
372 const FIFO_DEPTH_WORDS: u16 = 512; 372 const FIFO_DEPTH_WORDS: u16 = 512;
373 const ENDPOINT_COUNT: usize = 8; 373 const ENDPOINT_COUNT: usize = 8;
374 } else if #[cfg(stm32h7)] { 374 } else if #[cfg(any(stm32h7, stm32h7rs))] {
375 const FIFO_DEPTH_WORDS: u16 = 1024; 375 const FIFO_DEPTH_WORDS: u16 = 1024;
376 const ENDPOINT_COUNT: usize = 9; 376 const ENDPOINT_COUNT: usize = 9;
377 } else if #[cfg(stm32u5)] { 377 } else if #[cfg(stm32u5)] {
@@ -420,7 +420,7 @@ foreach_interrupt!(
420 stm32f469, 420 stm32f469,
421 stm32f479, 421 stm32f479,
422 stm32f7, 422 stm32f7,
423 stm32h7, 423 stm32h7, stm32h7rs,
424 ))] { 424 ))] {
425 const FIFO_DEPTH_WORDS: u16 = 1024; 425 const FIFO_DEPTH_WORDS: u16 = 1024;
426 const ENDPOINT_COUNT: usize = 9; 426 const ENDPOINT_COUNT: usize = 9;