pub fn init(
        rtc: RTC,
        prec: backup::Rtc,
        clock_source: RtcClock,
        clocks: &CoreClocks,
    ) -> Self {
        let mut prec = prec.reset().enable();

        let rcc = unsafe { &*RCC::ptr() };

        // Check and configure clock source
        let ker_ck = match clock_source {
            RtcClock::Lse { bypass, freq, .. } => {
                // Set LSEBYP before enabling
                rcc.bdcr.modify(|_, w| w.lsebyp().bit(bypass));
                // Ensure LSE is on and stable
                rcc.bdcr.modify(|_, w| w.lseon().on());
                while rcc.bdcr.read().lserdy().is_not_ready() {}

                Some(freq)
            }
            RtcClock::Hse { divider } => {
                // Set HSE divider
                assert!(divider < 64, "HSE Divider larger than 63");
                rcc.cfgr.modify(|_, w| w.rtcpre().bits(divider));

                clocks.hse_ck().map(|x| Hertz(x.0 / u32(divider)))
            }
            RtcClock::Lsi => clocks.lsi_ck(),
        }
        .expect("rtc_ker_ck not running")
        .0;

        assert!(ker_ck <= 1 << 22, "rtc_ker_ck too fast for prescaler");

        // Select RTC kernel clock
        prec.kernel_clk_mux(match clock_source {
            RtcClock::Hse { .. } => backup::RtcClkSel::HSE,
            RtcClock::Lsi => backup::RtcClkSel::LSI,
            RtcClock::Lse { .. } => backup::RtcClkSel::LSE,
        });

        // Now we can enable CSS, if required
        if let RtcClock::Lse { css: true, .. } = clock_source {
            rcc.bdcr.modify(|_, w| w.lsecsson().security_on());
        }

        // Disable RTC register write protection
        rtc.wpr.write(|w| unsafe { w.bits(0xCA) });
        rtc.wpr.write(|w| unsafe { w.bits(0x53) });

        // Enter initialization mode
        rtc.isr.modify(|_, w| w.init().set_bit());
        while rtc.isr.read().initf().bit_is_clear() {}

        // Enable Shadow Register Bypass
        rtc.cr.modify(|_, w| w.bypshad().set_bit());

        // Configure prescaler for 1Hz clock
        // Want to maximize a_pre_max for power reasons, though it reduces the
        // subsecond precision.
        let total_div = ker_ck;
        let a_pre_max = 1 << 7;
        let s_pre_max = 1 << 15;

        let (a_pre, s_pre) = if total_div <= a_pre_max {
            (total_div, 1)
        } else if total_div % a_pre_max == 0 {
            (a_pre_max, total_div / a_pre_max)
        } else {
            let mut a_pre = a_pre_max;
            while a_pre > 1 {
                if total_div % a_pre == 0 {
                    break;
                }
                a_pre -= 1;
            }
            let s_pre = total_div / a_pre;
            (a_pre, s_pre)
        };
        assert!(
            a_pre <= a_pre_max && s_pre <= s_pre_max,
            "Invalid RTC prescaler value"
        );

        rtc.prer.write(|w| {
            w.prediv_s()
                .bits(u16(s_pre - 1).unwrap())
                .prediv_a()
                .bits(u8(a_pre - 1).unwrap())
        });

        // Exit initialization mode
        rtc.isr.modify(|_, w| w.init().clear_bit());

        Rtc { reg: rtc, prec }
    }
/// Resets the RTC, including the backup registers, then initializes it.
Resets the RTC, including the backup registers, then initializes it.
Resets the RTC including the backup registers then initializes it .
pub fn init(
        rtc: RTC,
        prec: backup::Rtc,
        clock_source: RtcClock,
        clocks: &CoreClocks,
    ) -> Self {
        let mut prec = prec.reset().enable();
        let rcc = unsafe { &*RCC::ptr() };
        // Check and configure clock source
        let ker_ck = match clock_source {
            RtcClock::Lse { bypass, freq, .. } => {
                // Set LSEBYP before enabling
                rcc.bdcr.modify(|_, w| w.lsebyp().bit(bypass));
                // Ensure LSE is on and stable
                rcc.bdcr.modify(|_, w| w.lseon().on());
                while rcc.bdcr.read().lserdy().is_not_ready() {}
                Some(freq)
            }
            RtcClock::Hse { divider } => {
                // Set HSE divider
                assert!(divider < 64, "HSE Divider larger than 63");
                rcc.cfgr.modify(|_, w| w.rtcpre().bits(divider));
                clocks.hse_ck().map(|x| Hertz(x.0 / u32(divider)))
            }
            RtcClock::Lsi => clocks.lsi_ck(),
        }
        .expect("rtc_ker_ck not running")
        .0;
        assert!(ker_ck <= 1 << 22, "rtc_ker_ck too fast for prescaler");
        // Select RTC kernel clock
        prec.kernel_clk_mux(match clock_source {
            RtcClock::Hse { .. } => backup::RtcClkSel::HSE,
            RtcClock::Lsi => backup::RtcClkSel::LSI,
            RtcClock::Lse { .. } => backup::RtcClkSel::LSE,
        });
        // Now we can enable CSS, if required
        if let RtcClock::Lse { css: true, .. } = clock_source {
            rcc.bdcr.modify(|_, w| w.lsecsson().security_on());
        }
        // Disable RTC register write protection
        rtc.wpr.write(|w| unsafe { w.bits(0xCA) });
        rtc.wpr.write(|w| unsafe { w.bits(0x53) });
        // Enter initialization mode
        rtc.isr.modify(|_, w| w.init().set_bit());
        while rtc.isr.read().initf().bit_is_clear() {}
        // Enable Shadow Register Bypass
        rtc.cr.modify(|_, w| w.bypshad().set_bit());
        // Configure prescaler for 1Hz clock
        // Want to maximize a_pre_max for power reasons, though it reduces the
        // subsecond precision.
        let total_div = ker_ck;
        let a_pre_max = 1 << 7;
        let s_pre_max = 1 << 15;
        let (a_pre, s_pre) = if total_div <= a_pre_max {
            (total_div, 1)
        } else if total_div % a_pre_max == 0 {
            (a_pre_max, total_div / a_pre_max)
        } else {
            let mut a_pre = a_pre_max;
            while a_pre > 1 {
                if total_div % a_pre == 0 {
                    break;
                }
                a_pre -= 1;
            }
            let s_pre = total_div / a_pre;
            (a_pre, s_pre)
        };
        assert!(
            a_pre <= a_pre_max && s_pre <= s_pre_max,
            "Invalid RTC prescaler value"
        );
        rtc.prer.write(|w| {
            w.prediv_s()
                .bits(u16(s_pre - 1).unwrap())
                .prediv_a()
                .bits(u8(a_pre - 1).unwrap())
        });
        // Exit initialization mode
        rtc.isr.modify(|_, w| w.init().clear_bit());
        Rtc { reg: rtc, prec }
    }
