1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
use core::marker::PhantomData;
use embassy_hal_internal::PeripheralType;
use crate::gpio::{AfType, OutputType, Speed};
use crate::pac::RCC;
#[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))]
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,
rcc_h7rs,
rcc_n6
)))]
pub use crate::pac::rcc::vals::Mcosel as McoSource;
#[cfg(any(
rcc_f2,
rcc_f410,
rcc_f4,
rcc_f7,
rcc_h50,
rcc_h5,
rcc_h7ab,
rcc_h7rm0433,
rcc_h7,
rcc_h7rs,
rcc_n6
))]
pub use crate::pac::rcc::vals::{Mco1sel as Mco1Source, Mco2sel as Mco2Source};
use crate::{Peri, peripherals};
#[cfg(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37))]
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub enum McoPrescaler {
DIV1,
}
pub(crate) trait SealedMcoInstance {}
#[allow(private_bounds)]
pub trait McoInstance: PeripheralType + SealedMcoInstance + 'static {
type Source;
#[doc(hidden)]
unsafe fn _apply_clock_settings(source: Self::Source, prescaler: super::McoPrescaler);
}
pin_trait!(McoPin, McoInstance);
macro_rules! impl_peri {
($peri:ident, $source:ident, $set_source:ident, $set_prescaler:ident) => {
impl SealedMcoInstance for peripherals::$peri {}
impl McoInstance for peripherals::$peri {
type Source = $source;
unsafe fn _apply_clock_settings(source: Self::Source, _prescaler: McoPrescaler) {
#[cfg(not(any(stm32u5, stm32wba, stm32n6)))]
let r = RCC.cfgr();
#[cfg(any(stm32u5, stm32wba))]
let r = RCC.cfgr1();
#[cfg(any(stm32n6))]
let r = RCC.ccipr5();
r.modify(|w| {
w.$set_source(source);
#[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))]
w.$set_prescaler(_prescaler);
});
}
}
};
}
#[cfg(any(rcc_c0, rcc_c0v2, rcc_g0x0, rcc_g0x1, rcc_u0))]
#[allow(unused_imports)]
use self::{McoSource as Mco1Source, McoSource as Mco2Source};
#[cfg(mco)]
impl_peri!(MCO, McoSource, set_mcosel, set_mcopre);
#[cfg(mco1)]
impl_peri!(MCO1, Mco1Source, set_mco1sel, set_mco1pre);
#[cfg(mco2)]
impl_peri!(MCO2, Mco2Source, set_mco2sel, set_mco2pre);
pub struct Mco<'d, T: McoInstance> {
phantom: PhantomData<&'d mut T>,
}
impl<'d, T: McoInstance> Mco<'d, T> {
/// Create a new MCO instance.
pub fn new(_peri: Peri<'d, T>, pin: Peri<'d, impl McoPin<T>>, source: T::Source, config: McoConfig) -> Self {
critical_section::with(|_| unsafe {
T::_apply_clock_settings(source, config.prescaler);
set_as_af!(pin, AfType::output(OutputType::PushPull, config.speed));
});
Self { phantom: PhantomData }
}
}
#[non_exhaustive]
pub struct McoConfig {
/// Master Clock Out prescaler
pub prescaler: McoPrescaler,
/// IO Drive Strength
pub speed: Speed,
}
impl Default for McoConfig {
fn default() -> Self {
Self {
prescaler: McoPrescaler::DIV1,
speed: Speed::VeryHigh,
}
}
}
|