stm32: use private_bounds for sealed traits.

This commit is contained in:
Dario Nieuwenhuis 2024-03-23 01:38:51 +01:00
parent 389cbc0a77
commit 2bca875b5f
57 changed files with 955 additions and 1080 deletions

View File

@ -584,7 +584,7 @@ fn main() {
}; };
g.extend(quote! { g.extend(quote! {
impl crate::rcc::sealed::RccPeripheral for peripherals::#pname { impl crate::rcc::SealedRccPeripheral for peripherals::#pname {
fn frequency() -> crate::time::Hertz { fn frequency() -> crate::time::Hertz {
#clock_frequency #clock_frequency
} }
@ -1486,7 +1486,7 @@ fn main() {
#[crate::interrupt] #[crate::interrupt]
unsafe fn #irq () { unsafe fn #irq () {
#( #(
<crate::peripherals::#channels as crate::dma::sealed::ChannelInterrupt>::on_irq(); <crate::peripherals::#channels as crate::dma::ChannelInterrupt>::on_irq();
)* )*
} }
} }

View File

@ -33,7 +33,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
pub struct Vref; pub struct Vref;
impl<T: Instance> AdcPin<T> for Vref {} impl<T: Instance> AdcPin<T> for Vref {}
impl<T: Instance> super::sealed::AdcPin<T> for Vref { impl<T: Instance> super::SealedAdcPin<T> for Vref {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
17 17
} }
@ -41,7 +41,7 @@ impl<T: Instance> super::sealed::AdcPin<T> for Vref {
pub struct Temperature; pub struct Temperature;
impl<T: Instance> AdcPin<T> for Temperature {} impl<T: Instance> AdcPin<T> for Temperature {}
impl<T: Instance> super::sealed::AdcPin<T> for Temperature { impl<T: Instance> super::SealedAdcPin<T> for Temperature {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
16 16
} }

View File

@ -33,7 +33,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
pub struct Vref; pub struct Vref;
impl<T: Instance> AdcPin<T> for Vref {} impl<T: Instance> AdcPin<T> for Vref {}
impl<T: Instance> super::sealed::AdcPin<T> for Vref { impl<T: Instance> super::SealedAdcPin<T> for Vref {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
18 18
} }
@ -48,7 +48,7 @@ impl Vref {
pub struct Temperature; pub struct Temperature;
impl<T: Instance> AdcPin<T> for Temperature {} impl<T: Instance> AdcPin<T> for Temperature {}
impl<T: Instance> super::sealed::AdcPin<T> for Temperature { impl<T: Instance> super::SealedAdcPin<T> for Temperature {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
16 16
} }
@ -102,7 +102,7 @@ impl<'d, T: Instance> Adc<'d, T> {
} }
fn freq() -> Hertz { fn freq() -> Hertz {
<T as crate::rcc::sealed::RccPeripheral>::frequency() <T as crate::rcc::SealedRccPeripheral>::frequency()
} }
pub fn sample_time_for_us(&self, us: u32) -> SampleTime { pub fn sample_time_for_us(&self, us: u32) -> SampleTime {

View File

@ -65,7 +65,7 @@ fn update_vref<T: Instance>(op: i8) {
pub struct Vref<T: Instance>(core::marker::PhantomData<T>); pub struct Vref<T: Instance>(core::marker::PhantomData<T>);
impl<T: Instance> AdcPin<T> for Vref<T> {} impl<T: Instance> AdcPin<T> for Vref<T> {}
impl<T: Instance> super::sealed::AdcPin<T> for Vref<T> { impl<T: Instance> super::SealedAdcPin<T> for Vref<T> {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
17 17
} }
@ -124,7 +124,7 @@ impl<T: Instance> Drop for Vref<T> {
pub struct Temperature<T: Instance>(core::marker::PhantomData<T>); pub struct Temperature<T: Instance>(core::marker::PhantomData<T>);
impl<T: Instance> AdcPin<T> for Temperature<T> {} impl<T: Instance> AdcPin<T> for Temperature<T> {}
impl<T: Instance> super::sealed::AdcPin<T> for Temperature<T> { impl<T: Instance> super::SealedAdcPin<T> for Temperature<T> {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
16 16
} }

View File

@ -17,6 +17,8 @@ mod _version;
#[allow(unused)] #[allow(unused)]
#[cfg(not(adc_f3_v2))] #[cfg(not(adc_f3_v2))]
pub use _version::*; pub use _version::*;
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
use embassy_sync::waitqueue::AtomicWaker;
#[cfg(not(any(adc_f1, adc_f3_v2)))] #[cfg(not(any(adc_f1, adc_f3_v2)))]
pub use crate::pac::adc::vals::Res as Resolution; pub use crate::pac::adc::vals::Res as Resolution;
@ -31,63 +33,65 @@ pub struct Adc<'d, T: Instance> {
sample_time: SampleTime, sample_time: SampleTime,
} }
pub(crate) mod sealed { #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] pub struct State {
use embassy_sync::waitqueue::AtomicWaker; pub waker: AtomicWaker,
}
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
pub struct State { impl State {
pub waker: AtomicWaker, pub const fn new() -> Self {
} Self {
waker: AtomicWaker::new(),
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
impl State {
pub const fn new() -> Self {
Self {
waker: AtomicWaker::new(),
}
} }
} }
}
pub trait InterruptableInstance { trait SealedInstance {
type Interrupt: crate::interrupt::typelevel::Interrupt; #[allow(unused)]
} fn regs() -> crate::pac::adc::Adc;
#[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))]
fn common_regs() -> crate::pac::adccommon::AdcCommon;
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
fn state() -> &'static State;
}
pub trait Instance: InterruptableInstance { pub(crate) trait SealedAdcPin<T: Instance> {
fn regs() -> crate::pac::adc::Adc; #[cfg(any(adc_v1, adc_l0, adc_v2))]
#[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))] fn set_as_analog(&mut self) {}
fn common_regs() -> crate::pac::adccommon::AdcCommon;
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
fn state() -> &'static State;
}
pub trait AdcPin<T: Instance> { #[allow(unused)]
#[cfg(any(adc_v1, adc_l0, adc_v2))] fn channel(&self) -> u8;
fn set_as_analog(&mut self) {} }
fn channel(&self) -> u8; trait SealedInternalChannel<T> {
} #[allow(unused)]
fn channel(&self) -> u8;
pub trait InternalChannel<T> {
fn channel(&self) -> u8;
}
} }
/// ADC instance. /// ADC instance.
#[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)))] #[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)))]
pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {} #[allow(private_bounds)]
pub trait Instance: SealedInstance + crate::Peripheral<P = Self> {
type Interrupt: crate::interrupt::typelevel::Interrupt;
}
/// ADC instance. /// ADC instance.
#[cfg(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5))] #[cfg(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5))]
pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {} #[allow(private_bounds)]
pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {
type Interrupt: crate::interrupt::typelevel::Interrupt;
}
/// ADC pin. /// ADC pin.
pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} #[allow(private_bounds)]
pub trait AdcPin<T: Instance>: SealedAdcPin<T> {}
/// ADC internal channel. /// ADC internal channel.
pub trait InternalChannel<T>: sealed::InternalChannel<T> {} #[allow(private_bounds)]
pub trait InternalChannel<T>: SealedInternalChannel<T> {}
foreach_adc!( foreach_adc!(
($inst:ident, $common_inst:ident, $clock:ident) => { ($inst:ident, $common_inst:ident, $clock:ident) => {
impl crate::adc::sealed::Instance for peripherals::$inst { impl crate::adc::SealedInstance for peripherals::$inst {
fn regs() -> crate::pac::adc::Adc { fn regs() -> crate::pac::adc::Adc {
crate::pac::$inst crate::pac::$inst
} }
@ -98,21 +102,15 @@ foreach_adc!(
} }
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
fn state() -> &'static sealed::State { fn state() -> &'static State {
static STATE: sealed::State = sealed::State::new(); static STATE: State = State::new();
&STATE &STATE
} }
} }
foreach_interrupt!( impl crate::adc::Instance for peripherals::$inst {
($inst,adc,ADC,GLOBAL,$irq:ident) => { type Interrupt = crate::_generated::peripheral_interrupts::$inst::GLOBAL;
impl sealed::InterruptableInstance for peripherals::$inst { }
type Interrupt = crate::interrupt::typelevel::$irq;
}
};
);
impl crate::adc::Instance for peripherals::$inst {}
}; };
); );
@ -120,10 +118,10 @@ macro_rules! impl_adc_pin {
($inst:ident, $pin:ident, $ch:expr) => { ($inst:ident, $pin:ident, $ch:expr) => {
impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {} impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {}
impl crate::adc::sealed::AdcPin<peripherals::$inst> for crate::peripherals::$pin { impl crate::adc::SealedAdcPin<peripherals::$inst> for crate::peripherals::$pin {
#[cfg(any(adc_v1, adc_l0, adc_v2))] #[cfg(any(adc_v1, adc_l0, adc_v2))]
fn set_as_analog(&mut self) { fn set_as_analog(&mut self) {
<Self as crate::gpio::sealed::Pin>::set_as_analog(self); <Self as crate::gpio::SealedPin>::set_as_analog(self);
} }
fn channel(&self) -> u8 { fn channel(&self) -> u8 {

View File

@ -39,7 +39,7 @@ pub struct Vbat;
impl AdcPin<ADC> for Vbat {} impl AdcPin<ADC> for Vbat {}
#[cfg(not(adc_l0))] #[cfg(not(adc_l0))]
impl super::sealed::AdcPin<ADC> for Vbat { impl super::SealedAdcPin<ADC> for Vbat {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
18 18
} }
@ -47,7 +47,7 @@ impl super::sealed::AdcPin<ADC> for Vbat {
pub struct Vref; pub struct Vref;
impl AdcPin<ADC> for Vref {} impl AdcPin<ADC> for Vref {}
impl super::sealed::AdcPin<ADC> for Vref { impl super::SealedAdcPin<ADC> for Vref {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
17 17
} }
@ -55,7 +55,7 @@ impl super::sealed::AdcPin<ADC> for Vref {
pub struct Temperature; pub struct Temperature;
impl AdcPin<ADC> for Temperature {} impl AdcPin<ADC> for Temperature {}
impl super::sealed::AdcPin<ADC> for Temperature { impl super::SealedAdcPin<ADC> for Temperature {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
16 16
} }

View File

@ -16,7 +16,7 @@ pub const ADC_POWERUP_TIME_US: u32 = 3;
pub struct VrefInt; pub struct VrefInt;
impl AdcPin<ADC1> for VrefInt {} impl AdcPin<ADC1> for VrefInt {}
impl super::sealed::AdcPin<ADC1> for VrefInt { impl super::SealedAdcPin<ADC1> for VrefInt {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
17 17
} }
@ -31,7 +31,7 @@ impl VrefInt {
pub struct Temperature; pub struct Temperature;
impl AdcPin<ADC1> for Temperature {} impl AdcPin<ADC1> for Temperature {}
impl super::sealed::AdcPin<ADC1> for Temperature { impl super::SealedAdcPin<ADC1> for Temperature {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
cfg_if::cfg_if! { cfg_if::cfg_if! {
if #[cfg(any(stm32f2, stm32f40, stm32f41))] { if #[cfg(any(stm32f2, stm32f40, stm32f41))] {
@ -52,7 +52,7 @@ impl Temperature {
pub struct Vbat; pub struct Vbat;
impl AdcPin<ADC1> for Vbat {} impl AdcPin<ADC1> for Vbat {}
impl super::sealed::AdcPin<ADC1> for Vbat { impl super::SealedAdcPin<ADC1> for Vbat {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
18 18
} }

View File

@ -12,7 +12,7 @@ pub const VREF_CALIB_MV: u32 = 3000;
pub struct VrefInt; pub struct VrefInt;
impl<T: Instance> AdcPin<T> for VrefInt {} impl<T: Instance> AdcPin<T> for VrefInt {}
impl<T: Instance> super::sealed::AdcPin<T> for VrefInt { impl<T: Instance> super::SealedAdcPin<T> for VrefInt {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
cfg_if! { cfg_if! {
if #[cfg(adc_g0)] { if #[cfg(adc_g0)] {
@ -29,7 +29,7 @@ impl<T: Instance> super::sealed::AdcPin<T> for VrefInt {
pub struct Temperature; pub struct Temperature;
impl<T: Instance> AdcPin<T> for Temperature {} impl<T: Instance> AdcPin<T> for Temperature {}
impl<T: Instance> super::sealed::AdcPin<T> for Temperature { impl<T: Instance> super::SealedAdcPin<T> for Temperature {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
cfg_if! { cfg_if! {
if #[cfg(adc_g0)] { if #[cfg(adc_g0)] {
@ -46,7 +46,7 @@ impl<T: Instance> super::sealed::AdcPin<T> for Temperature {
pub struct Vbat; pub struct Vbat;
impl<T: Instance> AdcPin<T> for Vbat {} impl<T: Instance> AdcPin<T> for Vbat {}
impl<T: Instance> super::sealed::AdcPin<T> for Vbat { impl<T: Instance> super::SealedAdcPin<T> for Vbat {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
cfg_if! { cfg_if! {
if #[cfg(adc_g0)] { if #[cfg(adc_g0)] {
@ -65,7 +65,7 @@ cfg_if! {
if #[cfg(adc_h5)] { if #[cfg(adc_h5)] {
pub struct VddCore; pub struct VddCore;
impl<T: Instance> AdcPin<T> for VddCore {} impl<T: Instance> AdcPin<T> for VddCore {}
impl<T: Instance> super::sealed::AdcPin<T> for VddCore { impl<T: Instance> super::SealedAdcPin<T> for VddCore {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
6 6
} }

View File

@ -35,7 +35,7 @@ const VBAT_CHANNEL: u8 = 17;
/// Internal voltage reference channel. /// Internal voltage reference channel.
pub struct VrefInt; pub struct VrefInt;
impl<T: Instance> InternalChannel<T> for VrefInt {} impl<T: Instance> InternalChannel<T> for VrefInt {}
impl<T: Instance> super::sealed::InternalChannel<T> for VrefInt { impl<T: Instance> super::SealedInternalChannel<T> for VrefInt {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
VREF_CHANNEL VREF_CHANNEL
} }
@ -44,7 +44,7 @@ impl<T: Instance> super::sealed::InternalChannel<T> for VrefInt {
/// Internal temperature channel. /// Internal temperature channel.
pub struct Temperature; pub struct Temperature;
impl<T: Instance> InternalChannel<T> for Temperature {} impl<T: Instance> InternalChannel<T> for Temperature {}
impl<T: Instance> super::sealed::InternalChannel<T> for Temperature { impl<T: Instance> super::SealedInternalChannel<T> for Temperature {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
TEMP_CHANNEL TEMP_CHANNEL
} }
@ -53,7 +53,7 @@ impl<T: Instance> super::sealed::InternalChannel<T> for Temperature {
/// Internal battery voltage channel. /// Internal battery voltage channel.
pub struct Vbat; pub struct Vbat;
impl<T: Instance> InternalChannel<T> for Vbat {} impl<T: Instance> InternalChannel<T> for Vbat {}
impl<T: Instance> super::sealed::InternalChannel<T> for Vbat { impl<T: Instance> super::SealedInternalChannel<T> for Vbat {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
VBAT_CHANNEL VBAT_CHANNEL
} }
@ -276,7 +276,7 @@ impl<'d, T: Instance> Adc<'d, T> {
pub fn read<P>(&mut self, pin: &mut P) -> u16 pub fn read<P>(&mut self, pin: &mut P) -> u16
where where
P: AdcPin<T>, P: AdcPin<T>,
P: crate::gpio::sealed::Pin, P: crate::gpio::Pin,
{ {
pin.set_as_analog(); pin.set_as_analog();

View File

@ -7,9 +7,12 @@ pub mod bx;
pub use bx::{filter, Data, ExtendedId, Fifo, Frame, Header, Id, StandardId}; pub use bx::{filter, Data, ExtendedId, Fifo, Frame, Header, Id, StandardId};
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::channel::Channel;
use embassy_sync::waitqueue::AtomicWaker;
use futures::FutureExt; use futures::FutureExt;
use crate::gpio::sealed::AFType; use crate::gpio::AFType;
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::pac::can::vals::{Ide, Lec}; use crate::pac::can::vals::{Ide, Lec};
use crate::rcc::RccPeripheral; use crate::rcc::RccPeripheral;
@ -485,37 +488,30 @@ impl<'d, T: Instance> DerefMut for Can<'d, T> {
} }
} }
pub(crate) mod sealed { struct State {
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; pub tx_waker: AtomicWaker,
use embassy_sync::channel::Channel; pub err_waker: AtomicWaker,
use embassy_sync::waitqueue::AtomicWaker; pub rx_queue: Channel<CriticalSectionRawMutex, Envelope, 32>,
}
use super::Envelope; impl State {
pub const fn new() -> Self {
pub struct State { Self {
pub tx_waker: AtomicWaker, tx_waker: AtomicWaker::new(),
pub err_waker: AtomicWaker, err_waker: AtomicWaker::new(),
pub rx_queue: Channel<CriticalSectionRawMutex, Envelope, 32>, rx_queue: Channel::new(),
}
impl State {
pub const fn new() -> Self {
Self {
tx_waker: AtomicWaker::new(),
err_waker: AtomicWaker::new(),
rx_queue: Channel::new(),
}
} }
} }
}
pub trait Instance {
fn regs() -> crate::pac::can::Can; trait SealedInstance {
fn state() -> &'static State; fn regs() -> crate::pac::can::Can;
} fn state() -> &'static State;
} }
/// CAN instance trait. /// CAN instance trait.
pub trait Instance: sealed::Instance + RccPeripheral + 'static { #[allow(private_bounds)]
pub trait Instance: SealedInstance + RccPeripheral + 'static {
/// TX interrupt for this instance. /// TX interrupt for this instance.
type TXInterrupt: crate::interrupt::typelevel::Interrupt; type TXInterrupt: crate::interrupt::typelevel::Interrupt;
/// RX0 interrupt for this instance. /// RX0 interrupt for this instance.
@ -533,14 +529,14 @@ unsafe impl<'d, T: Instance> crate::can::bx::Instance for BxcanInstance<'d, T> {
foreach_peripheral!( foreach_peripheral!(
(can, $inst:ident) => { (can, $inst:ident) => {
impl sealed::Instance for peripherals::$inst { impl SealedInstance for peripherals::$inst {
fn regs() -> crate::pac::can::Can { fn regs() -> crate::pac::can::Can {
crate::pac::$inst crate::pac::$inst
} }
fn state() -> &'static sealed::State { fn state() -> &'static State {
static STATE: sealed::State = sealed::State::new(); static STATE: State = State::new();
&STATE &STATE
} }
} }

View File

@ -325,17 +325,6 @@ impl Registers {
*/ */
} }
/// Disables the CAN interface and returns back the raw peripheral it was created from.
#[inline]
pub fn free(mut self) {
//self.disable_interrupts(Interrupts::all());
//TODO check this!
self.enter_init_mode();
self.set_power_down_mode(true);
//self.control.instance
}
/// Applies the settings of a new FdCanConfig See [`FdCanConfig`] /// Applies the settings of a new FdCanConfig See [`FdCanConfig`]
#[inline] #[inline]
pub fn apply_config(&mut self, config: FdCanConfig) { pub fn apply_config(&mut self, config: FdCanConfig) {
@ -419,55 +408,6 @@ impl Registers {
self.leave_init_mode(config); self.leave_init_mode(config);
} }
/// Moves out of ConfigMode and into InternalLoopbackMode
#[inline]
pub fn into_internal_loopback(mut self, config: FdCanConfig) {
self.set_loopback_mode(LoopbackMode::Internal);
self.leave_init_mode(config);
}
/// Moves out of ConfigMode and into ExternalLoopbackMode
#[inline]
pub fn into_external_loopback(mut self, config: FdCanConfig) {
self.set_loopback_mode(LoopbackMode::External);
self.leave_init_mode(config);
}
/// Moves out of ConfigMode and into RestrictedOperationMode
#[inline]
pub fn into_restricted(mut self, config: FdCanConfig) {
self.set_restricted_operations(true);
self.leave_init_mode(config);
}
/// Moves out of ConfigMode and into NormalOperationMode
#[inline]
pub fn into_normal(mut self, config: FdCanConfig) {
self.set_normal_operations(true);
self.leave_init_mode(config);
}
/// Moves out of ConfigMode and into BusMonitoringMode
#[inline]
pub fn into_bus_monitoring(mut self, config: FdCanConfig) {
self.set_bus_monitoring_mode(true);
self.leave_init_mode(config);
}
/// Moves out of ConfigMode and into Testmode
#[inline]
pub fn into_test_mode(mut self, config: FdCanConfig) {
self.set_test_mode(true);
self.leave_init_mode(config);
}
/// Moves out of ConfigMode and into PoweredDownmode
#[inline]
pub fn into_powered_down(mut self, config: FdCanConfig) {
self.set_power_down_mode(true);
self.leave_init_mode(config);
}
/// Configures the bit timings. /// Configures the bit timings.
/// ///
/// You can use <http://www.bittiming.can-wiki.info/> to calculate the `btr` parameter. Enter /// You can use <http://www.bittiming.can-wiki.info/> to calculate the `btr` parameter. Enter
@ -565,6 +505,7 @@ impl Registers {
/// Configures and resets the timestamp counter /// Configures and resets the timestamp counter
#[inline] #[inline]
#[allow(unused)]
pub fn set_timestamp_counter_source(&mut self, select: TimestampSource) { pub fn set_timestamp_counter_source(&mut self, select: TimestampSource) {
#[cfg(stm32h7)] #[cfg(stm32h7)]
let (tcp, tss) = match select { let (tcp, tss) = match select {

View File

@ -5,10 +5,11 @@ use core::task::Poll;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::channel::Channel; use embassy_sync::channel::{Channel, DynamicReceiver, DynamicSender};
use embassy_sync::waitqueue::AtomicWaker;
use crate::can::fd::peripheral::Registers; use crate::can::fd::peripheral::Registers;
use crate::gpio::sealed::AFType; use crate::gpio::AFType;
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::rcc::RccPeripheral; use crate::rcc::RccPeripheral;
use crate::{interrupt, peripherals, Peripheral}; use crate::{interrupt, peripherals, Peripheral};
@ -53,8 +54,8 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup
} }
match &T::state().tx_mode { match &T::state().tx_mode {
sealed::TxMode::NonBuffered(waker) => waker.wake(), TxMode::NonBuffered(waker) => waker.wake(),
sealed::TxMode::ClassicBuffered(buf) => { TxMode::ClassicBuffered(buf) => {
if !T::registers().tx_queue_is_full() { if !T::registers().tx_queue_is_full() {
match buf.tx_receiver.try_receive() { match buf.tx_receiver.try_receive() {
Ok(frame) => { Ok(frame) => {
@ -64,7 +65,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup
} }
} }
} }
sealed::TxMode::FdBuffered(buf) => { TxMode::FdBuffered(buf) => {
if !T::registers().tx_queue_is_full() { if !T::registers().tx_queue_is_full() {
match buf.tx_receiver.try_receive() { match buf.tx_receiver.try_receive() {
Ok(frame) => { Ok(frame) => {
@ -467,14 +468,14 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
fn setup(self) -> Self { fn setup(self) -> Self {
// We don't want interrupts being processed while we change modes. // We don't want interrupts being processed while we change modes.
critical_section::with(|_| unsafe { critical_section::with(|_| unsafe {
let rx_inner = sealed::ClassicBufferedRxInner { let rx_inner = ClassicBufferedRxInner {
rx_sender: self.rx_buf.sender().into(), rx_sender: self.rx_buf.sender().into(),
}; };
let tx_inner = sealed::ClassicBufferedTxInner { let tx_inner = ClassicBufferedTxInner {
tx_receiver: self.tx_buf.receiver().into(), tx_receiver: self.tx_buf.receiver().into(),
}; };
T::mut_state().rx_mode = sealed::RxMode::ClassicBuffered(rx_inner); T::mut_state().rx_mode = RxMode::ClassicBuffered(rx_inner);
T::mut_state().tx_mode = sealed::TxMode::ClassicBuffered(tx_inner); T::mut_state().tx_mode = TxMode::ClassicBuffered(tx_inner);
}); });
self self
} }
@ -509,8 +510,8 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Dr
{ {
fn drop(&mut self) { fn drop(&mut self) {
critical_section::with(|_| unsafe { critical_section::with(|_| unsafe {
T::mut_state().rx_mode = sealed::RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); T::mut_state().rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
T::mut_state().tx_mode = sealed::TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); T::mut_state().tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
}); });
} }
} }
@ -585,14 +586,14 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
fn setup(self) -> Self { fn setup(self) -> Self {
// We don't want interrupts being processed while we change modes. // We don't want interrupts being processed while we change modes.
critical_section::with(|_| unsafe { critical_section::with(|_| unsafe {
let rx_inner = sealed::FdBufferedRxInner { let rx_inner = FdBufferedRxInner {
rx_sender: self.rx_buf.sender().into(), rx_sender: self.rx_buf.sender().into(),
}; };
let tx_inner = sealed::FdBufferedTxInner { let tx_inner = FdBufferedTxInner {
tx_receiver: self.tx_buf.receiver().into(), tx_receiver: self.tx_buf.receiver().into(),
}; };
T::mut_state().rx_mode = sealed::RxMode::FdBuffered(rx_inner); T::mut_state().rx_mode = RxMode::FdBuffered(rx_inner);
T::mut_state().tx_mode = sealed::TxMode::FdBuffered(tx_inner); T::mut_state().tx_mode = TxMode::FdBuffered(tx_inner);
}); });
self self
} }
@ -627,8 +628,8 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Dr
{ {
fn drop(&mut self) { fn drop(&mut self) {
critical_section::with(|_| unsafe { critical_section::with(|_| unsafe {
T::mut_state().rx_mode = sealed::RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); T::mut_state().rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
T::mut_state().tx_mode = sealed::TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); T::mut_state().tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
}); });
} }
} }
@ -677,192 +678,180 @@ impl<'c, 'd, T: Instance> FdcanRx<'d, T> {
} }
} }
pub(crate) mod sealed { struct ClassicBufferedRxInner {
use core::future::poll_fn; rx_sender: DynamicSender<'static, Result<(ClassicFrame, Timestamp), BusError>>,
use core::task::Poll; }
struct ClassicBufferedTxInner {
tx_receiver: DynamicReceiver<'static, ClassicFrame>,
}
use embassy_sync::channel::{DynamicReceiver, DynamicSender}; struct FdBufferedRxInner {
use embassy_sync::waitqueue::AtomicWaker; rx_sender: DynamicSender<'static, Result<(FdFrame, Timestamp), BusError>>,
}
struct FdBufferedTxInner {
tx_receiver: DynamicReceiver<'static, FdFrame>,
}
use super::CanHeader; enum RxMode {
use crate::can::_version::{BusError, Timestamp}; NonBuffered(AtomicWaker),
use crate::can::frame::{ClassicFrame, FdFrame}; ClassicBuffered(ClassicBufferedRxInner),
FdBuffered(FdBufferedRxInner),
}
pub struct ClassicBufferedRxInner { impl RxMode {
pub rx_sender: DynamicSender<'static, Result<(ClassicFrame, Timestamp), BusError>>, fn register(&self, arg: &core::task::Waker) {
} match self {
pub struct ClassicBufferedTxInner { RxMode::NonBuffered(waker) => waker.register(arg),
pub tx_receiver: DynamicReceiver<'static, ClassicFrame>, _ => {
} panic!("Bad Mode")
pub struct FdBufferedRxInner {
pub rx_sender: DynamicSender<'static, Result<(FdFrame, Timestamp), BusError>>,
}
pub struct FdBufferedTxInner {
pub tx_receiver: DynamicReceiver<'static, FdFrame>,
}
pub enum RxMode {
NonBuffered(AtomicWaker),
ClassicBuffered(ClassicBufferedRxInner),
FdBuffered(FdBufferedRxInner),
}
impl RxMode {
pub fn register(&self, arg: &core::task::Waker) {
match self {
RxMode::NonBuffered(waker) => waker.register(arg),
_ => {
panic!("Bad Mode")
}
}
}
pub fn on_interrupt<T: Instance>(&self, fifonr: usize) {
T::regs().ir().write(|w| w.set_rfn(fifonr, true));
match self {
RxMode::NonBuffered(waker) => {
waker.wake();
}
RxMode::ClassicBuffered(buf) => {
if let Some(result) = self.read::<T, _>() {
let _ = buf.rx_sender.try_send(result);
}
}
RxMode::FdBuffered(buf) => {
if let Some(result) = self.read::<T, _>() {
let _ = buf.rx_sender.try_send(result);
}
}
}
}
fn read<T: Instance, F: CanHeader>(&self) -> Option<Result<(F, Timestamp), BusError>> {
if let Some((msg, ts)) = T::registers().read(0) {
let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
Some(Ok((msg, ts)))
} else if let Some((msg, ts)) = T::registers().read(1) {
let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
Some(Ok((msg, ts)))
} else if let Some(err) = T::registers().curr_error() {
// TODO: this is probably wrong
Some(Err(err))
} else {
None
}
}
async fn read_async<T: Instance, F: CanHeader>(&self) -> Result<(F, Timestamp), BusError> {
poll_fn(|cx| {
T::state().err_waker.register(cx.waker());
self.register(cx.waker());
match self.read::<T, _>() {
Some(result) => Poll::Ready(result),
None => Poll::Pending,
}
})
.await
}
pub async fn read_classic<T: Instance>(&self) -> Result<(ClassicFrame, Timestamp), BusError> {
self.read_async::<T, _>().await
}
pub async fn read_fd<T: Instance>(&self) -> Result<(FdFrame, Timestamp), BusError> {
self.read_async::<T, _>().await
}
}
pub enum TxMode {
NonBuffered(AtomicWaker),
ClassicBuffered(ClassicBufferedTxInner),
FdBuffered(FdBufferedTxInner),
}
impl TxMode {
pub fn register(&self, arg: &core::task::Waker) {
match self {
TxMode::NonBuffered(waker) => {
waker.register(arg);
}
_ => {
panic!("Bad mode");
}
}
}
/// Queues the message to be sent but exerts backpressure. If a lower-priority
/// frame is dropped from the mailbox, it is returned. If no lower-priority frames
/// can be replaced, this call asynchronously waits for a frame to be successfully
/// transmitted, then tries again.
async fn write_generic<T: Instance, F: embedded_can::Frame + CanHeader>(&self, frame: &F) -> Option<F> {
poll_fn(|cx| {
self.register(cx.waker());
if let Ok(dropped) = T::registers().write(frame) {
return Poll::Ready(dropped);
}
// Couldn't replace any lower priority frames. Need to wait for some mailboxes
// to clear.
Poll::Pending
})
.await
}
/// Queues the message to be sent but exerts backpressure. If a lower-priority
/// frame is dropped from the mailbox, it is returned. If no lower-priority frames
/// can be replaced, this call asynchronously waits for a frame to be successfully
/// transmitted, then tries again.
pub async fn write<T: Instance>(&self, frame: &ClassicFrame) -> Option<ClassicFrame> {
self.write_generic::<T, _>(frame).await
}
/// Queues the message to be sent but exerts backpressure. If a lower-priority
/// frame is dropped from the mailbox, it is returned. If no lower-priority frames
/// can be replaced, this call asynchronously waits for a frame to be successfully
/// transmitted, then tries again.
pub async fn write_fd<T: Instance>(&self, frame: &FdFrame) -> Option<FdFrame> {
self.write_generic::<T, _>(frame).await
}
}
pub struct State {
pub rx_mode: RxMode,
pub tx_mode: TxMode,
pub ns_per_timer_tick: u64,
pub err_waker: AtomicWaker,
}
impl State {
pub const fn new() -> Self {
Self {
rx_mode: RxMode::NonBuffered(AtomicWaker::new()),
tx_mode: TxMode::NonBuffered(AtomicWaker::new()),
ns_per_timer_tick: 0,
err_waker: AtomicWaker::new(),
} }
} }
} }
pub trait Instance { fn on_interrupt<T: Instance>(&self, fifonr: usize) {
const MSG_RAM_OFFSET: usize; T::regs().ir().write(|w| w.set_rfn(fifonr, true));
match self {
RxMode::NonBuffered(waker) => {
waker.wake();
}
RxMode::ClassicBuffered(buf) => {
if let Some(result) = self.read::<T, _>() {
let _ = buf.rx_sender.try_send(result);
}
}
RxMode::FdBuffered(buf) => {
if let Some(result) = self.read::<T, _>() {
let _ = buf.rx_sender.try_send(result);
}
}
}
}
fn regs() -> &'static crate::pac::can::Fdcan; fn read<T: Instance, F: CanHeader>(&self) -> Option<Result<(F, Timestamp), BusError>> {
fn registers() -> crate::can::fd::peripheral::Registers; if let Some((msg, ts)) = T::registers().read(0) {
fn ram() -> &'static crate::pac::fdcanram::Fdcanram; let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
fn state() -> &'static State; Some(Ok((msg, ts)))
unsafe fn mut_state() -> &'static mut State; } else if let Some((msg, ts)) = T::registers().read(1) {
fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp; let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
Some(Ok((msg, ts)))
} else if let Some(err) = T::registers().curr_error() {
// TODO: this is probably wrong
Some(Err(err))
} else {
None
}
}
async fn read_async<T: Instance, F: CanHeader>(&self) -> Result<(F, Timestamp), BusError> {
poll_fn(|cx| {
T::state().err_waker.register(cx.waker());
self.register(cx.waker());
match self.read::<T, _>() {
Some(result) => Poll::Ready(result),
None => Poll::Pending,
}
})
.await
}
async fn read_classic<T: Instance>(&self) -> Result<(ClassicFrame, Timestamp), BusError> {
self.read_async::<T, _>().await
}
async fn read_fd<T: Instance>(&self) -> Result<(FdFrame, Timestamp), BusError> {
self.read_async::<T, _>().await
} }
} }
enum TxMode {
NonBuffered(AtomicWaker),
ClassicBuffered(ClassicBufferedTxInner),
FdBuffered(FdBufferedTxInner),
}
impl TxMode {
fn register(&self, arg: &core::task::Waker) {
match self {
TxMode::NonBuffered(waker) => {
waker.register(arg);
}
_ => {
panic!("Bad mode");
}
}
}
/// Queues the message to be sent but exerts backpressure. If a lower-priority
/// frame is dropped from the mailbox, it is returned. If no lower-priority frames
/// can be replaced, this call asynchronously waits for a frame to be successfully
/// transmitted, then tries again.
async fn write_generic<T: Instance, F: embedded_can::Frame + CanHeader>(&self, frame: &F) -> Option<F> {
poll_fn(|cx| {
self.register(cx.waker());
if let Ok(dropped) = T::registers().write(frame) {
return Poll::Ready(dropped);
}
// Couldn't replace any lower priority frames. Need to wait for some mailboxes
// to clear.
Poll::Pending
})
.await
}
/// Queues the message to be sent but exerts backpressure. If a lower-priority
/// frame is dropped from the mailbox, it is returned. If no lower-priority frames
/// can be replaced, this call asynchronously waits for a frame to be successfully
/// transmitted, then tries again.
async fn write<T: Instance>(&self, frame: &ClassicFrame) -> Option<ClassicFrame> {
self.write_generic::<T, _>(frame).await
}
/// Queues the message to be sent but exerts backpressure. If a lower-priority
/// frame is dropped from the mailbox, it is returned. If no lower-priority frames
/// can be replaced, this call asynchronously waits for a frame to be successfully
/// transmitted, then tries again.
async fn write_fd<T: Instance>(&self, frame: &FdFrame) -> Option<FdFrame> {
self.write_generic::<T, _>(frame).await
}
}
struct State {
pub rx_mode: RxMode,
pub tx_mode: TxMode,
pub ns_per_timer_tick: u64,
pub err_waker: AtomicWaker,
}
impl State {
const fn new() -> Self {
Self {
rx_mode: RxMode::NonBuffered(AtomicWaker::new()),
tx_mode: TxMode::NonBuffered(AtomicWaker::new()),
ns_per_timer_tick: 0,
err_waker: AtomicWaker::new(),
}
}
}
trait SealedInstance {
const MSG_RAM_OFFSET: usize;
fn regs() -> &'static crate::pac::can::Fdcan;
fn registers() -> crate::can::fd::peripheral::Registers;
fn state() -> &'static State;
unsafe fn mut_state() -> &'static mut State;
fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp;
}
/// Instance trait /// Instance trait
pub trait Instance: sealed::Instance + RccPeripheral + 'static { #[allow(private_bounds)]
pub trait Instance: SealedInstance + RccPeripheral + 'static {
/// Interrupt 0 /// Interrupt 0
type IT0Interrupt: crate::interrupt::typelevel::Interrupt; type IT0Interrupt: crate::interrupt::typelevel::Interrupt;
/// Interrupt 0 /// Interrupt 1
type IT1Interrupt: crate::interrupt::typelevel::Interrupt; type IT1Interrupt: crate::interrupt::typelevel::Interrupt;
} }
@ -871,7 +860,7 @@ pub struct FdcanInstance<'a, T>(PeripheralRef<'a, T>);
macro_rules! impl_fdcan { macro_rules! impl_fdcan {
($inst:ident, $msg_ram_inst:ident, $msg_ram_offset:literal) => { ($inst:ident, $msg_ram_inst:ident, $msg_ram_offset:literal) => {
impl sealed::Instance for peripherals::$inst { impl SealedInstance for peripherals::$inst {
const MSG_RAM_OFFSET: usize = $msg_ram_offset; const MSG_RAM_OFFSET: usize = $msg_ram_offset;
fn regs() -> &'static crate::pac::can::Fdcan { fn regs() -> &'static crate::pac::can::Fdcan {
@ -880,14 +869,11 @@ macro_rules! impl_fdcan {
fn registers() -> Registers { fn registers() -> Registers {
Registers{regs: &crate::pac::$inst, msgram: &crate::pac::$msg_ram_inst, msg_ram_offset: Self::MSG_RAM_OFFSET} Registers{regs: &crate::pac::$inst, msgram: &crate::pac::$msg_ram_inst, msg_ram_offset: Self::MSG_RAM_OFFSET}
} }
fn ram() -> &'static crate::pac::fdcanram::Fdcanram { unsafe fn mut_state() -> &'static mut State {
&crate::pac::$msg_ram_inst static mut STATE: State = State::new();
}
unsafe fn mut_state() -> &'static mut sealed::State {
static mut STATE: sealed::State = sealed::State::new();
&mut *core::ptr::addr_of_mut!(STATE) &mut *core::ptr::addr_of_mut!(STATE)
} }
fn state() -> &'static sealed::State { fn state() -> &'static State {
unsafe { peripherals::$inst::mut_state() } unsafe { peripherals::$inst::mut_state() }
} }

View File

@ -2,7 +2,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
use crate::pac::CRC as PAC_CRC; use crate::pac::CRC as PAC_CRC;
use crate::peripherals::CRC; use crate::peripherals::CRC;
use crate::rcc::sealed::RccPeripheral; use crate::rcc::SealedRccPeripheral;
use crate::Peripheral; use crate::Peripheral;
/// CRC driver. /// CRC driver.

View File

@ -3,7 +3,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
use crate::pac::crc::vals; use crate::pac::crc::vals;
use crate::pac::CRC as PAC_CRC; use crate::pac::CRC as PAC_CRC;
use crate::peripherals::CRC; use crate::peripherals::CRC;
use crate::rcc::sealed::RccPeripheral; use crate::rcc::SealedRccPeripheral;
use crate::Peripheral; use crate::Peripheral;
/// CRC driver. /// CRC driver.

View File

@ -1885,16 +1885,13 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
} }
} }
pub(crate) mod sealed { trait SealedInstance {
use super::*; fn regs() -> pac::cryp::Cryp;
pub trait Instance {
fn regs() -> pac::cryp::Cryp;
}
} }
/// CRYP instance trait. /// CRYP instance trait.
pub trait Instance: sealed::Instance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { #[allow(private_bounds)]
pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send {
/// Interrupt for this CRYP instance. /// Interrupt for this CRYP instance.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
@ -1905,7 +1902,7 @@ foreach_interrupt!(
type Interrupt = crate::interrupt::typelevel::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
impl sealed::Instance for peripherals::$inst { impl SealedInstance for peripherals::$inst {
fn regs() -> crate::pac::cryp::Cryp { fn regs() -> crate::pac::cryp::Cryp {
crate::pac::$inst crate::pac::$inst
} }

View File

@ -127,7 +127,7 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> {
pub fn new( pub fn new(
_peri: impl Peripheral<P = T> + 'd, _peri: impl Peripheral<P = T> + 'd,
dma: impl Peripheral<P = DMA> + 'd, dma: impl Peripheral<P = DMA> + 'd,
pin: impl Peripheral<P = impl DacPin<T, N> + crate::gpio::sealed::Pin> + 'd, pin: impl Peripheral<P = impl DacPin<T, N> + crate::gpio::Pin> + 'd,
) -> Self { ) -> Self {
into_ref!(dma, pin); into_ref!(dma, pin);
pin.set_as_analog(); pin.set_as_analog();
@ -392,8 +392,8 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> {
_peri: impl Peripheral<P = T> + 'd, _peri: impl Peripheral<P = T> + 'd,
dma_ch1: impl Peripheral<P = DMACh1> + 'd, dma_ch1: impl Peripheral<P = DMACh1> + 'd,
dma_ch2: impl Peripheral<P = DMACh2> + 'd, dma_ch2: impl Peripheral<P = DMACh2> + 'd,
pin_ch1: impl Peripheral<P = impl DacPin<T, 1> + crate::gpio::sealed::Pin> + 'd, pin_ch1: impl Peripheral<P = impl DacPin<T, 1> + crate::gpio::Pin> + 'd,
pin_ch2: impl Peripheral<P = impl DacPin<T, 2> + crate::gpio::sealed::Pin> + 'd, pin_ch2: impl Peripheral<P = impl DacPin<T, 2> + crate::gpio::Pin> + 'd,
) -> Self { ) -> Self {
into_ref!(dma_ch1, dma_ch2, pin_ch1, pin_ch2); into_ref!(dma_ch1, dma_ch2, pin_ch1, pin_ch2);
pin_ch1.set_as_analog(); pin_ch1.set_as_analog();
@ -488,14 +488,13 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> {
} }
} }
pub(crate) mod sealed { trait SealedInstance {
pub trait Instance { fn regs() -> &'static crate::pac::dac::Dac;
fn regs() -> &'static crate::pac::dac::Dac;
}
} }
/// DAC instance. /// DAC instance.
pub trait Instance: sealed::Instance + RccPeripheral + 'static {} #[allow(private_bounds)]
pub trait Instance: SealedInstance + RccPeripheral + 'static {}
dma_trait!(DacDma1, Instance); dma_trait!(DacDma1, Instance);
dma_trait!(DacDma2, Instance); dma_trait!(DacDma2, Instance);
@ -504,7 +503,7 @@ pub trait DacPin<T: Instance, const C: u8>: crate::gpio::Pin + 'static {}
foreach_peripheral!( foreach_peripheral!(
(dac, $inst:ident) => { (dac, $inst:ident) => {
impl crate::dac::sealed::Instance for peripherals::$inst { impl crate::dac::SealedInstance for peripherals::$inst {
fn regs() -> &'static crate::pac::dac::Dac { fn regs() -> &'static crate::pac::dac::Dac {
&crate::pac::$inst &crate::pac::$inst
} }

View File

@ -7,8 +7,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use crate::dma::Transfer; use crate::dma::Transfer;
use crate::gpio::sealed::AFType; use crate::gpio::{AFType, Speed};
use crate::gpio::Speed;
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::{interrupt, Peripheral}; use crate::{interrupt, Peripheral};
@ -431,14 +430,13 @@ where
} }
} }
mod sealed { trait SealedInstance: crate::rcc::RccPeripheral {
pub trait Instance: crate::rcc::RccPeripheral { fn regs(&self) -> crate::pac::dcmi::Dcmi;
fn regs(&self) -> crate::pac::dcmi::Dcmi;
}
} }
/// DCMI instance. /// DCMI instance.
pub trait Instance: sealed::Instance + 'static { #[allow(private_bounds)]
pub trait Instance: SealedInstance + 'static {
/// Interrupt for this instance. /// Interrupt for this instance.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
@ -465,7 +463,7 @@ pin_trait!(PixClkPin, Instance);
#[allow(unused)] #[allow(unused)]
macro_rules! impl_peripheral { macro_rules! impl_peripheral {
($inst:ident, $irq:ident) => { ($inst:ident, $irq:ident) => {
impl sealed::Instance for crate::peripherals::$inst { impl SealedInstance for crate::peripherals::$inst {
fn regs(&self) -> crate::pac::dcmi::Dcmi { fn regs(&self) -> crate::pac::dcmi::Dcmi {
crate::pac::$inst crate::pac::$inst
} }

View File

@ -19,9 +19,7 @@ pub(crate) fn configure_dmamux(info: &DmamuxInfo, request: u8) {
}); });
} }
pub(crate) mod dmamux_sealed { pub(crate) trait SealedMuxChannel {}
pub trait MuxChannel {}
}
/// DMAMUX1 instance. /// DMAMUX1 instance.
pub struct DMAMUX1; pub struct DMAMUX1;
@ -30,14 +28,15 @@ pub struct DMAMUX1;
pub struct DMAMUX2; pub struct DMAMUX2;
/// DMAMUX channel trait. /// DMAMUX channel trait.
pub trait MuxChannel: dmamux_sealed::MuxChannel { #[allow(private_bounds)]
pub trait MuxChannel: SealedMuxChannel {
/// DMAMUX instance this channel is on. /// DMAMUX instance this channel is on.
type Mux; type Mux;
} }
macro_rules! dmamux_channel_impl { macro_rules! dmamux_channel_impl {
($channel_peri:ident, $dmamux:ident) => { ($channel_peri:ident, $dmamux:ident) => {
impl crate::dma::dmamux_sealed::MuxChannel for crate::peripherals::$channel_peri {} impl crate::dma::SealedMuxChannel for crate::peripherals::$channel_peri {}
impl crate::dma::MuxChannel for crate::peripherals::$channel_peri { impl crate::dma::MuxChannel for crate::peripherals::$channel_peri {
type Mux = crate::dma::$dmamux; type Mux = crate::dma::$dmamux;
} }

View File

@ -39,18 +39,18 @@ pub type Request = u8;
#[cfg(not(any(dma_v2, bdma_v2, gpdma, dmamux)))] #[cfg(not(any(dma_v2, bdma_v2, gpdma, dmamux)))]
pub type Request = (); pub type Request = ();
pub(crate) mod sealed { pub(crate) trait SealedChannel {
pub trait Channel { fn id(&self) -> u8;
fn id(&self) -> u8; }
}
pub trait ChannelInterrupt { pub(crate) trait ChannelInterrupt {
#[cfg_attr(not(feature = "rt"), allow(unused))] #[cfg_attr(not(feature = "rt"), allow(unused))]
unsafe fn on_irq(); unsafe fn on_irq();
}
} }
/// DMA channel. /// DMA channel.
pub trait Channel: sealed::Channel + Peripheral<P = Self> + Into<AnyChannel> + 'static { #[allow(private_bounds)]
pub trait Channel: SealedChannel + Peripheral<P = Self> + Into<AnyChannel> + 'static {
/// Type-erase (degrade) this pin into an `AnyChannel`. /// Type-erase (degrade) this pin into an `AnyChannel`.
/// ///
/// This converts DMA channel singletons (`DMA1_CH3`, `DMA2_CH1`, ...), which /// This converts DMA channel singletons (`DMA1_CH3`, `DMA2_CH1`, ...), which
@ -64,12 +64,12 @@ pub trait Channel: sealed::Channel + Peripheral<P = Self> + Into<AnyChannel> + '
macro_rules! dma_channel_impl { macro_rules! dma_channel_impl {
($channel_peri:ident, $index:expr) => { ($channel_peri:ident, $index:expr) => {
impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri { impl crate::dma::SealedChannel for crate::peripherals::$channel_peri {
fn id(&self) -> u8 { fn id(&self) -> u8 {
$index $index
} }
} }
impl crate::dma::sealed::ChannelInterrupt for crate::peripherals::$channel_peri { impl crate::dma::ChannelInterrupt for crate::peripherals::$channel_peri {
unsafe fn on_irq() { unsafe fn on_irq() {
crate::dma::AnyChannel { id: $index }.on_irq(); crate::dma::AnyChannel { id: $index }.on_irq();
} }
@ -97,7 +97,7 @@ impl AnyChannel {
} }
} }
impl sealed::Channel for AnyChannel { impl SealedChannel for AnyChannel {
fn id(&self) -> u8 { fn id(&self) -> u8 {
self.id self.id
} }

View File

@ -20,14 +20,13 @@ impl WordSize {
} }
} }
mod sealed { trait SealedWord {}
pub trait Word {}
}
/// DMA word trait. /// DMA word trait.
/// ///
/// This is implemented for u8, u16, u32, etc. /// This is implemented for u8, u16, u32, etc.
pub trait Word: sealed::Word + Default + Copy + 'static { #[allow(private_bounds)]
pub trait Word: SealedWord + Default + Copy + 'static {
/// Word size /// Word size
fn size() -> WordSize; fn size() -> WordSize;
/// Amount of bits of this word size. /// Amount of bits of this word size.
@ -36,7 +35,7 @@ pub trait Word: sealed::Word + Default + Copy + 'static {
macro_rules! impl_word { macro_rules! impl_word {
(_, $T:ident, $bits:literal, $size:ident) => { (_, $T:ident, $bits:literal, $size:ident) => {
impl sealed::Word for $T {} impl SealedWord for $T {}
impl Word for $T { impl Word for $T {
fn bits() -> usize { fn bits() -> usize {
$bits $bits

View File

@ -177,16 +177,15 @@ pub unsafe trait PHY {
fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool; fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool;
} }
pub(crate) mod sealed { trait SealedInstance {
pub trait Instance { fn regs() -> crate::pac::eth::Eth;
fn regs() -> crate::pac::eth::Eth;
}
} }
/// Ethernet instance. /// Ethernet instance.
pub trait Instance: sealed::Instance + RccPeripheral + Send + 'static {} #[allow(private_bounds)]
pub trait Instance: SealedInstance + RccPeripheral + Send + 'static {}
impl sealed::Instance for crate::peripherals::ETH { impl SealedInstance for crate::peripherals::ETH {
fn regs() -> crate::pac::eth::Eth { fn regs() -> crate::pac::eth::Eth {
crate::pac::ETH crate::pac::ETH
} }

View File

@ -12,15 +12,14 @@ use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress
pub(crate) use self::rx_desc::{RDes, RDesRing}; pub(crate) use self::rx_desc::{RDes, RDesRing};
pub(crate) use self::tx_desc::{TDes, TDesRing}; pub(crate) use self::tx_desc::{TDes, TDesRing};
use super::*; use super::*;
use crate::gpio::sealed::{AFType, Pin as __GpioPin}; use crate::gpio::{AFType, AnyPin, SealedPin};
use crate::gpio::AnyPin;
use crate::interrupt::InterruptExt; use crate::interrupt::InterruptExt;
#[cfg(eth_v1a)] #[cfg(eth_v1a)]
use crate::pac::AFIO; use crate::pac::AFIO;
#[cfg(any(eth_v1b, eth_v1c))] #[cfg(any(eth_v1b, eth_v1c))]
use crate::pac::SYSCFG; use crate::pac::SYSCFG;
use crate::pac::{ETH, RCC}; use crate::pac::{ETH, RCC};
use crate::rcc::sealed::RccPeripheral; use crate::rcc::SealedRccPeripheral;
use crate::{interrupt, Peripheral}; use crate::{interrupt, Peripheral};
/// Interrupt handler. /// Interrupt handler.
@ -149,8 +148,8 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
#[cfg(any(eth_v1b, eth_v1c))] #[cfg(any(eth_v1b, eth_v1c))]
config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
let dma = ETH.ethernet_dma(); let dma = T::regs().ethernet_dma();
let mac = ETH.ethernet_mac(); let mac = T::regs().ethernet_mac();
// Reset and wait // Reset and wait
dma.dmabmr().modify(|w| w.set_sr(true)); dma.dmabmr().modify(|w| w.set_sr(true));
@ -192,7 +191,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
// TODO MTU size setting not found for v1 ethernet, check if correct // TODO MTU size setting not found for v1 ethernet, check if correct
let hclk = <T as RccPeripheral>::frequency(); let hclk = <T as SealedRccPeripheral>::frequency();
let hclk_mhz = hclk.0 / 1_000_000; let hclk_mhz = hclk.0 / 1_000_000;
// Set the MDC clock frequency in the range 1MHz - 2.5MHz // 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> {
fence(Ordering::SeqCst); fence(Ordering::SeqCst);
let mac = ETH.ethernet_mac(); let mac = T::regs().ethernet_mac();
let dma = ETH.ethernet_dma(); let dma = T::regs().ethernet_dma();
mac.maccr().modify(|w| { mac.maccr().modify(|w| {
w.set_re(true); w.set_re(true);
@ -275,7 +274,7 @@ pub struct EthernetStationManagement<T: Instance> {
unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> { unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 { fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 {
let mac = ETH.ethernet_mac(); let mac = T::regs().ethernet_mac();
mac.macmiiar().modify(|w| { mac.macmiiar().modify(|w| {
w.set_pa(phy_addr); w.set_pa(phy_addr);
@ -289,7 +288,7 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
} }
fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) { fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) {
let mac = ETH.ethernet_mac(); let mac = T::regs().ethernet_mac();
mac.macmiidr().write(|w| w.set_md(val)); mac.macmiidr().write(|w| w.set_md(val));
mac.macmiiar().modify(|w| { mac.macmiiar().modify(|w| {
@ -305,8 +304,8 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
impl<'d, T: Instance, P: PHY> Drop for Ethernet<'d, T, P> { impl<'d, T: Instance, P: PHY> Drop for Ethernet<'d, T, P> {
fn drop(&mut self) { fn drop(&mut self) {
let dma = ETH.ethernet_dma(); let dma = T::regs().ethernet_dma();
let mac = ETH.ethernet_mac(); let mac = T::regs().ethernet_mac();
// Disable the TX DMA and wait for any previous transmissions to be completed // Disable the TX DMA and wait for any previous transmissions to be completed
dma.dmaomr().modify(|w| w.set_st(St::STOPPED)); dma.dmaomr().modify(|w| w.set_st(St::STOPPED));

View File

@ -7,11 +7,10 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing};
use super::*; use super::*;
use crate::gpio::sealed::{AFType, Pin as _}; use crate::gpio::{AFType, AnyPin, SealedPin as _, Speed};
use crate::gpio::{AnyPin, Speed};
use crate::interrupt::InterruptExt; use crate::interrupt::InterruptExt;
use crate::pac::ETH; use crate::pac::ETH;
use crate::rcc::sealed::RccPeripheral; use crate::rcc::SealedRccPeripheral;
use crate::{interrupt, Peripheral}; use crate::{interrupt, Peripheral};
/// Interrupt handler. /// Interrupt handler.
@ -207,9 +206,9 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
phy: P, phy: P,
mac_addr: [u8; 6], mac_addr: [u8; 6],
) -> Self { ) -> Self {
let dma = ETH.ethernet_dma(); let dma = T::regs().ethernet_dma();
let mac = ETH.ethernet_mac(); let mac = T::regs().ethernet_mac();
let mtl = ETH.ethernet_mtl(); let mtl = T::regs().ethernet_mtl();
// Reset and wait // Reset and wait
dma.dmamr().modify(|w| w.set_swr(true)); dma.dmamr().modify(|w| w.set_swr(true));
@ -265,7 +264,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
w.set_rbsz(RX_BUFFER_SIZE as u16); w.set_rbsz(RX_BUFFER_SIZE as u16);
}); });
let hclk = <T as RccPeripheral>::frequency(); let hclk = <T as SealedRccPeripheral>::frequency();
let hclk_mhz = hclk.0 / 1_000_000; let hclk_mhz = hclk.0 / 1_000_000;
// Set the MDC clock frequency in the range 1MHz - 2.5MHz // 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> {
fence(Ordering::SeqCst); fence(Ordering::SeqCst);
let mac = ETH.ethernet_mac(); let mac = T::regs().ethernet_mac();
let mtl = ETH.ethernet_mtl(); let mtl = T::regs().ethernet_mtl();
let dma = ETH.ethernet_dma(); let dma = T::regs().ethernet_dma();
mac.maccr().modify(|w| { mac.maccr().modify(|w| {
w.set_re(true); w.set_re(true);
@ -334,7 +333,7 @@ pub struct EthernetStationManagement<T: Instance> {
unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> { unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 { fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 {
let mac = ETH.ethernet_mac(); let mac = T::regs().ethernet_mac();
mac.macmdioar().modify(|w| { mac.macmdioar().modify(|w| {
w.set_pa(phy_addr); w.set_pa(phy_addr);
@ -348,7 +347,7 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
} }
fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) { fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) {
let mac = ETH.ethernet_mac(); let mac = T::regs().ethernet_mac();
mac.macmdiodr().write(|w| w.set_md(val)); mac.macmdiodr().write(|w| w.set_md(val));
mac.macmdioar().modify(|w| { mac.macmdioar().modify(|w| {
@ -364,9 +363,9 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
impl<'d, T: Instance, P: PHY> Drop for Ethernet<'d, T, P> { impl<'d, T: Instance, P: PHY> Drop for Ethernet<'d, T, P> {
fn drop(&mut self) { fn drop(&mut self) {
let dma = ETH.ethernet_dma(); let dma = T::regs().ethernet_dma();
let mac = ETH.ethernet_mac(); let mac = T::regs().ethernet_mac();
let mtl = ETH.ethernet_mtl(); let mtl = T::regs().ethernet_mtl();
// Disable the TX DMA and wait for any previous transmissions to be completed // Disable the TX DMA and wait for any previous transmissions to be completed
dma.dmactx_cr().modify(|w| w.set_st(false)); dma.dmactx_cr().modify(|w| w.set_st(false));

View File

@ -330,12 +330,11 @@ macro_rules! impl_irq {
foreach_exti_irq!(impl_irq); foreach_exti_irq!(impl_irq);
pub(crate) mod sealed { trait SealedChannel {}
pub trait Channel {}
}
/// EXTI channel trait. /// EXTI channel trait.
pub trait Channel: sealed::Channel + Sized { #[allow(private_bounds)]
pub trait Channel: SealedChannel + Sized {
/// Get the EXTI channel number. /// Get the EXTI channel number.
fn number(&self) -> u8; fn number(&self) -> u8;
@ -359,7 +358,7 @@ pub struct AnyChannel {
} }
impl_peripheral!(AnyChannel); impl_peripheral!(AnyChannel);
impl sealed::Channel for AnyChannel {} impl SealedChannel for AnyChannel {}
impl Channel for AnyChannel { impl Channel for AnyChannel {
fn number(&self) -> u8 { fn number(&self) -> u8 {
self.number self.number
@ -368,7 +367,7 @@ impl Channel for AnyChannel {
macro_rules! impl_exti { macro_rules! impl_exti {
($type:ident, $number:expr) => { ($type:ident, $number:expr) => {
impl sealed::Channel for peripherals::$type {} impl SealedChannel for peripherals::$type {}
impl Channel for peripherals::$type { impl Channel for peripherals::$type {
fn number(&self) -> u8 { fn number(&self) -> u8 {
$number $number

View File

@ -3,8 +3,7 @@ use core::marker::PhantomData;
use embassy_hal_internal::into_ref; use embassy_hal_internal::into_ref;
use crate::gpio::sealed::AFType; use crate::gpio::{AFType, Pull, Speed};
use crate::gpio::{Pull, Speed};
use crate::Peripheral; use crate::Peripheral;
/// FMC driver /// FMC driver
@ -44,7 +43,7 @@ where
/// Get the kernel clock currently in use for this FMC instance. /// Get the kernel clock currently in use for this FMC instance.
pub fn source_clock_hz(&self) -> u32 { pub fn source_clock_hz(&self) -> u32 {
<T as crate::rcc::sealed::RccPeripheral>::frequency().0 <T as crate::rcc::SealedRccPeripheral>::frequency().0
} }
} }
@ -69,7 +68,7 @@ where
} }
fn source_clock_hz(&self) -> u32 { fn source_clock_hz(&self) -> u32 {
<T as crate::rcc::sealed::RccPeripheral>::frequency().0 <T as crate::rcc::SealedRccPeripheral>::frequency().0
} }
} }
@ -201,18 +200,17 @@ impl<'d, T: Instance> Fmc<'d, T> {
)); ));
} }
pub(crate) mod sealed { trait SealedInstance: crate::rcc::SealedRccPeripheral {
pub trait Instance: crate::rcc::sealed::RccPeripheral { const REGS: crate::pac::fmc::Fmc;
const REGS: crate::pac::fmc::Fmc;
}
} }
/// FMC instance trait. /// FMC instance trait.
pub trait Instance: sealed::Instance + 'static {} #[allow(private_bounds)]
pub trait Instance: SealedInstance + 'static {}
foreach_peripheral!( foreach_peripheral!(
(fmc, $inst:ident) => { (fmc, $inst:ident) => {
impl crate::fmc::sealed::Instance for crate::peripherals::$inst { impl crate::fmc::SealedInstance for crate::peripherals::$inst {
const REGS: crate::pac::fmc::Fmc = crate::pac::$inst; const REGS: crate::pac::fmc::Fmc = crate::pac::$inst;
} }
impl crate::fmc::Instance for crate::peripherals::$inst {} impl crate::fmc::Instance for crate::peripherals::$inst {}

View File

@ -6,7 +6,6 @@ use core::convert::Infallible;
use critical_section::CriticalSection; use critical_section::CriticalSection;
use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
use self::sealed::Pin as _;
use crate::pac::gpio::{self, vals}; use crate::pac::gpio::{self, vals};
use crate::{pac, peripherals, Peripheral}; use crate::{pac, peripherals, Peripheral};
@ -129,6 +128,18 @@ impl<'d> Flex<'d> {
}); });
} }
/// Put the pin into AF mode, unchecked.
///
/// This puts the pin into the AF mode, with the requested number, pull and speed. This is
/// completely unchecked, it can attach the pin to literally any peripheral, so use with care.
#[inline]
pub fn set_as_af_unchecked(&mut self, af_num: u8, af_type: AFType, pull: Pull, speed: Speed) {
critical_section::with(|_| {
self.pin.set_as_af_pull(af_num, af_type, pull);
self.pin.set_speed(speed);
});
}
/// Get whether the pin input level is high. /// Get whether the pin input level is high.
#[inline] #[inline]
pub fn is_high(&self) -> bool { pub fn is_high(&self) -> bool {
@ -508,172 +519,168 @@ pub enum OutputType {
OpenDrain, OpenDrain,
} }
impl From<OutputType> for sealed::AFType { impl From<OutputType> for AFType {
fn from(value: OutputType) -> Self { fn from(value: OutputType) -> Self {
match value { match value {
OutputType::OpenDrain => sealed::AFType::OutputOpenDrain, OutputType::OpenDrain => AFType::OutputOpenDrain,
OutputType::PushPull => sealed::AFType::OutputPushPull, OutputType::PushPull => AFType::OutputPushPull,
} }
} }
} }
#[allow(missing_docs)] /// Alternate function type settings
pub(crate) mod sealed { #[derive(Debug, Copy, Clone)]
use super::*; #[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum AFType {
/// Input
Input,
/// Output, drive the pin both high or low.
OutputPushPull,
/// Output, drive the pin low, or don't drive it at all if the output level is high.
OutputOpenDrain,
}
/// Alternate function type settings pub(crate) trait SealedPin {
#[derive(Debug, Copy, Clone)] fn pin_port(&self) -> u8;
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum AFType { #[inline]
/// Input fn _pin(&self) -> u8 {
Input, self.pin_port() % 16
/// Output, drive the pin both high or low. }
OutputPushPull, #[inline]
/// Output, drive the pin low, or don't drive it at all if the output level is high. fn _port(&self) -> u8 {
OutputOpenDrain, self.pin_port() / 16
} }
pub trait Pin { #[inline]
fn pin_port(&self) -> u8; fn block(&self) -> gpio::Gpio {
pac::GPIO(self._port() as _)
}
#[inline] /// Set the output as high.
fn _pin(&self) -> u8 { #[inline]
self.pin_port() % 16 fn set_high(&self) {
} let n = self._pin() as _;
#[inline] self.block().bsrr().write(|w| w.set_bs(n, true));
fn _port(&self) -> u8 { }
self.pin_port() / 16
}
#[inline] /// Set the output as low.
fn block(&self) -> gpio::Gpio { #[inline]
pac::GPIO(self._port() as _) fn set_low(&self) {
} let n = self._pin() as _;
self.block().bsrr().write(|w| w.set_br(n, true));
}
/// Set the output as high. #[inline]
#[inline] fn set_as_af(&self, af_num: u8, af_type: AFType) {
fn set_high(&self) { self.set_as_af_pull(af_num, af_type, Pull::None);
let n = self._pin() as _; }
self.block().bsrr().write(|w| w.set_bs(n, true));
}
/// Set the output as low. #[cfg(gpio_v1)]
#[inline] #[inline]
fn set_low(&self) { fn set_as_af_pull(&self, _af_num: u8, af_type: AFType, pull: Pull) {
let n = self._pin() as _; // F1 uses the AFIO register for remapping.
self.block().bsrr().write(|w| w.set_br(n, true)); // For now, this is not implemented, so af_num is ignored
} // _af_num should be zero here, since it is not set by stm32-data
let r = self.block();
let n = self._pin() as usize;
let crlh = if n < 8 { 0 } else { 1 };
match af_type {
AFType::Input => {
let cnf = match pull {
Pull::Up => {
r.bsrr().write(|w| w.set_bs(n, true));
vals::CnfIn::PULL
}
Pull::Down => {
r.bsrr().write(|w| w.set_br(n, true));
vals::CnfIn::PULL
}
Pull::None => vals::CnfIn::FLOATING,
};
#[inline] r.cr(crlh).modify(|w| {
fn set_as_af(&self, af_num: u8, af_type: AFType) { w.set_mode(n % 8, vals::Mode::INPUT);
self.set_as_af_pull(af_num, af_type, Pull::None); w.set_cnf_in(n % 8, cnf);
});
}
AFType::OutputPushPull => {
r.cr(crlh).modify(|w| {
w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ);
w.set_cnf_out(n % 8, vals::CnfOut::ALTPUSHPULL);
});
}
AFType::OutputOpenDrain => {
r.cr(crlh).modify(|w| {
w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ);
w.set_cnf_out(n % 8, vals::CnfOut::ALTOPENDRAIN);
});
}
} }
}
#[cfg(gpio_v2)]
#[inline]
fn set_as_af_pull(&self, af_num: u8, af_type: AFType, pull: Pull) {
let pin = self._pin() as usize;
let block = self.block();
block.afr(pin / 8).modify(|w| w.set_afr(pin % 8, af_num));
match af_type {
AFType::Input => {}
AFType::OutputPushPull => block.otyper().modify(|w| w.set_ot(pin, vals::Ot::PUSHPULL)),
AFType::OutputOpenDrain => block.otyper().modify(|w| w.set_ot(pin, vals::Ot::OPENDRAIN)),
}
block.pupdr().modify(|w| w.set_pupdr(pin, pull.into()));
block.moder().modify(|w| w.set_moder(pin, vals::Moder::ALTERNATE));
}
#[inline]
fn set_as_analog(&self) {
let pin = self._pin() as usize;
let block = self.block();
#[cfg(gpio_v1)]
{
let crlh = if pin < 8 { 0 } else { 1 };
block.cr(crlh).modify(|w| {
w.set_mode(pin % 8, vals::Mode::INPUT);
w.set_cnf_in(pin % 8, vals::CnfIn::ANALOG);
});
}
#[cfg(gpio_v2)]
block.moder().modify(|w| w.set_moder(pin, vals::Moder::ANALOG));
}
/// Set the pin as "disconnected", ie doing nothing and consuming the lowest
/// amount of power possible.
///
/// This is currently the same as set_as_analog but is semantically different really.
/// Drivers should set_as_disconnected pins when dropped.
#[inline]
fn set_as_disconnected(&self) {
self.set_as_analog();
}
#[inline]
fn set_speed(&self, speed: Speed) {
let pin = self._pin() as usize;
#[cfg(gpio_v1)] #[cfg(gpio_v1)]
#[inline] {
fn set_as_af_pull(&self, _af_num: u8, af_type: AFType, pull: Pull) { let crlh = if pin < 8 { 0 } else { 1 };
// F1 uses the AFIO register for remapping. self.block().cr(crlh).modify(|w| {
// For now, this is not implemented, so af_num is ignored w.set_mode(pin % 8, speed.into());
// _af_num should be zero here, since it is not set by stm32-data });
let r = self.block();
let n = self._pin() as usize;
let crlh = if n < 8 { 0 } else { 1 };
match af_type {
AFType::Input => {
let cnf = match pull {
Pull::Up => {
r.bsrr().write(|w| w.set_bs(n, true));
vals::CnfIn::PULL
}
Pull::Down => {
r.bsrr().write(|w| w.set_br(n, true));
vals::CnfIn::PULL
}
Pull::None => vals::CnfIn::FLOATING,
};
r.cr(crlh).modify(|w| {
w.set_mode(n % 8, vals::Mode::INPUT);
w.set_cnf_in(n % 8, cnf);
});
}
AFType::OutputPushPull => {
r.cr(crlh).modify(|w| {
w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ);
w.set_cnf_out(n % 8, vals::CnfOut::ALTPUSHPULL);
});
}
AFType::OutputOpenDrain => {
r.cr(crlh).modify(|w| {
w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ);
w.set_cnf_out(n % 8, vals::CnfOut::ALTOPENDRAIN);
});
}
}
} }
#[cfg(gpio_v2)] #[cfg(gpio_v2)]
#[inline] self.block().ospeedr().modify(|w| w.set_ospeedr(pin, speed.into()));
fn set_as_af_pull(&self, af_num: u8, af_type: AFType, pull: Pull) {
let pin = self._pin() as usize;
let block = self.block();
block.afr(pin / 8).modify(|w| w.set_afr(pin % 8, af_num));
match af_type {
AFType::Input => {}
AFType::OutputPushPull => block.otyper().modify(|w| w.set_ot(pin, vals::Ot::PUSHPULL)),
AFType::OutputOpenDrain => block.otyper().modify(|w| w.set_ot(pin, vals::Ot::OPENDRAIN)),
}
block.pupdr().modify(|w| w.set_pupdr(pin, pull.into()));
block.moder().modify(|w| w.set_moder(pin, vals::Moder::ALTERNATE));
}
#[inline]
fn set_as_analog(&self) {
let pin = self._pin() as usize;
let block = self.block();
#[cfg(gpio_v1)]
{
let crlh = if pin < 8 { 0 } else { 1 };
block.cr(crlh).modify(|w| {
w.set_mode(pin % 8, vals::Mode::INPUT);
w.set_cnf_in(pin % 8, vals::CnfIn::ANALOG);
});
}
#[cfg(gpio_v2)]
block.moder().modify(|w| w.set_moder(pin, vals::Moder::ANALOG));
}
/// Set the pin as "disconnected", ie doing nothing and consuming the lowest
/// amount of power possible.
///
/// This is currently the same as set_as_analog but is semantically different really.
/// Drivers should set_as_disconnected pins when dropped.
#[inline]
fn set_as_disconnected(&self) {
self.set_as_analog();
}
#[inline]
fn set_speed(&self, speed: Speed) {
let pin = self._pin() as usize;
#[cfg(gpio_v1)]
{
let crlh = if pin < 8 { 0 } else { 1 };
self.block().cr(crlh).modify(|w| {
w.set_mode(pin % 8, speed.into());
});
}
#[cfg(gpio_v2)]
self.block().ospeedr().modify(|w| w.set_ospeedr(pin, speed.into()));
}
} }
} }
/// GPIO pin trait. /// GPIO pin trait.
pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'static { #[allow(private_bounds)]
pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static {
/// EXTI channel assigned to this pin. /// EXTI channel assigned to this pin.
/// ///
/// For example, PC4 uses EXTI4. /// For example, PC4 uses EXTI4.
@ -737,7 +744,7 @@ impl Pin for AnyPin {
#[cfg(feature = "exti")] #[cfg(feature = "exti")]
type ExtiChannel = crate::exti::AnyChannel; type ExtiChannel = crate::exti::AnyChannel;
} }
impl sealed::Pin for AnyPin { impl SealedPin for AnyPin {
#[inline] #[inline]
fn pin_port(&self) -> u8 { fn pin_port(&self) -> u8 {
self.pin_port self.pin_port
@ -752,7 +759,7 @@ foreach_pin!(
#[cfg(feature = "exti")] #[cfg(feature = "exti")]
type ExtiChannel = peripherals::$exti_ch; type ExtiChannel = peripherals::$exti_ch;
} }
impl sealed::Pin for peripherals::$pin_name { impl SealedPin for peripherals::$pin_name {
#[inline] #[inline]
fn pin_port(&self) -> u8 { fn pin_port(&self) -> u8 {
$port_num * 16 + $pin_num $port_num * 16 + $pin_num
@ -769,7 +776,7 @@ foreach_pin!(
pub(crate) unsafe fn init(_cs: CriticalSection) { pub(crate) unsafe fn init(_cs: CriticalSection) {
#[cfg(afio)] #[cfg(afio)]
<crate::peripherals::AFIO as crate::rcc::sealed::RccPeripheral>::enable_and_reset_with_cs(_cs); <crate::peripherals::AFIO as crate::rcc::SealedRccPeripheral>::enable_and_reset_with_cs(_cs);
crate::_generated::init_gpio(); crate::_generated::init_gpio();
@ -1061,9 +1068,3 @@ impl<'d> embedded_hal_1::digital::StatefulOutputPin for Flex<'d> {
Ok((*self).is_set_low()) Ok((*self).is_set_low())
} }
} }
/// Low-level GPIO manipulation.
#[cfg(feature = "unstable-pac")]
pub mod low_level {
pub use super::sealed::*;
}

View File

@ -17,7 +17,7 @@ use crate::dma::NoDma;
use crate::dma::Transfer; use crate::dma::Transfer;
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::peripherals::HASH; use crate::peripherals::HASH;
use crate::rcc::sealed::RccPeripheral; use crate::rcc::SealedRccPeripheral;
use crate::{interrupt, pac, peripherals, Peripheral}; use crate::{interrupt, pac, peripherals, Peripheral};
#[cfg(hash_v1)] #[cfg(hash_v1)]
@ -561,16 +561,13 @@ impl<'d, T: Instance, D> Hash<'d, T, D> {
} }
} }
pub(crate) mod sealed { trait SealedInstance {
use super::*; fn regs() -> pac::hash::Hash;
pub trait Instance {
fn regs() -> pac::hash::Hash;
}
} }
/// HASH instance trait. /// HASH instance trait.
pub trait Instance: sealed::Instance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { #[allow(private_bounds)]
pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send {
/// Interrupt for this HASH instance. /// Interrupt for this HASH instance.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
@ -581,7 +578,7 @@ foreach_interrupt!(
type Interrupt = crate::interrupt::typelevel::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
impl sealed::Instance for peripherals::$inst { impl SealedInstance for peripherals::$inst {
fn regs() -> crate::pac::hash::Hash { fn regs() -> crate::pac::hash::Hash {
crate::pac::$inst crate::pac::$inst
} }

View File

@ -7,9 +7,7 @@ use core::marker::PhantomData;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{into_ref, PeripheralRef};
pub use traits::Instance; pub use traits::Instance;
#[allow(unused_imports)] use crate::gpio::{AFType, AnyPin};
use crate::gpio::sealed::{AFType, Pin};
use crate::gpio::AnyPin;
use crate::time::Hertz; use crate::time::Hertz;
use crate::Peripheral; use crate::Peripheral;
@ -54,16 +52,13 @@ pub struct ChF<T: Instance> {
phantom: PhantomData<T>, phantom: PhantomData<T>,
} }
mod sealed { trait SealedAdvancedChannel<T: Instance> {
use super::Instance; fn raw() -> usize;
pub trait AdvancedChannel<T: Instance> {
fn raw() -> usize;
}
} }
/// Advanced channel instance trait. /// Advanced channel instance trait.
pub trait AdvancedChannel<T: Instance>: sealed::AdvancedChannel<T> {} #[allow(private_bounds)]
pub trait AdvancedChannel<T: Instance>: SealedAdvancedChannel<T> {}
/// HRTIM PWM pin. /// HRTIM PWM pin.
pub struct PwmPin<'d, T, C> { pub struct PwmPin<'d, T, C> {
@ -113,7 +108,7 @@ macro_rules! advanced_channel_impl {
} }
} }
impl<T: Instance> sealed::AdvancedChannel<T> for $channel<T> { impl<T: Instance> SealedAdvancedChannel<T> for $channel<T> {
fn raw() -> usize { fn raw() -> usize {
$ch_num $ch_num
} }

View File

@ -1,4 +1,4 @@
use crate::rcc::sealed::RccPeripheral; use crate::rcc::RccPeripheral;
use crate::time::Hertz; use crate::time::Hertz;
#[repr(u8)] #[repr(u8)]
@ -72,94 +72,92 @@ impl Prescaler {
} }
} }
pub(crate) mod sealed { pub(crate) trait SealedInstance: RccPeripheral {
use super::*; fn regs() -> crate::pac::hrtim::Hrtim;
pub trait Instance: RccPeripheral { #[allow(unused)]
fn regs() -> crate::pac::hrtim::Hrtim; fn set_master_frequency(frequency: Hertz) {
let f = frequency.0;
fn set_master_frequency(frequency: Hertz) { // TODO: wire up HRTIM to the RCC mux infra.
let f = frequency.0; //#[cfg(stm32f334)]
//let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(Self::frequency()).0;
//#[cfg(not(stm32f334))]
let timer_f = Self::frequency().0;
// TODO: wire up HRTIM to the RCC mux infra. let psc_min = (timer_f / f) / (u16::MAX as u32 / 32);
//#[cfg(stm32f334)] let psc = if Self::regs().isr().read().dllrdy() {
//let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(Self::frequency()).0; Prescaler::compute_min_high_res(psc_min)
//#[cfg(not(stm32f334))] } else {
let timer_f = Self::frequency().0; Prescaler::compute_min_low_res(psc_min)
};
let psc_min = (timer_f / f) / (u16::MAX as u32 / 32); let timer_f = 32 * (timer_f / psc as u32);
let psc = if Self::regs().isr().read().dllrdy() { let per: u16 = (timer_f / f) as u16;
Prescaler::compute_min_high_res(psc_min)
} else {
Prescaler::compute_min_low_res(psc_min)
};
let timer_f = 32 * (timer_f / psc as u32); let regs = Self::regs();
let per: u16 = (timer_f / f) as u16;
let regs = Self::regs(); regs.mcr().modify(|w| w.set_ckpsc(psc.into()));
regs.mper().modify(|w| w.set_mper(per));
}
regs.mcr().modify(|w| w.set_ckpsc(psc.into())); fn set_channel_frequency(channel: usize, frequency: Hertz) {
regs.mper().modify(|w| w.set_mper(per)); let f = frequency.0;
}
fn set_channel_frequency(channel: usize, frequency: Hertz) { // TODO: wire up HRTIM to the RCC mux infra.
let f = frequency.0; //#[cfg(stm32f334)]
//let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(Self::frequency()).0;
//#[cfg(not(stm32f334))]
let timer_f = Self::frequency().0;
// TODO: wire up HRTIM to the RCC mux infra. let psc_min = (timer_f / f) / (u16::MAX as u32 / 32);
//#[cfg(stm32f334)] let psc = if Self::regs().isr().read().dllrdy() {
//let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(Self::frequency()).0; Prescaler::compute_min_high_res(psc_min)
//#[cfg(not(stm32f334))] } else {
let timer_f = Self::frequency().0; Prescaler::compute_min_low_res(psc_min)
};
let psc_min = (timer_f / f) / (u16::MAX as u32 / 32); let timer_f = 32 * (timer_f / psc as u32);
let psc = if Self::regs().isr().read().dllrdy() { let per: u16 = (timer_f / f) as u16;
Prescaler::compute_min_high_res(psc_min)
} else {
Prescaler::compute_min_low_res(psc_min)
};
let timer_f = 32 * (timer_f / psc as u32); let regs = Self::regs();
let per: u16 = (timer_f / f) as u16;
let regs = Self::regs(); regs.tim(channel).cr().modify(|w| w.set_ckpsc(psc.into()));
regs.tim(channel).per().modify(|w| w.set_per(per));
}
regs.tim(channel).cr().modify(|w| w.set_ckpsc(psc.into())); /// Set the dead time as a proportion of max_duty
regs.tim(channel).per().modify(|w| w.set_per(per)); fn set_channel_dead_time(channel: usize, dead_time: u16) {
} let regs = Self::regs();
/// Set the dead time as a proportion of max_duty let channel_psc: Prescaler = regs.tim(channel).cr().read().ckpsc().into();
fn set_channel_dead_time(channel: usize, dead_time: u16) {
let regs = Self::regs();
let channel_psc: Prescaler = regs.tim(channel).cr().read().ckpsc().into(); // The dead-time base clock runs 4 times slower than the hrtim base clock
// u9::MAX = 511
let psc_min = (channel_psc as u32 * dead_time as u32) / (4 * 511);
let psc = if Self::regs().isr().read().dllrdy() {
Prescaler::compute_min_high_res(psc_min)
} else {
Prescaler::compute_min_low_res(psc_min)
};
// The dead-time base clock runs 4 times slower than the hrtim base clock let dt_val = (psc as u32 * dead_time as u32) / (4 * channel_psc as u32);
// u9::MAX = 511
let psc_min = (channel_psc as u32 * dead_time as u32) / (4 * 511);
let psc = if Self::regs().isr().read().dllrdy() {
Prescaler::compute_min_high_res(psc_min)
} else {
Prescaler::compute_min_low_res(psc_min)
};
let dt_val = (psc as u32 * dead_time as u32) / (4 * channel_psc as u32); regs.tim(channel).dt().modify(|w| {
w.set_dtprsc(psc.into());
regs.tim(channel).dt().modify(|w| { w.set_dtf(dt_val as u16);
w.set_dtprsc(psc.into()); w.set_dtr(dt_val as u16);
w.set_dtf(dt_val as u16); });
w.set_dtr(dt_val as u16);
});
}
} }
} }
/// HRTIM instance trait. /// HRTIM instance trait.
pub trait Instance: sealed::Instance + 'static {} #[allow(private_bounds)]
pub trait Instance: SealedInstance + 'static {}
foreach_interrupt! { foreach_interrupt! {
($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => { ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => {
impl sealed::Instance for crate::peripherals::$inst { impl SealedInstance for crate::peripherals::$inst {
fn regs() -> crate::pac::hrtim::Hrtim { fn regs() -> crate::pac::hrtim::Hrtim {
crate::pac::$inst crate::pac::$inst
} }

View File

@ -14,8 +14,7 @@ use embassy_sync::waitqueue::AtomicWaker;
use embassy_time::{Duration, Instant}; use embassy_time::{Duration, Instant};
use crate::dma::NoDma; use crate::dma::NoDma;
use crate::gpio::sealed::AFType; use crate::gpio::{AFType, Pull};
use crate::gpio::Pull;
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::time::Hertz; use crate::time::Hertz;
use crate::{interrupt, peripherals}; use crate::{interrupt, peripherals};
@ -175,30 +174,27 @@ impl Timeout {
} }
} }
pub(crate) mod sealed { struct State {
use super::*; #[allow(unused)]
waker: AtomicWaker,
}
pub struct State { impl State {
#[allow(unused)] const fn new() -> Self {
pub waker: AtomicWaker, Self {
} waker: AtomicWaker::new(),
impl State {
pub const fn new() -> Self {
Self {
waker: AtomicWaker::new(),
}
} }
} }
}
pub trait Instance: crate::rcc::RccPeripheral {
fn regs() -> crate::pac::i2c::I2c; trait SealedInstance: crate::rcc::RccPeripheral {
fn state() -> &'static State; fn regs() -> crate::pac::i2c::I2c;
} fn state() -> &'static State;
} }
/// I2C peripheral instance /// I2C peripheral instance
pub trait Instance: sealed::Instance + 'static { #[allow(private_bounds)]
pub trait Instance: SealedInstance + 'static {
/// Event interrupt for this instance /// Event interrupt for this instance
type EventInterrupt: interrupt::typelevel::Interrupt; type EventInterrupt: interrupt::typelevel::Interrupt;
/// Error interrupt for this instance /// Error interrupt for this instance
@ -234,13 +230,13 @@ impl<T: Instance> interrupt::typelevel::Handler<T::ErrorInterrupt> for ErrorInte
foreach_peripheral!( foreach_peripheral!(
(i2c, $inst:ident) => { (i2c, $inst:ident) => {
impl sealed::Instance for peripherals::$inst { impl SealedInstance for peripherals::$inst {
fn regs() -> crate::pac::i2c::I2c { fn regs() -> crate::pac::i2c::I2c {
crate::pac::$inst crate::pac::$inst
} }
fn state() -> &'static sealed::State { fn state() -> &'static State {
static STATE: sealed::State = sealed::State::new(); static STATE: State = State::new();
&STATE &STATE
} }
} }

View File

@ -1,8 +1,7 @@
//! Inter-IC Sound (I2S) //! Inter-IC Sound (I2S)
use embassy_hal_internal::into_ref; use embassy_hal_internal::into_ref;
use crate::gpio::sealed::{AFType, Pin as _}; use crate::gpio::{AFType, AnyPin, SealedPin};
use crate::gpio::AnyPin;
use crate::pac::spi::vals; use crate::pac::spi::vals;
use crate::spi::{Config as SpiConfig, *}; use crate::spi::{Config as SpiConfig, *};
use crate::time::Hertz; use crate::time::Hertz;

View File

@ -4,11 +4,12 @@ use core::future::poll_fn;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use self::sealed::Instance; use embassy_sync::waitqueue::AtomicWaker;
use crate::interrupt; use crate::interrupt;
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::peripherals::IPCC; use crate::peripherals::IPCC;
use crate::rcc::sealed::RccPeripheral; use crate::rcc::SealedRccPeripheral;
/// Interrupt handler. /// Interrupt handler.
pub struct ReceiveInterruptHandler {} pub struct ReceiveInterruptHandler {}
@ -207,7 +208,7 @@ impl Ipcc {
} }
} }
impl sealed::Instance for crate::peripherals::IPCC { impl SealedInstance for crate::peripherals::IPCC {
fn regs() -> crate::pac::ipcc::Ipcc { fn regs() -> crate::pac::ipcc::Ipcc {
crate::pac::IPCC crate::pac::IPCC
} }
@ -216,58 +217,52 @@ impl sealed::Instance for crate::peripherals::IPCC {
crate::pac::PWR.cr4().modify(|w| w.set_c2boot(enabled)); crate::pac::PWR.cr4().modify(|w| w.set_c2boot(enabled));
} }
fn state() -> &'static self::sealed::State { fn state() -> &'static State {
static STATE: self::sealed::State = self::sealed::State::new(); static STATE: State = State::new();
&STATE &STATE
} }
} }
pub(crate) mod sealed { struct State {
use embassy_sync::waitqueue::AtomicWaker; rx_wakers: [AtomicWaker; 6],
tx_wakers: [AtomicWaker; 6],
}
use super::*; impl State {
const fn new() -> Self {
const WAKER: AtomicWaker = AtomicWaker::new();
pub struct State { Self {
rx_wakers: [AtomicWaker; 6], rx_wakers: [WAKER; 6],
tx_wakers: [AtomicWaker; 6], tx_wakers: [WAKER; 6],
}
impl State {
pub const fn new() -> Self {
const WAKER: AtomicWaker = AtomicWaker::new();
Self {
rx_wakers: [WAKER; 6],
tx_wakers: [WAKER; 6],
}
}
pub const fn rx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker {
match channel {
IpccChannel::Channel1 => &self.rx_wakers[0],
IpccChannel::Channel2 => &self.rx_wakers[1],
IpccChannel::Channel3 => &self.rx_wakers[2],
IpccChannel::Channel4 => &self.rx_wakers[3],
IpccChannel::Channel5 => &self.rx_wakers[4],
IpccChannel::Channel6 => &self.rx_wakers[5],
}
}
pub const fn tx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker {
match channel {
IpccChannel::Channel1 => &self.tx_wakers[0],
IpccChannel::Channel2 => &self.tx_wakers[1],
IpccChannel::Channel3 => &self.tx_wakers[2],
IpccChannel::Channel4 => &self.tx_wakers[3],
IpccChannel::Channel5 => &self.tx_wakers[4],
IpccChannel::Channel6 => &self.tx_wakers[5],
}
} }
} }
pub trait Instance: crate::rcc::RccPeripheral { const fn rx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker {
fn regs() -> crate::pac::ipcc::Ipcc; match channel {
fn set_cpu2(enabled: bool); IpccChannel::Channel1 => &self.rx_wakers[0],
fn state() -> &'static State; IpccChannel::Channel2 => &self.rx_wakers[1],
IpccChannel::Channel3 => &self.rx_wakers[2],
IpccChannel::Channel4 => &self.rx_wakers[3],
IpccChannel::Channel5 => &self.rx_wakers[4],
IpccChannel::Channel6 => &self.rx_wakers[5],
}
}
const fn tx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker {
match channel {
IpccChannel::Channel1 => &self.tx_wakers[0],
IpccChannel::Channel2 => &self.tx_wakers[1],
IpccChannel::Channel3 => &self.tx_wakers[2],
IpccChannel::Channel4 => &self.tx_wakers[3],
IpccChannel::Channel5 => &self.tx_wakers[4],
IpccChannel::Channel6 => &self.tx_wakers[5],
}
} }
} }
trait SealedInstance: crate::rcc::RccPeripheral {
fn regs() -> crate::pac::ipcc::Ipcc;
fn set_cpu2(enabled: bool);
fn state() -> &'static State;
}

View File

@ -158,7 +158,7 @@ pub(crate) use stm32_metapac as pac;
use crate::interrupt::Priority; use crate::interrupt::Priority;
#[cfg(feature = "rt")] #[cfg(feature = "rt")]
pub use crate::pac::NVIC_PRIO_BITS; pub use crate::pac::NVIC_PRIO_BITS;
use crate::rcc::sealed::RccPeripheral; use crate::rcc::SealedRccPeripheral;
/// `embassy-stm32` global configuration. /// `embassy-stm32` global configuration.
#[non_exhaustive] #[non_exhaustive]

View File

@ -81,8 +81,8 @@ impl<'d, T: Instance> OpAmp<'d, T> {
/// [`OpAmpOutput`] is dropped. /// [`OpAmpOutput`] is dropped.
pub fn buffer_ext( pub fn buffer_ext(
&'d mut self, &'d mut self,
in_pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::sealed::Pin>, in_pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::Pin>,
out_pin: impl Peripheral<P = impl OutputPin<T> + crate::gpio::sealed::Pin> + 'd, out_pin: impl Peripheral<P = impl OutputPin<T> + crate::gpio::Pin> + 'd,
gain: OpAmpGain, gain: OpAmpGain,
) -> OpAmpOutput<'d, T> { ) -> OpAmpOutput<'d, T> {
into_ref!(in_pin); into_ref!(in_pin);
@ -122,7 +122,7 @@ impl<'d, T: Instance> OpAmp<'d, T> {
#[cfg(opamp_g4)] #[cfg(opamp_g4)]
pub fn buffer_int( pub fn buffer_int(
&'d mut self, &'d mut self,
pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::sealed::Pin>, pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::Pin>,
gain: OpAmpGain, gain: OpAmpGain,
) -> OpAmpInternalOutput<'d, T> { ) -> OpAmpInternalOutput<'d, T> {
into_ref!(pin); into_ref!(pin);
@ -166,37 +166,39 @@ impl<'d, T: Instance> Drop for OpAmpInternalOutput<'d, T> {
} }
} }
/// Opamp instance trait. pub(crate) trait SealedInstance {
pub trait Instance: sealed::Instance + 'static {} fn regs() -> crate::pac::opamp::Opamp;
pub(crate) mod sealed {
pub trait Instance {
fn regs() -> crate::pac::opamp::Opamp;
}
pub trait NonInvertingPin<T: Instance> {
fn channel(&self) -> u8;
}
pub trait InvertingPin<T: Instance> {
fn channel(&self) -> u8;
}
pub trait OutputPin<T: Instance> {}
} }
pub(crate) trait SealedNonInvertingPin<T: Instance> {
fn channel(&self) -> u8;
}
pub(crate) trait SealedInvertingPin<T: Instance> {
#[allow(unused)]
fn channel(&self) -> u8;
}
pub(crate) trait SealedOutputPin<T: Instance> {}
/// Opamp instance trait.
#[allow(private_bounds)]
pub trait Instance: SealedInstance + 'static {}
/// Non-inverting pin trait. /// Non-inverting pin trait.
pub trait NonInvertingPin<T: Instance>: sealed::NonInvertingPin<T> {} #[allow(private_bounds)]
pub trait NonInvertingPin<T: Instance>: SealedNonInvertingPin<T> {}
/// Inverting pin trait. /// Inverting pin trait.
pub trait InvertingPin<T: Instance>: sealed::InvertingPin<T> {} #[allow(private_bounds)]
pub trait InvertingPin<T: Instance>: SealedInvertingPin<T> {}
/// Output pin trait. /// Output pin trait.
pub trait OutputPin<T: Instance>: sealed::OutputPin<T> {} #[allow(private_bounds)]
pub trait OutputPin<T: Instance>: SealedOutputPin<T> {}
macro_rules! impl_opamp_external_output { macro_rules! impl_opamp_external_output {
($inst:ident, $adc:ident, $ch:expr) => { ($inst:ident, $adc:ident, $ch:expr) => {
foreach_adc!( foreach_adc!(
($adc, $common_inst:ident, $adc_clock:ident) => { ($adc, $common_inst:ident, $adc_clock:ident) => {
impl<'d> crate::adc::sealed::AdcPin<crate::peripherals::$adc> impl<'d> crate::adc::SealedAdcPin<crate::peripherals::$adc>
for OpAmpOutput<'d, crate::peripherals::$inst> for OpAmpOutput<'d, crate::peripherals::$inst>
{ {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
@ -242,7 +244,7 @@ macro_rules! impl_opamp_internal_output {
($inst:ident, $adc:ident, $ch:expr) => { ($inst:ident, $adc:ident, $ch:expr) => {
foreach_adc!( foreach_adc!(
($adc, $common_inst:ident, $adc_clock:ident) => { ($adc, $common_inst:ident, $adc_clock:ident) => {
impl<'d> crate::adc::sealed::AdcPin<crate::peripherals::$adc> impl<'d> crate::adc::SealedAdcPin<crate::peripherals::$adc>
for OpAmpInternalOutput<'d, crate::peripherals::$inst> for OpAmpInternalOutput<'d, crate::peripherals::$inst>
{ {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
@ -291,7 +293,7 @@ foreach_peripheral!(
foreach_peripheral! { foreach_peripheral! {
(opamp, $inst:ident) => { (opamp, $inst:ident) => {
impl sealed::Instance for crate::peripherals::$inst { impl SealedInstance for crate::peripherals::$inst {
fn regs() -> crate::pac::opamp::Opamp { fn regs() -> crate::pac::opamp::Opamp {
crate::pac::$inst crate::pac::$inst
} }
@ -306,7 +308,7 @@ foreach_peripheral! {
macro_rules! impl_opamp_vp_pin { macro_rules! impl_opamp_vp_pin {
($inst:ident, $pin:ident, $ch:expr) => { ($inst:ident, $pin:ident, $ch:expr) => {
impl crate::opamp::NonInvertingPin<peripherals::$inst> for crate::peripherals::$pin {} impl crate::opamp::NonInvertingPin<peripherals::$inst> for crate::peripherals::$pin {}
impl crate::opamp::sealed::NonInvertingPin<peripherals::$inst> for crate::peripherals::$pin { impl crate::opamp::SealedNonInvertingPin<peripherals::$inst> for crate::peripherals::$pin {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
$ch $ch
} }
@ -318,6 +320,6 @@ macro_rules! impl_opamp_vp_pin {
macro_rules! impl_opamp_vout_pin { macro_rules! impl_opamp_vout_pin {
($inst:ident, $pin:ident) => { ($inst:ident, $pin:ident) => {
impl crate::opamp::OutputPin<peripherals::$inst> for crate::peripherals::$pin {} impl crate::opamp::OutputPin<peripherals::$inst> for crate::peripherals::$pin {}
impl crate::opamp::sealed::OutputPin<peripherals::$inst> for crate::peripherals::$pin {} impl crate::opamp::SealedOutputPin<peripherals::$inst> for crate::peripherals::$pin {}
}; };
} }

View File

@ -8,8 +8,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
use enums::*; use enums::*;
use crate::dma::Transfer; use crate::dma::Transfer;
use crate::gpio::sealed::AFType; use crate::gpio::{AFType, AnyPin, Pull};
use crate::gpio::{AnyPin, Pull};
use crate::pac::quadspi::Quadspi as Regs; use crate::pac::quadspi::Quadspi as Regs;
use crate::rcc::RccPeripheral; use crate::rcc::RccPeripheral;
use crate::{peripherals, Peripheral}; use crate::{peripherals, Peripheral};
@ -381,16 +380,13 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
} }
} }
pub(crate) mod sealed { trait SealedInstance {
use super::*; const REGS: Regs;
pub trait Instance {
const REGS: Regs;
}
} }
/// QSPI instance trait. /// QSPI instance trait.
pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {} #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {}
pin_trait!(SckPin, Instance); pin_trait!(SckPin, Instance);
pin_trait!(BK1D0Pin, Instance); pin_trait!(BK1D0Pin, Instance);
@ -409,7 +405,7 @@ dma_trait!(QuadDma, Instance);
foreach_peripheral!( foreach_peripheral!(
(quadspi, $inst:ident) => { (quadspi, $inst:ident) => {
impl sealed::Instance for peripherals::$inst { impl SealedInstance for peripherals::$inst {
const REGS: Regs = crate::pac::$inst; const REGS: Regs = crate::pac::$inst;
} }

View File

@ -2,7 +2,7 @@
use crate::pac::crs::vals::Syncsrc; use crate::pac::crs::vals::Syncsrc;
use crate::pac::{CRS, RCC}; use crate::pac::{CRS, RCC};
use crate::rcc::sealed::RccPeripheral; use crate::rcc::SealedRccPeripheral;
use crate::time::Hertz; use crate::time::Hertz;
/// HSI48 speed /// HSI48 speed

View File

@ -2,8 +2,7 @@ use core::marker::PhantomData;
use embassy_hal_internal::into_ref; use embassy_hal_internal::into_ref;
use crate::gpio::sealed::AFType; use crate::gpio::{AFType, Speed};
use crate::gpio::Speed;
#[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))] #[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))]
pub use crate::pac::rcc::vals::Mcopre as McoPrescaler; pub use crate::pac::rcc::vals::Mcopre as McoPrescaler;
#[cfg(not(any(rcc_f2, rcc_f410, rcc_f4, rcc_f7, rcc_h50, rcc_h5, rcc_h7ab, rcc_h7rm0433, rcc_h7)))] #[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 {
DIV1, DIV1,
} }
pub(crate) mod sealed { pub(crate) trait SealedMcoInstance {}
pub trait McoInstance {
type Source;
unsafe fn apply_clock_settings(source: Self::Source, prescaler: super::McoPrescaler);
}
}
pub trait McoInstance: sealed::McoInstance + 'static {} #[allow(private_bounds)]
pub trait McoInstance: SealedMcoInstance + 'static {
type Source;
#[doc(hidden)]
unsafe fn _apply_clock_settings(source: Self::Source, prescaler: super::McoPrescaler);
}
pin_trait!(McoPin, McoInstance); pin_trait!(McoPin, McoInstance);
macro_rules! impl_peri { macro_rules! impl_peri {
($peri:ident, $source:ident, $set_source:ident, $set_prescaler:ident) => { ($peri:ident, $source:ident, $set_source:ident, $set_prescaler:ident) => {
impl sealed::McoInstance for peripherals::$peri { impl SealedMcoInstance for peripherals::$peri {}
impl McoInstance for peripherals::$peri {
type Source = $source; type Source = $source;
unsafe fn apply_clock_settings(source: Self::Source, _prescaler: McoPrescaler) { unsafe fn _apply_clock_settings(source: Self::Source, _prescaler: McoPrescaler) {
#[cfg(not(any(stm32u5, stm32wba)))] #[cfg(not(any(stm32u5, stm32wba)))]
let r = RCC.cfgr(); let r = RCC.cfgr();
#[cfg(any(stm32u5, stm32wba))] #[cfg(any(stm32u5, stm32wba))]
@ -48,8 +49,6 @@ macro_rules! impl_peri {
}); });
} }
} }
impl McoInstance for peripherals::$peri {}
}; };
} }
@ -79,7 +78,7 @@ impl<'d, T: McoInstance> Mco<'d, T> {
into_ref!(pin); into_ref!(pin);
critical_section::with(|_| unsafe { critical_section::with(|_| unsafe {
T::apply_clock_settings(source, prescaler); T::_apply_clock_settings(source, prescaler);
pin.set_as_af(pin.af_num(), AFType::OutputPushPull); pin.set_as_af(pin.af_num(), AFType::OutputPushPull);
pin.set_speed(Speed::VeryHigh); pin.set_speed(Speed::VeryHigh);
}); });

View File

@ -10,6 +10,7 @@ pub use bd::*;
#[cfg(any(mco, mco1, mco2))] #[cfg(any(mco, mco1, mco2))]
mod mco; mod mco;
use critical_section::CriticalSection;
#[cfg(any(mco, mco1, mco2))] #[cfg(any(mco, mco1, mco2))]
pub use mco::*; pub use mco::*;
@ -32,6 +33,7 @@ mod _version;
pub use _version::*; pub use _version::*;
pub use crate::_generated::{mux, Clocks}; pub use crate::_generated::{mux, Clocks};
use crate::time::Hertz;
#[cfg(feature = "low-power")] #[cfg(feature = "low-power")]
/// Must be written within a critical section /// Must be written within a critical section
@ -63,29 +65,21 @@ pub(crate) unsafe fn get_freqs() -> &'static Clocks {
CLOCK_FREQS.assume_init_ref() CLOCK_FREQS.assume_init_ref()
} }
#[cfg(feature = "unstable-pac")] pub(crate) trait SealedRccPeripheral {
pub mod low_level { fn frequency() -> crate::time::Hertz;
pub use super::sealed::*; fn enable_and_reset_with_cs(cs: CriticalSection);
} fn disable_with_cs(cs: CriticalSection);
pub(crate) mod sealed { fn enable_and_reset() {
use critical_section::CriticalSection; critical_section::with(|cs| Self::enable_and_reset_with_cs(cs))
}
pub trait RccPeripheral { fn disable() {
fn frequency() -> crate::time::Hertz; critical_section::with(|cs| Self::disable_with_cs(cs))
fn enable_and_reset_with_cs(cs: CriticalSection);
fn disable_with_cs(cs: CriticalSection);
fn enable_and_reset() {
critical_section::with(|cs| Self::enable_and_reset_with_cs(cs))
}
fn disable() {
critical_section::with(|cs| Self::disable_with_cs(cs))
}
} }
} }
pub trait RccPeripheral: sealed::RccPeripheral + 'static {} #[allow(private_bounds)]
pub trait RccPeripheral: SealedRccPeripheral + 'static {}
#[allow(unused)] #[allow(unused)]
mod util { mod util {
@ -116,3 +110,12 @@ mod util {
Ok(Some(x)) Ok(Some(x))
} }
} }
/// Get the kernel clocok frequency of the peripheral `T`.
///
/// # Panics
///
/// Panics if the clock is not active.
pub fn frequency<T: RccPeripheral>() -> Hertz {
T::frequency()
}

View File

@ -222,16 +222,13 @@ impl<'d, T: Instance> RngCore for Rng<'d, T> {
impl<'d, T: Instance> CryptoRng for Rng<'d, T> {} impl<'d, T: Instance> CryptoRng for Rng<'d, T> {}
pub(crate) mod sealed { trait SealedInstance {
use super::*; fn regs() -> pac::rng::Rng;
pub trait Instance {
fn regs() -> pac::rng::Rng;
}
} }
/// RNG instance trait. /// RNG instance trait.
pub trait Instance: sealed::Instance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { #[allow(private_bounds)]
pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send {
/// Interrupt for this RNG instance. /// Interrupt for this RNG instance.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
@ -242,7 +239,7 @@ foreach_interrupt!(
type Interrupt = crate::interrupt::typelevel::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
impl sealed::Instance for peripherals::$inst { impl SealedInstance for peripherals::$inst {
fn regs() -> crate::pac::rng::Rng { fn regs() -> crate::pac::rng::Rng {
crate::pac::$inst crate::pac::$inst
} }

View File

@ -4,7 +4,7 @@ use chrono::{Datelike, NaiveDate, Timelike, Weekday};
#[cfg(any(feature = "defmt", feature = "time"))] #[cfg(any(feature = "defmt", feature = "time"))]
use crate::peripherals::RTC; use crate::peripherals::RTC;
#[cfg(any(feature = "defmt", feature = "time"))] #[cfg(any(feature = "defmt", feature = "time"))]
use crate::rtc::sealed::Instance; use crate::rtc::SealedInstance;
/// Represents an instant in time that can be substracted to compute a duration /// Represents an instant in time that can be substracted to compute a duration
pub struct RtcInstant { pub struct RtcInstant {

View File

@ -31,7 +31,6 @@ pub use _version::*;
use embassy_hal_internal::Peripheral; use embassy_hal_internal::Peripheral;
use crate::peripherals::RTC; use crate::peripherals::RTC;
use crate::rtc::sealed::Instance;
#[allow(dead_code)] #[allow(dead_code)]
#[repr(u8)] #[repr(u8)]
@ -212,7 +211,7 @@ impl Rtc {
/// Create a new RTC instance. /// Create a new RTC instance.
pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self {
#[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))] #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))]
<RTC as crate::rcc::sealed::RccPeripheral>::enable_and_reset(); <RTC as crate::rcc::SealedRccPeripheral>::enable_and_reset();
let mut this = Self { let mut this = Self {
#[cfg(feature = "low-power")] #[cfg(feature = "low-power")]
@ -437,7 +436,7 @@ impl Rtc {
.fpr(0) .fpr(0)
.modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
<RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend(); <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend();
}); });
} }
@ -449,8 +448,8 @@ impl Rtc {
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::pac::EXTI; use crate::pac::EXTI;
<RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend(); <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend();
unsafe { <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::enable() }; unsafe { <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::enable() };
EXTI.rtsr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); EXTI.rtsr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
EXTI.imr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); 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 {
tmp + (value & 0x0F) tmp + (value & 0x0F)
} }
pub(crate) mod sealed { trait SealedInstance {
use crate::pac::rtc::Rtc; const BACKUP_REGISTER_COUNT: usize;
pub trait Instance { #[cfg(feature = "low-power")]
const BACKUP_REGISTER_COUNT: usize; const EXTI_WAKEUP_LINE: usize;
#[cfg(feature = "low-power")] #[cfg(feature = "low-power")]
const EXTI_WAKEUP_LINE: usize; type WakeupInterrupt: crate::interrupt::typelevel::Interrupt;
#[cfg(feature = "low-power")] fn regs() -> crate::pac::rtc::Rtc {
type WakeupInterrupt: crate::interrupt::typelevel::Interrupt; crate::pac::RTC
fn regs() -> Rtc {
crate::pac::RTC
}
/// Read content of the backup register.
///
/// The registers retain their values during wakes from standby mode or system resets. They also
/// retain their value when Vdd is switched off as long as V_BAT is powered.
fn read_backup_register(rtc: &Rtc, register: usize) -> Option<u32>;
/// Set content of the backup register.
///
/// The registers retain their values during wakes from standby mode or system resets. They also
/// retain their value when Vdd is switched off as long as V_BAT is powered.
fn write_backup_register(rtc: &Rtc, register: usize, value: u32);
// fn apply_config(&mut self, rtc_config: RtcConfig);
} }
/// Read content of the backup register.
///
/// The registers retain their values during wakes from standby mode or system resets. They also
/// retain their value when Vdd is switched off as long as V_BAT is powered.
fn read_backup_register(rtc: &crate::pac::rtc::Rtc, register: usize) -> Option<u32>;
/// Set content of the backup register.
///
/// The registers retain their values during wakes from standby mode or system resets. They also
/// retain their value when Vdd is switched off as long as V_BAT is powered.
fn write_backup_register(rtc: &crate::pac::rtc::Rtc, register: usize, value: u32);
// fn apply_config(&mut self, rtc_config: RtcConfig);
} }

View File

@ -1,9 +1,8 @@
use stm32_metapac::rtc::vals::{Osel, Pol}; use stm32_metapac::rtc::vals::{Osel, Pol};
use super::sealed; use super::SealedInstance;
use crate::pac::rtc::Rtc; use crate::pac::rtc::Rtc;
use crate::peripherals::RTC; use crate::peripherals::RTC;
use crate::rtc::sealed::Instance;
#[allow(dead_code)] #[allow(dead_code)]
impl super::Rtc { impl super::Rtc {
@ -126,7 +125,7 @@ impl super::Rtc {
} }
} }
impl sealed::Instance for crate::peripherals::RTC { impl SealedInstance for crate::peripherals::RTC {
const BACKUP_REGISTER_COUNT: usize = 20; const BACKUP_REGISTER_COUNT: usize = 20;
#[cfg(all(feature = "low-power", stm32f4))] #[cfg(all(feature = "low-power", stm32f4))]

View File

@ -1,9 +1,9 @@
use stm32_metapac::rtc::vals::{Calp, Calw16, Calw8, Fmt, Key, Osel, Pol, TampalrmType}; use stm32_metapac::rtc::vals::{Calp, Calw16, Calw8, Fmt, Key, Osel, Pol, TampalrmType};
use super::{sealed, RtcCalibrationCyclePeriod}; use super::RtcCalibrationCyclePeriod;
use crate::pac::rtc::Rtc; use crate::pac::rtc::Rtc;
use crate::peripherals::RTC; use crate::peripherals::RTC;
use crate::rtc::sealed::Instance; use crate::rtc::SealedInstance;
impl super::Rtc { impl super::Rtc {
/// Applies the RTC config /// Applies the RTC config
@ -126,7 +126,7 @@ impl super::Rtc {
} }
} }
impl sealed::Instance for crate::peripherals::RTC { impl SealedInstance for crate::peripherals::RTC {
const BACKUP_REGISTER_COUNT: usize = 32; const BACKUP_REGISTER_COUNT: usize = 32;
#[cfg(all(feature = "low-power", stm32g4))] #[cfg(all(feature = "low-power", stm32g4))]

View File

@ -6,12 +6,10 @@ use core::marker::PhantomData;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{into_ref, PeripheralRef};
use self::sealed::WhichSubBlock;
pub use crate::dma::word; pub use crate::dma::word;
#[cfg(not(gpdma))] #[cfg(not(gpdma))]
use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer}; use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer};
use crate::gpio::sealed::{AFType, Pin as _}; use crate::gpio::{AFType, AnyPin, SealedPin as _};
use crate::gpio::AnyPin;
use crate::pac::sai::{vals, Sai as Regs}; use crate::pac::sai::{vals, Sai as Regs};
use crate::rcc::RccPeripheral; use crate::rcc::RccPeripheral;
use crate::{peripherals, Peripheral}; use crate::{peripherals, Peripheral};
@ -1041,43 +1039,42 @@ impl<'d, T: Instance, W: word::Word> Drop for Sai<'d, T, W> {
} }
} }
pub(crate) mod sealed { trait SealedInstance {
use super::*; const REGS: Regs;
}
pub trait Instance { #[derive(Copy, Clone)]
const REGS: Regs; enum WhichSubBlock {
} A = 0,
B = 1,
}
#[derive(Copy, Clone)] trait SealedSubBlock {
pub enum WhichSubBlock { const WHICH: WhichSubBlock;
A = 0,
B = 1,
}
pub trait SubBlock {
const WHICH: WhichSubBlock;
}
} }
/// Sub-block instance trait. /// Sub-block instance trait.
pub trait SubBlockInstance: sealed::SubBlock {} #[allow(private_bounds)]
pub trait SubBlockInstance: SealedSubBlock {}
/// Sub-block A. /// Sub-block A.
pub enum A {} pub enum A {}
impl sealed::SubBlock for A { impl SealedSubBlock for A {
const WHICH: WhichSubBlock = WhichSubBlock::A; const WHICH: WhichSubBlock = WhichSubBlock::A;
} }
impl SubBlockInstance for A {} impl SubBlockInstance for A {}
/// Sub-block B. /// Sub-block B.
pub enum B {} pub enum B {}
impl sealed::SubBlock for B { impl SealedSubBlock for B {
const WHICH: WhichSubBlock = WhichSubBlock::B; const WHICH: WhichSubBlock = WhichSubBlock::B;
} }
impl SubBlockInstance for B {} impl SubBlockInstance for B {}
/// SAI instance trait. /// SAI instance trait.
pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {} #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {}
pin_trait!(SckPin, Instance, SubBlockInstance); pin_trait!(SckPin, Instance, SubBlockInstance);
pin_trait!(FsPin, Instance, SubBlockInstance); pin_trait!(FsPin, Instance, SubBlockInstance);
pin_trait!(SdPin, Instance, SubBlockInstance); pin_trait!(SdPin, Instance, SubBlockInstance);
@ -1087,7 +1084,7 @@ dma_trait!(Dma, Instance, SubBlockInstance);
foreach_peripheral!( foreach_peripheral!(
(sai, $inst:ident) => { (sai, $inst:ident) => {
impl sealed::Instance for peripherals::$inst { impl SealedInstance for peripherals::$inst {
const REGS: Regs = crate::pac::$inst; const REGS: Regs = crate::pac::$inst;
} }

View File

@ -13,8 +13,7 @@ use embassy_sync::waitqueue::AtomicWaker;
use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR};
use crate::dma::NoDma; use crate::dma::NoDma;
use crate::gpio::sealed::{AFType, Pin}; use crate::gpio::{AFType, AnyPin, Pull, SealedPin, Speed};
use crate::gpio::{AnyPin, Pull, Speed};
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::pac::sdmmc::Sdmmc as RegBlock; use crate::pac::sdmmc::Sdmmc as RegBlock;
use crate::rcc::RccPeripheral; use crate::rcc::RccPeripheral;
@ -1418,19 +1417,17 @@ impl Cmd {
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
pub(crate) mod sealed { trait SealedInstance {
use super::*; fn regs() -> RegBlock;
fn state() -> &'static AtomicWaker;
pub trait Instance {
type Interrupt: interrupt::typelevel::Interrupt;
fn regs() -> RegBlock;
fn state() -> &'static AtomicWaker;
}
} }
/// SDMMC instance trait. /// SDMMC instance trait.
pub trait Instance: sealed::Instance + RccPeripheral + 'static {} #[allow(private_bounds)]
pub trait Instance: SealedInstance + RccPeripheral + 'static {
/// Interrupt for this instance.
type Interrupt: interrupt::typelevel::Interrupt;
}
pin_trait!(CkPin, Instance); pin_trait!(CkPin, Instance);
pin_trait!(CmdPin, Instance); pin_trait!(CmdPin, Instance);
@ -1457,9 +1454,7 @@ impl<T: Instance> SdmmcDma<T> for NoDma {}
foreach_peripheral!( foreach_peripheral!(
(sdmmc, $inst:ident) => { (sdmmc, $inst:ident) => {
impl sealed::Instance for peripherals::$inst { impl SealedInstance for peripherals::$inst {
type Interrupt = crate::interrupt::typelevel::$inst;
fn regs() -> RegBlock { fn regs() -> RegBlock {
crate::pac::$inst crate::pac::$inst
} }
@ -1470,6 +1465,8 @@ foreach_peripheral!(
} }
} }
impl Instance for peripherals::$inst {} impl Instance for peripherals::$inst {
type Interrupt = crate::interrupt::typelevel::$inst;
}
}; };
); );

View File

@ -9,8 +9,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
use crate::dma::{slice_ptr_parts, word, Transfer}; use crate::dma::{slice_ptr_parts, word, Transfer};
use crate::gpio::sealed::{AFType, Pin as _}; use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _};
use crate::gpio::{AnyPin, Pull};
use crate::pac::spi::{regs, vals, Spi as Regs}; use crate::pac::spi::{regs, vals, Spi as Regs};
use crate::rcc::RccPeripheral; use crate::rcc::RccPeripheral;
use crate::time::Hertz; use crate::time::Hertz;
@ -210,7 +209,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
// see RM0453 rev 1 section 7.2.13 page 291 // see RM0453 rev 1 section 7.2.13 page 291
// The SUBGHZSPI_SCK frequency is obtained by PCLK3 divided by two. // The SUBGHZSPI_SCK frequency is obtained by PCLK3 divided by two.
// The SUBGHZSPI_SCK clock maximum speed must not exceed 16 MHz. // The SUBGHZSPI_SCK clock maximum speed must not exceed 16 MHz.
let pclk3_freq = <peripherals::SUBGHZSPI as crate::rcc::sealed::RccPeripheral>::frequency().0; let pclk3_freq = <peripherals::SUBGHZSPI as crate::rcc::SealedRccPeripheral>::frequency().0;
let freq = Hertz(core::cmp::min(pclk3_freq / 2, 16_000_000)); let freq = Hertz(core::cmp::min(pclk3_freq / 2, 16_000_000));
let mut config = Config::default(); let mut config = Config::default();
config.mode = MODE_0; config.mode = MODE_0;
@ -271,13 +270,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
if mosi.is_none() { if mosi.is_none() {
w.set_rxonly(vals::Rxonly::OUTPUTDISABLED); w.set_rxonly(vals::Rxonly::OUTPUTDISABLED);
} }
w.set_dff(<u8 as sealed::Word>::CONFIG) w.set_dff(<u8 as SealedWord>::CONFIG)
}); });
} }
#[cfg(spi_v2)] #[cfg(spi_v2)]
{ {
T::REGS.cr2().modify(|w| { T::REGS.cr2().modify(|w| {
let (ds, frxth) = <u8 as sealed::Word>::CONFIG; let (ds, frxth) = <u8 as SealedWord>::CONFIG;
w.set_frxth(frxth); w.set_frxth(frxth);
w.set_ds(ds); w.set_ds(ds);
w.set_ssoe(false); w.set_ssoe(false);
@ -317,7 +316,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
T::REGS.cfg1().modify(|w| { T::REGS.cfg1().modify(|w| {
w.set_crcen(false); w.set_crcen(false);
w.set_mbr(br); w.set_mbr(br);
w.set_dsize(<u8 as sealed::Word>::CONFIG); w.set_dsize(<u8 as SealedWord>::CONFIG);
w.set_fthlv(vals::Fthlv::ONEFRAME); w.set_fthlv(vals::Fthlv::ONEFRAME);
}); });
T::REGS.cr2().modify(|w| { T::REGS.cr2().modify(|w| {
@ -336,7 +335,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
miso, miso,
txdma, txdma,
rxdma, rxdma,
current_word_size: <u8 as sealed::Word>::CONFIG, current_word_size: <u8 as SealedWord>::CONFIG,
} }
} }
@ -975,24 +974,21 @@ impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>, W: Word> embedded_hal_async::s
} }
} }
pub(crate) mod sealed { pub(crate) trait SealedInstance {
use super::*; const REGS: Regs;
}
pub trait Instance { trait SealedWord {
const REGS: Regs; const CONFIG: word_impl::Config;
}
pub trait Word {
const CONFIG: word_impl::Config;
}
} }
/// Word sizes usable for SPI. /// Word sizes usable for SPI.
pub trait Word: word::Word + sealed::Word {} #[allow(private_bounds)]
pub trait Word: word::Word + SealedWord {}
macro_rules! impl_word { macro_rules! impl_word {
($T:ty, $config:expr) => { ($T:ty, $config:expr) => {
impl sealed::Word for $T { impl SealedWord for $T {
const CONFIG: Config = $config; const CONFIG: Config = $config;
} }
impl Word for $T {} impl Word for $T {}
@ -1068,7 +1064,8 @@ mod word_impl {
} }
/// SPI instance trait. /// SPI instance trait.
pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {} #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {}
pin_trait!(SckPin, Instance); pin_trait!(SckPin, Instance);
pin_trait!(MosiPin, Instance); pin_trait!(MosiPin, Instance);
@ -1082,7 +1079,7 @@ dma_trait!(TxDma, Instance);
foreach_peripheral!( foreach_peripheral!(
(spi, $inst:ident) => { (spi, $inst:ident) => {
impl sealed::Instance for peripherals::$inst { impl SealedInstance for peripherals::$inst {
const REGS: Regs = crate::pac::$inst; const REGS: Regs = crate::pac::$inst;
} }

View File

@ -12,7 +12,7 @@ use stm32_metapac::timer::{regs, TimGp16};
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::pac::timer::vals; use crate::pac::timer::vals;
use crate::rcc::sealed::RccPeripheral; use crate::rcc::SealedRccPeripheral;
#[cfg(feature = "low-power")] #[cfg(feature = "low-power")]
use crate::rtc::Rtc; use crate::rtc::Rtc;
#[cfg(any(time_driver_tim1, time_driver_tim8, time_driver_tim20))] #[cfg(any(time_driver_tim1, time_driver_tim8, time_driver_tim20))]
@ -277,7 +277,7 @@ impl RtcDriver {
fn init(&'static self, cs: critical_section::CriticalSection) { fn init(&'static self, cs: critical_section::CriticalSection) {
let r = regs_gp16(); let r = regs_gp16();
<T as RccPeripheral>::enable_and_reset_with_cs(cs); <T as SealedRccPeripheral>::enable_and_reset_with_cs(cs);
let timer_freq = T::frequency(); let timer_freq = T::frequency();

View File

@ -7,8 +7,7 @@ use stm32_metapac::timer::vals;
use super::low_level::Timer; use super::low_level::Timer;
use super::{Channel1Pin, Channel2Pin, GeneralInstance4Channel}; use super::{Channel1Pin, Channel2Pin, GeneralInstance4Channel};
use crate::gpio::sealed::AFType; use crate::gpio::{AFType, AnyPin};
use crate::gpio::AnyPin;
use crate::Peripheral; use crate::Peripheral;
/// Counting direction /// Counting direction

View File

@ -16,11 +16,12 @@
use core::future::poll_fn; use core::future::poll_fn;
use core::marker::PhantomData; use core::marker::PhantomData;
use core::sync::atomic::Ordering; use core::sync::atomic::{AtomicBool, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker;
use crate::dma::{AnyChannel, Request, Transfer, TransferOptions}; use crate::dma::{AnyChannel, Request, Transfer, TransferOptions};
use crate::interrupt; use crate::interrupt;
@ -555,50 +556,47 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
} }
} }
/// UCPD instance trait. struct State {
pub trait Instance: sealed::Instance + RccPeripheral {} waker: AtomicWaker,
// Inverted logic for a default state of 0 so that the data goes into the .bss section.
drop_not_ready: AtomicBool,
}
mod sealed { impl State {
use core::sync::atomic::AtomicBool; pub const fn new() -> Self {
Self {
use embassy_sync::waitqueue::AtomicWaker; waker: AtomicWaker::new(),
drop_not_ready: AtomicBool::new(false),
pub struct State {
pub waker: AtomicWaker,
// Inverted logic for a default state of 0 so that the data goes into the .bss section.
pub drop_not_ready: AtomicBool,
}
impl State {
pub const fn new() -> Self {
Self {
waker: AtomicWaker::new(),
drop_not_ready: AtomicBool::new(false),
}
} }
} }
}
pub trait Instance { trait SealedInstance {
type Interrupt: crate::interrupt::typelevel::Interrupt; const REGS: crate::pac::ucpd::Ucpd;
const REGS: crate::pac::ucpd::Ucpd; fn state() -> &'static State;
fn state() -> &'static crate::ucpd::sealed::State; }
}
/// UCPD instance trait.
#[allow(private_bounds)]
pub trait Instance: SealedInstance + RccPeripheral {
/// Interrupt for this instance.
type Interrupt: crate::interrupt::typelevel::Interrupt;
} }
foreach_interrupt!( foreach_interrupt!(
($inst:ident, ucpd, UCPD, GLOBAL, $irq:ident) => { ($inst:ident, ucpd, UCPD, GLOBAL, $irq:ident) => {
impl sealed::Instance for crate::peripherals::$inst { impl SealedInstance for crate::peripherals::$inst {
type Interrupt = crate::interrupt::typelevel::$irq;
const REGS: crate::pac::ucpd::Ucpd = crate::pac::$inst; const REGS: crate::pac::ucpd::Ucpd = crate::pac::$inst;
fn state() -> &'static crate::ucpd::sealed::State { fn state() -> &'static State {
static STATE: crate::ucpd::sealed::State = crate::ucpd::sealed::State::new(); static STATE: State = State::new();
&STATE &STATE
} }
} }
impl Instance for crate::peripherals::$inst {} impl Instance for crate::peripherals::$inst {
type Interrupt = crate::interrupt::typelevel::$irq;
}
}; };
); );

View File

@ -10,10 +10,11 @@ use core::task::Poll;
use embassy_embedded_hal::SetConfig; use embassy_embedded_hal::SetConfig;
use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker;
use futures::future::{select, Either}; use futures::future::{select, Either};
use crate::dma::{NoDma, Transfer}; use crate::dma::{NoDma, Transfer};
use crate::gpio::sealed::AFType; use crate::gpio::AFType;
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
#[allow(unused_imports)] #[allow(unused_imports)]
#[cfg(not(any(usart_v1, usart_v2)))] #[cfg(not(any(usart_v1, usart_v2)))]
@ -1326,8 +1327,6 @@ mod ringbuffered;
#[cfg(not(gpdma))] #[cfg(not(gpdma))]
pub use ringbuffered::RingBufferedUartRx; pub use ringbuffered::RingBufferedUartRx;
use self::sealed::Kind;
#[cfg(any(usart_v1, usart_v2))] #[cfg(any(usart_v1, usart_v2))]
fn tdr(r: crate::pac::usart::Usart) -> *mut u8 { fn tdr(r: crate::pac::usart::Usart) -> *mut u8 {
r.dr().as_ptr() as _ r.dr().as_ptr() as _
@ -1370,52 +1369,50 @@ fn clear_interrupt_flags(r: Regs, sr: regs::Isr) {
r.icr().write(|w| *w = regs::Icr(sr.0)); r.icr().write(|w| *w = regs::Icr(sr.0));
} }
pub(crate) mod sealed { #[derive(Clone, Copy, PartialEq, Eq)]
use embassy_sync::waitqueue::AtomicWaker; enum Kind {
Uart,
#[cfg(any(usart_v3, usart_v4))]
#[allow(unused)]
Lpuart,
}
use super::*; struct State {
rx_waker: AtomicWaker,
}
#[derive(Clone, Copy, PartialEq, Eq)] impl State {
pub enum Kind { const fn new() -> Self {
Uart, Self {
#[cfg(any(usart_v3, usart_v4))] rx_waker: AtomicWaker::new(),
Lpuart,
}
pub struct State {
pub rx_waker: AtomicWaker,
pub tx_waker: AtomicWaker,
}
impl State {
pub const fn new() -> Self {
Self {
rx_waker: AtomicWaker::new(),
tx_waker: AtomicWaker::new(),
}
} }
} }
}
pub trait BasicInstance: crate::rcc::RccPeripheral {
const KIND: Kind; trait SealedBasicInstance: crate::rcc::RccPeripheral {
type Interrupt: interrupt::typelevel::Interrupt; const KIND: Kind;
fn regs() -> Regs; fn regs() -> Regs;
fn state() -> &'static State; fn state() -> &'static State;
fn buffered_state() -> &'static buffered::State; fn buffered_state() -> &'static buffered::State;
} }
pub trait FullInstance: BasicInstance { trait SealedFullInstance: SealedBasicInstance {
fn regs_uart() -> crate::pac::usart::Usart; #[allow(unused)]
} fn regs_uart() -> crate::pac::usart::Usart;
} }
/// Basic UART driver instance /// Basic UART driver instance
pub trait BasicInstance: Peripheral<P = Self> + sealed::BasicInstance + 'static + Send {} #[allow(private_bounds)]
pub trait BasicInstance: Peripheral<P = Self> + SealedBasicInstance + 'static + Send {
/// Interrupt for this instance.
type Interrupt: interrupt::typelevel::Interrupt;
}
/// Full UART driver instance /// Full UART driver instance
pub trait FullInstance: sealed::FullInstance {} #[allow(private_bounds)]
pub trait FullInstance: SealedFullInstance {}
pin_trait!(RxPin, BasicInstance); pin_trait!(RxPin, BasicInstance);
pin_trait!(TxPin, BasicInstance); pin_trait!(TxPin, BasicInstance);
@ -1429,16 +1426,15 @@ dma_trait!(RxDma, BasicInstance);
macro_rules! impl_usart { macro_rules! impl_usart {
($inst:ident, $irq:ident, $kind:expr) => { ($inst:ident, $irq:ident, $kind:expr) => {
impl sealed::BasicInstance for crate::peripherals::$inst { impl SealedBasicInstance for crate::peripherals::$inst {
const KIND: Kind = $kind; const KIND: Kind = $kind;
type Interrupt = crate::interrupt::typelevel::$irq;
fn regs() -> Regs { fn regs() -> Regs {
unsafe { Regs::from_ptr(crate::pac::$inst.as_ptr()) } unsafe { Regs::from_ptr(crate::pac::$inst.as_ptr()) }
} }
fn state() -> &'static crate::usart::sealed::State { fn state() -> &'static crate::usart::State {
static STATE: crate::usart::sealed::State = crate::usart::sealed::State::new(); static STATE: crate::usart::State = crate::usart::State::new();
&STATE &STATE
} }
@ -1448,7 +1444,9 @@ macro_rules! impl_usart {
} }
} }
impl BasicInstance for peripherals::$inst {} impl BasicInstance for peripherals::$inst {
type Interrupt = crate::interrupt::typelevel::$irq;
}
}; };
} }
@ -1460,7 +1458,7 @@ foreach_interrupt!(
($inst:ident, usart, $block:ident, $signal_name:ident, $irq:ident) => { ($inst:ident, usart, $block:ident, $signal_name:ident, $irq:ident) => {
impl_usart!($inst, $irq, Kind::Uart); impl_usart!($inst, $irq, Kind::Uart);
impl sealed::FullInstance for peripherals::$inst { impl SealedFullInstance for peripherals::$inst {
fn regs_uart() -> crate::pac::usart::Usart { fn regs_uart() -> crate::pac::usart::Usart {
crate::pac::$inst crate::pac::$inst
} }

View File

@ -6,7 +6,7 @@ mod _version;
pub use _version::*; pub use _version::*;
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::rcc::sealed::RccPeripheral; use crate::rcc::SealedRccPeripheral;
/// clock, power initialization stuff that's common for USB and OTG. /// clock, power initialization stuff that's common for USB and OTG.
fn common_init<T: Instance>() { fn common_init<T: Instance>() {
@ -65,5 +65,5 @@ fn common_init<T: Instance>() {
T::Interrupt::unpend(); T::Interrupt::unpend();
unsafe { T::Interrupt::enable() }; unsafe { T::Interrupt::enable() };
<T as RccPeripheral>::enable_and_reset(); <T as SealedRccPeripheral>::enable_and_reset();
} }

View File

@ -11,11 +11,11 @@ use embassy_usb_driver::{
}; };
use futures::future::poll_fn; use futures::future::poll_fn;
use crate::gpio::sealed::AFType; use crate::gpio::AFType;
use crate::interrupt; use crate::interrupt;
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::pac::otg::{regs, vals}; use crate::pac::otg::{regs, vals};
use crate::rcc::sealed::RccPeripheral; use crate::rcc::{RccPeripheral, SealedRccPeripheral};
use crate::time::Hertz; use crate::time::Hertz;
/// Interrupt handler. /// Interrupt handler.
@ -809,7 +809,7 @@ impl<'d, T: Instance> Bus<'d, T> {
fn disable(&mut self) { fn disable(&mut self) {
T::Interrupt::disable(); T::Interrupt::disable();
<T as RccPeripheral>::disable(); <T as SealedRccPeripheral>::disable();
#[cfg(stm32l4)] #[cfg(stm32l4)]
crate::pac::PWR.cr2().modify(|w| w.set_usv(false)); 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 {
// Using Instance::ENDPOINT_COUNT requires feature(const_generic_expr) so just define maximum eps // Using Instance::ENDPOINT_COUNT requires feature(const_generic_expr) so just define maximum eps
const MAX_EP_COUNT: usize = 9; const MAX_EP_COUNT: usize = 9;
pub(crate) mod sealed { trait SealedInstance {
pub trait Instance { const HIGH_SPEED: bool;
const HIGH_SPEED: bool; const FIFO_DEPTH_WORDS: u16;
const FIFO_DEPTH_WORDS: u16; const ENDPOINT_COUNT: usize;
const ENDPOINT_COUNT: usize;
fn regs() -> crate::pac::otg::Otg; fn regs() -> crate::pac::otg::Otg;
fn state() -> &'static super::State<{ super::MAX_EP_COUNT }>; fn state() -> &'static super::State<{ MAX_EP_COUNT }>;
}
} }
/// USB instance trait. /// USB instance trait.
pub trait Instance: sealed::Instance + RccPeripheral + 'static { #[allow(private_bounds)]
pub trait Instance: SealedInstance + RccPeripheral + 'static {
/// Interrupt for this USB instance. /// Interrupt for this USB instance.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
@ -1473,7 +1472,7 @@ pin_trait!(UlpiD7Pin, Instance);
foreach_interrupt!( foreach_interrupt!(
(USB_OTG_FS, otg, $block:ident, GLOBAL, $irq:ident) => { (USB_OTG_FS, otg, $block:ident, GLOBAL, $irq:ident) => {
impl sealed::Instance for crate::peripherals::USB_OTG_FS { impl SealedInstance for crate::peripherals::USB_OTG_FS {
const HIGH_SPEED: bool = false; const HIGH_SPEED: bool = false;
cfg_if::cfg_if! { cfg_if::cfg_if! {
@ -1538,7 +1537,7 @@ foreach_interrupt!(
}; };
(USB_OTG_HS, otg, $block:ident, GLOBAL, $irq:ident) => { (USB_OTG_HS, otg, $block:ident, GLOBAL, $irq:ident) => {
impl sealed::Instance for crate::peripherals::USB_OTG_HS { impl SealedInstance for crate::peripherals::USB_OTG_HS {
const HIGH_SPEED: bool = true; const HIGH_SPEED: bool = true;
cfg_if::cfg_if! { cfg_if::cfg_if! {

View File

@ -15,7 +15,7 @@ use embassy_usb_driver::{
use crate::pac::usb::regs; use crate::pac::usb::regs;
use crate::pac::usb::vals::{EpType, Stat}; use crate::pac::usb::vals::{EpType, Stat};
use crate::pac::USBRAM; use crate::pac::USBRAM;
use crate::rcc::sealed::RccPeripheral; use crate::rcc::RccPeripheral;
use crate::{interrupt, Peripheral}; use crate::{interrupt, Peripheral};
/// Interrupt handler. /// Interrupt handler.
@ -277,8 +277,8 @@ impl<'d, T: Instance> Driver<'d, T> {
#[cfg(not(stm32l1))] #[cfg(not(stm32l1))]
{ {
dp.set_as_af(dp.af_num(), crate::gpio::sealed::AFType::OutputPushPull); dp.set_as_af(dp.af_num(), crate::gpio::AFType::OutputPushPull);
dm.set_as_af(dm.af_num(), crate::gpio::sealed::AFType::OutputPushPull); dm.set_as_af(dm.af_num(), crate::gpio::AFType::OutputPushPull);
} }
#[cfg(stm32l1)] #[cfg(stm32l1)]
let _ = (dp, dm); // suppress "unused" warnings. let _ = (dp, dm); // suppress "unused" warnings.
@ -1037,14 +1037,13 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
} }
} }
pub(crate) mod sealed { trait SealedInstance {
pub trait Instance { fn regs() -> crate::pac::usb::Usb;
fn regs() -> crate::pac::usb::Usb;
}
} }
/// USB instance trait. /// USB instance trait.
pub trait Instance: sealed::Instance + RccPeripheral + 'static { #[allow(private_bounds)]
pub trait Instance: SealedInstance + RccPeripheral + 'static {
/// Interrupt for this USB instance. /// Interrupt for this USB instance.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
@ -1055,7 +1054,7 @@ pin_trait!(DmPin, Instance);
foreach_interrupt!( foreach_interrupt!(
($inst:ident, usb, $block:ident, LP, $irq:ident) => { ($inst:ident, usb, $block:ident, LP, $irq:ident) => {
impl sealed::Instance for crate::peripherals::$inst { impl SealedInstance for crate::peripherals::$inst {
fn regs() -> crate::pac::usb::Usb { fn regs() -> crate::pac::usb::Usb {
crate::pac::$inst crate::pac::$inst
} }

View File

@ -80,18 +80,17 @@ impl<'d, T: Instance> IndependentWatchdog<'d, T> {
} }
} }
mod sealed { trait SealedInstance {
pub trait Instance { fn regs() -> crate::pac::iwdg::Iwdg;
fn regs() -> crate::pac::iwdg::Iwdg;
}
} }
/// IWDG instance trait. /// IWDG instance trait.
pub trait Instance: sealed::Instance {} #[allow(private_bounds)]
pub trait Instance: SealedInstance {}
foreach_peripheral!( foreach_peripheral!(
(iwdg, $inst:ident) => { (iwdg, $inst:ident) => {
impl sealed::Instance for crate::peripherals::$inst { impl SealedInstance for crate::peripherals::$inst {
fn regs() -> crate::pac::iwdg::Iwdg { fn regs() -> crate::pac::iwdg::Iwdg {
crate::pac::$inst crate::pac::$inst
} }

View File

@ -6,7 +6,7 @@ use embassy_executor::Spawner;
use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray}; use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray};
use embassy_stm32::pac::timer::vals::Mms; use embassy_stm32::pac::timer::vals::Mms;
use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7};
use embassy_stm32::rcc::low_level::RccPeripheral; use embassy_stm32::rcc::frequency;
use embassy_stm32::time::Hertz; use embassy_stm32::time::Hertz;
use embassy_stm32::timer::low_level::Timer; use embassy_stm32::timer::low_level::Timer;
use micromath::F32Ext; use micromath::F32Ext;
@ -59,11 +59,11 @@ async fn main(spawner: Spawner) {
async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
let data: &[u8; 256] = &calculate_array::<256>(); let data: &[u8; 256] = &calculate_array::<256>();
info!("TIM6 frequency is {}", TIM6::frequency()); info!("TIM6 frequency is {}", frequency::<TIM6>());
const FREQUENCY: Hertz = Hertz::hz(200); const FREQUENCY: Hertz = Hertz::hz(200);
// Compute the reload value such that we obtain the FREQUENCY for the sine // Compute the reload value such that we obtain the FREQUENCY for the sine
let reload: u32 = (TIM6::frequency().0 / FREQUENCY.0) / data.len() as u32; let reload: u32 = (frequency::<TIM6>().0 / FREQUENCY.0) / data.len() as u32;
// Depends on your clock and on the specific chip used, you may need higher or lower values here // Depends on your clock and on the specific chip used, you may need higher or lower values here
if reload < 10 { if reload < 10 {
@ -84,7 +84,7 @@ async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
debug!( debug!(
"TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", "TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
TIM6::frequency(), frequency::<TIM6>(),
FREQUENCY, FREQUENCY,
reload, reload,
reload as u16, reload as u16,
@ -102,10 +102,10 @@ async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
let data: &[u8; 256] = &calculate_array::<256>(); let data: &[u8; 256] = &calculate_array::<256>();
info!("TIM7 frequency is {}", TIM7::frequency()); info!("TIM7 frequency is {}", frequency::<TIM6>());
const FREQUENCY: Hertz = Hertz::hz(600); const FREQUENCY: Hertz = Hertz::hz(600);
let reload: u32 = (TIM7::frequency().0 / FREQUENCY.0) / data.len() as u32; let reload: u32 = (frequency::<TIM7>().0 / FREQUENCY.0) / data.len() as u32;
if reload < 10 { if reload < 10 {
error!("Reload value {} below threshold!", reload); error!("Reload value {} below threshold!", reload);
@ -125,7 +125,7 @@ async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
debug!( debug!(
"TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
TIM7::frequency(), frequency::<TIM7>(),
FREQUENCY, FREQUENCY,
reload, reload,
reload as u16, reload as u16,

View File

@ -3,8 +3,7 @@
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::gpio::low_level::AFType; use embassy_stm32::gpio::{AFType, Flex, Pull, Speed};
use embassy_stm32::gpio::Speed;
use embassy_stm32::time::{khz, Hertz}; use embassy_stm32::time::{khz, Hertz};
use embassy_stm32::timer::low_level::{OutputCompareMode, Timer as LLTimer}; use embassy_stm32::timer::low_level::{OutputCompareMode, Timer as LLTimer};
use embassy_stm32::timer::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance32bit4Channel}; use embassy_stm32::timer::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance32bit4Channel};
@ -59,6 +58,10 @@ async fn main(_spawner: Spawner) {
} }
pub struct SimplePwm32<'d, T: GeneralInstance32bit4Channel> { pub struct SimplePwm32<'d, T: GeneralInstance32bit4Channel> {
tim: LLTimer<'d, T>, tim: LLTimer<'d, T>,
_ch1: Flex<'d>,
_ch2: Flex<'d>,
_ch3: Flex<'d>,
_ch4: Flex<'d>,
} }
impl<'d, T: GeneralInstance32bit4Channel> SimplePwm32<'d, T> { impl<'d, T: GeneralInstance32bit4Channel> SimplePwm32<'d, T> {
@ -72,16 +75,26 @@ impl<'d, T: GeneralInstance32bit4Channel> SimplePwm32<'d, T> {
) -> Self { ) -> Self {
into_ref!(ch1, ch2, ch3, ch4); into_ref!(ch1, ch2, ch3, ch4);
ch1.set_speed(Speed::VeryHigh); let af1 = ch1.af_num();
ch1.set_as_af(ch1.af_num(), AFType::OutputPushPull); let af2 = ch2.af_num();
ch2.set_speed(Speed::VeryHigh); let af3 = ch3.af_num();
ch2.set_as_af(ch1.af_num(), AFType::OutputPushPull); let af4 = ch4.af_num();
ch3.set_speed(Speed::VeryHigh); let mut ch1 = Flex::new(ch1);
ch3.set_as_af(ch1.af_num(), AFType::OutputPushPull); let mut ch2 = Flex::new(ch2);
ch4.set_speed(Speed::VeryHigh); let mut ch3 = Flex::new(ch3);
ch4.set_as_af(ch1.af_num(), AFType::OutputPushPull); let mut ch4 = Flex::new(ch4);
ch1.set_as_af_unchecked(af1, AFType::OutputPushPull, Pull::None, Speed::VeryHigh);
ch2.set_as_af_unchecked(af2, AFType::OutputPushPull, Pull::None, Speed::VeryHigh);
ch3.set_as_af_unchecked(af3, AFType::OutputPushPull, Pull::None, Speed::VeryHigh);
ch4.set_as_af_unchecked(af4, AFType::OutputPushPull, Pull::None, Speed::VeryHigh);
let mut this = Self { tim: LLTimer::new(tim) }; let mut this = Self {
tim: LLTimer::new(tim),
_ch1: ch1,
_ch2: ch2,
_ch3: ch3,
_ch4: ch4,
};
this.set_frequency(freq); this.set_frequency(freq);
this.tim.start(); this.tim.start();

View File

@ -6,7 +6,7 @@ use embassy_executor::Spawner;
use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray}; use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray};
use embassy_stm32::pac::timer::vals::Mms; use embassy_stm32::pac::timer::vals::Mms;
use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7};
use embassy_stm32::rcc::low_level::RccPeripheral; use embassy_stm32::rcc::frequency;
use embassy_stm32::time::Hertz; use embassy_stm32::time::Hertz;
use embassy_stm32::timer::low_level::Timer; use embassy_stm32::timer::low_level::Timer;
use micromath::F32Ext; use micromath::F32Ext;
@ -30,11 +30,11 @@ async fn main(spawner: Spawner) {
async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
let data: &[u8; 256] = &calculate_array::<256>(); let data: &[u8; 256] = &calculate_array::<256>();
info!("TIM6 frequency is {}", TIM6::frequency()); info!("TIM6 frequency is {}", frequency::<TIM6>());
const FREQUENCY: Hertz = Hertz::hz(200); const FREQUENCY: Hertz = Hertz::hz(200);
// Compute the reload value such that we obtain the FREQUENCY for the sine // Compute the reload value such that we obtain the FREQUENCY for the sine
let reload: u32 = (TIM6::frequency().0 / FREQUENCY.0) / data.len() as u32; let reload: u32 = (frequency::<TIM6>().0 / FREQUENCY.0) / data.len() as u32;
// Depends on your clock and on the specific chip used, you may need higher or lower values here // Depends on your clock and on the specific chip used, you may need higher or lower values here
if reload < 10 { if reload < 10 {
@ -55,7 +55,7 @@ async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
debug!( debug!(
"TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", "TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
TIM6::frequency(), frequency::<TIM6>(),
FREQUENCY, FREQUENCY,
reload, reload,
reload as u16, reload as u16,
@ -73,10 +73,10 @@ async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
let data: &[u8; 256] = &calculate_array::<256>(); let data: &[u8; 256] = &calculate_array::<256>();
info!("TIM7 frequency is {}", TIM7::frequency()); info!("TIM7 frequency is {}", frequency::<TIM7>());
const FREQUENCY: Hertz = Hertz::hz(600); const FREQUENCY: Hertz = Hertz::hz(600);
let reload: u32 = (TIM7::frequency().0 / FREQUENCY.0) / data.len() as u32; let reload: u32 = (frequency::<TIM7>().0 / FREQUENCY.0) / data.len() as u32;
if reload < 10 { if reload < 10 {
error!("Reload value {} below threshold!", reload); error!("Reload value {} below threshold!", reload);
@ -96,7 +96,7 @@ async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
debug!( debug!(
"TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
TIM7::frequency(), frequency::<TIM7>(),
FREQUENCY, FREQUENCY,
reload, reload,
reload as u16, reload as u16,