stm32g0xx_hal/rcc/
clockout.rs

1use crate::gpio::*;
2use crate::rcc::*;
3use crate::stm32::RCC;
4
5pub type LscoPin = PA2<DefaultMode>;
6
7pub struct Lsco {
8    pin: LscoPin,
9}
10
11impl Lsco {
12    pub fn enable(&self) {
13        let rcc = unsafe { &(*RCC::ptr()) };
14        rcc.bdcr.modify(|_, w| w.lscoen().set_bit());
15    }
16
17    pub fn disable(&self) {
18        let rcc = unsafe { &(*RCC::ptr()) };
19        rcc.bdcr.modify(|_, w| w.lscoen().clear_bit());
20    }
21
22    pub fn release(self) -> LscoPin {
23        self.pin.into_analog()
24    }
25}
26
27pub trait LSCOExt {
28    fn lsco(self, src: LSCOSrc, rcc: &mut Rcc) -> Lsco;
29}
30
31impl LSCOExt for LscoPin {
32    fn lsco(self, src: LSCOSrc, rcc: &mut Rcc) -> Lsco {
33        let src_select_bit = match src {
34            LSCOSrc::LSE => {
35                rcc.enable_lse(false);
36                true
37            }
38            LSCOSrc::LSI => {
39                rcc.enable_lsi();
40                false
41            }
42        };
43        rcc.unlock_rtc();
44        self.set_alt_mode(AltFunction::AF0);
45        rcc.bdcr.modify(|_, w| w.lscosel().bit(src_select_bit));
46        Lsco { pin: self }
47    }
48}
49
50pub struct Mco<PIN> {
51    pin: PIN,
52    src_bits: u8,
53}
54
55impl<PIN> Mco<PIN>
56where
57    PIN: MCOExt<PIN>,
58{
59    pub fn enable(&self) {
60        let rcc = unsafe { &(*RCC::ptr()) };
61        rcc.cfgr
62            .modify(|_, w| unsafe { w.mcosel().bits(self.src_bits) });
63    }
64
65    pub fn disable(&self) {
66        let rcc = unsafe { &(*RCC::ptr()) };
67        rcc.cfgr.modify(|_, w| unsafe { w.mcosel().bits(0) });
68    }
69
70    pub fn release(self) -> PIN {
71        self.pin.release()
72    }
73}
74
75pub trait MCOExt<PIN> {
76    fn mco(self, src: MCOSrc, psc: Prescaler, rcc: &mut Rcc) -> Mco<PIN>;
77    fn release(self) -> PIN;
78}
79
80macro_rules! mco {
81    ($($PIN:ty),+) => {
82        $(
83            impl MCOExt<$PIN> for $PIN {
84                fn mco(self, src: MCOSrc, psc: Prescaler, rcc: &mut Rcc) -> Mco<$PIN> {
85                    let psc_bits = match psc {
86                        Prescaler::NotDivided => 0b000,
87                        Prescaler::Div2 => 0b001,
88                        Prescaler::Div4 => 0b010,
89                        Prescaler::Div8 => 0b011,
90                        Prescaler::Div16 => 0b100,
91                        Prescaler::Div32 => 0b101,
92                        Prescaler::Div64 => 0b110,
93                        _ => 0b111,
94                    };
95
96                    rcc.cfgr.modify(|r, w| unsafe {
97                        w.bits((r.bits() & !(0b111 << 28)) | (psc_bits << 28))
98                    });
99
100                    let src_bits = match src {
101                        MCOSrc::SysClk => 0b001,
102                        MCOSrc::HSI => {
103                            rcc.enable_hsi();
104                            0b011
105                        },
106                        MCOSrc::HSE => {
107                            rcc.enable_hse(false);
108                            0b100
109                        },
110                        MCOSrc::PLL => 0b101,
111                        MCOSrc::LSI => {
112                            rcc.enable_lsi();
113                            0b110
114                        },
115                        MCOSrc::LSE => {
116                            rcc.enable_lse(false);
117                            0b111
118                        },
119                    };
120
121                    self.set_alt_mode(AltFunction::AF0);
122                    Mco { src_bits, pin: self }
123                }
124
125                fn release(self) -> $PIN {
126                    self.into_analog()
127                }
128            }
129        )+
130    };
131}
132
133mco!(PA8<DefaultMode>, PA9<DefaultMode>, PF2<DefaultMode>);