pub fn init ( rtc : RTC , prec : backup :: Rtc , clock_source : RtcClock , clocks : & CoreClocks , ) -> Self { let mut prec = prec . reset ( ) . enable ( ) ; let rcc = unsafe { & * RCC :: ptr ( ) } ; // Check and configure clock source let ker_ck = match clock_source { RtcClock :: Lse { bypass , freq , .. } => { // Set LSEBYP before enabling rcc . bdcr . modify ( | _ , w | w . lsebyp ( ) . bit ( bypass ) ) ; // Ensure LSE is on and stable rcc . bdcr . modify ( | _ , w | w . lseon ( ) . on ( ) ) ; while rcc . bdcr . read ( ) . lserdy ( ) . is_not_ready ( ) { } Some ( freq ) } RtcClock :: Hse { divider } => { // Set HSE divider assert ! ( divider 64 " " ) ; rcc . cfgr . modify ( | _ , w | w . rtcpre ( ) . bits ( divider ) ) ; clocks . hse_ck ( ) . map ( | x | Hertz ( x . 0 / u32 ( divider ) ) ) } RtcClock :: Lsi => clocks . lsi_ck ( ) , } . expect ( " " ) . 0 ; assert ! ( ker_ck 1 22 " " ) ; // Select RTC kernel clock prec . kernel_clk_mux ( match clock_source { RtcClock :: Hse { .. } => backup :: RtcClkSel :: HSE , RtcClock :: Lsi => backup :: RtcClkSel :: LSI , RtcClock :: Lse { .. } => backup :: RtcClkSel :: LSE , } ) ; // Now we can enable CSS, if required if let RtcClock :: Lse { css : true , .. } = clock_source { rcc . bdcr . modify ( | _ , w | w . lsecsson ( ) . security_on ( ) ) ; } // Disable RTC register write protection rtc . wpr . write ( | w | unsafe { w . bits ( 0xCA ) } ) ; rtc . wpr . write ( | w | unsafe { w . bits ( 0x53 ) } ) ; // Enter initialization mode rtc . isr . modify ( | _ , w | w . init ( ) . set_bit ( ) ) ; while rtc . isr . read ( ) . initf ( ) . bit_is_clear ( ) { } // Enable Shadow Register Bypass rtc . cr . modify ( | _ , w | w . bypshad ( ) . set_bit ( ) ) ; // Configure prescaler for 1Hz clock // Want to maximize a_pre_max for power reasons, though it reduces the // subsecond precision. let total_div = ker_ck ; let a_pre_max = 1 << 7 ; let s_pre_max = 1 << 15 ; let ( a_pre , s_pre ) = if total_div <= a_pre_max { ( total_div , 1 ) } else if total_div % a_pre_max == 0 { ( a_pre_max , total_div / a_pre_max ) } else { let mut a_pre = a_pre_max ; while a_pre > 1 { if total_div % a_pre == 0 { break ; } a_pre -= 1 ; } let s_pre = total_div / a_pre ; ( a_pre , s_pre ) } ; assert ! ( a_pre a_pre_max s_pre s_pre_max " " ) ; rtc . prer . write ( | w | { w . prediv_s ( ) . bits ( u16 ( s_pre - 1 ) . unwrap ( ) ) . prediv_a ( ) . bits ( u8 ( a_pre - 1 ) . unwrap ( ) ) } ) ; // Exit initialization mode rtc . isr . modify ( | _ , w | w . init ( ) . clear_bit ( ) ) ; Rtc { reg : rtc , prec } }
Resets the RTC, including the backup registers, then initializes it.
Resets the RTC including the backup registers then initializes it .
rtc
RTC
prec
backup::Rtc
clock_source
RtcClock
clocks
&CoreClocks
rtc
RTC
prec
backup::Rtc
clock_source
RtcClock
clocks
&CoreClocks