Skip to content

Commit 9121243

Browse files
Merge #37
37: dualcore: Basic dual core support. r=jordens a=richardeoin Only the Cortex-M7 core is currently supported upstream Co-authored-by: Richard Meadows <[email protected]>
2 parents 24d1359 + 373284e commit 9121243

File tree

11 files changed

+138
-34
lines changed

11 files changed

+138
-34
lines changed

.travis.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,12 @@ before_script:
1717
- rustup target add thumbv7em-none-eabihf
1818

1919
env:
20-
- MCU=stm32h742
2120
- MCU=stm32h743
2221
- MCU=stm32h753
23-
- MCU=stm32h750
24-
- MCU=stm32h742v
2522
- MCU=stm32h743v
2623
- MCU=stm32h753v
27-
- MCU=stm32h750v
24+
- MCU=stm32h747cm7
25+
- MCU=stm32h757cm7
2826

2927
matrix:
3028
allow_failures:

Cargo.toml

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,21 @@ default = ["unproven"]
3939
unproven = ["embedded-hal/unproven"]
4040
device-selected = []
4141
revision_v = []
42+
singlecore = []
43+
dualcore = []
44+
cm4 = []
45+
cm7 = []
4246
rt = ["stm32h7/rt"]
43-
stm32h742 = ["stm32h7/stm32h743", "device-selected"]
44-
stm32h743 = ["stm32h7/stm32h743", "device-selected"]
45-
stm32h753 = ["stm32h7/stm32h753", "device-selected"]
46-
stm32h750 = ["stm32h7/stm32h743", "device-selected"]
47-
stm32h742v = ["stm32h7/stm32h743v", "device-selected", "revision_v"]
48-
stm32h743v = ["stm32h7/stm32h743v", "device-selected", "revision_v"]
49-
stm32h753v = ["stm32h7/stm32h753v", "device-selected", "revision_v"]
50-
stm32h750v = ["stm32h7/stm32h743v", "device-selected", "revision_v"]
47+
stm32h742 = ["stm32h7/stm32h743", "device-selected", "singlecore"]
48+
stm32h743 = ["stm32h7/stm32h743", "device-selected", "singlecore"]
49+
stm32h753 = ["stm32h7/stm32h753", "device-selected", "singlecore"]
50+
stm32h750 = ["stm32h7/stm32h743", "device-selected", "singlecore"]
51+
stm32h742v = ["stm32h7/stm32h743v", "device-selected", "revision_v", "singlecore"]
52+
stm32h743v = ["stm32h7/stm32h743v", "device-selected", "revision_v", "singlecore"]
53+
stm32h753v = ["stm32h7/stm32h753v", "device-selected", "revision_v", "singlecore"]
54+
stm32h750v = ["stm32h7/stm32h743v", "device-selected", "revision_v", "singlecore"]
55+
stm32h747cm7 = ["stm32h7/stm32h747cm7", "device-selected", "revision_v", "dualcore", "cm7"]
56+
stm32h757cm7 = ["stm32h7/stm32h757cm7", "device-selected", "revision_v", "dualcore", "cm7"]
5157

5258

5359
[profile.dev]

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ supported with the following feature gates:
3333

3434
Again, feature gates `stm32h742v`, `stm32h750v` also exist.
3535

36+
There is also support for dual core parts. Currently only the
37+
Cortex-M7 core is supported.
38+
39+
* stm32h747cm7 ✔️
40+
* stm32h757cm7 ✔️
41+
3642
The idea behind this crate is to gloss over the slight differences in
3743
the various peripherals available on those MCUs so a HAL can be
3844
written for all chips in that same family without having to cut and

