Skip to content

Commit 89d1e6f

Browse files
authored
rcc: add LSCO functionality
1 parent 2c2b082 commit 89d1e6f

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [Unreleased]
8+
### Added
9+
- Added `rcc::Lsco` to use the low-speed oscillator output.
10+
711
## [0.5.1] - 2022-05-14
812
### Added
913
- Added `Rtc::alarm_{a,b}` to get the alarm value.

hal/src/gpio.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ pub(crate) mod sealed {
265265
af_trait!(Tim17Ch1, set_tim17_ch1_af);
266266
af_trait!(Tim17Bkin, set_tim17_bkin_af);
267267
af_trait!(Tim17Ch1n, set_tim17_ch1n_af);
268+
af_trait!(Lsco, set_lsco_af);
268269

269270
/// Indicate a GPIO pin can be sampled by the ADC.
270271
pub trait AdcCh {
@@ -592,6 +593,8 @@ pub mod pins {
592593
};
593594
}
594595

596+
impl_af!(Lsco, A2, set_lsco_af, 0);
597+
595598
impl_af!(LpTim1Out, A4, set_lptim1_out_af, 1);
596599
impl_af!(LpTim1Out, A14, set_lptim1_out_af, 1);
597600
impl_af!(LpTim1Out, B2, set_lptim1_out_af, 1);

hal/src/rcc.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::{pac, Ratio};
1010
use cortex_m::{interrupt::CriticalSection, peripheral::syst::SystClkSource};
1111

1212
use pac::flash::acr::LATENCY_A;
13+
pub use pac::rcc::bdcr::LSCOSEL_A as LscoSel;
1314
pub use pac::rcc::csr::LSIPRE_A as LsiPre;
1415

1516
fn hclk3_prescaler_div(rcc: &pac::RCC) -> u16 {
@@ -959,3 +960,101 @@ pub unsafe fn pulse_reset_backup_domain(rcc: &mut pac::RCC, pwr: &mut pac::PWR)
959960
rcc.bdcr.modify(|_, w| w.bdrst().set_bit());
960961
rcc.bdcr.modify(|_, w| w.bdrst().clear_bit());
961962
}
963+
964+
/// Low-speed oscillator output pin.
965+
#[derive(Debug)]
966+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
967+
pub struct Lsco {
968+
pin: crate::gpio::pins::A2,
969+
}
970+
971+
impl Lsco {
972+
/// Enable the low-speed oscillator output.
973+
///
974+
/// # Safety
975+
///
976+
/// 1. Backup domain write protect must be disabled.
977+
/// 2. The selected clock must be enabled for system use.
978+
///
979+
/// # Example
980+
///
981+
/// ```no_run
982+
/// use stm32wlxx_hal::{
983+
/// gpio::PortA,
984+
/// pac,
985+
/// rcc::{Lsco, LscoSel},
986+
/// };
987+
///
988+
/// let mut dp: pac::Peripherals = pac::Peripherals::take().unwrap();
989+
///
990+
/// // disable backup domain write protect
991+
/// dp.PWR.cr1.modify(|_, w| w.dbp().enabled());
992+
///
993+
/// // enable the LSE clock
994+
/// dp.RCC
995+
/// .bdcr
996+
/// .modify(|_, w| w.lseon().on().lsesysen().enabled());
997+
/// while dp.RCC.bdcr.read().lserdy().is_not_ready() {}
998+
/// while dp.RCC.bdcr.read().lsesysrdy().is_not_ready() {}
999+
///
1000+
/// let gpioa: PortA = PortA::split(dp.GPIOA, &mut dp.RCC);
1001+
/// let a2: Lsco = cortex_m::interrupt::free(|cs| unsafe {
1002+
/// Lsco::enable(gpioa.a2, LscoSel::LSE, &mut dp.RCC, cs)
1003+
/// });
1004+
/// ```
1005+
#[inline]
1006+
pub unsafe fn enable(
1007+
mut a2: crate::gpio::pins::A2,
1008+
sel: LscoSel,
1009+
rcc: &mut pac::RCC,
1010+
cs: &CriticalSection,
1011+
) -> Self {
1012+
use crate::gpio::sealed::Lsco;
1013+
a2.set_lsco_af(cs);
1014+
rcc.bdcr
1015+
.modify(|_, w| w.lscoen().enabled().lscosel().variant(sel));
1016+
Self { pin: a2 }
1017+
}
1018+
1019+
/// Disable the low-speed oscillator output.
1020+
///
1021+
/// # Safety
1022+
///
1023+
/// 1. Backup domain write protect must be disabled.
1024+
///
1025+
/// # Example
1026+
///
1027+
/// ```no_run
1028+
/// use stm32wlxx_hal::{
1029+
/// gpio::{pins, PortA},
1030+
/// pac,
1031+
/// rcc::{Lsco, LscoSel},
1032+
/// };
1033+
///
1034+
/// let mut dp: pac::Peripherals = pac::Peripherals::take().unwrap();
1035+
///
1036+
/// // disable backup domain write protect
1037+
/// dp.PWR.cr1.modify(|_, w| w.dbp().enabled());
1038+
///
1039+
/// // enable the LSE clock
1040+
/// dp.RCC
1041+
/// .bdcr
1042+
/// .modify(|_, w| w.lseon().on().lsesysen().enabled());
1043+
/// while dp.RCC.bdcr.read().lserdy().is_not_ready() {}
1044+
/// while dp.RCC.bdcr.read().lsesysrdy().is_not_ready() {}
1045+
///
1046+
/// let gpioa: PortA = PortA::split(dp.GPIOA, &mut dp.RCC);
1047+
/// let lsco: Lsco = cortex_m::interrupt::free(|cs| unsafe {
1048+
/// Lsco::enable(gpioa.a2, LscoSel::LSE, &mut dp.RCC, cs)
1049+
/// });
1050+
///
1051+
/// // ... use LSCO
1052+
///
1053+
/// let a2: pins::A2 = unsafe { lsco.disable(&mut dp.RCC) };
1054+
/// ```
1055+
#[inline]
1056+
pub unsafe fn disable(self, rcc: &mut pac::RCC) -> crate::gpio::pins::A2 {
1057+
rcc.bdcr.modify(|_, w| w.lscoen().disabled());
1058+
self.pin
1059+
}
1060+
}

0 commit comments

Comments
 (0)