aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/build.rs4
-rw-r--r--embassy-stm32/src/adc/f1.rs4
-rw-r--r--embassy-stm32/src/adc/f3.rs6
-rw-r--r--embassy-stm32/src/adc/f3_v1_1.rs4
-rw-r--r--embassy-stm32/src/adc/mod.rs100
-rw-r--r--embassy-stm32/src/adc/v1.rs6
-rw-r--r--embassy-stm32/src/adc/v2.rs6
-rw-r--r--embassy-stm32/src/adc/v3.rs8
-rw-r--r--embassy-stm32/src/adc/v4.rs8
-rw-r--r--embassy-stm32/src/can/bxcan.rs52
-rw-r--r--embassy-stm32/src/can/fd/peripheral.rs61
-rw-r--r--embassy-stm32/src/can/fdcan.rs330
-rw-r--r--embassy-stm32/src/crc/v1.rs2
-rw-r--r--embassy-stm32/src/crc/v2v3.rs2
-rw-r--r--embassy-stm32/src/cryp/mod.rs13
-rw-r--r--embassy-stm32/src/dac/mod.rs17
-rw-r--r--embassy-stm32/src/dcmi.rs14
-rw-r--r--embassy-stm32/src/dma/dmamux.rs9
-rw-r--r--embassy-stm32/src/dma/mod.rs24
-rw-r--r--embassy-stm32/src/dma/word.rs9
-rw-r--r--embassy-stm32/src/eth/mod.rs11
-rw-r--r--embassy-stm32/src/eth/v1/mod.rs23
-rw-r--r--embassy-stm32/src/eth/v2/mod.rs29
-rw-r--r--embassy-stm32/src/exti.rs11
-rw-r--r--embassy-stm32/src/fmc.rs18
-rw-r--r--embassy-stm32/src/gpio.rs299
-rw-r--r--embassy-stm32/src/hash/mod.rs15
-rw-r--r--embassy-stm32/src/hrtim/mod.rs17
-rw-r--r--embassy-stm32/src/hrtim/traits.rs128
-rw-r--r--embassy-stm32/src/i2c/mod.rs40
-rw-r--r--embassy-stm32/src/i2s.rs3
-rw-r--r--embassy-stm32/src/ipcc.rs83
-rw-r--r--embassy-stm32/src/lib.rs2
-rw-r--r--embassy-stm32/src/opamp.rs54
-rw-r--r--embassy-stm32/src/qspi/mod.rs16
-rw-r--r--embassy-stm32/src/rcc/hsi48.rs2
-rw-r--r--embassy-stm32/src/rcc/mco.rs27
-rw-r--r--embassy-stm32/src/rcc/mod.rs41
-rw-r--r--embassy-stm32/src/rng.rs13
-rw-r--r--embassy-stm32/src/rtc/datetime.rs2
-rw-r--r--embassy-stm32/src/rtc/mod.rs53
-rw-r--r--embassy-stm32/src/rtc/v2.rs5
-rw-r--r--embassy-stm32/src/rtc/v3.rs6
-rw-r--r--embassy-stm32/src/sai/mod.rs41
-rw-r--r--embassy-stm32/src/sdmmc/mod.rs29
-rw-r--r--embassy-stm32/src/spi/mod.rs37
-rw-r--r--embassy-stm32/src/time_driver.rs4
-rw-r--r--embassy-stm32/src/timer/qei.rs3
-rw-r--r--embassy-stm32/src/ucpd.rs60
-rw-r--r--embassy-stm32/src/usart/mod.rs82
-rw-r--r--embassy-stm32/src/usb/mod.rs4
-rw-r--r--embassy-stm32/src/usb/otg.rs27
-rw-r--r--embassy-stm32/src/usb/usb.rs17
-rw-r--r--embassy-stm32/src/wdg/mod.rs11
-rw-r--r--examples/stm32h7/src/bin/dac_dma.rs14
-rw-r--r--examples/stm32h7/src/bin/low_level_timer_api.rs37
-rw-r--r--examples/stm32l4/src/bin/dac_dma.rs14
57 files changed, 916 insertions, 1041 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index ee224da67..15bb8ea62 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -584,7 +584,7 @@ fn main() {
584 }; 584 };
585 585
586 g.extend(quote! { 586 g.extend(quote! {
587 impl crate::rcc::sealed::RccPeripheral for peripherals::#pname { 587 impl crate::rcc::SealedRccPeripheral for peripherals::#pname {
588 fn frequency() -> crate::time::Hertz { 588 fn frequency() -> crate::time::Hertz {
589 #clock_frequency 589 #clock_frequency
590 } 590 }
@@ -1486,7 +1486,7 @@ fn main() {
1486 #[crate::interrupt] 1486 #[crate::interrupt]
1487 unsafe fn #irq () { 1487 unsafe fn #irq () {
1488 #( 1488 #(
1489 <crate::peripherals::#channels as crate::dma::sealed::ChannelInterrupt>::on_irq(); 1489 <crate::peripherals::#channels as crate::dma::ChannelInterrupt>::on_irq();
1490 )* 1490 )*
1491 } 1491 }
1492 } 1492 }
diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs
index b27b99827..cecf67947 100644
--- a/embassy-stm32/src/adc/f1.rs
+++ b/embassy-stm32/src/adc/f1.rs
@@ -33,7 +33,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
33 33
34pub struct Vref; 34pub struct Vref;
35impl<T: Instance> AdcPin<T> for Vref {} 35impl<T: Instance> AdcPin<T> for Vref {}
36impl<T: Instance> super::sealed::AdcPin<T> for Vref { 36impl<T: Instance> super::SealedAdcPin<T> for Vref {
37 fn channel(&self) -> u8 { 37 fn channel(&self) -> u8 {
38 17 38 17
39 } 39 }
@@ -41,7 +41,7 @@ impl<T: Instance> super::sealed::AdcPin<T> for Vref {
41 41
42pub struct Temperature; 42pub struct Temperature;
43impl<T: Instance> AdcPin<T> for Temperature {} 43impl<T: Instance> AdcPin<T> for Temperature {}
44impl<T: Instance> super::sealed::AdcPin<T> for Temperature { 44impl<T: Instance> super::SealedAdcPin<T> for Temperature {
45 fn channel(&self) -> u8 { 45 fn channel(&self) -> u8 {
46 16 46 16
47 } 47 }
diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs
index efade1f64..c5581dba1 100644
--- a/embassy-stm32/src/adc/f3.rs
+++ b/embassy-stm32/src/adc/f3.rs
@@ -33,7 +33,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
33 33
34pub struct Vref; 34pub struct Vref;
35impl<T: Instance> AdcPin<T> for Vref {} 35impl<T: Instance> AdcPin<T> for Vref {}
36impl<T: Instance> super::sealed::AdcPin<T> for Vref { 36impl<T: Instance> super::SealedAdcPin<T> for Vref {
37 fn channel(&self) -> u8 { 37 fn channel(&self) -> u8 {
38 18 38 18
39 } 39 }
@@ -48,7 +48,7 @@ impl Vref {
48 48
49pub struct Temperature; 49pub struct Temperature;
50impl<T: Instance> AdcPin<T> for Temperature {} 50impl<T: Instance> AdcPin<T> for Temperature {}
51impl<T: Instance> super::sealed::AdcPin<T> for Temperature { 51impl<T: Instance> super::SealedAdcPin<T> for Temperature {
52 fn channel(&self) -> u8 { 52 fn channel(&self) -> u8 {
53 16 53 16
54 } 54 }
@@ -102,7 +102,7 @@ impl<'d, T: Instance> Adc<'d, T> {
102 } 102 }
103 103
104 fn freq() -> Hertz { 104 fn freq() -> Hertz {
105 <T as crate::rcc::sealed::RccPeripheral>::frequency() 105 <T as crate::rcc::SealedRccPeripheral>::frequency()
106 } 106 }
107 107
108 pub fn sample_time_for_us(&self, us: u32) -> SampleTime { 108 pub fn sample_time_for_us(&self, us: u32) -> SampleTime {
diff --git a/embassy-stm32/src/adc/f3_v1_1.rs b/embassy-stm32/src/adc/f3_v1_1.rs
index f842893fa..672ace04f 100644
--- a/embassy-stm32/src/adc/f3_v1_1.rs
+++ b/embassy-stm32/src/adc/f3_v1_1.rs
@@ -65,7 +65,7 @@ fn update_vref<T: Instance>(op: i8) {
65 65
66pub struct Vref<T: Instance>(core::marker::PhantomData<T>); 66pub struct Vref<T: Instance>(core::marker::PhantomData<T>);
67impl<T: Instance> AdcPin<T> for Vref<T> {} 67impl<T: Instance> AdcPin<T> for Vref<T> {}
68impl<T: Instance> super::sealed::AdcPin<T> for Vref<T> { 68impl<T: Instance> super::SealedAdcPin<T> for Vref<T> {
69 fn channel(&self) -> u8 { 69 fn channel(&self) -> u8 {
70 17 70 17
71 } 71 }
@@ -124,7 +124,7 @@ impl<T: Instance> Drop for Vref<T> {
124 124
125pub struct Temperature<T: Instance>(core::marker::PhantomData<T>); 125pub struct Temperature<T: Instance>(core::marker::PhantomData<T>);
126impl<T: Instance> AdcPin<T> for Temperature<T> {} 126impl<T: Instance> AdcPin<T> for Temperature<T> {}
127impl<T: Instance> super::sealed::AdcPin<T> for Temperature<T> { 127impl<T: Instance> super::SealedAdcPin<T> for Temperature<T> {
128 fn channel(&self) -> u8 { 128 fn channel(&self) -> u8 {
129 16 129 16
130 } 130 }
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index 0d0d40549..ead2357ce 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -17,6 +17,8 @@ mod _version;
17#[allow(unused)] 17#[allow(unused)]
18#[cfg(not(adc_f3_v2))] 18#[cfg(not(adc_f3_v2))]
19pub use _version::*; 19pub use _version::*;
20#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
21use embassy_sync::waitqueue::AtomicWaker;
20 22
21#[cfg(not(any(adc_f1, adc_f3_v2)))] 23#[cfg(not(any(adc_f1, adc_f3_v2)))]
22pub use crate::pac::adc::vals::Res as Resolution; 24pub use crate::pac::adc::vals::Res as Resolution;
@@ -31,63 +33,65 @@ pub struct Adc<'d, T: Instance> {
31 sample_time: SampleTime, 33 sample_time: SampleTime,
32} 34}
33 35
34pub(crate) mod sealed { 36#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
35 #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] 37pub struct State {
36 use embassy_sync::waitqueue::AtomicWaker; 38 pub waker: AtomicWaker,
37 39}
38 #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
39 pub struct State {
40 pub waker: AtomicWaker,
41 }
42 40
43 #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] 41#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
44 impl State { 42impl State {
45 pub const fn new() -> Self { 43 pub const fn new() -> Self {
46 Self { 44 Self {
47 waker: AtomicWaker::new(), 45 waker: AtomicWaker::new(),
48 }
49 } 46 }
50 } 47 }
48}
51 49
52 pub trait InterruptableInstance { 50trait SealedInstance {
53 type Interrupt: crate::interrupt::typelevel::Interrupt; 51 #[allow(unused)]
54 } 52 fn regs() -> crate::pac::adc::Adc;
55 53 #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))]
56 pub trait Instance: InterruptableInstance { 54 fn common_regs() -> crate::pac::adccommon::AdcCommon;
57 fn regs() -> crate::pac::adc::Adc; 55 #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
58 #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))] 56 fn state() -> &'static State;
59 fn common_regs() -> crate::pac::adccommon::AdcCommon; 57}
60 #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
61 fn state() -> &'static State;
62 }
63 58
64 pub trait AdcPin<T: Instance> { 59pub(crate) trait SealedAdcPin<T: Instance> {
65 #[cfg(any(adc_v1, adc_l0, adc_v2))] 60 #[cfg(any(adc_v1, adc_l0, adc_v2))]
66 fn set_as_analog(&mut self) {} 61 fn set_as_analog(&mut self) {}
67 62
68 fn channel(&self) -> u8; 63 #[allow(unused)]
69 } 64 fn channel(&self) -> u8;
65}
70 66
71 pub trait InternalChannel<T> { 67trait SealedInternalChannel<T> {
72 fn channel(&self) -> u8; 68 #[allow(unused)]
73 } 69 fn channel(&self) -> u8;
74} 70}
75 71
76/// ADC instance. 72/// ADC instance.
77#[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5)))] 73#[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5)))]
78pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {} 74#[allow(private_bounds)]
75pub trait Instance: SealedInstance + crate::Peripheral<P = Self> {
76 type Interrupt: crate::interrupt::typelevel::Interrupt;
77}
79/// ADC instance. 78/// ADC instance.
80#[cfg(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5))] 79#[cfg(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5))]
81pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {} 80#[allow(private_bounds)]
81pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {
82 type Interrupt: crate::interrupt::typelevel::Interrupt;
83}
82 84
83/// ADC pin. 85/// ADC pin.
84pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} 86#[allow(private_bounds)]
87pub trait AdcPin<T: Instance>: SealedAdcPin<T> {}
85/// ADC internal channel. 88/// ADC internal channel.
86pub trait InternalChannel<T>: sealed::InternalChannel<T> {} 89#[allow(private_bounds)]
90pub trait InternalChannel<T>: SealedInternalChannel<T> {}
87 91
88foreach_adc!( 92foreach_adc!(
89 ($inst:ident, $common_inst:ident, $clock:ident) => { 93 ($inst:ident, $common_inst:ident, $clock:ident) => {
90 impl crate::adc::sealed::Instance for peripherals::$inst { 94 impl crate::adc::SealedInstance for peripherals::$inst {
91 fn regs() -> crate::pac::adc::Adc { 95 fn regs() -> crate::pac::adc::Adc {
92 crate::pac::$inst 96 crate::pac::$inst
93 } 97 }
@@ -98,21 +102,15 @@ foreach_adc!(
98 } 102 }
99 103
100 #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] 104 #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
101 fn state() -> &'static sealed::State { 105 fn state() -> &'static State {
102 static STATE: sealed::State = sealed::State::new(); 106 static STATE: State = State::new();
103 &STATE 107 &STATE
104 } 108 }
105 } 109 }
106 110
107 foreach_interrupt!( 111 impl crate::adc::Instance for peripherals::$inst {
108 ($inst,adc,ADC,GLOBAL,$irq:ident) => { 112 type Interrupt = crate::_generated::peripheral_interrupts::$inst::GLOBAL;
109 impl sealed::InterruptableInstance for peripherals::$inst { 113 }
110 type Interrupt = crate::interrupt::typelevel::$irq;
111 }
112 };
113 );
114
115 impl crate::adc::Instance for peripherals::$inst {}
116 }; 114 };
117); 115);
118 116
@@ -120,10 +118,10 @@ macro_rules! impl_adc_pin {
120 ($inst:ident, $pin:ident, $ch:expr) => { 118 ($inst:ident, $pin:ident, $ch:expr) => {
121 impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {} 119 impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {}
122 120
123 impl crate::adc::sealed::AdcPin<peripherals::$inst> for crate::peripherals::$pin { 121 impl crate::adc::SealedAdcPin<peripherals::$inst> for crate::peripherals::$pin {
124 #[cfg(any(adc_v1, adc_l0, adc_v2))] 122 #[cfg(any(adc_v1, adc_l0, adc_v2))]
125 fn set_as_analog(&mut self) { 123 fn set_as_analog(&mut self) {
126 <Self as crate::gpio::sealed::Pin>::set_as_analog(self); 124 <Self as crate::gpio::SealedPin>::set_as_analog(self);
127 } 125 }
128 126
129 fn channel(&self) -> u8 { 127 fn channel(&self) -> u8 {
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs
index a8dc6ce98..e9b46be80 100644
--- a/embassy-stm32/src/adc/v1.rs
+++ b/embassy-stm32/src/adc/v1.rs
@@ -39,7 +39,7 @@ pub struct Vbat;
39impl AdcPin<ADC> for Vbat {} 39impl AdcPin<ADC> for Vbat {}
40 40
41#[cfg(not(adc_l0))] 41#[cfg(not(adc_l0))]
42impl super::sealed::AdcPin<ADC> for Vbat { 42impl super::SealedAdcPin<ADC> for Vbat {
43 fn channel(&self) -> u8 { 43 fn channel(&self) -> u8 {
44 18 44 18
45 } 45 }
@@ -47,7 +47,7 @@ impl super::sealed::AdcPin<ADC> for Vbat {
47 47
48pub struct Vref; 48pub struct Vref;
49impl AdcPin<ADC> for Vref {} 49impl AdcPin<ADC> for Vref {}
50impl super::sealed::AdcPin<ADC> for Vref { 50impl super::SealedAdcPin<ADC> for Vref {
51 fn channel(&self) -> u8 { 51 fn channel(&self) -> u8 {
52 17 52 17
53 } 53 }
@@ -55,7 +55,7 @@ impl super::sealed::AdcPin<ADC> for Vref {
55 55
56pub struct Temperature; 56pub struct Temperature;
57impl AdcPin<ADC> for Temperature {} 57impl AdcPin<ADC> for Temperature {}
58impl super::sealed::AdcPin<ADC> for Temperature { 58impl super::SealedAdcPin<ADC> for Temperature {
59 fn channel(&self) -> u8 { 59 fn channel(&self) -> u8 {
60 16 60 16
61 } 61 }
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index f6f7dbfcc..a43eb72db 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -16,7 +16,7 @@ pub const ADC_POWERUP_TIME_US: u32 = 3;
16 16
17pub struct VrefInt; 17pub struct VrefInt;
18impl AdcPin<ADC1> for VrefInt {} 18impl AdcPin<ADC1> for VrefInt {}
19impl super::sealed::AdcPin<ADC1> for VrefInt { 19impl super::SealedAdcPin<ADC1> for VrefInt {
20 fn channel(&self) -> u8 { 20 fn channel(&self) -> u8 {
21 17 21 17
22 } 22 }
@@ -31,7 +31,7 @@ impl VrefInt {
31 31
32pub struct Temperature; 32pub struct Temperature;
33impl AdcPin<ADC1> for Temperature {} 33impl AdcPin<ADC1> for Temperature {}
34impl super::sealed::AdcPin<ADC1> for Temperature { 34impl super::SealedAdcPin<ADC1> for Temperature {
35 fn channel(&self) -> u8 { 35 fn channel(&self) -> u8 {
36 cfg_if::cfg_if! { 36 cfg_if::cfg_if! {
37 if #[cfg(any(stm32f2, stm32f40, stm32f41))] { 37 if #[cfg(any(stm32f2, stm32f40, stm32f41))] {
@@ -52,7 +52,7 @@ impl Temperature {
52 52
53pub struct Vbat; 53pub struct Vbat;
54impl AdcPin<ADC1> for Vbat {} 54impl AdcPin<ADC1> for Vbat {}
55impl super::sealed::AdcPin<ADC1> for Vbat { 55impl super::SealedAdcPin<ADC1> for Vbat {
56 fn channel(&self) -> u8 { 56 fn channel(&self) -> u8 {
57 18 57 18
58 } 58 }
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index 5f3512cad..8c9b47197 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -12,7 +12,7 @@ pub const VREF_CALIB_MV: u32 = 3000;
12 12
13pub struct VrefInt; 13pub struct VrefInt;
14impl<T: Instance> AdcPin<T> for VrefInt {} 14impl<T: Instance> AdcPin<T> for VrefInt {}
15impl<T: Instance> super::sealed::AdcPin<T> for VrefInt { 15impl<T: Instance> super::SealedAdcPin<T> for VrefInt {
16 fn channel(&self) -> u8 { 16 fn channel(&self) -> u8 {
17 cfg_if! { 17 cfg_if! {
18 if #[cfg(adc_g0)] { 18 if #[cfg(adc_g0)] {
@@ -29,7 +29,7 @@ impl<T: Instance> super::sealed::AdcPin<T> for VrefInt {
29 29
30pub struct Temperature; 30pub struct Temperature;
31impl<T: Instance> AdcPin<T> for Temperature {} 31impl<T: Instance> AdcPin<T> for Temperature {}
32impl<T: Instance> super::sealed::AdcPin<T> for Temperature { 32impl<T: Instance> super::SealedAdcPin<T> for Temperature {
33 fn channel(&self) -> u8 { 33 fn channel(&self) -> u8 {
34 cfg_if! { 34 cfg_if! {
35 if #[cfg(adc_g0)] { 35 if #[cfg(adc_g0)] {
@@ -46,7 +46,7 @@ impl<T: Instance> super::sealed::AdcPin<T> for Temperature {
46 46
47pub struct Vbat; 47pub struct Vbat;
48impl<T: Instance> AdcPin<T> for Vbat {} 48impl<T: Instance> AdcPin<T> for Vbat {}
49impl<T: Instance> super::sealed::AdcPin<T> for Vbat { 49impl<T: Instance> super::SealedAdcPin<T> for Vbat {
50 fn channel(&self) -> u8 { 50 fn channel(&self) -> u8 {
51 cfg_if! { 51 cfg_if! {
52 if #[cfg(adc_g0)] { 52 if #[cfg(adc_g0)] {
@@ -65,7 +65,7 @@ cfg_if! {
65 if #[cfg(adc_h5)] { 65 if #[cfg(adc_h5)] {
66 pub struct VddCore; 66 pub struct VddCore;
67 impl<T: Instance> AdcPin<T> for VddCore {} 67 impl<T: Instance> AdcPin<T> for VddCore {}
68 impl<T: Instance> super::sealed::AdcPin<T> for VddCore { 68 impl<T: Instance> super::SealedAdcPin<T> for VddCore {
69 fn channel(&self) -> u8 { 69 fn channel(&self) -> u8 {
70 6 70 6
71 } 71 }
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index 3fd047375..1ae25bea2 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -35,7 +35,7 @@ const VBAT_CHANNEL: u8 = 17;
35/// Internal voltage reference channel. 35/// Internal voltage reference channel.
36pub struct VrefInt; 36pub struct VrefInt;
37impl<T: Instance> InternalChannel<T> for VrefInt {} 37impl<T: Instance> InternalChannel<T> for VrefInt {}
38impl<T: Instance> super::sealed::InternalChannel<T> for VrefInt { 38impl<T: Instance> super::SealedInternalChannel<T> for VrefInt {
39 fn channel(&self) -> u8 { 39 fn channel(&self) -> u8 {
40 VREF_CHANNEL 40 VREF_CHANNEL
41 } 41 }
@@ -44,7 +44,7 @@ impl<T: Instance> super::sealed::InternalChannel<T> for VrefInt {
44/// Internal temperature channel. 44/// Internal temperature channel.
45pub struct Temperature; 45pub struct Temperature;
46impl<T: Instance> InternalChannel<T> for Temperature {} 46impl<T: Instance> InternalChannel<T> for Temperature {}
47impl<T: Instance> super::sealed::InternalChannel<T> for Temperature { 47impl<T: Instance> super::SealedInternalChannel<T> for Temperature {
48 fn channel(&self) -> u8 { 48 fn channel(&self) -> u8 {
49 TEMP_CHANNEL 49 TEMP_CHANNEL
50 } 50 }
@@ -53,7 +53,7 @@ impl<T: Instance> super::sealed::InternalChannel<T> for Temperature {
53/// Internal battery voltage channel. 53/// Internal battery voltage channel.
54pub struct Vbat; 54pub struct Vbat;
55impl<T: Instance> InternalChannel<T> for Vbat {} 55impl<T: Instance> InternalChannel<T> for Vbat {}
56impl<T: Instance> super::sealed::InternalChannel<T> for Vbat { 56impl<T: Instance> super::SealedInternalChannel<T> for Vbat {
57 fn channel(&self) -> u8 { 57 fn channel(&self) -> u8 {
58 VBAT_CHANNEL 58 VBAT_CHANNEL
59 } 59 }
@@ -276,7 +276,7 @@ impl<'d, T: Instance> Adc<'d, T> {
276 pub fn read<P>(&mut self, pin: &mut P) -> u16 276 pub fn read<P>(&mut self, pin: &mut P) -> u16
277 where 277 where
278 P: AdcPin<T>, 278 P: AdcPin<T>,
279 P: crate::gpio::sealed::Pin, 279 P: crate::gpio::Pin,
280 { 280 {
281 pin.set_as_analog(); 281 pin.set_as_analog();
282 282
diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs
index 1a625bdc4..017c5110d 100644
--- a/embassy-stm32/src/can/bxcan.rs
+++ b/embassy-stm32/src/can/bxcan.rs
@@ -7,9 +7,12 @@ pub mod bx;
7 7
8pub use bx::{filter, Data, ExtendedId, Fifo, Frame, Header, Id, StandardId}; 8pub use bx::{filter, Data, ExtendedId, Fifo, Frame, Header, Id, StandardId};
9use embassy_hal_internal::{into_ref, PeripheralRef}; 9use embassy_hal_internal::{into_ref, PeripheralRef};
10use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
11use embassy_sync::channel::Channel;
12use embassy_sync::waitqueue::AtomicWaker;
10use futures::FutureExt; 13use futures::FutureExt;
11 14
12use crate::gpio::sealed::AFType; 15use crate::gpio::AFType;
13use crate::interrupt::typelevel::Interrupt; 16use crate::interrupt::typelevel::Interrupt;
14use crate::pac::can::vals::{Ide, Lec}; 17use crate::pac::can::vals::{Ide, Lec};
15use crate::rcc::RccPeripheral; 18use crate::rcc::RccPeripheral;
@@ -485,37 +488,30 @@ impl<'d, T: Instance> DerefMut for Can<'d, T> {
485 } 488 }
486} 489}
487 490
488pub(crate) mod sealed { 491struct State {
489 use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 492 pub tx_waker: AtomicWaker,
490 use embassy_sync::channel::Channel; 493 pub err_waker: AtomicWaker,
491 use embassy_sync::waitqueue::AtomicWaker; 494 pub rx_queue: Channel<CriticalSectionRawMutex, Envelope, 32>,
492 495}
493 use super::Envelope;
494
495 pub struct State {
496 pub tx_waker: AtomicWaker,
497 pub err_waker: AtomicWaker,
498 pub rx_queue: Channel<CriticalSectionRawMutex, Envelope, 32>,
499 }
500 496
501 impl State { 497impl State {
502 pub const fn new() -> Self { 498 pub const fn new() -> Self {
503 Self { 499 Self {
504 tx_waker: AtomicWaker::new(), 500 tx_waker: AtomicWaker::new(),
505 err_waker: AtomicWaker::new(), 501 err_waker: AtomicWaker::new(),
506 rx_queue: Channel::new(), 502 rx_queue: Channel::new(),
507 }
508 } 503 }
509 } 504 }
505}
510 506
511 pub trait Instance { 507trait SealedInstance {
512 fn regs() -> crate::pac::can::Can; 508 fn regs() -> crate::pac::can::Can;
513 fn state() -> &'static State; 509 fn state() -> &'static State;
514 }
515} 510}
516 511
517/// CAN instance trait. 512/// CAN instance trait.
518pub trait Instance: sealed::Instance + RccPeripheral + 'static { 513#[allow(private_bounds)]
514pub trait Instance: SealedInstance + RccPeripheral + 'static {
519 /// TX interrupt for this instance. 515 /// TX interrupt for this instance.
520 type TXInterrupt: crate::interrupt::typelevel::Interrupt; 516 type TXInterrupt: crate::interrupt::typelevel::Interrupt;
521 /// RX0 interrupt for this instance. 517 /// RX0 interrupt for this instance.
@@ -533,14 +529,14 @@ unsafe impl<'d, T: Instance> crate::can::bx::Instance for BxcanInstance<'d, T> {
533 529
534foreach_peripheral!( 530foreach_peripheral!(
535 (can, $inst:ident) => { 531 (can, $inst:ident) => {
536 impl sealed::Instance for peripherals::$inst { 532 impl SealedInstance for peripherals::$inst {
537 533
538 fn regs() -> crate::pac::can::Can { 534 fn regs() -> crate::pac::can::Can {
539 crate::pac::$inst 535 crate::pac::$inst
540 } 536 }
541 537
542 fn state() -> &'static sealed::State { 538 fn state() -> &'static State {
543 static STATE: sealed::State = sealed::State::new(); 539 static STATE: State = State::new();
544 &STATE 540 &STATE
545 } 541 }
546 } 542 }
diff --git a/embassy-stm32/src/can/fd/peripheral.rs b/embassy-stm32/src/can/fd/peripheral.rs
index 682e13f4b..76b76afe1 100644
--- a/embassy-stm32/src/can/fd/peripheral.rs
+++ b/embassy-stm32/src/can/fd/peripheral.rs
@@ -325,17 +325,6 @@ impl Registers {
325 */ 325 */
326 } 326 }
327 327
328 /// Disables the CAN interface and returns back the raw peripheral it was created from.
329 #[inline]
330 pub fn free(mut self) {
331 //self.disable_interrupts(Interrupts::all());
332
333 //TODO check this!
334 self.enter_init_mode();
335 self.set_power_down_mode(true);
336 //self.control.instance
337 }
338
339 /// Applies the settings of a new FdCanConfig See [`FdCanConfig`] 328 /// Applies the settings of a new FdCanConfig See [`FdCanConfig`]
340 #[inline] 329 #[inline]
341 pub fn apply_config(&mut self, config: FdCanConfig) { 330 pub fn apply_config(&mut self, config: FdCanConfig) {
@@ -419,55 +408,6 @@ impl Registers {
419 self.leave_init_mode(config); 408 self.leave_init_mode(config);
420 } 409 }
421 410
422 /// Moves out of ConfigMode and into InternalLoopbackMode
423 #[inline]
424 pub fn into_internal_loopback(mut self, config: FdCanConfig) {
425 self.set_loopback_mode(LoopbackMode::Internal);
426 self.leave_init_mode(config);
427 }
428
429 /// Moves out of ConfigMode and into ExternalLoopbackMode
430 #[inline]
431 pub fn into_external_loopback(mut self, config: FdCanConfig) {
432 self.set_loopback_mode(LoopbackMode::External);
433 self.leave_init_mode(config);
434 }
435
436 /// Moves out of ConfigMode and into RestrictedOperationMode
437 #[inline]
438 pub fn into_restricted(mut self, config: FdCanConfig) {
439 self.set_restricted_operations(true);
440 self.leave_init_mode(config);
441 }
442
443 /// Moves out of ConfigMode and into NormalOperationMode
444 #[inline]
445 pub fn into_normal(mut self, config: FdCanConfig) {
446 self.set_normal_operations(true);
447 self.leave_init_mode(config);
448 }
449
450 /// Moves out of ConfigMode and into BusMonitoringMode
451 #[inline]
452 pub fn into_bus_monitoring(mut self, config: FdCanConfig) {
453 self.set_bus_monitoring_mode(true);
454 self.leave_init_mode(config);
455 }
456
457 /// Moves out of ConfigMode and into Testmode
458 #[inline]
459 pub fn into_test_mode(mut self, config: FdCanConfig) {
460 self.set_test_mode(true);
461 self.leave_init_mode(config);
462 }
463
464 /// Moves out of ConfigMode and into PoweredDownmode
465 #[inline]
466 pub fn into_powered_down(mut self, config: FdCanConfig) {
467 self.set_power_down_mode(true);
468 self.leave_init_mode(config);
469 }
470
471 /// Configures the bit timings. 411 /// Configures the bit timings.
472 /// 412 ///
473 /// You can use <http://www.bittiming.can-wiki.info/> to calculate the `btr` parameter. Enter 413 /// You can use <http://www.bittiming.can-wiki.info/> to calculate the `btr` parameter. Enter
@@ -565,6 +505,7 @@ impl Registers {
565 505
566 /// Configures and resets the timestamp counter 506 /// Configures and resets the timestamp counter
567 #[inline] 507 #[inline]
508 #[allow(unused)]
568 pub fn set_timestamp_counter_source(&mut self, select: TimestampSource) { 509 pub fn set_timestamp_counter_source(&mut self, select: TimestampSource) {
569 #[cfg(stm32h7)] 510 #[cfg(stm32h7)]
570 let (tcp, tss) = match select { 511 let (tcp, tss) = match select {
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs
index 4c40f10e3..4ea036ab4 100644
--- a/embassy-stm32/src/can/fdcan.rs
+++ b/embassy-stm32/src/can/fdcan.rs
@@ -5,10 +5,11 @@ use core::task::Poll;
5 5
6use embassy_hal_internal::{into_ref, PeripheralRef}; 6use embassy_hal_internal::{into_ref, PeripheralRef};
7use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 7use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
8use embassy_sync::channel::Channel; 8use embassy_sync::channel::{Channel, DynamicReceiver, DynamicSender};
9use embassy_sync::waitqueue::AtomicWaker;
9 10
10use crate::can::fd::peripheral::Registers; 11use crate::can::fd::peripheral::Registers;
11use crate::gpio::sealed::AFType; 12use crate::gpio::AFType;
12use crate::interrupt::typelevel::Interrupt; 13use crate::interrupt::typelevel::Interrupt;
13use crate::rcc::RccPeripheral; 14use crate::rcc::RccPeripheral;
14use crate::{interrupt, peripherals, Peripheral}; 15use crate::{interrupt, peripherals, Peripheral};
@@ -53,8 +54,8 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup
53 } 54 }
54 55
55 match &T::state().tx_mode { 56 match &T::state().tx_mode {
56 sealed::TxMode::NonBuffered(waker) => waker.wake(), 57 TxMode::NonBuffered(waker) => waker.wake(),
57 sealed::TxMode::ClassicBuffered(buf) => { 58 TxMode::ClassicBuffered(buf) => {
58 if !T::registers().tx_queue_is_full() { 59 if !T::registers().tx_queue_is_full() {
59 match buf.tx_receiver.try_receive() { 60 match buf.tx_receiver.try_receive() {
60 Ok(frame) => { 61 Ok(frame) => {
@@ -64,7 +65,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup
64 } 65 }
65 } 66 }
66 } 67 }
67 sealed::TxMode::FdBuffered(buf) => { 68 TxMode::FdBuffered(buf) => {
68 if !T::registers().tx_queue_is_full() { 69 if !T::registers().tx_queue_is_full() {
69 match buf.tx_receiver.try_receive() { 70 match buf.tx_receiver.try_receive() {
70 Ok(frame) => { 71 Ok(frame) => {
@@ -467,14 +468,14 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
467 fn setup(self) -> Self { 468 fn setup(self) -> Self {
468 // We don't want interrupts being processed while we change modes. 469 // We don't want interrupts being processed while we change modes.
469 critical_section::with(|_| unsafe { 470 critical_section::with(|_| unsafe {
470 let rx_inner = sealed::ClassicBufferedRxInner { 471 let rx_inner = ClassicBufferedRxInner {
471 rx_sender: self.rx_buf.sender().into(), 472 rx_sender: self.rx_buf.sender().into(),
472 }; 473 };
473 let tx_inner = sealed::ClassicBufferedTxInner { 474 let tx_inner = ClassicBufferedTxInner {
474 tx_receiver: self.tx_buf.receiver().into(), 475 tx_receiver: self.tx_buf.receiver().into(),
475 }; 476 };
476 T::mut_state().rx_mode = sealed::RxMode::ClassicBuffered(rx_inner); 477 T::mut_state().rx_mode = RxMode::ClassicBuffered(rx_inner);
477 T::mut_state().tx_mode = sealed::TxMode::ClassicBuffered(tx_inner); 478 T::mut_state().tx_mode = TxMode::ClassicBuffered(tx_inner);
478 }); 479 });
479 self 480 self
480 } 481 }
@@ -509,8 +510,8 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Dr
509{ 510{
510 fn drop(&mut self) { 511 fn drop(&mut self) {
511 critical_section::with(|_| unsafe { 512 critical_section::with(|_| unsafe {
512 T::mut_state().rx_mode = sealed::RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); 513 T::mut_state().rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
513 T::mut_state().tx_mode = sealed::TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); 514 T::mut_state().tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
514 }); 515 });
515 } 516 }
516} 517}
@@ -585,14 +586,14 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
585 fn setup(self) -> Self { 586 fn setup(self) -> Self {
586 // We don't want interrupts being processed while we change modes. 587 // We don't want interrupts being processed while we change modes.
587 critical_section::with(|_| unsafe { 588 critical_section::with(|_| unsafe {
588 let rx_inner = sealed::FdBufferedRxInner { 589 let rx_inner = FdBufferedRxInner {
589 rx_sender: self.rx_buf.sender().into(), 590 rx_sender: self.rx_buf.sender().into(),
590 }; 591 };
591 let tx_inner = sealed::FdBufferedTxInner { 592 let tx_inner = FdBufferedTxInner {
592 tx_receiver: self.tx_buf.receiver().into(), 593 tx_receiver: self.tx_buf.receiver().into(),
593 }; 594 };
594 T::mut_state().rx_mode = sealed::RxMode::FdBuffered(rx_inner); 595 T::mut_state().rx_mode = RxMode::FdBuffered(rx_inner);
595 T::mut_state().tx_mode = sealed::TxMode::FdBuffered(tx_inner); 596 T::mut_state().tx_mode = TxMode::FdBuffered(tx_inner);
596 }); 597 });
597 self 598 self
598 } 599 }
@@ -627,8 +628,8 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Dr
627{ 628{
628 fn drop(&mut self) { 629 fn drop(&mut self) {
629 critical_section::with(|_| unsafe { 630 critical_section::with(|_| unsafe {
630 T::mut_state().rx_mode = sealed::RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); 631 T::mut_state().rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
631 T::mut_state().tx_mode = sealed::TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); 632 T::mut_state().tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
632 }); 633 });
633 } 634 }
634} 635}
@@ -677,192 +678,180 @@ impl<'c, 'd, T: Instance> FdcanRx<'d, T> {
677 } 678 }
678} 679}
679 680
680pub(crate) mod sealed { 681struct ClassicBufferedRxInner {
681 use core::future::poll_fn; 682 rx_sender: DynamicSender<'static, Result<(ClassicFrame, Timestamp), BusError>>,
682 use core::task::Poll; 683}
683 684struct ClassicBufferedTxInner {
684 use embassy_sync::channel::{DynamicReceiver, DynamicSender}; 685 tx_receiver: DynamicReceiver<'static, ClassicFrame>,
685 use embassy_sync::waitqueue::AtomicWaker; 686}
686
687 use super::CanHeader;
688 use crate::can::_version::{BusError, Timestamp};
689 use crate::can::frame::{ClassicFrame, FdFrame};
690
691 pub struct ClassicBufferedRxInner {
692 pub rx_sender: DynamicSender<'static, Result<(ClassicFrame, Timestamp), BusError>>,
693 }
694 pub struct ClassicBufferedTxInner {
695 pub tx_receiver: DynamicReceiver<'static, ClassicFrame>,
696 }
697 687
698 pub struct FdBufferedRxInner { 688struct FdBufferedRxInner {
699 pub rx_sender: DynamicSender<'static, Result<(FdFrame, Timestamp), BusError>>, 689 rx_sender: DynamicSender<'static, Result<(FdFrame, Timestamp), BusError>>,
700 } 690}
701 pub struct FdBufferedTxInner { 691struct FdBufferedTxInner {
702 pub tx_receiver: DynamicReceiver<'static, FdFrame>, 692 tx_receiver: DynamicReceiver<'static, FdFrame>,
703 } 693}
704 694
705 pub enum RxMode { 695enum RxMode {
706 NonBuffered(AtomicWaker), 696 NonBuffered(AtomicWaker),
707 ClassicBuffered(ClassicBufferedRxInner), 697 ClassicBuffered(ClassicBufferedRxInner),
708 FdBuffered(FdBufferedRxInner), 698 FdBuffered(FdBufferedRxInner),
709 } 699}
710 700
711 impl RxMode { 701impl RxMode {
712 pub fn register(&self, arg: &core::task::Waker) { 702 fn register(&self, arg: &core::task::Waker) {
713 match self { 703 match self {
714 RxMode::NonBuffered(waker) => waker.register(arg), 704 RxMode::NonBuffered(waker) => waker.register(arg),
715 _ => { 705 _ => {
716 panic!("Bad Mode") 706 panic!("Bad Mode")
717 }
718 } 707 }
719 } 708 }
709 }
720 710
721 pub fn on_interrupt<T: Instance>(&self, fifonr: usize) { 711 fn on_interrupt<T: Instance>(&self, fifonr: usize) {
722 T::regs().ir().write(|w| w.set_rfn(fifonr, true)); 712 T::regs().ir().write(|w| w.set_rfn(fifonr, true));
723 match self { 713 match self {
724 RxMode::NonBuffered(waker) => { 714 RxMode::NonBuffered(waker) => {
725 waker.wake(); 715 waker.wake();
726 } 716 }
727 RxMode::ClassicBuffered(buf) => { 717 RxMode::ClassicBuffered(buf) => {
728 if let Some(result) = self.read::<T, _>() { 718 if let Some(result) = self.read::<T, _>() {
729 let _ = buf.rx_sender.try_send(result); 719 let _ = buf.rx_sender.try_send(result);
730 }
731 }
732 RxMode::FdBuffered(buf) => {
733 if let Some(result) = self.read::<T, _>() {
734 let _ = buf.rx_sender.try_send(result);
735 }
736 } 720 }
737 } 721 }
738 } 722 RxMode::FdBuffered(buf) => {
739 723 if let Some(result) = self.read::<T, _>() {
740 fn read<T: Instance, F: CanHeader>(&self) -> Option<Result<(F, Timestamp), BusError>> { 724 let _ = buf.rx_sender.try_send(result);
741 if let Some((msg, ts)) = T::registers().read(0) { 725 }
742 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
743 Some(Ok((msg, ts)))
744 } else if let Some((msg, ts)) = T::registers().read(1) {
745 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
746 Some(Ok((msg, ts)))
747 } else if let Some(err) = T::registers().curr_error() {
748 // TODO: this is probably wrong
749 Some(Err(err))
750 } else {
751 None
752 } 726 }
753 } 727 }
728 }
754 729
755 async fn read_async<T: Instance, F: CanHeader>(&self) -> Result<(F, Timestamp), BusError> { 730 fn read<T: Instance, F: CanHeader>(&self) -> Option<Result<(F, Timestamp), BusError>> {
756 poll_fn(|cx| { 731 if let Some((msg, ts)) = T::registers().read(0) {
757 T::state().err_waker.register(cx.waker()); 732 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
758 self.register(cx.waker()); 733 Some(Ok((msg, ts)))
759 match self.read::<T, _>() { 734 } else if let Some((msg, ts)) = T::registers().read(1) {
760 Some(result) => Poll::Ready(result), 735 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
761 None => Poll::Pending, 736 Some(Ok((msg, ts)))
762 } 737 } else if let Some(err) = T::registers().curr_error() {
763 }) 738 // TODO: this is probably wrong
764 .await 739 Some(Err(err))
740 } else {
741 None
765 } 742 }
743 }
766 744
767 pub async fn read_classic<T: Instance>(&self) -> Result<(ClassicFrame, Timestamp), BusError> { 745 async fn read_async<T: Instance, F: CanHeader>(&self) -> Result<(F, Timestamp), BusError> {
768 self.read_async::<T, _>().await 746 poll_fn(|cx| {
769 } 747 T::state().err_waker.register(cx.waker());
748 self.register(cx.waker());
749 match self.read::<T, _>() {
750 Some(result) => Poll::Ready(result),
751 None => Poll::Pending,
752 }
753 })
754 .await
755 }
770 756
771 pub async fn read_fd<T: Instance>(&self) -> Result<(FdFrame, Timestamp), BusError> { 757 async fn read_classic<T: Instance>(&self) -> Result<(ClassicFrame, Timestamp), BusError> {
772 self.read_async::<T, _>().await 758 self.read_async::<T, _>().await
773 }
774 } 759 }
775 760
776 pub enum TxMode { 761 async fn read_fd<T: Instance>(&self) -> Result<(FdFrame, Timestamp), BusError> {
777 NonBuffered(AtomicWaker), 762 self.read_async::<T, _>().await
778 ClassicBuffered(ClassicBufferedTxInner),
779 FdBuffered(FdBufferedTxInner),
780 } 763 }
764}
781 765
782 impl TxMode { 766enum TxMode {
783 pub fn register(&self, arg: &core::task::Waker) { 767 NonBuffered(AtomicWaker),
784 match self { 768 ClassicBuffered(ClassicBufferedTxInner),
785 TxMode::NonBuffered(waker) => { 769 FdBuffered(FdBufferedTxInner),
786 waker.register(arg); 770}
787 } 771
788 _ => { 772impl TxMode {
789 panic!("Bad mode"); 773 fn register(&self, arg: &core::task::Waker) {
790 } 774 match self {
775 TxMode::NonBuffered(waker) => {
776 waker.register(arg);
777 }
778 _ => {
779 panic!("Bad mode");
791 } 780 }
792 } 781 }
782 }
793 783
794 /// Queues the message to be sent but exerts backpressure. If a lower-priority 784 /// Queues the message to be sent but exerts backpressure. If a lower-priority
795 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames 785 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames
796 /// can be replaced, this call asynchronously waits for a frame to be successfully 786 /// can be replaced, this call asynchronously waits for a frame to be successfully
797 /// transmitted, then tries again. 787 /// transmitted, then tries again.
798 async fn write_generic<T: Instance, F: embedded_can::Frame + CanHeader>(&self, frame: &F) -> Option<F> { 788 async fn write_generic<T: Instance, F: embedded_can::Frame + CanHeader>(&self, frame: &F) -> Option<F> {
799 poll_fn(|cx| { 789 poll_fn(|cx| {
800 self.register(cx.waker()); 790 self.register(cx.waker());
801 791
802 if let Ok(dropped) = T::registers().write(frame) { 792 if let Ok(dropped) = T::registers().write(frame) {
803 return Poll::Ready(dropped); 793 return Poll::Ready(dropped);
804 } 794 }
805 795
806 // Couldn't replace any lower priority frames. Need to wait for some mailboxes 796 // Couldn't replace any lower priority frames. Need to wait for some mailboxes
807 // to clear. 797 // to clear.
808 Poll::Pending 798 Poll::Pending
809 }) 799 })
810 .await 800 .await
811 } 801 }
812 802
813 /// Queues the message to be sent but exerts backpressure. If a lower-priority 803 /// Queues the message to be sent but exerts backpressure. If a lower-priority
814 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames 804 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames
815 /// can be replaced, this call asynchronously waits for a frame to be successfully 805 /// can be replaced, this call asynchronously waits for a frame to be successfully
816 /// transmitted, then tries again. 806 /// transmitted, then tries again.
817 pub async fn write<T: Instance>(&self, frame: &ClassicFrame) -> Option<ClassicFrame> { 807 async fn write<T: Instance>(&self, frame: &ClassicFrame) -> Option<ClassicFrame> {
818 self.write_generic::<T, _>(frame).await 808 self.write_generic::<T, _>(frame).await
819 } 809 }
820 810
821 /// Queues the message to be sent but exerts backpressure. If a lower-priority 811 /// Queues the message to be sent but exerts backpressure. If a lower-priority
822 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames 812 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames
823 /// can be replaced, this call asynchronously waits for a frame to be successfully 813 /// can be replaced, this call asynchronously waits for a frame to be successfully
824 /// transmitted, then tries again. 814 /// transmitted, then tries again.
825 pub async fn write_fd<T: Instance>(&self, frame: &FdFrame) -> Option<FdFrame> { 815 async fn write_fd<T: Instance>(&self, frame: &FdFrame) -> Option<FdFrame> {
826 self.write_generic::<T, _>(frame).await 816 self.write_generic::<T, _>(frame).await
827 }
828 } 817 }
818}
829 819
830 pub struct State { 820struct State {
831 pub rx_mode: RxMode, 821 pub rx_mode: RxMode,
832 pub tx_mode: TxMode, 822 pub tx_mode: TxMode,
833 pub ns_per_timer_tick: u64, 823 pub ns_per_timer_tick: u64,
834 824
835 pub err_waker: AtomicWaker, 825 pub err_waker: AtomicWaker,
836 } 826}
837 827
838 impl State { 828impl State {
839 pub const fn new() -> Self { 829 const fn new() -> Self {
840 Self { 830 Self {
841 rx_mode: RxMode::NonBuffered(AtomicWaker::new()), 831 rx_mode: RxMode::NonBuffered(AtomicWaker::new()),
842 tx_mode: TxMode::NonBuffered(AtomicWaker::new()), 832 tx_mode: TxMode::NonBuffered(AtomicWaker::new()),
843 ns_per_timer_tick: 0, 833 ns_per_timer_tick: 0,
844 err_waker: AtomicWaker::new(), 834 err_waker: AtomicWaker::new(),
845 }
846 } 835 }
847 } 836 }
837}
848 838
849 pub trait Instance { 839trait SealedInstance {
850 const MSG_RAM_OFFSET: usize; 840 const MSG_RAM_OFFSET: usize;
851 841
852 fn regs() -> &'static crate::pac::can::Fdcan; 842 fn regs() -> &'static crate::pac::can::Fdcan;
853 fn registers() -> crate::can::fd::peripheral::Registers; 843 fn registers() -> crate::can::fd::peripheral::Registers;
854 fn ram() -> &'static crate::pac::fdcanram::Fdcanram; 844 fn state() -> &'static State;
855 fn state() -> &'static State; 845 unsafe fn mut_state() -> &'static mut State;
856 unsafe fn mut_state() -> &'static mut State; 846 fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp;
857 fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp;
858 }
859} 847}
860 848
861/// Instance trait 849/// Instance trait
862pub trait Instance: sealed::Instance + RccPeripheral + 'static { 850#[allow(private_bounds)]
851pub trait Instance: SealedInstance + RccPeripheral + 'static {
863 /// Interrupt 0 852 /// Interrupt 0
864 type IT0Interrupt: crate::interrupt::typelevel::Interrupt; 853 type IT0Interrupt: crate::interrupt::typelevel::Interrupt;
865 /// Interrupt 0 854 /// Interrupt 1
866 type IT1Interrupt: crate::interrupt::typelevel::Interrupt; 855 type IT1Interrupt: crate::interrupt::typelevel::Interrupt;
867} 856}
868 857
@@ -871,7 +860,7 @@ pub struct FdcanInstance<'a, T>(PeripheralRef<'a, T>);
871 860
872macro_rules! impl_fdcan { 861macro_rules! impl_fdcan {
873 ($inst:ident, $msg_ram_inst:ident, $msg_ram_offset:literal) => { 862 ($inst:ident, $msg_ram_inst:ident, $msg_ram_offset:literal) => {
874 impl sealed::Instance for peripherals::$inst { 863 impl SealedInstance for peripherals::$inst {
875 const MSG_RAM_OFFSET: usize = $msg_ram_offset; 864 const MSG_RAM_OFFSET: usize = $msg_ram_offset;
876 865
877 fn regs() -> &'static crate::pac::can::Fdcan { 866 fn regs() -> &'static crate::pac::can::Fdcan {
@@ -880,14 +869,11 @@ macro_rules! impl_fdcan {
880 fn registers() -> Registers { 869 fn registers() -> Registers {
881 Registers{regs: &crate::pac::$inst, msgram: &crate::pac::$msg_ram_inst, msg_ram_offset: Self::MSG_RAM_OFFSET} 870 Registers{regs: &crate::pac::$inst, msgram: &crate::pac::$msg_ram_inst, msg_ram_offset: Self::MSG_RAM_OFFSET}
882 } 871 }
883 fn ram() -> &'static crate::pac::fdcanram::Fdcanram { 872 unsafe fn mut_state() -> &'static mut State {
884 &crate::pac::$msg_ram_inst 873 static mut STATE: State = State::new();
885 }
886 unsafe fn mut_state() -> &'static mut sealed::State {
887 static mut STATE: sealed::State = sealed::State::new();
888 &mut *core::ptr::addr_of_mut!(STATE) 874 &mut *core::ptr::addr_of_mut!(STATE)
889 } 875 }
890 fn state() -> &'static sealed::State { 876 fn state() -> &'static State {
891 unsafe { peripherals::$inst::mut_state() } 877 unsafe { peripherals::$inst::mut_state() }
892 } 878 }
893 879
diff --git a/embassy-stm32/src/crc/v1.rs b/embassy-stm32/src/crc/v1.rs
index 0166ab819..f8909d438 100644
--- a/embassy-stm32/src/crc/v1.rs
+++ b/embassy-stm32/src/crc/v1.rs
@@ -2,7 +2,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
2 2
3use crate::pac::CRC as PAC_CRC; 3use crate::pac::CRC as PAC_CRC;
4use crate::peripherals::CRC; 4use crate::peripherals::CRC;
5use crate::rcc::sealed::RccPeripheral; 5use crate::rcc::SealedRccPeripheral;
6use crate::Peripheral; 6use crate::Peripheral;
7 7
8/// CRC driver. 8/// CRC driver.
diff --git a/embassy-stm32/src/crc/v2v3.rs b/embassy-stm32/src/crc/v2v3.rs
index 0c4ae55ce..46f5ea1be 100644
--- a/embassy-stm32/src/crc/v2v3.rs
+++ b/embassy-stm32/src/crc/v2v3.rs
@@ -3,7 +3,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
3use crate::pac::crc::vals; 3use crate::pac::crc::vals;
4use crate::pac::CRC as PAC_CRC; 4use crate::pac::CRC as PAC_CRC;
5use crate::peripherals::CRC; 5use crate::peripherals::CRC;
6use crate::rcc::sealed::RccPeripheral; 6use crate::rcc::SealedRccPeripheral;
7use crate::Peripheral; 7use crate::Peripheral;
8 8
9/// CRC driver. 9/// CRC driver.
diff --git a/embassy-stm32/src/cryp/mod.rs b/embassy-stm32/src/cryp/mod.rs
index 74b095b6f..18b5ec918 100644
--- a/embassy-stm32/src/cryp/mod.rs
+++ b/embassy-stm32/src/cryp/mod.rs
@@ -1885,16 +1885,13 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1885 } 1885 }
1886} 1886}
1887 1887
1888pub(crate) mod sealed { 1888trait SealedInstance {
1889 use super::*; 1889 fn regs() -> pac::cryp::Cryp;
1890
1891 pub trait Instance {
1892 fn regs() -> pac::cryp::Cryp;
1893 }
1894} 1890}
1895 1891
1896/// CRYP instance trait. 1892/// CRYP instance trait.
1897pub trait Instance: sealed::Instance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { 1893#[allow(private_bounds)]
1894pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send {
1898 /// Interrupt for this CRYP instance. 1895 /// Interrupt for this CRYP instance.
1899 type Interrupt: interrupt::typelevel::Interrupt; 1896 type Interrupt: interrupt::typelevel::Interrupt;
1900} 1897}
@@ -1905,7 +1902,7 @@ foreach_interrupt!(
1905 type Interrupt = crate::interrupt::typelevel::$irq; 1902 type Interrupt = crate::interrupt::typelevel::$irq;
1906 } 1903 }
1907 1904
1908 impl sealed::Instance for peripherals::$inst { 1905 impl SealedInstance for peripherals::$inst {
1909 fn regs() -> crate::pac::cryp::Cryp { 1906 fn regs() -> crate::pac::cryp::Cryp {
1910 crate::pac::$inst 1907 crate::pac::$inst
1911 } 1908 }
diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs
index 60f9404c2..acfed8356 100644
--- a/embassy-stm32/src/dac/mod.rs
+++ b/embassy-stm32/src/dac/mod.rs
@@ -127,7 +127,7 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> {
127 pub fn new( 127 pub fn new(
128 _peri: impl Peripheral<P = T> + 'd, 128 _peri: impl Peripheral<P = T> + 'd,
129 dma: impl Peripheral<P = DMA> + 'd, 129 dma: impl Peripheral<P = DMA> + 'd,
130 pin: impl Peripheral<P = impl DacPin<T, N> + crate::gpio::sealed::Pin> + 'd, 130 pin: impl Peripheral<P = impl DacPin<T, N> + crate::gpio::Pin> + 'd,
131 ) -> Self { 131 ) -> Self {
132 into_ref!(dma, pin); 132 into_ref!(dma, pin);
133 pin.set_as_analog(); 133 pin.set_as_analog();
@@ -392,8 +392,8 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> {
392 _peri: impl Peripheral<P = T> + 'd, 392 _peri: impl Peripheral<P = T> + 'd,
393 dma_ch1: impl Peripheral<P = DMACh1> + 'd, 393 dma_ch1: impl Peripheral<P = DMACh1> + 'd,
394 dma_ch2: impl Peripheral<P = DMACh2> + 'd, 394 dma_ch2: impl Peripheral<P = DMACh2> + 'd,
395 pin_ch1: impl Peripheral<P = impl DacPin<T, 1> + crate::gpio::sealed::Pin> + 'd, 395 pin_ch1: impl Peripheral<P = impl DacPin<T, 1> + crate::gpio::Pin> + 'd,
396 pin_ch2: impl Peripheral<P = impl DacPin<T, 2> + crate::gpio::sealed::Pin> + 'd, 396 pin_ch2: impl Peripheral<P = impl DacPin<T, 2> + crate::gpio::Pin> + 'd,
397 ) -> Self { 397 ) -> Self {
398 into_ref!(dma_ch1, dma_ch2, pin_ch1, pin_ch2); 398 into_ref!(dma_ch1, dma_ch2, pin_ch1, pin_ch2);
399 pin_ch1.set_as_analog(); 399 pin_ch1.set_as_analog();
@@ -488,14 +488,13 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> {
488 } 488 }
489} 489}
490 490
491pub(crate) mod sealed { 491trait SealedInstance {
492 pub trait Instance { 492 fn regs() -> &'static crate::pac::dac::Dac;
493 fn regs() -> &'static crate::pac::dac::Dac;
494 }
495} 493}
496 494
497/// DAC instance. 495/// DAC instance.
498pub trait Instance: sealed::Instance + RccPeripheral + 'static {} 496#[allow(private_bounds)]
497pub trait Instance: SealedInstance + RccPeripheral + 'static {}
499dma_trait!(DacDma1, Instance); 498dma_trait!(DacDma1, Instance);
500dma_trait!(DacDma2, Instance); 499dma_trait!(DacDma2, Instance);
501 500
@@ -504,7 +503,7 @@ pub trait DacPin<T: Instance, const C: u8>: crate::gpio::Pin + 'static {}
504 503
505foreach_peripheral!( 504foreach_peripheral!(
506 (dac, $inst:ident) => { 505 (dac, $inst:ident) => {
507 impl crate::dac::sealed::Instance for peripherals::$inst { 506 impl crate::dac::SealedInstance for peripherals::$inst {
508 fn regs() -> &'static crate::pac::dac::Dac { 507 fn regs() -> &'static crate::pac::dac::Dac {
509 &crate::pac::$inst 508 &crate::pac::$inst
510 } 509 }
diff --git a/embassy-stm32/src/dcmi.rs b/embassy-stm32/src/dcmi.rs
index 826b04a4b..646ee2ce2 100644
--- a/embassy-stm32/src/dcmi.rs
+++ b/embassy-stm32/src/dcmi.rs
@@ -7,8 +7,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
7use embassy_sync::waitqueue::AtomicWaker; 7use embassy_sync::waitqueue::AtomicWaker;
8 8
9use crate::dma::Transfer; 9use crate::dma::Transfer;
10use crate::gpio::sealed::AFType; 10use crate::gpio::{AFType, Speed};
11use crate::gpio::Speed;
12use crate::interrupt::typelevel::Interrupt; 11use crate::interrupt::typelevel::Interrupt;
13use crate::{interrupt, Peripheral}; 12use crate::{interrupt, Peripheral};
14 13
@@ -431,14 +430,13 @@ where
431 } 430 }
432} 431}
433 432
434mod sealed { 433trait SealedInstance: crate::rcc::RccPeripheral {
435 pub trait Instance: crate::rcc::RccPeripheral { 434 fn regs(&self) -> crate::pac::dcmi::Dcmi;
436 fn regs(&self) -> crate::pac::dcmi::Dcmi;
437 }
438} 435}
439 436
440/// DCMI instance. 437/// DCMI instance.
441pub trait Instance: sealed::Instance + 'static { 438#[allow(private_bounds)]
439pub trait Instance: SealedInstance + 'static {
442 /// Interrupt for this instance. 440 /// Interrupt for this instance.
443 type Interrupt: interrupt::typelevel::Interrupt; 441 type Interrupt: interrupt::typelevel::Interrupt;
444} 442}
@@ -465,7 +463,7 @@ pin_trait!(PixClkPin, Instance);
465#[allow(unused)] 463#[allow(unused)]
466macro_rules! impl_peripheral { 464macro_rules! impl_peripheral {
467 ($inst:ident, $irq:ident) => { 465 ($inst:ident, $irq:ident) => {
468 impl sealed::Instance for crate::peripherals::$inst { 466 impl SealedInstance for crate::peripherals::$inst {
469 fn regs(&self) -> crate::pac::dcmi::Dcmi { 467 fn regs(&self) -> crate::pac::dcmi::Dcmi {
470 crate::pac::$inst 468 crate::pac::$inst
471 } 469 }
diff --git a/embassy-stm32/src/dma/dmamux.rs b/embassy-stm32/src/dma/dmamux.rs
index 1e9ab5944..dc7cd3a66 100644
--- a/embassy-stm32/src/dma/dmamux.rs
+++ b/embassy-stm32/src/dma/dmamux.rs
@@ -19,9 +19,7 @@ pub(crate) fn configure_dmamux(info: &DmamuxInfo, request: u8) {
19 }); 19 });
20} 20}
21 21
22pub(crate) mod dmamux_sealed { 22pub(crate) trait SealedMuxChannel {}
23 pub trait MuxChannel {}
24}
25 23
26/// DMAMUX1 instance. 24/// DMAMUX1 instance.
27pub struct DMAMUX1; 25pub struct DMAMUX1;
@@ -30,14 +28,15 @@ pub struct DMAMUX1;
30pub struct DMAMUX2; 28pub struct DMAMUX2;
31 29
32/// DMAMUX channel trait. 30/// DMAMUX channel trait.
33pub trait MuxChannel: dmamux_sealed::MuxChannel { 31#[allow(private_bounds)]
32pub trait MuxChannel: SealedMuxChannel {
34 /// DMAMUX instance this channel is on. 33 /// DMAMUX instance this channel is on.
35 type Mux; 34 type Mux;
36} 35}
37 36
38macro_rules! dmamux_channel_impl { 37macro_rules! dmamux_channel_impl {
39 ($channel_peri:ident, $dmamux:ident) => { 38 ($channel_peri:ident, $dmamux:ident) => {
40 impl crate::dma::dmamux_sealed::MuxChannel for crate::peripherals::$channel_peri {} 39 impl crate::dma::SealedMuxChannel for crate::peripherals::$channel_peri {}
41 impl crate::dma::MuxChannel for crate::peripherals::$channel_peri { 40 impl crate::dma::MuxChannel for crate::peripherals::$channel_peri {
42 type Mux = crate::dma::$dmamux; 41 type Mux = crate::dma::$dmamux;
43 } 42 }
diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs
index 2f98b9857..7e3681469 100644
--- a/embassy-stm32/src/dma/mod.rs
+++ b/embassy-stm32/src/dma/mod.rs
@@ -39,18 +39,18 @@ pub type Request = u8;
39#[cfg(not(any(dma_v2, bdma_v2, gpdma, dmamux)))] 39#[cfg(not(any(dma_v2, bdma_v2, gpdma, dmamux)))]
40pub type Request = (); 40pub type Request = ();
41 41
42pub(crate) mod sealed { 42pub(crate) trait SealedChannel {
43 pub trait Channel { 43 fn id(&self) -> u8;
44 fn id(&self) -> u8; 44}
45 } 45
46 pub trait ChannelInterrupt { 46pub(crate) trait ChannelInterrupt {
47 #[cfg_attr(not(feature = "rt"), allow(unused))] 47 #[cfg_attr(not(feature = "rt"), allow(unused))]
48 unsafe fn on_irq(); 48 unsafe fn on_irq();
49 }
50} 49}
51 50
52/// DMA channel. 51/// DMA channel.
53pub trait Channel: sealed::Channel + Peripheral<P = Self> + Into<AnyChannel> + 'static { 52#[allow(private_bounds)]
53pub trait Channel: SealedChannel + Peripheral<P = Self> + Into<AnyChannel> + 'static {
54 /// Type-erase (degrade) this pin into an `AnyChannel`. 54 /// Type-erase (degrade) this pin into an `AnyChannel`.
55 /// 55 ///
56 /// This converts DMA channel singletons (`DMA1_CH3`, `DMA2_CH1`, ...), which 56 /// This converts DMA channel singletons (`DMA1_CH3`, `DMA2_CH1`, ...), which
@@ -64,12 +64,12 @@ pub trait Channel: sealed::Channel + Peripheral<P = Self> + Into<AnyChannel> + '
64 64
65macro_rules! dma_channel_impl { 65macro_rules! dma_channel_impl {
66 ($channel_peri:ident, $index:expr) => { 66 ($channel_peri:ident, $index:expr) => {
67 impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri { 67 impl crate::dma::SealedChannel for crate::peripherals::$channel_peri {
68 fn id(&self) -> u8 { 68 fn id(&self) -> u8 {
69 $index 69 $index
70 } 70 }
71 } 71 }
72 impl crate::dma::sealed::ChannelInterrupt for crate::peripherals::$channel_peri { 72 impl crate::dma::ChannelInterrupt for crate::peripherals::$channel_peri {
73 unsafe fn on_irq() { 73 unsafe fn on_irq() {
74 crate::dma::AnyChannel { id: $index }.on_irq(); 74 crate::dma::AnyChannel { id: $index }.on_irq();
75 } 75 }
@@ -97,7 +97,7 @@ impl AnyChannel {
97 } 97 }
98} 98}
99 99
100impl sealed::Channel for AnyChannel { 100impl SealedChannel for AnyChannel {
101 fn id(&self) -> u8 { 101 fn id(&self) -> u8 {
102 self.id 102 self.id
103 } 103 }
diff --git a/embassy-stm32/src/dma/word.rs b/embassy-stm32/src/dma/word.rs
index a72c4b7d9..fb1bde860 100644
--- a/embassy-stm32/src/dma/word.rs
+++ b/embassy-stm32/src/dma/word.rs
@@ -20,14 +20,13 @@ impl WordSize {
20 } 20 }
21} 21}
22 22
23mod sealed { 23trait SealedWord {}
24 pub trait Word {}
25}
26 24
27/// DMA word trait. 25/// DMA word trait.
28/// 26///
29/// This is implemented for u8, u16, u32, etc. 27/// This is implemented for u8, u16, u32, etc.
30pub trait Word: sealed::Word + Default + Copy + 'static { 28#[allow(private_bounds)]
29pub trait Word: SealedWord + Default + Copy + 'static {
31 /// Word size 30 /// Word size
32 fn size() -> WordSize; 31 fn size() -> WordSize;
33 /// Amount of bits of this word size. 32 /// Amount of bits of this word size.
@@ -36,7 +35,7 @@ pub trait Word: sealed::Word + Default + Copy + 'static {
36 35
37macro_rules! impl_word { 36macro_rules! impl_word {
38 (_, $T:ident, $bits:literal, $size:ident) => { 37 (_, $T:ident, $bits:literal, $size:ident) => {
39 impl sealed::Word for $T {} 38 impl SealedWord for $T {}
40 impl Word for $T { 39 impl Word for $T {
41 fn bits() -> usize { 40 fn bits() -> usize {
42 $bits 41 $bits
diff --git a/embassy-stm32/src/eth/mod.rs b/embassy-stm32/src/eth/mod.rs
index 71fe09c3f..bfe8a60d6 100644
--- a/embassy-stm32/src/eth/mod.rs
+++ b/embassy-stm32/src/eth/mod.rs
@@ -177,16 +177,15 @@ pub unsafe trait PHY {
177 fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool; 177 fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool;
178} 178}
179 179
180pub(crate) mod sealed { 180trait SealedInstance {
181 pub trait Instance { 181 fn regs() -> crate::pac::eth::Eth;
182 fn regs() -> crate::pac::eth::Eth;
183 }
184} 182}
185 183
186/// Ethernet instance. 184/// Ethernet instance.
187pub trait Instance: sealed::Instance + RccPeripheral + Send + 'static {} 185#[allow(private_bounds)]
186pub trait Instance: SealedInstance + RccPeripheral + Send + 'static {}
188 187
189impl sealed::Instance for crate::peripherals::ETH { 188impl SealedInstance for crate::peripherals::ETH {
190 fn regs() -> crate::pac::eth::Eth { 189 fn regs() -> crate::pac::eth::Eth {
191 crate::pac::ETH 190 crate::pac::ETH
192 } 191 }
diff --git a/embassy-stm32/src/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs
index e5b7b0452..6f0174def 100644
--- a/embassy-stm32/src/eth/v1/mod.rs
+++ b/embassy-stm32/src/eth/v1/mod.rs
@@ -12,15 +12,14 @@ use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress
12pub(crate) use self::rx_desc::{RDes, RDesRing}; 12pub(crate) use self::rx_desc::{RDes, RDesRing};
13pub(crate) use self::tx_desc::{TDes, TDesRing}; 13pub(crate) use self::tx_desc::{TDes, TDesRing};
14use super::*; 14use super::*;
15use crate::gpio::sealed::{AFType, Pin as __GpioPin}; 15use crate::gpio::{AFType, AnyPin, SealedPin};
16use crate::gpio::AnyPin;
17use crate::interrupt::InterruptExt; 16use crate::interrupt::InterruptExt;
18#[cfg(eth_v1a)] 17#[cfg(eth_v1a)]
19use crate::pac::AFIO; 18use crate::pac::AFIO;
20#[cfg(any(eth_v1b, eth_v1c))] 19#[cfg(any(eth_v1b, eth_v1c))]
21use crate::pac::SYSCFG; 20use crate::pac::SYSCFG;
22use crate::pac::{ETH, RCC}; 21use crate::pac::{ETH, RCC};
23use crate::rcc::sealed::RccPeripheral; 22use crate::rcc::SealedRccPeripheral;
24use crate::{interrupt, Peripheral}; 23use crate::{interrupt, Peripheral};
25 24
26/// Interrupt handler. 25/// Interrupt handler.
@@ -149,8 +148,8 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
149 #[cfg(any(eth_v1b, eth_v1c))] 148 #[cfg(any(eth_v1b, eth_v1c))]
150 config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); 149 config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
151 150
152 let dma = ETH.ethernet_dma(); 151 let dma = T::regs().ethernet_dma();
153 let mac = ETH.ethernet_mac(); 152 let mac = T::regs().ethernet_mac();
154 153
155 // Reset and wait 154 // Reset and wait
156 dma.dmabmr().modify(|w| w.set_sr(true)); 155 dma.dmabmr().modify(|w| w.set_sr(true));
@@ -192,7 +191,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
192 191
193 // TODO MTU size setting not found for v1 ethernet, check if correct 192 // TODO MTU size setting not found for v1 ethernet, check if correct
194 193
195 let hclk = <T as RccPeripheral>::frequency(); 194 let hclk = <T as SealedRccPeripheral>::frequency();
196 let hclk_mhz = hclk.0 / 1_000_000; 195 let hclk_mhz = hclk.0 / 1_000_000;
197 196
198 // Set the MDC clock frequency in the range 1MHz - 2.5MHz 197 // Set the MDC clock frequency in the range 1MHz - 2.5MHz
@@ -235,8 +234,8 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
235 234
236 fence(Ordering::SeqCst); 235 fence(Ordering::SeqCst);
237 236
238 let mac = ETH.ethernet_mac(); 237 let mac = T::regs().ethernet_mac();
239 let dma = ETH.ethernet_dma(); 238 let dma = T::regs().ethernet_dma();
240 239
241 mac.maccr().modify(|w| { 240 mac.maccr().modify(|w| {
242 w.set_re(true); 241 w.set_re(true);
@@ -275,7 +274,7 @@ pub struct EthernetStationManagement<T: Instance> {
275 274
276unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> { 275unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
277 fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 { 276 fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 {
278 let mac = ETH.ethernet_mac(); 277 let mac = T::regs().ethernet_mac();
279 278
280 mac.macmiiar().modify(|w| { 279 mac.macmiiar().modify(|w| {
281 w.set_pa(phy_addr); 280 w.set_pa(phy_addr);
@@ -289,7 +288,7 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
289 } 288 }
290 289
291 fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) { 290 fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) {
292 let mac = ETH.ethernet_mac(); 291 let mac = T::regs().ethernet_mac();
293 292
294 mac.macmiidr().write(|w| w.set_md(val)); 293 mac.macmiidr().write(|w| w.set_md(val));
295 mac.macmiiar().modify(|w| { 294 mac.macmiiar().modify(|w| {
@@ -305,8 +304,8 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
305 304
306impl<'d, T: Instance, P: PHY> Drop for Ethernet<'d, T, P> { 305impl<'d, T: Instance, P: PHY> Drop for Ethernet<'d, T, P> {
307 fn drop(&mut self) { 306 fn drop(&mut self) {
308 let dma = ETH.ethernet_dma(); 307 let dma = T::regs().ethernet_dma();
309 let mac = ETH.ethernet_mac(); 308 let mac = T::regs().ethernet_mac();
310 309
311 // Disable the TX DMA and wait for any previous transmissions to be completed 310 // Disable the TX DMA and wait for any previous transmissions to be completed
312 dma.dmaomr().modify(|w| w.set_st(St::STOPPED)); 311 dma.dmaomr().modify(|w| w.set_st(St::STOPPED));
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs
index 8d69561d4..c6e015022 100644
--- a/embassy-stm32/src/eth/v2/mod.rs
+++ b/embassy-stm32/src/eth/v2/mod.rs
@@ -7,11 +7,10 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
7 7
8pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; 8pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing};
9use super::*; 9use super::*;
10use crate::gpio::sealed::{AFType, Pin as _}; 10use crate::gpio::{AFType, AnyPin, SealedPin as _, Speed};
11use crate::gpio::{AnyPin, Speed};
12use crate::interrupt::InterruptExt; 11use crate::interrupt::InterruptExt;
13use crate::pac::ETH; 12use crate::pac::ETH;
14use crate::rcc::sealed::RccPeripheral; 13use crate::rcc::SealedRccPeripheral;
15use crate::{interrupt, Peripheral}; 14use crate::{interrupt, Peripheral};
16 15
17/// Interrupt handler. 16/// Interrupt handler.
@@ -207,9 +206,9 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
207 phy: P, 206 phy: P,
208 mac_addr: [u8; 6], 207 mac_addr: [u8; 6],
209 ) -> Self { 208 ) -> Self {
210 let dma = ETH.ethernet_dma(); 209 let dma = T::regs().ethernet_dma();
211 let mac = ETH.ethernet_mac(); 210 let mac = T::regs().ethernet_mac();
212 let mtl = ETH.ethernet_mtl(); 211 let mtl = T::regs().ethernet_mtl();
213 212
214 // Reset and wait 213 // Reset and wait
215 dma.dmamr().modify(|w| w.set_swr(true)); 214 dma.dmamr().modify(|w| w.set_swr(true));
@@ -265,7 +264,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
265 w.set_rbsz(RX_BUFFER_SIZE as u16); 264 w.set_rbsz(RX_BUFFER_SIZE as u16);
266 }); 265 });
267 266
268 let hclk = <T as RccPeripheral>::frequency(); 267 let hclk = <T as SealedRccPeripheral>::frequency();
269 let hclk_mhz = hclk.0 / 1_000_000; 268 let hclk_mhz = hclk.0 / 1_000_000;
270 269
271 // Set the MDC clock frequency in the range 1MHz - 2.5MHz 270 // Set the MDC clock frequency in the range 1MHz - 2.5MHz
@@ -296,9 +295,9 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
296 295
297 fence(Ordering::SeqCst); 296 fence(Ordering::SeqCst);
298 297
299 let mac = ETH.ethernet_mac(); 298 let mac = T::regs().ethernet_mac();
300 let mtl = ETH.ethernet_mtl(); 299 let mtl = T::regs().ethernet_mtl();
301 let dma = ETH.ethernet_dma(); 300 let dma = T::regs().ethernet_dma();
302 301
303 mac.maccr().modify(|w| { 302 mac.maccr().modify(|w| {
304 w.set_re(true); 303 w.set_re(true);
@@ -334,7 +333,7 @@ pub struct EthernetStationManagement<T: Instance> {
334 333
335unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> { 334unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
336 fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 { 335 fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 {
337 let mac = ETH.ethernet_mac(); 336 let mac = T::regs().ethernet_mac();
338 337
339 mac.macmdioar().modify(|w| { 338 mac.macmdioar().modify(|w| {
340 w.set_pa(phy_addr); 339 w.set_pa(phy_addr);
@@ -348,7 +347,7 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
348 } 347 }
349 348
350 fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) { 349 fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) {
351 let mac = ETH.ethernet_mac(); 350 let mac = T::regs().ethernet_mac();
352 351
353 mac.macmdiodr().write(|w| w.set_md(val)); 352 mac.macmdiodr().write(|w| w.set_md(val));
354 mac.macmdioar().modify(|w| { 353 mac.macmdioar().modify(|w| {
@@ -364,9 +363,9 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
364 363
365impl<'d, T: Instance, P: PHY> Drop for Ethernet<'d, T, P> { 364impl<'d, T: Instance, P: PHY> Drop for Ethernet<'d, T, P> {
366 fn drop(&mut self) { 365 fn drop(&mut self) {
367 let dma = ETH.ethernet_dma(); 366 let dma = T::regs().ethernet_dma();
368 let mac = ETH.ethernet_mac(); 367 let mac = T::regs().ethernet_mac();
369 let mtl = ETH.ethernet_mtl(); 368 let mtl = T::regs().ethernet_mtl();
370 369
371 // Disable the TX DMA and wait for any previous transmissions to be completed 370 // Disable the TX DMA and wait for any previous transmissions to be completed
372 dma.dmactx_cr().modify(|w| w.set_st(false)); 371 dma.dmactx_cr().modify(|w| w.set_st(false));
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs
index bd10ba158..8d5dae436 100644
--- a/embassy-stm32/src/exti.rs
+++ b/embassy-stm32/src/exti.rs
@@ -330,12 +330,11 @@ macro_rules! impl_irq {
330 330
331foreach_exti_irq!(impl_irq); 331foreach_exti_irq!(impl_irq);
332 332
333pub(crate) mod sealed { 333trait SealedChannel {}
334 pub trait Channel {}
335}
336 334
337/// EXTI channel trait. 335/// EXTI channel trait.
338pub trait Channel: sealed::Channel + Sized { 336#[allow(private_bounds)]
337pub trait Channel: SealedChannel + Sized {
339 /// Get the EXTI channel number. 338 /// Get the EXTI channel number.
340 fn number(&self) -> u8; 339 fn number(&self) -> u8;
341 340
@@ -359,7 +358,7 @@ pub struct AnyChannel {
359} 358}
360 359
361impl_peripheral!(AnyChannel); 360impl_peripheral!(AnyChannel);
362impl sealed::Channel for AnyChannel {} 361impl SealedChannel for AnyChannel {}
363impl Channel for AnyChannel { 362impl Channel for AnyChannel {
364 fn number(&self) -> u8 { 363 fn number(&self) -> u8 {
365 self.number 364 self.number
@@ -368,7 +367,7 @@ impl Channel for AnyChannel {
368 367
369macro_rules! impl_exti { 368macro_rules! impl_exti {
370 ($type:ident, $number:expr) => { 369 ($type:ident, $number:expr) => {
371 impl sealed::Channel for peripherals::$type {} 370 impl SealedChannel for peripherals::$type {}
372 impl Channel for peripherals::$type { 371 impl Channel for peripherals::$type {
373 fn number(&self) -> u8 { 372 fn number(&self) -> u8 {
374 $number 373 $number
diff --git a/embassy-stm32/src/fmc.rs b/embassy-stm32/src/fmc.rs
index 9d731a512..aced69878 100644
--- a/embassy-stm32/src/fmc.rs
+++ b/embassy-stm32/src/fmc.rs
@@ -3,8 +3,7 @@ use core::marker::PhantomData;
3 3
4use embassy_hal_internal::into_ref; 4use embassy_hal_internal::into_ref;
5 5
6use crate::gpio::sealed::AFType; 6use crate::gpio::{AFType, Pull, Speed};
7use crate::gpio::{Pull, Speed};
8use crate::Peripheral; 7use crate::Peripheral;
9 8
10/// FMC driver 9/// FMC driver
@@ -44,7 +43,7 @@ where
44 43
45 /// Get the kernel clock currently in use for this FMC instance. 44 /// Get the kernel clock currently in use for this FMC instance.
46 pub fn source_clock_hz(&self) -> u32 { 45 pub fn source_clock_hz(&self) -> u32 {
47 <T as crate::rcc::sealed::RccPeripheral>::frequency().0 46 <T as crate::rcc::SealedRccPeripheral>::frequency().0
48 } 47 }
49} 48}
50 49
@@ -69,7 +68,7 @@ where
69 } 68 }
70 69
71 fn source_clock_hz(&self) -> u32 { 70 fn source_clock_hz(&self) -> u32 {
72 <T as crate::rcc::sealed::RccPeripheral>::frequency().0 71 <T as crate::rcc::SealedRccPeripheral>::frequency().0
73 } 72 }
74} 73}
75 74
@@ -201,18 +200,17 @@ impl<'d, T: Instance> Fmc<'d, T> {
201 )); 200 ));
202} 201}
203 202
204pub(crate) mod sealed { 203trait SealedInstance: crate::rcc::SealedRccPeripheral {
205 pub trait Instance: crate::rcc::sealed::RccPeripheral { 204 const REGS: crate::pac::fmc::Fmc;
206 const REGS: crate::pac::fmc::Fmc;
207 }
208} 205}
209 206
210/// FMC instance trait. 207/// FMC instance trait.
211pub trait Instance: sealed::Instance + 'static {} 208#[allow(private_bounds)]
209pub trait Instance: SealedInstance + 'static {}
212 210
213foreach_peripheral!( 211foreach_peripheral!(
214 (fmc, $inst:ident) => { 212 (fmc, $inst:ident) => {
215 impl crate::fmc::sealed::Instance for crate::peripherals::$inst { 213 impl crate::fmc::SealedInstance for crate::peripherals::$inst {
216 const REGS: crate::pac::fmc::Fmc = crate::pac::$inst; 214 const REGS: crate::pac::fmc::Fmc = crate::pac::$inst;
217 } 215 }
218 impl crate::fmc::Instance for crate::peripherals::$inst {} 216 impl crate::fmc::Instance for crate::peripherals::$inst {}
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs
index 7cc28ff56..33f22f676 100644
--- a/embassy-stm32/src/gpio.rs
+++ b/embassy-stm32/src/gpio.rs
@@ -6,7 +6,6 @@ use core::convert::Infallible;
6use critical_section::CriticalSection; 6use critical_section::CriticalSection;
7use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; 7use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
8 8
9use self::sealed::Pin as _;
10use crate::pac::gpio::{self, vals}; 9use crate::pac::gpio::{self, vals};
11use crate::{pac, peripherals, Peripheral}; 10use crate::{pac, peripherals, Peripheral};
12 11
@@ -129,6 +128,18 @@ impl<'d> Flex<'d> {
129 }); 128 });
130 } 129 }
131 130
131 /// Put the pin into AF mode, unchecked.
132 ///
133 /// This puts the pin into the AF mode, with the requested number, pull and speed. This is
134 /// completely unchecked, it can attach the pin to literally any peripheral, so use with care.
135 #[inline]
136 pub fn set_as_af_unchecked(&mut self, af_num: u8, af_type: AFType, pull: Pull, speed: Speed) {
137 critical_section::with(|_| {
138 self.pin.set_as_af_pull(af_num, af_type, pull);
139 self.pin.set_speed(speed);
140 });
141 }
142
132 /// Get whether the pin input level is high. 143 /// Get whether the pin input level is high.
133 #[inline] 144 #[inline]
134 pub fn is_high(&self) -> bool { 145 pub fn is_high(&self) -> bool {
@@ -508,172 +519,168 @@ pub enum OutputType {
508 OpenDrain, 519 OpenDrain,
509} 520}
510 521
511impl From<OutputType> for sealed::AFType { 522impl From<OutputType> for AFType {
512 fn from(value: OutputType) -> Self { 523 fn from(value: OutputType) -> Self {
513 match value { 524 match value {
514 OutputType::OpenDrain => sealed::AFType::OutputOpenDrain, 525 OutputType::OpenDrain => AFType::OutputOpenDrain,
515 OutputType::PushPull => sealed::AFType::OutputPushPull, 526 OutputType::PushPull => AFType::OutputPushPull,
516 } 527 }
517 } 528 }
518} 529}
519 530
520#[allow(missing_docs)] 531/// Alternate function type settings
521pub(crate) mod sealed { 532#[derive(Debug, Copy, Clone)]
522 use super::*; 533#[cfg_attr(feature = "defmt", derive(defmt::Format))]
523 534pub enum AFType {
524 /// Alternate function type settings 535 /// Input
525 #[derive(Debug, Copy, Clone)] 536 Input,
526 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 537 /// Output, drive the pin both high or low.
527 pub enum AFType { 538 OutputPushPull,
528 /// Input 539 /// Output, drive the pin low, or don't drive it at all if the output level is high.
529 Input, 540 OutputOpenDrain,
530 /// Output, drive the pin both high or low. 541}
531 OutputPushPull,
532 /// Output, drive the pin low, or don't drive it at all if the output level is high.
533 OutputOpenDrain,
534 }
535
536 pub trait Pin {
537 fn pin_port(&self) -> u8;
538
539 #[inline]
540 fn _pin(&self) -> u8 {
541 self.pin_port() % 16
542 }
543 #[inline]
544 fn _port(&self) -> u8 {
545 self.pin_port() / 16
546 }
547 542
548 #[inline] 543pub(crate) trait SealedPin {
549 fn block(&self) -> gpio::Gpio { 544 fn pin_port(&self) -> u8;
550 pac::GPIO(self._port() as _)
551 }
552 545
553 /// Set the output as high. 546 #[inline]
554 #[inline] 547 fn _pin(&self) -> u8 {
555 fn set_high(&self) { 548 self.pin_port() % 16
556 let n = self._pin() as _; 549 }
557 self.block().bsrr().write(|w| w.set_bs(n, true)); 550 #[inline]
558 } 551 fn _port(&self) -> u8 {
552 self.pin_port() / 16
553 }
559 554
560 /// Set the output as low. 555 #[inline]
561 #[inline] 556 fn block(&self) -> gpio::Gpio {
562 fn set_low(&self) { 557 pac::GPIO(self._port() as _)
563 let n = self._pin() as _; 558 }
564 self.block().bsrr().write(|w| w.set_br(n, true));
565 }
566 559
567 #[inline] 560 /// Set the output as high.
568 fn set_as_af(&self, af_num: u8, af_type: AFType) { 561 #[inline]
569 self.set_as_af_pull(af_num, af_type, Pull::None); 562 fn set_high(&self) {
570 } 563 let n = self._pin() as _;
564 self.block().bsrr().write(|w| w.set_bs(n, true));
565 }
571 566
572 #[cfg(gpio_v1)] 567 /// Set the output as low.
573 #[inline] 568 #[inline]
574 fn set_as_af_pull(&self, _af_num: u8, af_type: AFType, pull: Pull) { 569 fn set_low(&self) {
575 // F1 uses the AFIO register for remapping. 570 let n = self._pin() as _;
576 // For now, this is not implemented, so af_num is ignored 571 self.block().bsrr().write(|w| w.set_br(n, true));
577 // _af_num should be zero here, since it is not set by stm32-data 572 }
578 let r = self.block();
579 let n = self._pin() as usize;
580 let crlh = if n < 8 { 0 } else { 1 };
581 match af_type {
582 AFType::Input => {
583 let cnf = match pull {
584 Pull::Up => {
585 r.bsrr().write(|w| w.set_bs(n, true));
586 vals::CnfIn::PULL
587 }
588 Pull::Down => {
589 r.bsrr().write(|w| w.set_br(n, true));
590 vals::CnfIn::PULL
591 }
592 Pull::None => vals::CnfIn::FLOATING,
593 };
594
595 r.cr(crlh).modify(|w| {
596 w.set_mode(n % 8, vals::Mode::INPUT);
597 w.set_cnf_in(n % 8, cnf);
598 });
599 }
600 AFType::OutputPushPull => {
601 r.cr(crlh).modify(|w| {
602 w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ);
603 w.set_cnf_out(n % 8, vals::CnfOut::ALTPUSHPULL);
604 });
605 }
606 AFType::OutputOpenDrain => {
607 r.cr(crlh).modify(|w| {
608 w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ);
609 w.set_cnf_out(n % 8, vals::CnfOut::ALTOPENDRAIN);
610 });
611 }
612 }
613 }
614 573
615 #[cfg(gpio_v2)] 574 #[inline]
616 #[inline] 575 fn set_as_af(&self, af_num: u8, af_type: AFType) {
617 fn set_as_af_pull(&self, af_num: u8, af_type: AFType, pull: Pull) { 576 self.set_as_af_pull(af_num, af_type, Pull::None);
618 let pin = self._pin() as usize; 577 }
619 let block = self.block();
620 block.afr(pin / 8).modify(|w| w.set_afr(pin % 8, af_num));
621 match af_type {
622 AFType::Input => {}
623 AFType::OutputPushPull => block.otyper().modify(|w| w.set_ot(pin, vals::Ot::PUSHPULL)),
624 AFType::OutputOpenDrain => block.otyper().modify(|w| w.set_ot(pin, vals::Ot::OPENDRAIN)),
625 }
626 block.pupdr().modify(|w| w.set_pupdr(pin, pull.into()));
627 578
628 block.moder().modify(|w| w.set_moder(pin, vals::Moder::ALTERNATE)); 579 #[cfg(gpio_v1)]
629 } 580 #[inline]
581 fn set_as_af_pull(&self, _af_num: u8, af_type: AFType, pull: Pull) {
582 // F1 uses the AFIO register for remapping.
583 // For now, this is not implemented, so af_num is ignored
584 // _af_num should be zero here, since it is not set by stm32-data
585 let r = self.block();
586 let n = self._pin() as usize;
587 let crlh = if n < 8 { 0 } else { 1 };
588 match af_type {
589 AFType::Input => {
590 let cnf = match pull {
591 Pull::Up => {
592 r.bsrr().write(|w| w.set_bs(n, true));
593 vals::CnfIn::PULL
594 }
595 Pull::Down => {
596 r.bsrr().write(|w| w.set_br(n, true));
597 vals::CnfIn::PULL
598 }
599 Pull::None => vals::CnfIn::FLOATING,
600 };
630 601
631 #[inline] 602 r.cr(crlh).modify(|w| {
632 fn set_as_analog(&self) { 603 w.set_mode(n % 8, vals::Mode::INPUT);
633 let pin = self._pin() as usize; 604 w.set_cnf_in(n % 8, cnf);
634 let block = self.block();
635 #[cfg(gpio_v1)]
636 {
637 let crlh = if pin < 8 { 0 } else { 1 };
638 block.cr(crlh).modify(|w| {
639 w.set_mode(pin % 8, vals::Mode::INPUT);
640 w.set_cnf_in(pin % 8, vals::CnfIn::ANALOG);
641 }); 605 });
642 } 606 }
643 #[cfg(gpio_v2)] 607 AFType::OutputPushPull => {
644 block.moder().modify(|w| w.set_moder(pin, vals::Moder::ANALOG)); 608 r.cr(crlh).modify(|w| {
609 w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ);
610 w.set_cnf_out(n % 8, vals::CnfOut::ALTPUSHPULL);
611 });
612 }
613 AFType::OutputOpenDrain => {
614 r.cr(crlh).modify(|w| {
615 w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ);
616 w.set_cnf_out(n % 8, vals::CnfOut::ALTOPENDRAIN);
617 });
618 }
619 }
620 }
621
622 #[cfg(gpio_v2)]
623 #[inline]
624 fn set_as_af_pull(&self, af_num: u8, af_type: AFType, pull: Pull) {
625 let pin = self._pin() as usize;
626 let block = self.block();
627 block.afr(pin / 8).modify(|w| w.set_afr(pin % 8, af_num));
628 match af_type {
629 AFType::Input => {}
630 AFType::OutputPushPull => block.otyper().modify(|w| w.set_ot(pin, vals::Ot::PUSHPULL)),
631 AFType::OutputOpenDrain => block.otyper().modify(|w| w.set_ot(pin, vals::Ot::OPENDRAIN)),
645 } 632 }
633 block.pupdr().modify(|w| w.set_pupdr(pin, pull.into()));
634
635 block.moder().modify(|w| w.set_moder(pin, vals::Moder::ALTERNATE));
636 }
646 637
647 /// Set the pin as "disconnected", ie doing nothing and consuming the lowest 638 #[inline]
648 /// amount of power possible. 639 fn set_as_analog(&self) {
649 /// 640 let pin = self._pin() as usize;
650 /// This is currently the same as set_as_analog but is semantically different really. 641 let block = self.block();
651 /// Drivers should set_as_disconnected pins when dropped. 642 #[cfg(gpio_v1)]
652 #[inline] 643 {
653 fn set_as_disconnected(&self) { 644 let crlh = if pin < 8 { 0 } else { 1 };
654 self.set_as_analog(); 645 block.cr(crlh).modify(|w| {
646 w.set_mode(pin % 8, vals::Mode::INPUT);
647 w.set_cnf_in(pin % 8, vals::CnfIn::ANALOG);
648 });
655 } 649 }
650 #[cfg(gpio_v2)]
651 block.moder().modify(|w| w.set_moder(pin, vals::Moder::ANALOG));
652 }
656 653
657 #[inline] 654 /// Set the pin as "disconnected", ie doing nothing and consuming the lowest
658 fn set_speed(&self, speed: Speed) { 655 /// amount of power possible.
659 let pin = self._pin() as usize; 656 ///
657 /// This is currently the same as set_as_analog but is semantically different really.
658 /// Drivers should set_as_disconnected pins when dropped.
659 #[inline]
660 fn set_as_disconnected(&self) {
661 self.set_as_analog();
662 }
660 663
661 #[cfg(gpio_v1)] 664 #[inline]
662 { 665 fn set_speed(&self, speed: Speed) {
663 let crlh = if pin < 8 { 0 } else { 1 }; 666 let pin = self._pin() as usize;
664 self.block().cr(crlh).modify(|w| {
665 w.set_mode(pin % 8, speed.into());
666 });
667 }
668 667
669 #[cfg(gpio_v2)] 668 #[cfg(gpio_v1)]
670 self.block().ospeedr().modify(|w| w.set_ospeedr(pin, speed.into())); 669 {
670 let crlh = if pin < 8 { 0 } else { 1 };
671 self.block().cr(crlh).modify(|w| {
672 w.set_mode(pin % 8, speed.into());
673 });
671 } 674 }
675
676 #[cfg(gpio_v2)]
677 self.block().ospeedr().modify(|w| w.set_ospeedr(pin, speed.into()));
672 } 678 }
673} 679}
674 680
675/// GPIO pin trait. 681/// GPIO pin trait.
676pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'static { 682#[allow(private_bounds)]
683pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static {
677 /// EXTI channel assigned to this pin. 684 /// EXTI channel assigned to this pin.
678 /// 685 ///
679 /// For example, PC4 uses EXTI4. 686 /// For example, PC4 uses EXTI4.
@@ -737,7 +744,7 @@ impl Pin for AnyPin {
737 #[cfg(feature = "exti")] 744 #[cfg(feature = "exti")]
738 type ExtiChannel = crate::exti::AnyChannel; 745 type ExtiChannel = crate::exti::AnyChannel;
739} 746}
740impl sealed::Pin for AnyPin { 747impl SealedPin for AnyPin {
741 #[inline] 748 #[inline]
742 fn pin_port(&self) -> u8 { 749 fn pin_port(&self) -> u8 {
743 self.pin_port 750 self.pin_port
@@ -752,7 +759,7 @@ foreach_pin!(
752 #[cfg(feature = "exti")] 759 #[cfg(feature = "exti")]
753 type ExtiChannel = peripherals::$exti_ch; 760 type ExtiChannel = peripherals::$exti_ch;
754 } 761 }
755 impl sealed::Pin for peripherals::$pin_name { 762 impl SealedPin for peripherals::$pin_name {
756 #[inline] 763 #[inline]
757 fn pin_port(&self) -> u8 { 764 fn pin_port(&self) -> u8 {
758 $port_num * 16 + $pin_num 765 $port_num * 16 + $pin_num
@@ -769,7 +776,7 @@ foreach_pin!(
769 776
770pub(crate) unsafe fn init(_cs: CriticalSection) { 777pub(crate) unsafe fn init(_cs: CriticalSection) {
771 #[cfg(afio)] 778 #[cfg(afio)]
772 <crate::peripherals::AFIO as crate::rcc::sealed::RccPeripheral>::enable_and_reset_with_cs(_cs); 779 <crate::peripherals::AFIO as crate::rcc::SealedRccPeripheral>::enable_and_reset_with_cs(_cs);
773 780
774 crate::_generated::init_gpio(); 781 crate::_generated::init_gpio();
775 782
@@ -1061,9 +1068,3 @@ impl<'d> embedded_hal_1::digital::StatefulOutputPin for Flex<'d> {
1061 Ok((*self).is_set_low()) 1068 Ok((*self).is_set_low())
1062 } 1069 }
1063} 1070}
1064
1065/// Low-level GPIO manipulation.
1066#[cfg(feature = "unstable-pac")]
1067pub mod low_level {
1068 pub use super::sealed::*;
1069}
diff --git a/embassy-stm32/src/hash/mod.rs b/embassy-stm32/src/hash/mod.rs
index b47814f8b..787d5b1c9 100644
--- a/embassy-stm32/src/hash/mod.rs
+++ b/embassy-stm32/src/hash/mod.rs
@@ -17,7 +17,7 @@ use crate::dma::NoDma;
17use crate::dma::Transfer; 17use crate::dma::Transfer;
18use crate::interrupt::typelevel::Interrupt; 18use crate::interrupt::typelevel::Interrupt;
19use crate::peripherals::HASH; 19use crate::peripherals::HASH;
20use crate::rcc::sealed::RccPeripheral; 20use crate::rcc::SealedRccPeripheral;
21use crate::{interrupt, pac, peripherals, Peripheral}; 21use crate::{interrupt, pac, peripherals, Peripheral};
22 22
23#[cfg(hash_v1)] 23#[cfg(hash_v1)]
@@ -561,16 +561,13 @@ impl<'d, T: Instance, D> Hash<'d, T, D> {
561 } 561 }
562} 562}
563 563
564pub(crate) mod sealed { 564trait SealedInstance {
565 use super::*; 565 fn regs() -> pac::hash::Hash;
566
567 pub trait Instance {
568 fn regs() -> pac::hash::Hash;
569 }
570} 566}
571 567
572/// HASH instance trait. 568/// HASH instance trait.
573pub trait Instance: sealed::Instance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { 569#[allow(private_bounds)]
570pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send {
574 /// Interrupt for this HASH instance. 571 /// Interrupt for this HASH instance.
575 type Interrupt: interrupt::typelevel::Interrupt; 572 type Interrupt: interrupt::typelevel::Interrupt;
576} 573}
@@ -581,7 +578,7 @@ foreach_interrupt!(
581 type Interrupt = crate::interrupt::typelevel::$irq; 578 type Interrupt = crate::interrupt::typelevel::$irq;
582 } 579 }
583 580
584 impl sealed::Instance for peripherals::$inst { 581 impl SealedInstance for peripherals::$inst {
585 fn regs() -> crate::pac::hash::Hash { 582 fn regs() -> crate::pac::hash::Hash {
586 crate::pac::$inst 583 crate::pac::$inst
587 } 584 }
diff --git a/embassy-stm32/src/hrtim/mod.rs b/embassy-stm32/src/hrtim/mod.rs
index 3ec646fc3..02e45819c 100644
--- a/embassy-stm32/src/hrtim/mod.rs
+++ b/embassy-stm32/src/hrtim/mod.rs
@@ -7,9 +7,7 @@ use core::marker::PhantomData;
7use embassy_hal_internal::{into_ref, PeripheralRef}; 7use embassy_hal_internal::{into_ref, PeripheralRef};
8pub use traits::Instance; 8pub use traits::Instance;
9 9
10#[allow(unused_imports)] 10use crate::gpio::{AFType, AnyPin};
11use crate::gpio::sealed::{AFType, Pin};
12use crate::gpio::AnyPin;
13use crate::time::Hertz; 11use crate::time::Hertz;
14use crate::Peripheral; 12use crate::Peripheral;
15 13
@@ -54,16 +52,13 @@ pub struct ChF<T: Instance> {
54 phantom: PhantomData<T>, 52 phantom: PhantomData<T>,
55} 53}
56 54
57mod sealed { 55trait SealedAdvancedChannel<T: Instance> {
58 use super::Instance; 56 fn raw() -> usize;
59
60 pub trait AdvancedChannel<T: Instance> {
61 fn raw() -> usize;
62 }
63} 57}
64 58
65/// Advanced channel instance trait. 59/// Advanced channel instance trait.
66pub trait AdvancedChannel<T: Instance>: sealed::AdvancedChannel<T> {} 60#[allow(private_bounds)]
61pub trait AdvancedChannel<T: Instance>: SealedAdvancedChannel<T> {}
67 62
68/// HRTIM PWM pin. 63/// HRTIM PWM pin.
69pub struct PwmPin<'d, T, C> { 64pub struct PwmPin<'d, T, C> {
@@ -113,7 +108,7 @@ macro_rules! advanced_channel_impl {
113 } 108 }
114 } 109 }
115 110
116 impl<T: Instance> sealed::AdvancedChannel<T> for $channel<T> { 111 impl<T: Instance> SealedAdvancedChannel<T> for $channel<T> {
117 fn raw() -> usize { 112 fn raw() -> usize {
118 $ch_num 113 $ch_num
119 } 114 }
diff --git a/embassy-stm32/src/hrtim/traits.rs b/embassy-stm32/src/hrtim/traits.rs
index dcc2b9ef4..75f9971e2 100644
--- a/embassy-stm32/src/hrtim/traits.rs
+++ b/embassy-stm32/src/hrtim/traits.rs
@@ -1,4 +1,4 @@
1use crate::rcc::sealed::RccPeripheral; 1use crate::rcc::RccPeripheral;
2use crate::time::Hertz; 2use crate::time::Hertz;
3 3
4#[repr(u8)] 4#[repr(u8)]
@@ -72,94 +72,92 @@ impl Prescaler {
72 } 72 }
73} 73}
74 74
75pub(crate) mod sealed { 75pub(crate) trait SealedInstance: RccPeripheral {
76 use super::*; 76 fn regs() -> crate::pac::hrtim::Hrtim;
77 77
78 pub trait Instance: RccPeripheral { 78 #[allow(unused)]
79 fn regs() -> crate::pac::hrtim::Hrtim; 79 fn set_master_frequency(frequency: Hertz) {
80 let f = frequency.0;
80 81
81 fn set_master_frequency(frequency: Hertz) { 82 // TODO: wire up HRTIM to the RCC mux infra.
82 let f = frequency.0; 83 //#[cfg(stm32f334)]
84 //let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(Self::frequency()).0;
85 //#[cfg(not(stm32f334))]
86 let timer_f = Self::frequency().0;
83 87
84 // TODO: wire up HRTIM to the RCC mux infra. 88 let psc_min = (timer_f / f) / (u16::MAX as u32 / 32);
85 //#[cfg(stm32f334)] 89 let psc = if Self::regs().isr().read().dllrdy() {
86 //let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(Self::frequency()).0; 90 Prescaler::compute_min_high_res(psc_min)
87 //#[cfg(not(stm32f334))] 91 } else {
88 let timer_f = Self::frequency().0; 92 Prescaler::compute_min_low_res(psc_min)
93 };
89 94
90 let psc_min = (timer_f / f) / (u16::MAX as u32 / 32); 95 let timer_f = 32 * (timer_f / psc as u32);
91 let psc = if Self::regs().isr().read().dllrdy() { 96 let per: u16 = (timer_f / f) as u16;
92 Prescaler::compute_min_high_res(psc_min)
93 } else {
94 Prescaler::compute_min_low_res(psc_min)
95 };
96 97
97 let timer_f = 32 * (timer_f / psc as u32); 98 let regs = Self::regs();
98 let per: u16 = (timer_f / f) as u16;
99 99
100 let regs = Self::regs(); 100 regs.mcr().modify(|w| w.set_ckpsc(psc.into()));
101 101 regs.mper().modify(|w| w.set_mper(per));
102 regs.mcr().modify(|w| w.set_ckpsc(psc.into())); 102 }
103 regs.mper().modify(|w| w.set_mper(per));
104 }
105 103
106 fn set_channel_frequency(channel: usize, frequency: Hertz) { 104 fn set_channel_frequency(channel: usize, frequency: Hertz) {
107 let f = frequency.0; 105 let f = frequency.0;
108 106
109 // TODO: wire up HRTIM to the RCC mux infra. 107 // TODO: wire up HRTIM to the RCC mux infra.
110 //#[cfg(stm32f334)] 108 //#[cfg(stm32f334)]
111 //let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(Self::frequency()).0; 109 //let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(Self::frequency()).0;
112 //#[cfg(not(stm32f334))] 110 //#[cfg(not(stm32f334))]
113 let timer_f = Self::frequency().0; 111 let timer_f = Self::frequency().0;
114 112
115 let psc_min = (timer_f / f) / (u16::MAX as u32 / 32); 113 let psc_min = (timer_f / f) / (u16::MAX as u32 / 32);
116 let psc = if Self::regs().isr().read().dllrdy() { 114 let psc = if Self::regs().isr().read().dllrdy() {
117 Prescaler::compute_min_high_res(psc_min) 115 Prescaler::compute_min_high_res(psc_min)
118 } else { 116 } else {
119 Prescaler::compute_min_low_res(psc_min) 117 Prescaler::compute_min_low_res(psc_min)
120 }; 118 };
121 119
122 let timer_f = 32 * (timer_f / psc as u32); 120 let timer_f = 32 * (timer_f / psc as u32);
123 let per: u16 = (timer_f / f) as u16; 121 let per: u16 = (timer_f / f) as u16;
124 122
125 let regs = Self::regs(); 123 let regs = Self::regs();
126 124
127 regs.tim(channel).cr().modify(|w| w.set_ckpsc(psc.into())); 125 regs.tim(channel).cr().modify(|w| w.set_ckpsc(psc.into()));
128 regs.tim(channel).per().modify(|w| w.set_per(per)); 126 regs.tim(channel).per().modify(|w| w.set_per(per));
129 } 127 }
130 128
131 /// Set the dead time as a proportion of max_duty 129 /// Set the dead time as a proportion of max_duty
132 fn set_channel_dead_time(channel: usize, dead_time: u16) { 130 fn set_channel_dead_time(channel: usize, dead_time: u16) {
133 let regs = Self::regs(); 131 let regs = Self::regs();
134 132
135 let channel_psc: Prescaler = regs.tim(channel).cr().read().ckpsc().into(); 133 let channel_psc: Prescaler = regs.tim(channel).cr().read().ckpsc().into();
136 134
137 // The dead-time base clock runs 4 times slower than the hrtim base clock 135 // The dead-time base clock runs 4 times slower than the hrtim base clock
138 // u9::MAX = 511 136 // u9::MAX = 511
139 let psc_min = (channel_psc as u32 * dead_time as u32) / (4 * 511); 137 let psc_min = (channel_psc as u32 * dead_time as u32) / (4 * 511);
140 let psc = if Self::regs().isr().read().dllrdy() { 138 let psc = if Self::regs().isr().read().dllrdy() {
141 Prescaler::compute_min_high_res(psc_min) 139 Prescaler::compute_min_high_res(psc_min)
142 } else { 140 } else {
143 Prescaler::compute_min_low_res(psc_min) 141 Prescaler::compute_min_low_res(psc_min)
144 }; 142 };
145 143
146 let dt_val = (psc as u32 * dead_time as u32) / (4 * channel_psc as u32); 144 let dt_val = (psc as u32 * dead_time as u32) / (4 * channel_psc as u32);
147 145
148 regs.tim(channel).dt().modify(|w| { 146 regs.tim(channel).dt().modify(|w| {
149 w.set_dtprsc(psc.into()); 147 w.set_dtprsc(psc.into());
150 w.set_dtf(dt_val as u16); 148 w.set_dtf(dt_val as u16);
151 w.set_dtr(dt_val as u16); 149 w.set_dtr(dt_val as u16);
152 }); 150 });
153 }
154 } 151 }
155} 152}
156 153
157/// HRTIM instance trait. 154/// HRTIM instance trait.
158pub trait Instance: sealed::Instance + 'static {} 155#[allow(private_bounds)]
156pub trait Instance: SealedInstance + 'static {}
159 157
160foreach_interrupt! { 158foreach_interrupt! {
161 ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => { 159 ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => {
162 impl sealed::Instance for crate::peripherals::$inst { 160 impl SealedInstance for crate::peripherals::$inst {
163 fn regs() -> crate::pac::hrtim::Hrtim { 161 fn regs() -> crate::pac::hrtim::Hrtim {
164 crate::pac::$inst 162 crate::pac::$inst
165 } 163 }
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index 2c606c3c9..f1b11cc44 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -14,8 +14,7 @@ use embassy_sync::waitqueue::AtomicWaker;
14use embassy_time::{Duration, Instant}; 14use embassy_time::{Duration, Instant};
15 15
16use crate::dma::NoDma; 16use crate::dma::NoDma;
17use crate::gpio::sealed::AFType; 17use crate::gpio::{AFType, Pull};
18use crate::gpio::Pull;
19use crate::interrupt::typelevel::Interrupt; 18use crate::interrupt::typelevel::Interrupt;
20use crate::time::Hertz; 19use crate::time::Hertz;
21use crate::{interrupt, peripherals}; 20use crate::{interrupt, peripherals};
@@ -175,30 +174,27 @@ impl Timeout {
175 } 174 }
176} 175}
177 176
178pub(crate) mod sealed { 177struct State {
179 use super::*; 178 #[allow(unused)]
180 179 waker: AtomicWaker,
181 pub struct State { 180}
182 #[allow(unused)]
183 pub waker: AtomicWaker,
184 }
185 181
186 impl State { 182impl State {
187 pub const fn new() -> Self { 183 const fn new() -> Self {
188 Self { 184 Self {
189 waker: AtomicWaker::new(), 185 waker: AtomicWaker::new(),
190 }
191 } 186 }
192 } 187 }
188}
193 189
194 pub trait Instance: crate::rcc::RccPeripheral { 190trait SealedInstance: crate::rcc::RccPeripheral {
195 fn regs() -> crate::pac::i2c::I2c; 191 fn regs() -> crate::pac::i2c::I2c;
196 fn state() -> &'static State; 192 fn state() -> &'static State;
197 }
198} 193}
199 194
200/// I2C peripheral instance 195/// I2C peripheral instance
201pub trait Instance: sealed::Instance + 'static { 196#[allow(private_bounds)]
197pub trait Instance: SealedInstance + 'static {
202 /// Event interrupt for this instance 198 /// Event interrupt for this instance
203 type EventInterrupt: interrupt::typelevel::Interrupt; 199 type EventInterrupt: interrupt::typelevel::Interrupt;
204 /// Error interrupt for this instance 200 /// Error interrupt for this instance
@@ -234,13 +230,13 @@ impl<T: Instance> interrupt::typelevel::Handler<T::ErrorInterrupt> for ErrorInte
234 230
235foreach_peripheral!( 231foreach_peripheral!(
236 (i2c, $inst:ident) => { 232 (i2c, $inst:ident) => {
237 impl sealed::Instance for peripherals::$inst { 233 impl SealedInstance for peripherals::$inst {
238 fn regs() -> crate::pac::i2c::I2c { 234 fn regs() -> crate::pac::i2c::I2c {
239 crate::pac::$inst 235 crate::pac::$inst
240 } 236 }
241 237
242 fn state() -> &'static sealed::State { 238 fn state() -> &'static State {
243 static STATE: sealed::State = sealed::State::new(); 239 static STATE: State = State::new();
244 &STATE 240 &STATE
245 } 241 }
246 } 242 }
diff --git a/embassy-stm32/src/i2s.rs b/embassy-stm32/src/i2s.rs
index fa9ec0532..c5a606b21 100644
--- a/embassy-stm32/src/i2s.rs
+++ b/embassy-stm32/src/i2s.rs
@@ -1,8 +1,7 @@
1//! Inter-IC Sound (I2S) 1//! Inter-IC Sound (I2S)
2use embassy_hal_internal::into_ref; 2use embassy_hal_internal::into_ref;
3 3
4use crate::gpio::sealed::{AFType, Pin as _}; 4use crate::gpio::{AFType, AnyPin, SealedPin};
5use crate::gpio::AnyPin;
6use crate::pac::spi::vals; 5use crate::pac::spi::vals;
7use crate::spi::{Config as SpiConfig, *}; 6use crate::spi::{Config as SpiConfig, *};
8use crate::time::Hertz; 7use crate::time::Hertz;
diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs
index 523719bb9..4d535cce2 100644
--- a/embassy-stm32/src/ipcc.rs
+++ b/embassy-stm32/src/ipcc.rs
@@ -4,11 +4,12 @@ use core::future::poll_fn;
4use core::sync::atomic::{compiler_fence, Ordering}; 4use core::sync::atomic::{compiler_fence, Ordering};
5use core::task::Poll; 5use core::task::Poll;
6 6
7use self::sealed::Instance; 7use embassy_sync::waitqueue::AtomicWaker;
8
8use crate::interrupt; 9use crate::interrupt;
9use crate::interrupt::typelevel::Interrupt; 10use crate::interrupt::typelevel::Interrupt;
10use crate::peripherals::IPCC; 11use crate::peripherals::IPCC;
11use crate::rcc::sealed::RccPeripheral; 12use crate::rcc::SealedRccPeripheral;
12 13
13/// Interrupt handler. 14/// Interrupt handler.
14pub struct ReceiveInterruptHandler {} 15pub struct ReceiveInterruptHandler {}
@@ -207,7 +208,7 @@ impl Ipcc {
207 } 208 }
208} 209}
209 210
210impl sealed::Instance for crate::peripherals::IPCC { 211impl SealedInstance for crate::peripherals::IPCC {
211 fn regs() -> crate::pac::ipcc::Ipcc { 212 fn regs() -> crate::pac::ipcc::Ipcc {
212 crate::pac::IPCC 213 crate::pac::IPCC
213 } 214 }
@@ -216,58 +217,52 @@ impl sealed::Instance for crate::peripherals::IPCC {
216 crate::pac::PWR.cr4().modify(|w| w.set_c2boot(enabled)); 217 crate::pac::PWR.cr4().modify(|w| w.set_c2boot(enabled));
217 } 218 }
218 219
219 fn state() -> &'static self::sealed::State { 220 fn state() -> &'static State {
220 static STATE: self::sealed::State = self::sealed::State::new(); 221 static STATE: State = State::new();
221 &STATE 222 &STATE
222 } 223 }
223} 224}
224 225
225pub(crate) mod sealed { 226struct State {
226 use embassy_sync::waitqueue::AtomicWaker; 227 rx_wakers: [AtomicWaker; 6],
227 228 tx_wakers: [AtomicWaker; 6],
228 use super::*; 229}
229
230 pub struct State {
231 rx_wakers: [AtomicWaker; 6],
232 tx_wakers: [AtomicWaker; 6],
233 }
234 230
235 impl State { 231impl State {
236 pub const fn new() -> Self { 232 const fn new() -> Self {
237 const WAKER: AtomicWaker = AtomicWaker::new(); 233 const WAKER: AtomicWaker = AtomicWaker::new();
238 234
239 Self { 235 Self {
240 rx_wakers: [WAKER; 6], 236 rx_wakers: [WAKER; 6],
241 tx_wakers: [WAKER; 6], 237 tx_wakers: [WAKER; 6],
242 }
243 } 238 }
239 }
244 240
245 pub const fn rx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker { 241 const fn rx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker {
246 match channel { 242 match channel {
247 IpccChannel::Channel1 => &self.rx_wakers[0], 243 IpccChannel::Channel1 => &self.rx_wakers[0],
248 IpccChannel::Channel2 => &self.rx_wakers[1], 244 IpccChannel::Channel2 => &self.rx_wakers[1],
249 IpccChannel::Channel3 => &self.rx_wakers[2], 245 IpccChannel::Channel3 => &self.rx_wakers[2],
250 IpccChannel::Channel4 => &self.rx_wakers[3], 246 IpccChannel::Channel4 => &self.rx_wakers[3],
251 IpccChannel::Channel5 => &self.rx_wakers[4], 247 IpccChannel::Channel5 => &self.rx_wakers[4],
252 IpccChannel::Channel6 => &self.rx_wakers[5], 248 IpccChannel::Channel6 => &self.rx_wakers[5],
253 }
254 } 249 }
250 }
255 251
256 pub const fn tx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker { 252 const fn tx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker {
257 match channel { 253 match channel {
258 IpccChannel::Channel1 => &self.tx_wakers[0], 254 IpccChannel::Channel1 => &self.tx_wakers[0],
259 IpccChannel::Channel2 => &self.tx_wakers[1], 255 IpccChannel::Channel2 => &self.tx_wakers[1],
260 IpccChannel::Channel3 => &self.tx_wakers[2], 256 IpccChannel::Channel3 => &self.tx_wakers[2],
261 IpccChannel::Channel4 => &self.tx_wakers[3], 257 IpccChannel::Channel4 => &self.tx_wakers[3],
262 IpccChannel::Channel5 => &self.tx_wakers[4], 258 IpccChannel::Channel5 => &self.tx_wakers[4],
263 IpccChannel::Channel6 => &self.tx_wakers[5], 259 IpccChannel::Channel6 => &self.tx_wakers[5],
264 }
265 } 260 }
266 } 261 }
262}
267 263
268 pub trait Instance: crate::rcc::RccPeripheral { 264trait SealedInstance: crate::rcc::RccPeripheral {
269 fn regs() -> crate::pac::ipcc::Ipcc; 265 fn regs() -> crate::pac::ipcc::Ipcc;
270 fn set_cpu2(enabled: bool); 266 fn set_cpu2(enabled: bool);
271 fn state() -> &'static State; 267 fn state() -> &'static State;
272 }
273} 268}
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 9e26a3513..6a3d1c463 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -158,7 +158,7 @@ pub(crate) use stm32_metapac as pac;
158use crate::interrupt::Priority; 158use crate::interrupt::Priority;
159#[cfg(feature = "rt")] 159#[cfg(feature = "rt")]
160pub use crate::pac::NVIC_PRIO_BITS; 160pub use crate::pac::NVIC_PRIO_BITS;
161use crate::rcc::sealed::RccPeripheral; 161use crate::rcc::SealedRccPeripheral;
162 162
163/// `embassy-stm32` global configuration. 163/// `embassy-stm32` global configuration.
164#[non_exhaustive] 164#[non_exhaustive]
diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs
index cf531e266..a3b4352c0 100644
--- a/embassy-stm32/src/opamp.rs
+++ b/embassy-stm32/src/opamp.rs
@@ -81,8 +81,8 @@ impl<'d, T: Instance> OpAmp<'d, T> {
81 /// [`OpAmpOutput`] is dropped. 81 /// [`OpAmpOutput`] is dropped.
82 pub fn buffer_ext( 82 pub fn buffer_ext(
83 &'d mut self, 83 &'d mut self,
84 in_pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::sealed::Pin>, 84 in_pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::Pin>,
85 out_pin: impl Peripheral<P = impl OutputPin<T> + crate::gpio::sealed::Pin> + 'd, 85 out_pin: impl Peripheral<P = impl OutputPin<T> + crate::gpio::Pin> + 'd,
86 gain: OpAmpGain, 86 gain: OpAmpGain,
87 ) -> OpAmpOutput<'d, T> { 87 ) -> OpAmpOutput<'d, T> {
88 into_ref!(in_pin); 88 into_ref!(in_pin);
@@ -122,7 +122,7 @@ impl<'d, T: Instance> OpAmp<'d, T> {
122 #[cfg(opamp_g4)] 122 #[cfg(opamp_g4)]
123 pub fn buffer_int( 123 pub fn buffer_int(
124 &'d mut self, 124 &'d mut self,
125 pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::sealed::Pin>, 125 pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::Pin>,
126 gain: OpAmpGain, 126 gain: OpAmpGain,
127 ) -> OpAmpInternalOutput<'d, T> { 127 ) -> OpAmpInternalOutput<'d, T> {
128 into_ref!(pin); 128 into_ref!(pin);
@@ -166,37 +166,39 @@ impl<'d, T: Instance> Drop for OpAmpInternalOutput<'d, T> {
166 } 166 }
167} 167}
168 168
169/// Opamp instance trait. 169pub(crate) trait SealedInstance {
170pub trait Instance: sealed::Instance + 'static {} 170 fn regs() -> crate::pac::opamp::Opamp;
171 171}
172pub(crate) mod sealed {
173 pub trait Instance {
174 fn regs() -> crate::pac::opamp::Opamp;
175 }
176
177 pub trait NonInvertingPin<T: Instance> {
178 fn channel(&self) -> u8;
179 }
180 172
181 pub trait InvertingPin<T: Instance> { 173pub(crate) trait SealedNonInvertingPin<T: Instance> {
182 fn channel(&self) -> u8; 174 fn channel(&self) -> u8;
183 } 175}
184 176
185 pub trait OutputPin<T: Instance> {} 177pub(crate) trait SealedInvertingPin<T: Instance> {
178 #[allow(unused)]
179 fn channel(&self) -> u8;
186} 180}
187 181
182pub(crate) trait SealedOutputPin<T: Instance> {}
183
184/// Opamp instance trait.
185#[allow(private_bounds)]
186pub trait Instance: SealedInstance + 'static {}
188/// Non-inverting pin trait. 187/// Non-inverting pin trait.
189pub trait NonInvertingPin<T: Instance>: sealed::NonInvertingPin<T> {} 188#[allow(private_bounds)]
189pub trait NonInvertingPin<T: Instance>: SealedNonInvertingPin<T> {}
190/// Inverting pin trait. 190/// Inverting pin trait.
191pub trait InvertingPin<T: Instance>: sealed::InvertingPin<T> {} 191#[allow(private_bounds)]
192pub trait InvertingPin<T: Instance>: SealedInvertingPin<T> {}
192/// Output pin trait. 193/// Output pin trait.
193pub trait OutputPin<T: Instance>: sealed::OutputPin<T> {} 194#[allow(private_bounds)]
195pub trait OutputPin<T: Instance>: SealedOutputPin<T> {}
194 196
195macro_rules! impl_opamp_external_output { 197macro_rules! impl_opamp_external_output {
196 ($inst:ident, $adc:ident, $ch:expr) => { 198 ($inst:ident, $adc:ident, $ch:expr) => {
197 foreach_adc!( 199 foreach_adc!(
198 ($adc, $common_inst:ident, $adc_clock:ident) => { 200 ($adc, $common_inst:ident, $adc_clock:ident) => {
199 impl<'d> crate::adc::sealed::AdcPin<crate::peripherals::$adc> 201 impl<'d> crate::adc::SealedAdcPin<crate::peripherals::$adc>
200 for OpAmpOutput<'d, crate::peripherals::$inst> 202 for OpAmpOutput<'d, crate::peripherals::$inst>
201 { 203 {
202 fn channel(&self) -> u8 { 204 fn channel(&self) -> u8 {
@@ -242,7 +244,7 @@ macro_rules! impl_opamp_internal_output {
242 ($inst:ident, $adc:ident, $ch:expr) => { 244 ($inst:ident, $adc:ident, $ch:expr) => {
243 foreach_adc!( 245 foreach_adc!(
244 ($adc, $common_inst:ident, $adc_clock:ident) => { 246 ($adc, $common_inst:ident, $adc_clock:ident) => {
245 impl<'d> crate::adc::sealed::AdcPin<crate::peripherals::$adc> 247 impl<'d> crate::adc::SealedAdcPin<crate::peripherals::$adc>
246 for OpAmpInternalOutput<'d, crate::peripherals::$inst> 248 for OpAmpInternalOutput<'d, crate::peripherals::$inst>
247 { 249 {
248 fn channel(&self) -> u8 { 250 fn channel(&self) -> u8 {
@@ -291,7 +293,7 @@ foreach_peripheral!(
291 293
292foreach_peripheral! { 294foreach_peripheral! {
293 (opamp, $inst:ident) => { 295 (opamp, $inst:ident) => {
294 impl sealed::Instance for crate::peripherals::$inst { 296 impl SealedInstance for crate::peripherals::$inst {
295 fn regs() -> crate::pac::opamp::Opamp { 297 fn regs() -> crate::pac::opamp::Opamp {
296 crate::pac::$inst 298 crate::pac::$inst
297 } 299 }
@@ -306,7 +308,7 @@ foreach_peripheral! {
306macro_rules! impl_opamp_vp_pin { 308macro_rules! impl_opamp_vp_pin {
307 ($inst:ident, $pin:ident, $ch:expr) => { 309 ($inst:ident, $pin:ident, $ch:expr) => {
308 impl crate::opamp::NonInvertingPin<peripherals::$inst> for crate::peripherals::$pin {} 310 impl crate::opamp::NonInvertingPin<peripherals::$inst> for crate::peripherals::$pin {}
309 impl crate::opamp::sealed::NonInvertingPin<peripherals::$inst> for crate::peripherals::$pin { 311 impl crate::opamp::SealedNonInvertingPin<peripherals::$inst> for crate::peripherals::$pin {
310 fn channel(&self) -> u8 { 312 fn channel(&self) -> u8 {
311 $ch 313 $ch
312 } 314 }
@@ -318,6 +320,6 @@ macro_rules! impl_opamp_vp_pin {
318macro_rules! impl_opamp_vout_pin { 320macro_rules! impl_opamp_vout_pin {
319 ($inst:ident, $pin:ident) => { 321 ($inst:ident, $pin:ident) => {
320 impl crate::opamp::OutputPin<peripherals::$inst> for crate::peripherals::$pin {} 322 impl crate::opamp::OutputPin<peripherals::$inst> for crate::peripherals::$pin {}
321 impl crate::opamp::sealed::OutputPin<peripherals::$inst> for crate::peripherals::$pin {} 323 impl crate::opamp::SealedOutputPin<peripherals::$inst> for crate::peripherals::$pin {}
322 }; 324 };
323} 325}
diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs
index 8a709a89e..3c054e666 100644
--- a/embassy-stm32/src/qspi/mod.rs
+++ b/embassy-stm32/src/qspi/mod.rs
@@ -8,8 +8,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
8use enums::*; 8use enums::*;
9 9
10use crate::dma::Transfer; 10use crate::dma::Transfer;
11use crate::gpio::sealed::AFType; 11use crate::gpio::{AFType, AnyPin, Pull};
12use crate::gpio::{AnyPin, Pull};
13use crate::pac::quadspi::Quadspi as Regs; 12use crate::pac::quadspi::Quadspi as Regs;
14use crate::rcc::RccPeripheral; 13use crate::rcc::RccPeripheral;
15use crate::{peripherals, Peripheral}; 14use crate::{peripherals, Peripheral};
@@ -381,16 +380,13 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
381 } 380 }
382} 381}
383 382
384pub(crate) mod sealed { 383trait SealedInstance {
385 use super::*; 384 const REGS: Regs;
386
387 pub trait Instance {
388 const REGS: Regs;
389 }
390} 385}
391 386
392/// QSPI instance trait. 387/// QSPI instance trait.
393pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {} 388#[allow(private_bounds)]
389pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {}
394 390
395pin_trait!(SckPin, Instance); 391pin_trait!(SckPin, Instance);
396pin_trait!(BK1D0Pin, Instance); 392pin_trait!(BK1D0Pin, Instance);
@@ -409,7 +405,7 @@ dma_trait!(QuadDma, Instance);
409 405
410foreach_peripheral!( 406foreach_peripheral!(
411 (quadspi, $inst:ident) => { 407 (quadspi, $inst:ident) => {
412 impl sealed::Instance for peripherals::$inst { 408 impl SealedInstance for peripherals::$inst {
413 const REGS: Regs = crate::pac::$inst; 409 const REGS: Regs = crate::pac::$inst;
414 } 410 }
415 411
diff --git a/embassy-stm32/src/rcc/hsi48.rs b/embassy-stm32/src/rcc/hsi48.rs
index 19a8c8cb9..6f0d7b379 100644
--- a/embassy-stm32/src/rcc/hsi48.rs
+++ b/embassy-stm32/src/rcc/hsi48.rs
@@ -2,7 +2,7 @@
2 2
3use crate::pac::crs::vals::Syncsrc; 3use crate::pac::crs::vals::Syncsrc;
4use crate::pac::{CRS, RCC}; 4use crate::pac::{CRS, RCC};
5use crate::rcc::sealed::RccPeripheral; 5use crate::rcc::SealedRccPeripheral;
6use crate::time::Hertz; 6use crate::time::Hertz;
7 7
8/// HSI48 speed 8/// HSI48 speed
diff --git a/embassy-stm32/src/rcc/mco.rs b/embassy-stm32/src/rcc/mco.rs
index 654943bc1..d8604e07e 100644
--- a/embassy-stm32/src/rcc/mco.rs
+++ b/embassy-stm32/src/rcc/mco.rs
@@ -2,8 +2,7 @@ use core::marker::PhantomData;
2 2
3use embassy_hal_internal::into_ref; 3use embassy_hal_internal::into_ref;
4 4
5use crate::gpio::sealed::AFType; 5use crate::gpio::{AFType, Speed};
6use crate::gpio::Speed;
7#[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))] 6#[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))]
8pub use crate::pac::rcc::vals::Mcopre as McoPrescaler; 7pub use crate::pac::rcc::vals::Mcopre as McoPrescaler;
9#[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(rcc_f2, rcc_f410, rcc_f4, rcc_f7, rcc_h50, rcc_h5, rcc_h7ab, rcc_h7rm0433, rcc_h7)))]
@@ -19,23 +18,25 @@ pub enum McoPrescaler {
19 DIV1, 18 DIV1,
20} 19}
21 20
22pub(crate) mod sealed { 21pub(crate) trait SealedMcoInstance {}
23 pub trait McoInstance {
24 type Source;
25 unsafe fn apply_clock_settings(source: Self::Source, prescaler: super::McoPrescaler);
26 }
27}
28 22
29pub trait McoInstance: sealed::McoInstance + 'static {} 23#[allow(private_bounds)]
24pub trait McoInstance: SealedMcoInstance + 'static {
25 type Source;
26
27 #[doc(hidden)]
28 unsafe fn _apply_clock_settings(source: Self::Source, prescaler: super::McoPrescaler);
29}
30 30
31pin_trait!(McoPin, McoInstance); 31pin_trait!(McoPin, McoInstance);
32 32
33macro_rules! impl_peri { 33macro_rules! impl_peri {
34 ($peri:ident, $source:ident, $set_source:ident, $set_prescaler:ident) => { 34 ($peri:ident, $source:ident, $set_source:ident, $set_prescaler:ident) => {
35 impl sealed::McoInstance for peripherals::$peri { 35 impl SealedMcoInstance for peripherals::$peri {}
36 impl McoInstance for peripherals::$peri {
36 type Source = $source; 37 type Source = $source;
37 38
38 unsafe fn apply_clock_settings(source: Self::Source, _prescaler: McoPrescaler) { 39 unsafe fn _apply_clock_settings(source: Self::Source, _prescaler: McoPrescaler) {
39 #[cfg(not(any(stm32u5, stm32wba)))] 40 #[cfg(not(any(stm32u5, stm32wba)))]
40 let r = RCC.cfgr(); 41 let r = RCC.cfgr();
41 #[cfg(any(stm32u5, stm32wba))] 42 #[cfg(any(stm32u5, stm32wba))]
@@ -48,8 +49,6 @@ macro_rules! impl_peri {
48 }); 49 });
49 } 50 }
50 } 51 }
51
52 impl McoInstance for peripherals::$peri {}
53 }; 52 };
54} 53}
55 54
@@ -79,7 +78,7 @@ impl<'d, T: McoInstance> Mco<'d, T> {
79 into_ref!(pin); 78 into_ref!(pin);
80 79
81 critical_section::with(|_| unsafe { 80 critical_section::with(|_| unsafe {
82 T::apply_clock_settings(source, prescaler); 81 T::_apply_clock_settings(source, prescaler);
83 pin.set_as_af(pin.af_num(), AFType::OutputPushPull); 82 pin.set_as_af(pin.af_num(), AFType::OutputPushPull);
84 pin.set_speed(Speed::VeryHigh); 83 pin.set_speed(Speed::VeryHigh);
85 }); 84 });
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index 910ebe205..d53d02203 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -10,6 +10,7 @@ pub use bd::*;
10 10
11#[cfg(any(mco, mco1, mco2))] 11#[cfg(any(mco, mco1, mco2))]
12mod mco; 12mod mco;
13use critical_section::CriticalSection;
13#[cfg(any(mco, mco1, mco2))] 14#[cfg(any(mco, mco1, mco2))]
14pub use mco::*; 15pub use mco::*;
15 16
@@ -32,6 +33,7 @@ mod _version;
32pub use _version::*; 33pub use _version::*;
33 34
34pub use crate::_generated::{mux, Clocks}; 35pub use crate::_generated::{mux, Clocks};
36use crate::time::Hertz;
35 37
36#[cfg(feature = "low-power")] 38#[cfg(feature = "low-power")]
37/// Must be written within a critical section 39/// Must be written within a critical section
@@ -63,29 +65,21 @@ pub(crate) unsafe fn get_freqs() -> &'static Clocks {
63 CLOCK_FREQS.assume_init_ref() 65 CLOCK_FREQS.assume_init_ref()
64} 66}
65 67
66#[cfg(feature = "unstable-pac")] 68pub(crate) trait SealedRccPeripheral {
67pub mod low_level { 69 fn frequency() -> crate::time::Hertz;
68 pub use super::sealed::*; 70 fn enable_and_reset_with_cs(cs: CriticalSection);
69} 71 fn disable_with_cs(cs: CriticalSection);
70
71pub(crate) mod sealed {
72 use critical_section::CriticalSection;
73
74 pub trait RccPeripheral {
75 fn frequency() -> crate::time::Hertz;
76 fn enable_and_reset_with_cs(cs: CriticalSection);
77 fn disable_with_cs(cs: CriticalSection);
78 72
79 fn enable_and_reset() { 73 fn enable_and_reset() {
80 critical_section::with(|cs| Self::enable_and_reset_with_cs(cs)) 74 critical_section::with(|cs| Self::enable_and_reset_with_cs(cs))
81 } 75 }
82 fn disable() { 76 fn disable() {
83 critical_section::with(|cs| Self::disable_with_cs(cs)) 77 critical_section::with(|cs| Self::disable_with_cs(cs))
84 }
85 } 78 }
86} 79}
87 80
88pub trait RccPeripheral: sealed::RccPeripheral + 'static {} 81#[allow(private_bounds)]
82pub trait RccPeripheral: SealedRccPeripheral + 'static {}
89 83
90#[allow(unused)] 84#[allow(unused)]
91mod util { 85mod util {
@@ -116,3 +110,12 @@ mod util {
116 Ok(Some(x)) 110 Ok(Some(x))
117 } 111 }
118} 112}
113
114/// Get the kernel clocok frequency of the peripheral `T`.
115///
116/// # Panics
117///
118/// Panics if the clock is not active.
119pub fn frequency<T: RccPeripheral>() -> Hertz {
120 T::frequency()
121}
diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs
index ca641f352..7a228e4a4 100644
--- a/embassy-stm32/src/rng.rs
+++ b/embassy-stm32/src/rng.rs
@@ -222,16 +222,13 @@ impl<'d, T: Instance> RngCore for Rng<'d, T> {
222 222
223impl<'d, T: Instance> CryptoRng for Rng<'d, T> {} 223impl<'d, T: Instance> CryptoRng for Rng<'d, T> {}
224 224
225pub(crate) mod sealed { 225trait SealedInstance {
226 use super::*; 226 fn regs() -> pac::rng::Rng;
227
228 pub trait Instance {
229 fn regs() -> pac::rng::Rng;
230 }
231} 227}
232 228
233/// RNG instance trait. 229/// RNG instance trait.
234pub trait Instance: sealed::Instance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { 230#[allow(private_bounds)]
231pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send {
235 /// Interrupt for this RNG instance. 232 /// Interrupt for this RNG instance.
236 type Interrupt: interrupt::typelevel::Interrupt; 233 type Interrupt: interrupt::typelevel::Interrupt;
237} 234}
@@ -242,7 +239,7 @@ foreach_interrupt!(
242 type Interrupt = crate::interrupt::typelevel::$irq; 239 type Interrupt = crate::interrupt::typelevel::$irq;
243 } 240 }
244 241
245 impl sealed::Instance for peripherals::$inst { 242 impl SealedInstance for peripherals::$inst {
246 fn regs() -> crate::pac::rng::Rng { 243 fn regs() -> crate::pac::rng::Rng {
247 crate::pac::$inst 244 crate::pac::$inst
248 } 245 }
diff --git a/embassy-stm32/src/rtc/datetime.rs b/embassy-stm32/src/rtc/datetime.rs
index 2bad79923..bab8cf4a3 100644
--- a/embassy-stm32/src/rtc/datetime.rs
+++ b/embassy-stm32/src/rtc/datetime.rs
@@ -4,7 +4,7 @@ use chrono::{Datelike, NaiveDate, Timelike, Weekday};
4#[cfg(any(feature = "defmt", feature = "time"))] 4#[cfg(any(feature = "defmt", feature = "time"))]
5use crate::peripherals::RTC; 5use crate::peripherals::RTC;
6#[cfg(any(feature = "defmt", feature = "time"))] 6#[cfg(any(feature = "defmt", feature = "time"))]
7use crate::rtc::sealed::Instance; 7use crate::rtc::SealedInstance;
8 8
9/// Represents an instant in time that can be substracted to compute a duration 9/// Represents an instant in time that can be substracted to compute a duration
10pub struct RtcInstant { 10pub struct RtcInstant {
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index 169505501..00abe9356 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -31,7 +31,6 @@ pub use _version::*;
31use embassy_hal_internal::Peripheral; 31use embassy_hal_internal::Peripheral;
32 32
33use crate::peripherals::RTC; 33use crate::peripherals::RTC;
34use crate::rtc::sealed::Instance;
35 34
36#[allow(dead_code)] 35#[allow(dead_code)]
37#[repr(u8)] 36#[repr(u8)]
@@ -212,7 +211,7 @@ impl Rtc {
212 /// Create a new RTC instance. 211 /// Create a new RTC instance.
213 pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { 212 pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self {
214 #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))] 213 #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))]
215 <RTC as crate::rcc::sealed::RccPeripheral>::enable_and_reset(); 214 <RTC as crate::rcc::SealedRccPeripheral>::enable_and_reset();
216 215
217 let mut this = Self { 216 let mut this = Self {
218 #[cfg(feature = "low-power")] 217 #[cfg(feature = "low-power")]
@@ -437,7 +436,7 @@ impl Rtc {
437 .fpr(0) 436 .fpr(0)
438 .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); 437 .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
439 438
440 <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend(); 439 <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend();
441 }); 440 });
442 } 441 }
443 442
@@ -449,8 +448,8 @@ impl Rtc {
449 use crate::interrupt::typelevel::Interrupt; 448 use crate::interrupt::typelevel::Interrupt;
450 use crate::pac::EXTI; 449 use crate::pac::EXTI;
451 450
452 <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend(); 451 <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend();
453 unsafe { <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::enable() }; 452 unsafe { <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::enable() };
454 453
455 EXTI.rtsr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); 454 EXTI.rtsr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
456 EXTI.imr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); 455 EXTI.imr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
@@ -477,34 +476,30 @@ pub(crate) fn bcd2_to_byte(bcd: (u8, u8)) -> u8 {
477 tmp + (value & 0x0F) 476 tmp + (value & 0x0F)
478} 477}
479 478
480pub(crate) mod sealed { 479trait SealedInstance {
481 use crate::pac::rtc::Rtc; 480 const BACKUP_REGISTER_COUNT: usize;
482 481
483 pub trait Instance { 482 #[cfg(feature = "low-power")]
484 const BACKUP_REGISTER_COUNT: usize; 483 const EXTI_WAKEUP_LINE: usize;
485
486 #[cfg(feature = "low-power")]
487 const EXTI_WAKEUP_LINE: usize;
488 484
489 #[cfg(feature = "low-power")] 485 #[cfg(feature = "low-power")]
490 type WakeupInterrupt: crate::interrupt::typelevel::Interrupt; 486 type WakeupInterrupt: crate::interrupt::typelevel::Interrupt;
491 487
492 fn regs() -> Rtc { 488 fn regs() -> crate::pac::rtc::Rtc {
493 crate::pac::RTC 489 crate::pac::RTC
494 } 490 }
495 491
496 /// Read content of the backup register. 492 /// Read content of the backup register.
497 /// 493 ///
498 /// The registers retain their values during wakes from standby mode or system resets. They also 494 /// The registers retain their values during wakes from standby mode or system resets. They also
499 /// retain their value when Vdd is switched off as long as V_BAT is powered. 495 /// retain their value when Vdd is switched off as long as V_BAT is powered.
500 fn read_backup_register(rtc: &Rtc, register: usize) -> Option<u32>; 496 fn read_backup_register(rtc: &crate::pac::rtc::Rtc, register: usize) -> Option<u32>;
501 497
502 /// Set content of the backup register. 498 /// Set content of the backup register.
503 /// 499 ///
504 /// The registers retain their values during wakes from standby mode or system resets. They also 500 /// The registers retain their values during wakes from standby mode or system resets. They also
505 /// retain their value when Vdd is switched off as long as V_BAT is powered. 501 /// retain their value when Vdd is switched off as long as V_BAT is powered.
506 fn write_backup_register(rtc: &Rtc, register: usize, value: u32); 502 fn write_backup_register(rtc: &crate::pac::rtc::Rtc, register: usize, value: u32);
507 503
508 // fn apply_config(&mut self, rtc_config: RtcConfig); 504 // fn apply_config(&mut self, rtc_config: RtcConfig);
509 }
510} 505}
diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs
index 1eda097a7..92f9de846 100644
--- a/embassy-stm32/src/rtc/v2.rs
+++ b/embassy-stm32/src/rtc/v2.rs
@@ -1,9 +1,8 @@
1use stm32_metapac::rtc::vals::{Osel, Pol}; 1use stm32_metapac::rtc::vals::{Osel, Pol};
2 2
3use super::sealed; 3use super::SealedInstance;
4use crate::pac::rtc::Rtc; 4use crate::pac::rtc::Rtc;
5use crate::peripherals::RTC; 5use crate::peripherals::RTC;
6use crate::rtc::sealed::Instance;
7 6
8#[allow(dead_code)] 7#[allow(dead_code)]
9impl super::Rtc { 8impl super::Rtc {
@@ -126,7 +125,7 @@ impl super::Rtc {
126 } 125 }
127} 126}
128 127
129impl sealed::Instance for crate::peripherals::RTC { 128impl SealedInstance for crate::peripherals::RTC {
130 const BACKUP_REGISTER_COUNT: usize = 20; 129 const BACKUP_REGISTER_COUNT: usize = 20;
131 130
132 #[cfg(all(feature = "low-power", stm32f4))] 131 #[cfg(all(feature = "low-power", stm32f4))]
diff --git a/embassy-stm32/src/rtc/v3.rs b/embassy-stm32/src/rtc/v3.rs
index 3d44a52ff..8a78d16e1 100644
--- a/embassy-stm32/src/rtc/v3.rs
+++ b/embassy-stm32/src/rtc/v3.rs
@@ -1,9 +1,9 @@
1use stm32_metapac::rtc::vals::{Calp, Calw16, Calw8, Fmt, Key, Osel, Pol, TampalrmType}; 1use stm32_metapac::rtc::vals::{Calp, Calw16, Calw8, Fmt, Key, Osel, Pol, TampalrmType};
2 2
3use super::{sealed, RtcCalibrationCyclePeriod}; 3use super::RtcCalibrationCyclePeriod;
4use crate::pac::rtc::Rtc; 4use crate::pac::rtc::Rtc;
5use crate::peripherals::RTC; 5use crate::peripherals::RTC;
6use crate::rtc::sealed::Instance; 6use crate::rtc::SealedInstance;
7 7
8impl super::Rtc { 8impl super::Rtc {
9 /// Applies the RTC config 9 /// Applies the RTC config
@@ -126,7 +126,7 @@ impl super::Rtc {
126 } 126 }
127} 127}
128 128
129impl sealed::Instance for crate::peripherals::RTC { 129impl SealedInstance for crate::peripherals::RTC {
130 const BACKUP_REGISTER_COUNT: usize = 32; 130 const BACKUP_REGISTER_COUNT: usize = 32;
131 131
132 #[cfg(all(feature = "low-power", stm32g4))] 132 #[cfg(all(feature = "low-power", stm32g4))]
diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs
index 294620031..54dd81524 100644
--- a/embassy-stm32/src/sai/mod.rs
+++ b/embassy-stm32/src/sai/mod.rs
@@ -6,12 +6,10 @@ use core::marker::PhantomData;
6 6
7use embassy_hal_internal::{into_ref, PeripheralRef}; 7use embassy_hal_internal::{into_ref, PeripheralRef};
8 8
9use self::sealed::WhichSubBlock;
10pub use crate::dma::word; 9pub use crate::dma::word;
11#[cfg(not(gpdma))] 10#[cfg(not(gpdma))]
12use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer}; 11use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer};
13use crate::gpio::sealed::{AFType, Pin as _}; 12use crate::gpio::{AFType, AnyPin, SealedPin as _};
14use crate::gpio::AnyPin;
15use crate::pac::sai::{vals, Sai as Regs}; 13use crate::pac::sai::{vals, Sai as Regs};
16use crate::rcc::RccPeripheral; 14use crate::rcc::RccPeripheral;
17use crate::{peripherals, Peripheral}; 15use crate::{peripherals, Peripheral};
@@ -1041,43 +1039,42 @@ impl<'d, T: Instance, W: word::Word> Drop for Sai<'d, T, W> {
1041 } 1039 }
1042} 1040}
1043 1041
1044pub(crate) mod sealed { 1042trait SealedInstance {
1045 use super::*; 1043 const REGS: Regs;
1046 1044}
1047 pub trait Instance {
1048 const REGS: Regs;
1049 }
1050 1045
1051 #[derive(Copy, Clone)] 1046#[derive(Copy, Clone)]
1052 pub enum WhichSubBlock { 1047enum WhichSubBlock {
1053 A = 0, 1048 A = 0,
1054 B = 1, 1049 B = 1,
1055 } 1050}
1056 1051
1057 pub trait SubBlock { 1052trait SealedSubBlock {
1058 const WHICH: WhichSubBlock; 1053 const WHICH: WhichSubBlock;
1059 }
1060} 1054}
1061 1055
1062/// Sub-block instance trait. 1056/// Sub-block instance trait.
1063pub trait SubBlockInstance: sealed::SubBlock {} 1057#[allow(private_bounds)]
1058pub trait SubBlockInstance: SealedSubBlock {}
1064 1059
1065/// Sub-block A. 1060/// Sub-block A.
1066pub enum A {} 1061pub enum A {}
1067impl sealed::SubBlock for A { 1062impl SealedSubBlock for A {
1068 const WHICH: WhichSubBlock = WhichSubBlock::A; 1063 const WHICH: WhichSubBlock = WhichSubBlock::A;
1069} 1064}
1070impl SubBlockInstance for A {} 1065impl SubBlockInstance for A {}
1071 1066
1072/// Sub-block B. 1067/// Sub-block B.
1073pub enum B {} 1068pub enum B {}
1074impl sealed::SubBlock for B { 1069impl SealedSubBlock for B {
1075 const WHICH: WhichSubBlock = WhichSubBlock::B; 1070 const WHICH: WhichSubBlock = WhichSubBlock::B;
1076} 1071}
1077impl SubBlockInstance for B {} 1072impl SubBlockInstance for B {}
1078 1073
1079/// SAI instance trait. 1074/// SAI instance trait.
1080pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {} 1075#[allow(private_bounds)]
1076pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {}
1077
1081pin_trait!(SckPin, Instance, SubBlockInstance); 1078pin_trait!(SckPin, Instance, SubBlockInstance);
1082pin_trait!(FsPin, Instance, SubBlockInstance); 1079pin_trait!(FsPin, Instance, SubBlockInstance);
1083pin_trait!(SdPin, Instance, SubBlockInstance); 1080pin_trait!(SdPin, Instance, SubBlockInstance);
@@ -1087,7 +1084,7 @@ dma_trait!(Dma, Instance, SubBlockInstance);
1087 1084
1088foreach_peripheral!( 1085foreach_peripheral!(
1089 (sai, $inst:ident) => { 1086 (sai, $inst:ident) => {
1090 impl sealed::Instance for peripherals::$inst { 1087 impl SealedInstance for peripherals::$inst {
1091 const REGS: Regs = crate::pac::$inst; 1088 const REGS: Regs = crate::pac::$inst;
1092 } 1089 }
1093 1090
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs
index c0b3a2183..f79a11606 100644
--- a/embassy-stm32/src/sdmmc/mod.rs
+++ b/embassy-stm32/src/sdmmc/mod.rs
@@ -13,8 +13,7 @@ use embassy_sync::waitqueue::AtomicWaker;
13use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; 13use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR};
14 14
15use crate::dma::NoDma; 15use crate::dma::NoDma;
16use crate::gpio::sealed::{AFType, Pin}; 16use crate::gpio::{AFType, AnyPin, Pull, SealedPin, Speed};
17use crate::gpio::{AnyPin, Pull, Speed};
18use crate::interrupt::typelevel::Interrupt; 17use crate::interrupt::typelevel::Interrupt;
19use crate::pac::sdmmc::Sdmmc as RegBlock; 18use crate::pac::sdmmc::Sdmmc as RegBlock;
20use crate::rcc::RccPeripheral; 19use crate::rcc::RccPeripheral;
@@ -1418,19 +1417,17 @@ impl Cmd {
1418 1417
1419////////////////////////////////////////////////////// 1418//////////////////////////////////////////////////////
1420 1419
1421pub(crate) mod sealed { 1420trait SealedInstance {
1422 use super::*; 1421 fn regs() -> RegBlock;
1423 1422 fn state() -> &'static AtomicWaker;
1424 pub trait Instance {
1425 type Interrupt: interrupt::typelevel::Interrupt;
1426
1427 fn regs() -> RegBlock;
1428 fn state() -> &'static AtomicWaker;
1429 }
1430} 1423}
1431 1424
1432/// SDMMC instance trait. 1425/// SDMMC instance trait.
1433pub trait Instance: sealed::Instance + RccPeripheral + 'static {} 1426#[allow(private_bounds)]
1427pub trait Instance: SealedInstance + RccPeripheral + 'static {
1428 /// Interrupt for this instance.
1429 type Interrupt: interrupt::typelevel::Interrupt;
1430}
1434 1431
1435pin_trait!(CkPin, Instance); 1432pin_trait!(CkPin, Instance);
1436pin_trait!(CmdPin, Instance); 1433pin_trait!(CmdPin, Instance);
@@ -1457,9 +1454,7 @@ impl<T: Instance> SdmmcDma<T> for NoDma {}
1457 1454
1458foreach_peripheral!( 1455foreach_peripheral!(
1459 (sdmmc, $inst:ident) => { 1456 (sdmmc, $inst:ident) => {
1460 impl sealed::Instance for peripherals::$inst { 1457 impl SealedInstance for peripherals::$inst {
1461 type Interrupt = crate::interrupt::typelevel::$inst;
1462
1463 fn regs() -> RegBlock { 1458 fn regs() -> RegBlock {
1464 crate::pac::$inst 1459 crate::pac::$inst
1465 } 1460 }
@@ -1470,6 +1465,8 @@ foreach_peripheral!(
1470 } 1465 }
1471 } 1466 }
1472 1467
1473 impl Instance for peripherals::$inst {} 1468 impl Instance for peripherals::$inst {
1469 type Interrupt = crate::interrupt::typelevel::$inst;
1470 }
1474 }; 1471 };
1475); 1472);
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index b517f640a..0b38c4288 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -9,8 +9,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
9pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 9pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
10 10
11use crate::dma::{slice_ptr_parts, word, Transfer}; 11use crate::dma::{slice_ptr_parts, word, Transfer};
12use crate::gpio::sealed::{AFType, Pin as _}; 12use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _};
13use crate::gpio::{AnyPin, Pull};
14use crate::pac::spi::{regs, vals, Spi as Regs}; 13use crate::pac::spi::{regs, vals, Spi as Regs};
15use crate::rcc::RccPeripheral; 14use crate::rcc::RccPeripheral;
16use crate::time::Hertz; 15use crate::time::Hertz;
@@ -210,7 +209,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
210 // see RM0453 rev 1 section 7.2.13 page 291 209 // see RM0453 rev 1 section 7.2.13 page 291
211 // The SUBGHZSPI_SCK frequency is obtained by PCLK3 divided by two. 210 // The SUBGHZSPI_SCK frequency is obtained by PCLK3 divided by two.
212 // The SUBGHZSPI_SCK clock maximum speed must not exceed 16 MHz. 211 // The SUBGHZSPI_SCK clock maximum speed must not exceed 16 MHz.
213 let pclk3_freq = <peripherals::SUBGHZSPI as crate::rcc::sealed::RccPeripheral>::frequency().0; 212 let pclk3_freq = <peripherals::SUBGHZSPI as crate::rcc::SealedRccPeripheral>::frequency().0;
214 let freq = Hertz(core::cmp::min(pclk3_freq / 2, 16_000_000)); 213 let freq = Hertz(core::cmp::min(pclk3_freq / 2, 16_000_000));
215 let mut config = Config::default(); 214 let mut config = Config::default();
216 config.mode = MODE_0; 215 config.mode = MODE_0;
@@ -271,13 +270,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
271 if mosi.is_none() { 270 if mosi.is_none() {
272 w.set_rxonly(vals::Rxonly::OUTPUTDISABLED); 271 w.set_rxonly(vals::Rxonly::OUTPUTDISABLED);
273 } 272 }
274 w.set_dff(<u8 as sealed::Word>::CONFIG) 273 w.set_dff(<u8 as SealedWord>::CONFIG)
275 }); 274 });
276 } 275 }
277 #[cfg(spi_v2)] 276 #[cfg(spi_v2)]
278 { 277 {
279 T::REGS.cr2().modify(|w| { 278 T::REGS.cr2().modify(|w| {
280 let (ds, frxth) = <u8 as sealed::Word>::CONFIG; 279 let (ds, frxth) = <u8 as SealedWord>::CONFIG;
281 w.set_frxth(frxth); 280 w.set_frxth(frxth);
282 w.set_ds(ds); 281 w.set_ds(ds);
283 w.set_ssoe(false); 282 w.set_ssoe(false);
@@ -317,7 +316,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
317 T::REGS.cfg1().modify(|w| { 316 T::REGS.cfg1().modify(|w| {
318 w.set_crcen(false); 317 w.set_crcen(false);
319 w.set_mbr(br); 318 w.set_mbr(br);
320 w.set_dsize(<u8 as sealed::Word>::CONFIG); 319 w.set_dsize(<u8 as SealedWord>::CONFIG);
321 w.set_fthlv(vals::Fthlv::ONEFRAME); 320 w.set_fthlv(vals::Fthlv::ONEFRAME);
322 }); 321 });
323 T::REGS.cr2().modify(|w| { 322 T::REGS.cr2().modify(|w| {
@@ -336,7 +335,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
336 miso, 335 miso,
337 txdma, 336 txdma,
338 rxdma, 337 rxdma,
339 current_word_size: <u8 as sealed::Word>::CONFIG, 338 current_word_size: <u8 as SealedWord>::CONFIG,
340 } 339 }
341 } 340 }
342 341
@@ -975,24 +974,21 @@ impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>, W: Word> embedded_hal_async::s
975 } 974 }
976} 975}
977 976
978pub(crate) mod sealed { 977pub(crate) trait SealedInstance {
979 use super::*; 978 const REGS: Regs;
980 979}
981 pub trait Instance {
982 const REGS: Regs;
983 }
984 980
985 pub trait Word { 981trait SealedWord {
986 const CONFIG: word_impl::Config; 982 const CONFIG: word_impl::Config;
987 }
988} 983}
989 984
990/// Word sizes usable for SPI. 985/// Word sizes usable for SPI.
991pub trait Word: word::Word + sealed::Word {} 986#[allow(private_bounds)]
987pub trait Word: word::Word + SealedWord {}
992 988
993macro_rules! impl_word { 989macro_rules! impl_word {
994 ($T:ty, $config:expr) => { 990 ($T:ty, $config:expr) => {
995 impl sealed::Word for $T { 991 impl SealedWord for $T {
996 const CONFIG: Config = $config; 992 const CONFIG: Config = $config;
997 } 993 }
998 impl Word for $T {} 994 impl Word for $T {}
@@ -1068,7 +1064,8 @@ mod word_impl {
1068} 1064}
1069 1065
1070/// SPI instance trait. 1066/// SPI instance trait.
1071pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {} 1067#[allow(private_bounds)]
1068pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {}
1072 1069
1073pin_trait!(SckPin, Instance); 1070pin_trait!(SckPin, Instance);
1074pin_trait!(MosiPin, Instance); 1071pin_trait!(MosiPin, Instance);
@@ -1082,7 +1079,7 @@ dma_trait!(TxDma, Instance);
1082 1079
1083foreach_peripheral!( 1080foreach_peripheral!(
1084 (spi, $inst:ident) => { 1081 (spi, $inst:ident) => {
1085 impl sealed::Instance for peripherals::$inst { 1082 impl SealedInstance for peripherals::$inst {
1086 const REGS: Regs = crate::pac::$inst; 1083 const REGS: Regs = crate::pac::$inst;
1087 } 1084 }
1088 1085
diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs
index c961fc14b..cc8161276 100644
--- a/embassy-stm32/src/time_driver.rs
+++ b/embassy-stm32/src/time_driver.rs
@@ -12,7 +12,7 @@ use stm32_metapac::timer::{regs, TimGp16};
12 12
13use crate::interrupt::typelevel::Interrupt; 13use crate::interrupt::typelevel::Interrupt;
14use crate::pac::timer::vals; 14use crate::pac::timer::vals;
15use crate::rcc::sealed::RccPeripheral; 15use crate::rcc::SealedRccPeripheral;
16#[cfg(feature = "low-power")] 16#[cfg(feature = "low-power")]
17use crate::rtc::Rtc; 17use crate::rtc::Rtc;
18#[cfg(any(time_driver_tim1, time_driver_tim8, time_driver_tim20))] 18#[cfg(any(time_driver_tim1, time_driver_tim8, time_driver_tim20))]
@@ -277,7 +277,7 @@ impl RtcDriver {
277 fn init(&'static self, cs: critical_section::CriticalSection) { 277 fn init(&'static self, cs: critical_section::CriticalSection) {
278 let r = regs_gp16(); 278 let r = regs_gp16();
279 279
280 <T as RccPeripheral>::enable_and_reset_with_cs(cs); 280 <T as SealedRccPeripheral>::enable_and_reset_with_cs(cs);
281 281
282 let timer_freq = T::frequency(); 282 let timer_freq = T::frequency();
283 283
diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs
index b6ab939cc..ab9879be6 100644
--- a/embassy-stm32/src/timer/qei.rs
+++ b/embassy-stm32/src/timer/qei.rs
@@ -7,8 +7,7 @@ use stm32_metapac::timer::vals;
7 7
8use super::low_level::Timer; 8use super::low_level::Timer;
9use super::{Channel1Pin, Channel2Pin, GeneralInstance4Channel}; 9use super::{Channel1Pin, Channel2Pin, GeneralInstance4Channel};
10use crate::gpio::sealed::AFType; 10use crate::gpio::{AFType, AnyPin};
11use crate::gpio::AnyPin;
12use crate::Peripheral; 11use crate::Peripheral;
13 12
14/// Counting direction 13/// Counting direction
diff --git a/embassy-stm32/src/ucpd.rs b/embassy-stm32/src/ucpd.rs
index 9c37d2c04..fe614b811 100644
--- a/embassy-stm32/src/ucpd.rs
+++ b/embassy-stm32/src/ucpd.rs
@@ -16,11 +16,12 @@
16 16
17use core::future::poll_fn; 17use core::future::poll_fn;
18use core::marker::PhantomData; 18use core::marker::PhantomData;
19use core::sync::atomic::Ordering; 19use core::sync::atomic::{AtomicBool, Ordering};
20use core::task::Poll; 20use core::task::Poll;
21 21
22use embassy_hal_internal::drop::OnDrop; 22use embassy_hal_internal::drop::OnDrop;
23use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 23use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
24use embassy_sync::waitqueue::AtomicWaker;
24 25
25use crate::dma::{AnyChannel, Request, Transfer, TransferOptions}; 26use crate::dma::{AnyChannel, Request, Transfer, TransferOptions};
26use crate::interrupt; 27use crate::interrupt;
@@ -555,50 +556,47 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
555 } 556 }
556} 557}
557 558
558/// UCPD instance trait. 559struct State {
559pub trait Instance: sealed::Instance + RccPeripheral {} 560 waker: AtomicWaker,
560 561 // Inverted logic for a default state of 0 so that the data goes into the .bss section.
561mod sealed { 562 drop_not_ready: AtomicBool,
562 use core::sync::atomic::AtomicBool; 563}
563
564 use embassy_sync::waitqueue::AtomicWaker;
565
566 pub struct State {
567 pub waker: AtomicWaker,
568 // Inverted logic for a default state of 0 so that the data goes into the .bss section.
569 pub drop_not_ready: AtomicBool,
570 }
571 564
572 impl State { 565impl State {
573 pub const fn new() -> Self { 566 pub const fn new() -> Self {
574 Self { 567 Self {
575 waker: AtomicWaker::new(), 568 waker: AtomicWaker::new(),
576 drop_not_ready: AtomicBool::new(false), 569 drop_not_ready: AtomicBool::new(false),
577 }
578 } 570 }
579 } 571 }
572}
580 573
581 pub trait Instance { 574trait SealedInstance {
582 type Interrupt: crate::interrupt::typelevel::Interrupt; 575 const REGS: crate::pac::ucpd::Ucpd;
583 const REGS: crate::pac::ucpd::Ucpd; 576 fn state() -> &'static State;
584 fn state() -> &'static crate::ucpd::sealed::State; 577}
585 } 578
579/// UCPD instance trait.
580#[allow(private_bounds)]
581pub trait Instance: SealedInstance + RccPeripheral {
582 /// Interrupt for this instance.
583 type Interrupt: crate::interrupt::typelevel::Interrupt;
586} 584}
587 585
588foreach_interrupt!( 586foreach_interrupt!(
589 ($inst:ident, ucpd, UCPD, GLOBAL, $irq:ident) => { 587 ($inst:ident, ucpd, UCPD, GLOBAL, $irq:ident) => {
590 impl sealed::Instance for crate::peripherals::$inst { 588 impl SealedInstance for crate::peripherals::$inst {
591 type Interrupt = crate::interrupt::typelevel::$irq;
592
593 const REGS: crate::pac::ucpd::Ucpd = crate::pac::$inst; 589 const REGS: crate::pac::ucpd::Ucpd = crate::pac::$inst;
594 590
595 fn state() -> &'static crate::ucpd::sealed::State { 591 fn state() -> &'static State {
596 static STATE: crate::ucpd::sealed::State = crate::ucpd::sealed::State::new(); 592 static STATE: State = State::new();
597 &STATE 593 &STATE
598 } 594 }
599 } 595 }
600 596
601 impl Instance for crate::peripherals::$inst {} 597 impl Instance for crate::peripherals::$inst {
598 type Interrupt = crate::interrupt::typelevel::$irq;
599 }
602 }; 600 };
603); 601);
604 602
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index ea727b010..7ab33043a 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -10,10 +10,11 @@ use core::task::Poll;
10use embassy_embedded_hal::SetConfig; 10use embassy_embedded_hal::SetConfig;
11use embassy_hal_internal::drop::OnDrop; 11use embassy_hal_internal::drop::OnDrop;
12use embassy_hal_internal::{into_ref, PeripheralRef}; 12use embassy_hal_internal::{into_ref, PeripheralRef};
13use embassy_sync::waitqueue::AtomicWaker;
13use futures::future::{select, Either}; 14use futures::future::{select, Either};
14 15
15use crate::dma::{NoDma, Transfer}; 16use crate::dma::{NoDma, Transfer};
16use crate::gpio::sealed::AFType; 17use crate::gpio::AFType;
17use crate::interrupt::typelevel::Interrupt; 18use crate::interrupt::typelevel::Interrupt;
18#[allow(unused_imports)] 19#[allow(unused_imports)]
19#[cfg(not(any(usart_v1, usart_v2)))] 20#[cfg(not(any(usart_v1, usart_v2)))]
@@ -1326,8 +1327,6 @@ mod ringbuffered;
1326#[cfg(not(gpdma))] 1327#[cfg(not(gpdma))]
1327pub use ringbuffered::RingBufferedUartRx; 1328pub use ringbuffered::RingBufferedUartRx;
1328 1329
1329use self::sealed::Kind;
1330
1331#[cfg(any(usart_v1, usart_v2))] 1330#[cfg(any(usart_v1, usart_v2))]
1332fn tdr(r: crate::pac::usart::Usart) -> *mut u8 { 1331fn tdr(r: crate::pac::usart::Usart) -> *mut u8 {
1333 r.dr().as_ptr() as _ 1332 r.dr().as_ptr() as _
@@ -1370,52 +1369,50 @@ fn clear_interrupt_flags(r: Regs, sr: regs::Isr) {
1370 r.icr().write(|w| *w = regs::Icr(sr.0)); 1369 r.icr().write(|w| *w = regs::Icr(sr.0));
1371} 1370}
1372 1371
1373pub(crate) mod sealed { 1372#[derive(Clone, Copy, PartialEq, Eq)]
1374 use embassy_sync::waitqueue::AtomicWaker; 1373enum Kind {
1375 1374 Uart,
1376 use super::*; 1375 #[cfg(any(usart_v3, usart_v4))]
1377 1376 #[allow(unused)]
1378 #[derive(Clone, Copy, PartialEq, Eq)] 1377 Lpuart,
1379 pub enum Kind { 1378}
1380 Uart,
1381 #[cfg(any(usart_v3, usart_v4))]
1382 Lpuart,
1383 }
1384 1379
1385 pub struct State { 1380struct State {
1386 pub rx_waker: AtomicWaker, 1381 rx_waker: AtomicWaker,
1387 pub tx_waker: AtomicWaker, 1382}
1388 }
1389 1383
1390 impl State { 1384impl State {
1391 pub const fn new() -> Self { 1385 const fn new() -> Self {
1392 Self { 1386 Self {
1393 rx_waker: AtomicWaker::new(), 1387 rx_waker: AtomicWaker::new(),
1394 tx_waker: AtomicWaker::new(),
1395 }
1396 } 1388 }
1397 } 1389 }
1390}
1398 1391
1399 pub trait BasicInstance: crate::rcc::RccPeripheral { 1392trait SealedBasicInstance: crate::rcc::RccPeripheral {
1400 const KIND: Kind; 1393 const KIND: Kind;
1401 type Interrupt: interrupt::typelevel::Interrupt;
1402 1394
1403 fn regs() -> Regs; 1395 fn regs() -> Regs;
1404 fn state() -> &'static State; 1396 fn state() -> &'static State;
1405 1397
1406 fn buffered_state() -> &'static buffered::State; 1398 fn buffered_state() -> &'static buffered::State;
1407 } 1399}
1408 1400
1409 pub trait FullInstance: BasicInstance { 1401trait SealedFullInstance: SealedBasicInstance {
1410 fn regs_uart() -> crate::pac::usart::Usart; 1402 #[allow(unused)]
1411 } 1403 fn regs_uart() -> crate::pac::usart::Usart;
1412} 1404}
1413 1405
1414/// Basic UART driver instance 1406/// Basic UART driver instance
1415pub trait BasicInstance: Peripheral<P = Self> + sealed::BasicInstance + 'static + Send {} 1407#[allow(private_bounds)]
1408pub trait BasicInstance: Peripheral<P = Self> + SealedBasicInstance + 'static + Send {
1409 /// Interrupt for this instance.
1410 type Interrupt: interrupt::typelevel::Interrupt;
1411}
1416 1412
1417/// Full UART driver instance 1413/// Full UART driver instance
1418pub trait FullInstance: sealed::FullInstance {} 1414#[allow(private_bounds)]
1415pub trait FullInstance: SealedFullInstance {}
1419 1416
1420pin_trait!(RxPin, BasicInstance); 1417pin_trait!(RxPin, BasicInstance);
1421pin_trait!(TxPin, BasicInstance); 1418pin_trait!(TxPin, BasicInstance);
@@ -1429,16 +1426,15 @@ dma_trait!(RxDma, BasicInstance);
1429 1426
1430macro_rules! impl_usart { 1427macro_rules! impl_usart {
1431 ($inst:ident, $irq:ident, $kind:expr) => { 1428 ($inst:ident, $irq:ident, $kind:expr) => {
1432 impl sealed::BasicInstance for crate::peripherals::$inst { 1429 impl SealedBasicInstance for crate::peripherals::$inst {
1433 const KIND: Kind = $kind; 1430 const KIND: Kind = $kind;
1434 type Interrupt = crate::interrupt::typelevel::$irq;
1435 1431
1436 fn regs() -> Regs { 1432 fn regs() -> Regs {
1437 unsafe { Regs::from_ptr(crate::pac::$inst.as_ptr()) } 1433 unsafe { Regs::from_ptr(crate::pac::$inst.as_ptr()) }
1438 } 1434 }
1439 1435
1440 fn state() -> &'static crate::usart::sealed::State { 1436 fn state() -> &'static crate::usart::State {
1441 static STATE: crate::usart::sealed::State = crate::usart::sealed::State::new(); 1437 static STATE: crate::usart::State = crate::usart::State::new();
1442 &STATE 1438 &STATE
1443 } 1439 }
1444 1440
@@ -1448,7 +1444,9 @@ macro_rules! impl_usart {
1448 } 1444 }
1449 } 1445 }
1450 1446
1451 impl BasicInstance for peripherals::$inst {} 1447 impl BasicInstance for peripherals::$inst {
1448 type Interrupt = crate::interrupt::typelevel::$irq;
1449 }
1452 }; 1450 };
1453} 1451}
1454 1452
@@ -1460,7 +1458,7 @@ foreach_interrupt!(
1460 ($inst:ident, usart, $block:ident, $signal_name:ident, $irq:ident) => { 1458 ($inst:ident, usart, $block:ident, $signal_name:ident, $irq:ident) => {
1461 impl_usart!($inst, $irq, Kind::Uart); 1459 impl_usart!($inst, $irq, Kind::Uart);
1462 1460
1463 impl sealed::FullInstance for peripherals::$inst { 1461 impl SealedFullInstance for peripherals::$inst {
1464 fn regs_uart() -> crate::pac::usart::Usart { 1462 fn regs_uart() -> crate::pac::usart::Usart {
1465 crate::pac::$inst 1463 crate::pac::$inst
1466 } 1464 }
diff --git a/embassy-stm32/src/usb/mod.rs b/embassy-stm32/src/usb/mod.rs
index 788f61f16..1e3c44167 100644
--- a/embassy-stm32/src/usb/mod.rs
+++ b/embassy-stm32/src/usb/mod.rs
@@ -6,7 +6,7 @@ mod _version;
6pub use _version::*; 6pub use _version::*;
7 7
8use crate::interrupt::typelevel::Interrupt; 8use crate::interrupt::typelevel::Interrupt;
9use crate::rcc::sealed::RccPeripheral; 9use crate::rcc::SealedRccPeripheral;
10 10
11/// clock, power initialization stuff that's common for USB and OTG. 11/// clock, power initialization stuff that's common for USB and OTG.
12fn common_init<T: Instance>() { 12fn common_init<T: Instance>() {
@@ -65,5 +65,5 @@ fn common_init<T: Instance>() {
65 T::Interrupt::unpend(); 65 T::Interrupt::unpend();
66 unsafe { T::Interrupt::enable() }; 66 unsafe { T::Interrupt::enable() };
67 67
68 <T as RccPeripheral>::enable_and_reset(); 68 <T as SealedRccPeripheral>::enable_and_reset();
69} 69}
diff --git a/embassy-stm32/src/usb/otg.rs b/embassy-stm32/src/usb/otg.rs
index d4095b466..b0e7067bd 100644
--- a/embassy-stm32/src/usb/otg.rs
+++ b/embassy-stm32/src/usb/otg.rs
@@ -11,11 +11,11 @@ use embassy_usb_driver::{
11}; 11};
12use futures::future::poll_fn; 12use futures::future::poll_fn;
13 13
14use crate::gpio::sealed::AFType; 14use crate::gpio::AFType;
15use crate::interrupt; 15use crate::interrupt;
16use crate::interrupt::typelevel::Interrupt; 16use crate::interrupt::typelevel::Interrupt;
17use crate::pac::otg::{regs, vals}; 17use crate::pac::otg::{regs, vals};
18use crate::rcc::sealed::RccPeripheral; 18use crate::rcc::{RccPeripheral, SealedRccPeripheral};
19use crate::time::Hertz; 19use crate::time::Hertz;
20 20
21/// Interrupt handler. 21/// Interrupt handler.
@@ -809,7 +809,7 @@ impl<'d, T: Instance> Bus<'d, T> {
809 fn disable(&mut self) { 809 fn disable(&mut self) {
810 T::Interrupt::disable(); 810 T::Interrupt::disable();
811 811
812 <T as RccPeripheral>::disable(); 812 <T as SealedRccPeripheral>::disable();
813 813
814 #[cfg(stm32l4)] 814 #[cfg(stm32l4)]
815 crate::pac::PWR.cr2().modify(|w| w.set_usv(false)); 815 crate::pac::PWR.cr2().modify(|w| w.set_usv(false));
@@ -1436,19 +1436,18 @@ fn quirk_setup_late_cnak(r: crate::pac::otg::Otg) -> bool {
1436// Using Instance::ENDPOINT_COUNT requires feature(const_generic_expr) so just define maximum eps 1436// Using Instance::ENDPOINT_COUNT requires feature(const_generic_expr) so just define maximum eps
1437const MAX_EP_COUNT: usize = 9; 1437const MAX_EP_COUNT: usize = 9;
1438 1438
1439pub(crate) mod sealed { 1439trait SealedInstance {
1440 pub trait Instance { 1440 const HIGH_SPEED: bool;
1441 const HIGH_SPEED: bool; 1441 const FIFO_DEPTH_WORDS: u16;
1442 const FIFO_DEPTH_WORDS: u16; 1442 const ENDPOINT_COUNT: usize;
1443 const ENDPOINT_COUNT: usize;
1444 1443
1445 fn regs() -> crate::pac::otg::Otg; 1444 fn regs() -> crate::pac::otg::Otg;
1446 fn state() -> &'static super::State<{ super::MAX_EP_COUNT }>; 1445 fn state() -> &'static super::State<{ MAX_EP_COUNT }>;
1447 }
1448} 1446}
1449 1447
1450/// USB instance trait. 1448/// USB instance trait.
1451pub trait Instance: sealed::Instance + RccPeripheral + 'static { 1449#[allow(private_bounds)]
1450pub trait Instance: SealedInstance + RccPeripheral + 'static {
1452 /// Interrupt for this USB instance. 1451 /// Interrupt for this USB instance.
1453 type Interrupt: interrupt::typelevel::Interrupt; 1452 type Interrupt: interrupt::typelevel::Interrupt;
1454} 1453}
@@ -1473,7 +1472,7 @@ pin_trait!(UlpiD7Pin, Instance);
1473 1472
1474foreach_interrupt!( 1473foreach_interrupt!(
1475 (USB_OTG_FS, otg, $block:ident, GLOBAL, $irq:ident) => { 1474 (USB_OTG_FS, otg, $block:ident, GLOBAL, $irq:ident) => {
1476 impl sealed::Instance for crate::peripherals::USB_OTG_FS { 1475 impl SealedInstance for crate::peripherals::USB_OTG_FS {
1477 const HIGH_SPEED: bool = false; 1476 const HIGH_SPEED: bool = false;
1478 1477
1479 cfg_if::cfg_if! { 1478 cfg_if::cfg_if! {
@@ -1538,7 +1537,7 @@ foreach_interrupt!(
1538 }; 1537 };
1539 1538
1540 (USB_OTG_HS, otg, $block:ident, GLOBAL, $irq:ident) => { 1539 (USB_OTG_HS, otg, $block:ident, GLOBAL, $irq:ident) => {
1541 impl sealed::Instance for crate::peripherals::USB_OTG_HS { 1540 impl SealedInstance for crate::peripherals::USB_OTG_HS {
1542 const HIGH_SPEED: bool = true; 1541 const HIGH_SPEED: bool = true;
1543 1542
1544 cfg_if::cfg_if! { 1543 cfg_if::cfg_if! {
diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs
index c4f9140da..f48808cb3 100644
--- a/embassy-stm32/src/usb/usb.rs
+++ b/embassy-stm32/src/usb/usb.rs
@@ -15,7 +15,7 @@ use embassy_usb_driver::{
15use crate::pac::usb::regs; 15use crate::pac::usb::regs;
16use crate::pac::usb::vals::{EpType, Stat}; 16use crate::pac::usb::vals::{EpType, Stat};
17use crate::pac::USBRAM; 17use crate::pac::USBRAM;
18use crate::rcc::sealed::RccPeripheral; 18use crate::rcc::RccPeripheral;
19use crate::{interrupt, Peripheral}; 19use crate::{interrupt, Peripheral};
20 20
21/// Interrupt handler. 21/// Interrupt handler.
@@ -277,8 +277,8 @@ impl<'d, T: Instance> Driver<'d, T> {
277 277
278 #[cfg(not(stm32l1))] 278 #[cfg(not(stm32l1))]
279 { 279 {
280 dp.set_as_af(dp.af_num(), crate::gpio::sealed::AFType::OutputPushPull); 280 dp.set_as_af(dp.af_num(), crate::gpio::AFType::OutputPushPull);
281 dm.set_as_af(dm.af_num(), crate::gpio::sealed::AFType::OutputPushPull); 281 dm.set_as_af(dm.af_num(), crate::gpio::AFType::OutputPushPull);
282 } 282 }
283 #[cfg(stm32l1)] 283 #[cfg(stm32l1)]
284 let _ = (dp, dm); // suppress "unused" warnings. 284 let _ = (dp, dm); // suppress "unused" warnings.
@@ -1037,14 +1037,13 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
1037 } 1037 }
1038} 1038}
1039 1039
1040pub(crate) mod sealed { 1040trait SealedInstance {
1041 pub trait Instance { 1041 fn regs() -> crate::pac::usb::Usb;
1042 fn regs() -> crate::pac::usb::Usb;
1043 }
1044} 1042}
1045 1043
1046/// USB instance trait. 1044/// USB instance trait.
1047pub trait Instance: sealed::Instance + RccPeripheral + 'static { 1045#[allow(private_bounds)]
1046pub trait Instance: SealedInstance + RccPeripheral + 'static {
1048 /// Interrupt for this USB instance. 1047 /// Interrupt for this USB instance.
1049 type Interrupt: interrupt::typelevel::Interrupt; 1048 type Interrupt: interrupt::typelevel::Interrupt;
1050} 1049}
@@ -1055,7 +1054,7 @@ pin_trait!(DmPin, Instance);
1055 1054
1056foreach_interrupt!( 1055foreach_interrupt!(
1057 ($inst:ident, usb, $block:ident, LP, $irq:ident) => { 1056 ($inst:ident, usb, $block:ident, LP, $irq:ident) => {
1058 impl sealed::Instance for crate::peripherals::$inst { 1057 impl SealedInstance for crate::peripherals::$inst {
1059 fn regs() -> crate::pac::usb::Usb { 1058 fn regs() -> crate::pac::usb::Usb {
1060 crate::pac::$inst 1059 crate::pac::$inst
1061 } 1060 }
diff --git a/embassy-stm32/src/wdg/mod.rs b/embassy-stm32/src/wdg/mod.rs
index 2ff0db09e..ab21c4b6b 100644
--- a/embassy-stm32/src/wdg/mod.rs
+++ b/embassy-stm32/src/wdg/mod.rs
@@ -80,18 +80,17 @@ impl<'d, T: Instance> IndependentWatchdog<'d, T> {
80 } 80 }
81} 81}
82 82
83mod sealed { 83trait SealedInstance {
84 pub trait Instance { 84 fn regs() -> crate::pac::iwdg::Iwdg;
85 fn regs() -> crate::pac::iwdg::Iwdg;
86 }
87} 85}
88 86
89/// IWDG instance trait. 87/// IWDG instance trait.
90pub trait Instance: sealed::Instance {} 88#[allow(private_bounds)]
89pub trait Instance: SealedInstance {}
91 90
92foreach_peripheral!( 91foreach_peripheral!(
93 (iwdg, $inst:ident) => { 92 (iwdg, $inst:ident) => {
94 impl sealed::Instance for crate::peripherals::$inst { 93 impl SealedInstance for crate::peripherals::$inst {
95 fn regs() -> crate::pac::iwdg::Iwdg { 94 fn regs() -> crate::pac::iwdg::Iwdg {
96 crate::pac::$inst 95 crate::pac::$inst
97 } 96 }
diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs
index c45747f35..3a9887e3c 100644
--- a/examples/stm32h7/src/bin/dac_dma.rs
+++ b/examples/stm32h7/src/bin/dac_dma.rs
@@ -6,7 +6,7 @@ use embassy_executor::Spawner;
6use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray}; 6use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray};
7use embassy_stm32::pac::timer::vals::Mms; 7use embassy_stm32::pac::timer::vals::Mms;
8use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; 8use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7};
9use embassy_stm32::rcc::low_level::RccPeripheral; 9use embassy_stm32::rcc::frequency;
10use embassy_stm32::time::Hertz; 10use embassy_stm32::time::Hertz;
11use embassy_stm32::timer::low_level::Timer; 11use embassy_stm32::timer::low_level::Timer;
12use micromath::F32Ext; 12use micromath::F32Ext;
@@ -59,11 +59,11 @@ async fn main(spawner: Spawner) {
59async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { 59async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
60 let data: &[u8; 256] = &calculate_array::<256>(); 60 let data: &[u8; 256] = &calculate_array::<256>();
61 61
62 info!("TIM6 frequency is {}", TIM6::frequency()); 62 info!("TIM6 frequency is {}", frequency::<TIM6>());
63 const FREQUENCY: Hertz = Hertz::hz(200); 63 const FREQUENCY: Hertz = Hertz::hz(200);
64 64
65 // Compute the reload value such that we obtain the FREQUENCY for the sine 65 // Compute the reload value such that we obtain the FREQUENCY for the sine
66 let reload: u32 = (TIM6::frequency().0 / FREQUENCY.0) / data.len() as u32; 66 let reload: u32 = (frequency::<TIM6>().0 / FREQUENCY.0) / data.len() as u32;
67 67
68 // Depends on your clock and on the specific chip used, you may need higher or lower values here 68 // Depends on your clock and on the specific chip used, you may need higher or lower values here
69 if reload < 10 { 69 if reload < 10 {
@@ -84,7 +84,7 @@ async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
84 84
85 debug!( 85 debug!(
86 "TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", 86 "TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
87 TIM6::frequency(), 87 frequency::<TIM6>(),
88 FREQUENCY, 88 FREQUENCY,
89 reload, 89 reload,
90 reload as u16, 90 reload as u16,
@@ -102,10 +102,10 @@ async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
102async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { 102async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
103 let data: &[u8; 256] = &calculate_array::<256>(); 103 let data: &[u8; 256] = &calculate_array::<256>();
104 104
105 info!("TIM7 frequency is {}", TIM7::frequency()); 105 info!("TIM7 frequency is {}", frequency::<TIM6>());
106 106
107 const FREQUENCY: Hertz = Hertz::hz(600); 107 const FREQUENCY: Hertz = Hertz::hz(600);
108 let reload: u32 = (TIM7::frequency().0 / FREQUENCY.0) / data.len() as u32; 108 let reload: u32 = (frequency::<TIM7>().0 / FREQUENCY.0) / data.len() as u32;
109 109
110 if reload < 10 { 110 if reload < 10 {
111 error!("Reload value {} below threshold!", reload); 111 error!("Reload value {} below threshold!", reload);
@@ -125,7 +125,7 @@ async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
125 125
126 debug!( 126 debug!(
127 "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", 127 "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
128 TIM7::frequency(), 128 frequency::<TIM7>(),
129 FREQUENCY, 129 FREQUENCY,
130 reload, 130 reload,
131 reload as u16, 131 reload as u16,
diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs
index 780fbc6f0..a95b44b74 100644
--- a/examples/stm32h7/src/bin/low_level_timer_api.rs
+++ b/examples/stm32h7/src/bin/low_level_timer_api.rs
@@ -3,8 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::gpio::low_level::AFType; 6use embassy_stm32::gpio::{AFType, Flex, Pull, Speed};
7use embassy_stm32::gpio::Speed;
8use embassy_stm32::time::{khz, Hertz}; 7use embassy_stm32::time::{khz, Hertz};
9use embassy_stm32::timer::low_level::{OutputCompareMode, Timer as LLTimer}; 8use embassy_stm32::timer::low_level::{OutputCompareMode, Timer as LLTimer};
10use embassy_stm32::timer::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance32bit4Channel}; 9use embassy_stm32::timer::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance32bit4Channel};
@@ -59,6 +58,10 @@ async fn main(_spawner: Spawner) {
59} 58}
60pub struct SimplePwm32<'d, T: GeneralInstance32bit4Channel> { 59pub struct SimplePwm32<'d, T: GeneralInstance32bit4Channel> {
61 tim: LLTimer<'d, T>, 60 tim: LLTimer<'d, T>,
61 _ch1: Flex<'d>,
62 _ch2: Flex<'d>,
63 _ch3: Flex<'d>,
64 _ch4: Flex<'d>,
62} 65}
63 66
64impl<'d, T: GeneralInstance32bit4Channel> SimplePwm32<'d, T> { 67impl<'d, T: GeneralInstance32bit4Channel> SimplePwm32<'d, T> {
@@ -72,16 +75,26 @@ impl<'d, T: GeneralInstance32bit4Channel> SimplePwm32<'d, T> {
72 ) -> Self { 75 ) -> Self {
73 into_ref!(ch1, ch2, ch3, ch4); 76 into_ref!(ch1, ch2, ch3, ch4);
74 77
75 ch1.set_speed(Speed::VeryHigh); 78 let af1 = ch1.af_num();
76 ch1.set_as_af(ch1.af_num(), AFType::OutputPushPull); 79 let af2 = ch2.af_num();
77 ch2.set_speed(Speed::VeryHigh); 80 let af3 = ch3.af_num();
78 ch2.set_as_af(ch1.af_num(), AFType::OutputPushPull); 81 let af4 = ch4.af_num();
79 ch3.set_speed(Speed::VeryHigh); 82 let mut ch1 = Flex::new(ch1);
80 ch3.set_as_af(ch1.af_num(), AFType::OutputPushPull); 83 let mut ch2 = Flex::new(ch2);
81 ch4.set_speed(Speed::VeryHigh); 84 let mut ch3 = Flex::new(ch3);
82 ch4.set_as_af(ch1.af_num(), AFType::OutputPushPull); 85 let mut ch4 = Flex::new(ch4);
83 86 ch1.set_as_af_unchecked(af1, AFType::OutputPushPull, Pull::None, Speed::VeryHigh);
84 let mut this = Self { tim: LLTimer::new(tim) }; 87 ch2.set_as_af_unchecked(af2, AFType::OutputPushPull, Pull::None, Speed::VeryHigh);
88 ch3.set_as_af_unchecked(af3, AFType::OutputPushPull, Pull::None, Speed::VeryHigh);
89 ch4.set_as_af_unchecked(af4, AFType::OutputPushPull, Pull::None, Speed::VeryHigh);
90
91 let mut this = Self {
92 tim: LLTimer::new(tim),
93 _ch1: ch1,
94 _ch2: ch2,
95 _ch3: ch3,
96 _ch4: ch4,
97 };
85 98
86 this.set_frequency(freq); 99 this.set_frequency(freq);
87 this.tim.start(); 100 this.tim.start();
diff --git a/examples/stm32l4/src/bin/dac_dma.rs b/examples/stm32l4/src/bin/dac_dma.rs
index 98edd39c0..d01b016c0 100644
--- a/examples/stm32l4/src/bin/dac_dma.rs
+++ b/examples/stm32l4/src/bin/dac_dma.rs
@@ -6,7 +6,7 @@ use embassy_executor::Spawner;
6use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray}; 6use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray};
7use embassy_stm32::pac::timer::vals::Mms; 7use embassy_stm32::pac::timer::vals::Mms;
8use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; 8use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7};
9use embassy_stm32::rcc::low_level::RccPeripheral; 9use embassy_stm32::rcc::frequency;
10use embassy_stm32::time::Hertz; 10use embassy_stm32::time::Hertz;
11use embassy_stm32::timer::low_level::Timer; 11use embassy_stm32::timer::low_level::Timer;
12use micromath::F32Ext; 12use micromath::F32Ext;
@@ -30,11 +30,11 @@ async fn main(spawner: Spawner) {
30async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { 30async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
31 let data: &[u8; 256] = &calculate_array::<256>(); 31 let data: &[u8; 256] = &calculate_array::<256>();
32 32
33 info!("TIM6 frequency is {}", TIM6::frequency()); 33 info!("TIM6 frequency is {}", frequency::<TIM6>());
34 const FREQUENCY: Hertz = Hertz::hz(200); 34 const FREQUENCY: Hertz = Hertz::hz(200);
35 35
36 // Compute the reload value such that we obtain the FREQUENCY for the sine 36 // Compute the reload value such that we obtain the FREQUENCY for the sine
37 let reload: u32 = (TIM6::frequency().0 / FREQUENCY.0) / data.len() as u32; 37 let reload: u32 = (frequency::<TIM6>().0 / FREQUENCY.0) / data.len() as u32;
38 38
39 // Depends on your clock and on the specific chip used, you may need higher or lower values here 39 // Depends on your clock and on the specific chip used, you may need higher or lower values here
40 if reload < 10 { 40 if reload < 10 {
@@ -55,7 +55,7 @@ async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
55 55
56 debug!( 56 debug!(
57 "TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", 57 "TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
58 TIM6::frequency(), 58 frequency::<TIM6>(),
59 FREQUENCY, 59 FREQUENCY,
60 reload, 60 reload,
61 reload as u16, 61 reload as u16,
@@ -73,10 +73,10 @@ async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
73async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { 73async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
74 let data: &[u8; 256] = &calculate_array::<256>(); 74 let data: &[u8; 256] = &calculate_array::<256>();
75 75
76 info!("TIM7 frequency is {}", TIM7::frequency()); 76 info!("TIM7 frequency is {}", frequency::<TIM7>());
77 77
78 const FREQUENCY: Hertz = Hertz::hz(600); 78 const FREQUENCY: Hertz = Hertz::hz(600);
79 let reload: u32 = (TIM7::frequency().0 / FREQUENCY.0) / data.len() as u32; 79 let reload: u32 = (frequency::<TIM7>().0 / FREQUENCY.0) / data.len() as u32;
80 80
81 if reload < 10 { 81 if reload < 10 {
82 error!("Reload value {} below threshold!", reload); 82 error!("Reload value {} below threshold!", reload);
@@ -96,7 +96,7 @@ async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
96 96
97 debug!( 97 debug!(
98 "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", 98 "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
99 TIM7::frequency(), 99 frequency::<TIM7>(),
100 FREQUENCY, 100 FREQUENCY,
101 reload, 101 reload,
102 reload as u16, 102 reload as u16,