examples/watchdog.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,14 @@ fn main() -> ! {
2828
let rcc = dp.RCC.constrain();
2929
let ccdr = rcc.sys_ck(96.mhz()).freeze(vos, &dp.SYSCFG);
3030

31+
#[cfg(any(feature = "singlecore"))]
3132
let mut watchdog = SystemWindowWatchdog::new(dp.WWDG, &ccdr);
3233

34+
#[cfg(all(feature = "dualcore", feature = "cm7"))]
35+
let mut watchdog = SystemWindowWatchdog::new(dp.WWDG1, &ccdr);
36+
#[cfg(all(feature = "dualcore", feature = "cm4"))]
37+
let mut watchdog = SystemWindowWatchdog::new(dp.WWDG2, &ccdr);
38+
3339
println!(log, "");
3440
println!(log, "stm32h7xx-hal example - Watchdog");
3541
println!(log, "");

src/delay.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,20 @@ impl DelayUs<u32> for Delay {
6161
const MAX_RVR: u32 = 0x00FF_FFFF;
6262

6363
// With c_ck up to 480e6, we need u64 for delays > 8.9s
64+
#[cfg(any(feature = "singlecore"))]
6465
let mut total_rvr =
6566
u64::from(us) * u64::from(self.clocks.c_ck().0 / 1_000_000);
6667

68+
// Dual core has an additional divide by 8
69+
#[cfg(all(feature = "dualcore", feature = "cm7"))]
70+
let mut total_rvr =
71+
u64::from(us) * u64::from(self.clocks.c_ck().0 / 8_000_000);
72+
73+
// CM4 dervived from HCLK
74+
#[cfg(all(feature = "dualcore", feature = "cm4"))]
75+
let mut total_rvr =
76+
u64::from(us) * u64::from(self.clocks.hclk().0 / 8_000_000);
77+
6778
while total_rvr != 0 {
6879
let current_rvr = if total_rvr <= MAX_RVR.into() {
6980
total_rvr as u32

src/gpio.rs

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -270,17 +270,41 @@ macro_rules! gpio {
270270

271271
/// Enable external interrupts from this pin.
272272
fn enable_interrupt(&mut self, exti: &mut EXTI) {
273-
exti.cpuimr1.modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.i)) });
273+
#[cfg(any(feature = "singlecore"))]
274+
let imr1 = &exti.cpuimr1;
275+
#[cfg(all(feature = "dualcore", feature = "cm7"))]
276+
let imr1 = &exti.c1imr1;
277+
#[cfg(all(feature = "dualcore", feature = "cm4"))]
278+
let imr1 = &exti.c2imr1;
279+
280+
imr1.modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.i)) });
274281
}
275282

276283
/// Disable external interrupts from this pin
277284
fn disable_interrupt(&mut self, exti: &mut EXTI) {
278-
exti.cpuimr1.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << self.i)) });
285+
#[cfg(any(feature = "singlecore"))]
286+
let imr1 = &exti.cpuimr1;
287+
#[cfg(all(feature = "dualcore", feature = "cm7"))]
288+
let imr1 = &exti.c1imr1;
289+
#[cfg(all(feature = "dualcore", feature = "cm4"))]
290+
let imr1 = &exti.c2imr1;
291+
292+
imr1.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << self.i)) });
279293
}
280294

281295
/// Clear the interrupt pending bit for this pin
282296
fn clear_interrupt_pending_bit(&mut self) {
283-
unsafe { (*EXTI::ptr()).cpupr1.write(|w| w.bits(1 << self.i) ) };
297+
unsafe {
298+
#[cfg(any(feature = "singlecore"))]
299+
let pr1 = &(*EXTI::ptr()).cpupr1;
300+
#[cfg(all(feature = "dualcore", feature = "cm7"))]
301+
let pr1 = &(*EXTI::ptr()).c1pr1;
302+
#[cfg(all(feature = "dualcore", feature = "cm4"))]
303+
let pr1 = &(*EXTI::ptr()).c2pr1;
304+
305+
306+
pr1.write(|w| w.bits(1 << self.i) );
307+
}
284308
}
285309
}
286310

@@ -693,20 +717,42 @@ macro_rules! gpio {
693717

694718
/// Enable external interrupts from this pin.
695719
fn enable_interrupt(&mut self, exti: &mut EXTI) {
696-
exti.cpuimr1.modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) });
720+
#[cfg(any(feature = "singlecore"))]
721+
let imr1 = &exti.cpuimr1;
722+
#[cfg(all(feature = "dualcore", feature = "cm7"))]
723+
let imr1 = &exti.c1imr1;
724+
#[cfg(all(feature = "dualcore", feature = "cm4"))]
725+
let imr1 = &exti.c2imr1;
726+
727+
imr1.modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) });
697728
}
698729

