@@ -10,6 +10,7 @@ use crate::{pac, Ratio};
1010use cortex_m:: { interrupt:: CriticalSection , peripheral:: syst:: SystClkSource } ;
1111
1212use pac:: flash:: acr:: LATENCY_A ;
13+ pub use pac:: rcc:: bdcr:: LSCOSEL_A as LscoSel ;
1314pub use pac:: rcc:: csr:: LSIPRE_A as LsiPre ;
1415
1516fn 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