699730
/// Disable external interrupts from this pin
700731
fn disable_interrupt(&mut self, exti: &mut EXTI) {
701-
exti.cpuimr1.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) });
732+
#[cfg(any(feature = "singlecore"))]
733+
let imr1 = &exti.cpuimr1;
734+
#[cfg(all(feature = "dualcore", feature = "cm7"))]
735+
let imr1 = &exti.c1imr1;
736+
#[cfg(all(feature = "dualcore", feature = "cm4"))]
737+
let imr1 = &exti.c2imr1;
738+
739+
imr1.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) });
702740
}
703741

704742
/// Clear the interrupt pending bit for this pin
705743
fn clear_interrupt_pending_bit(&mut self) {
706-
unsafe { (*EXTI::ptr()).cpupr1.write(|w| w.bits(1 << $i) ) };
744+
unsafe {
745+
#[cfg(any(feature = "singlecore"))]
746+
let pr1 = &(*(EXTI::ptr())).cpupr1;
747+
#[cfg(all(feature = "dualcore", feature = "cm7"))]
748+
let pr1 = &(*(EXTI::ptr())).c1pr1;
749+
#[cfg(all(feature = "dualcore", feature = "cm4"))]
750+
let pr1 = &(*(EXTI::ptr())).c2pr1;
751+
752+
pr1.write(|w| w.bits(1 << $i));
753+
};
707754
}
708755
}
709-
710756
)+
711757
}
712758
}

src/lib.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ compile_error!(
1515
stm32h743v
1616
stm32h753v
1717
stm32h750v
18+
stm32h747cm7
19+
stm32h757cm7
1820
"
1921
);
2022

@@ -23,27 +25,34 @@ pub use embedded_hal as hal;
2325
pub use nb;
2426
pub use nb::block;
2527

28+
// Single core
2629
#[cfg(any(
2730
feature = "stm32h742",
2831
feature = "stm32h743",
2932
feature = "stm32h750",
3033
))]
3134
pub use stm32h7::stm32h743 as stm32;
32-
#[cfg(any(
33-
feature = "stm32h753",
34-
))]
35-
pub use stm32h7::stm32h753 as stm32;
3635
#[cfg(any(
3736
feature = "stm32h742v",
3837
feature = "stm32h743v",
3938
feature = "stm32h750v",
4039
))]
4140
pub use stm32h7::stm32h743v as stm32;
42-
#[cfg(any(
43-
feature = "stm32h753v",
44-
))]
41+
42+
// Single core with crypto
43+
#[cfg(any(feature = "stm32h753",))]
44+
pub use stm32h7::stm32h753 as stm32;
45+
#[cfg(any(feature = "stm32h753v",))]
4546
pub use stm32h7::stm32h753v as stm32;
4647

48+
// Dual core
49+
#[cfg(any(feature = "stm32h747cm7",))]
50+
pub use stm32h7::stm32h747cm7 as stm32;
51+
#[cfg(any(feature = "stm32h757cm7",))]
52+
pub use stm32h7::stm32h757cm7 as stm32;
53+
54+
#[cfg(all(feature = "singlecore", feature = "dualcore"))]
55+
compile_error!("Cannot not select both singlecore and dualcore");
4756

4857
#[cfg(feature = "device-selected")]
4958
pub use crate::stm32 as pac;
@@ -54,6 +63,8 @@ pub use crate::stm32 as device;
5463
#[cfg(feature = "rt")]
5564
pub use crate::stm32::interrupt;
5665

66+
#[cfg(feature = "device-selected")]
67+
pub mod adc;
5768
#[cfg(feature = "device-selected")]
5869
pub mod delay;
5970
#[cfg(feature = "device-selected")]
@@ -86,5 +97,3 @@ pub mod time;
8697
pub mod timer;
8798
#[cfg(feature = "device-selected")]
8899
pub mod watchdog;
89-
#[cfg(feature = "device-selected")]
90-
pub mod adc;

src/prelude.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
//! Prelude
22
pub use embedded_hal::prelude::*;
33

4+
#[cfg(all(feature = "device-selected", feature = "singlecore"))]
45
pub use crate::adc::AdcExt as _stm32h7xx_hal_adc_AdcExt;
56
pub use crate::delay::DelayExt as _stm32h7xx_hal_delay_DelayExt;
7+
#[cfg(all(feature = "device-selected", feature = "singlecore"))]
68
pub use crate::flash::FlashExt as _stm32h7xx_hal_flash_FlashExt;
79
pub use crate::gpio::GpioExt as _stm32h7xx_hal_gpio_GpioExt;
810
pub use crate::i2c::I2cExt as _stm32h7xx_hal_i2c_I2cExt;

src/pwr.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,17 @@ pub enum VoltageScale {
3232

3333
impl Pwr {
3434
pub fn freeze(self) -> VoltageScale {
35-
// go to VOS1 voltage scale for high perf
35+
#[cfg(any(feature = "singlecore"))]
3636
self.rb.cr3.write(|w| {
3737
w.scuen().set_bit().ldoen().set_bit().bypass().clear_bit()
3838
});
39+
40+
#[cfg(any(feature = "dualcore"))]
41+
self.rb.cr3.modify(|_, w| {
42+
w.sden().set_bit().ldoen().clear_bit() // SMPS
43+
});
44+
45+
// go to VOS1 voltage scale for high performance
3946
while self.rb.csr1.read().actvosrdy().bit_is_clear() {}
4047
self.rb.d3cr.write(|w| unsafe { w.vos().bits(0b11) });
4148
while self.rb.d3cr.read().vosrdy().bit_is_clear() {}

src/serial.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use crate::stm32::rcc::d2ccip2r;
1212
use crate::stm32::usart1::cr1::{M0_A as M0, PCE_A as PCE, PS_A as PS};
1313
use stm32h7::Variant::Val;
1414

15-
use crate::stm32::{USART1, USART2, USART3, USART6};
1615
use crate::stm32::{UART4, UART5, UART7, UART8};
16+
use crate::stm32::{USART1, USART2, USART3, USART6};
1717

1818
use crate::gpio::gpioa::{
1919
PA0, PA1, PA10, PA11, PA12, PA15, PA2, PA3, PA4, PA8, PA9,
@@ -672,17 +672,24 @@ usart! {
672672
USART3: (usart3, apb1l, usart3en, usart3rst, pclk1),
673673
USART6: (usart6, apb2, usart6en, usart6rst, pclk2),
674674

675-
UART4: (uart4, apb1l, uart4en, uart4rst, pclk1),
676675
UART5: (uart5, apb1l, uart5en, uart5rst, pclk1),
677676
UART7: (uart7, apb1l, uart7en, uart7rst, pclk1),
678677
UART8: (uart8, apb1l, uart8en, uart8rst, pclk1),
679678
}
679+
#[cfg(any(feature = "singlecore"))]
680+
usart! {
681+
UART4: (uart4, apb1l, uart4en, uart4rst, pclk1),
682+
}
680683

681684
usart16sel! {
682685
USART1, USART6,
683686
}
684687
usart234578sel! {
685-
USART2, USART3, UART4, UART5, UART7, UART8,
688+
USART2, USART3, UART5, UART7, UART8,
689+
}
690+
#[cfg(any(feature = "singlecore"))]
691+
usart234578sel! {
692+
UART4,
686693
}
687694

688695
impl<USART> fmt::Write for Tx<USART>

src/watchdog.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@
22
33
use crate::hal::watchdog::{Watchdog, WatchdogEnable};
44
use crate::rcc::Ccdr;
5-
use crate::stm32::WWDG;
65
use crate::time::{Hertz, MilliSeconds};
76
use cast::u8;
87

8+
/// Select Window Watchdog hardware based on core
9+
#[cfg(any(feature = "singlecore"))]
10+
use crate::stm32::WWDG;
11+
#[cfg(all(feature = "dualcore", feature = "cm7"))]
12+
use crate::stm32::WWDG1 as WWDG;
13+
#[cfg(all(feature = "dualcore", feature = "cm4"))]
14+
use crate::stm32::WWDG2 as WWDG;
15+
916
/// Implements the System Window Watchdog
1017
pub struct SystemWindowWatchdog {
1118
wwdg: WWDG,
@@ -50,7 +57,6 @@ impl WatchdogEnable for SystemWindowWatchdog {
5057
(4096 * 2u32.pow(7) * 64) / (self.pclk3_frequency.0 / 1000);
5158
assert!(period_ms <= maximum);
5259

53-
5460
// timeout = pclk * 4096 * 2^WDGTB[2:0] * (t[5:0] +1)
5561
let ratio = period_ms * (self.pclk3_frequency.0 / 1000) / 4096;
5662

0 commit comments

Comments
 (0)