From 56c943add9ad17de7336c605e20285d3eb6c023d Mon Sep 17 00:00:00 2001 From: Sh3Rm4n Date: Tue, 8 Dec 2020 15:33:16 +0100 Subject: [PATCH 1/4] TODO rtc comments --- src/rtc.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/rtc.rs b/src/rtc.rs index 0b42b20b1..ef70decd1 100644 --- a/src/rtc.rs +++ b/src/rtc.rs @@ -16,6 +16,10 @@ pub enum Error { InvalidInputData, } +/// RTC Clock input source ??? +/// https://github.com/stm32-rs/stm32f3xx-hal/pull/93/files#diff-27f77b66fb3d3624adbb9ac9e90b661819630850787da3b9f47a48a663a5634cR16 +/// And what about RTCSEL_A? +/// https://docs.rs/stm32f3/0.12.1/stm32f3/stm32f303/rcc/bdcr/enum.RTCSEL_A.html pub const LSE_BITS: u8 = 0b01; pub struct Rtc { @@ -24,11 +28,17 @@ pub struct Rtc { impl Rtc { /// Create and enable a new RTC, and configure its clock source and prescalers. + // TODO Even though LSE is the only supported type for now, + // the API should be flexible enough tot allow further imporvements + // wither (at least a major) breaking API change. /// From AN4759, Table 7, when using the LSE (The only clock source this module /// supports currently), set `prediv_s` to 255, and `prediv_a` to 127 to get a /// calendar clock of 1Hz. + // TODO could'nt that be determined via clocks? /// The `bypass` argument is `true` if you're using an external oscillator that /// doesn't connect to `OSC32_IN`, such as a MEMS resonator. + // TODO what to pass to prediv_s and prediv_a + // TODO bypass to enum? pub fn new( regs: RTC, prediv_s: u16, @@ -40,8 +50,13 @@ impl Rtc { ) -> Self { let mut result = Self { regs }; + // TODO + // These are one time used functions and not very + // long ones either, + // expand them up to here enable_lse(bdcr, bypass); unlock(apb1, pwr); + // Support enable(bdcr); result.set_24h_fmt(); @@ -381,6 +396,9 @@ fn hours_to_u8(hours: Hours) -> Result { /// Enable the low frequency external oscillator. This is the only mode currently /// supported, to avoid exposing the `CR` and `CRS` registers. +// TODO If these limitations are the problem, +// why not use something like a builder pattern +// to bee able to avoid these dependencies on CR and CRS? fn enable_lse(bdcr: &mut BDCR, bypass: bool) { bdcr.bdcr() .modify(|_, w| w.lseon().set_bit().lsebyp().bit(bypass)); @@ -407,6 +425,10 @@ fn unlock(apb1: &mut APB1, pwr: &mut PWR) { fn enable(bdcr: &mut BDCR) { bdcr.bdcr().modify(|_, w| w.bdrst().enabled()); bdcr.bdcr().modify(|_, w| { + // FIXME LSE BITS is a pub const + // but here we just set it? + // What about lsi and hsi + // and does bypass play a role here? w.rtcsel().lse(); w.rtcen().enabled(); w.bdrst().disabled() From aee8181d0eb9bbb56cd8af45be6b8dea36d13379 Mon Sep 17 00:00:00 2001 From: Sh3Rm4n Date: Tue, 8 Dec 2020 15:34:16 +0100 Subject: [PATCH 2/4] Rename regs to rtc --- src/rtc.rs | 67 +++++++++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/src/rtc.rs b/src/rtc.rs index ef70decd1..0465c11e6 100644 --- a/src/rtc.rs +++ b/src/rtc.rs @@ -23,7 +23,7 @@ pub enum Error { pub const LSE_BITS: u8 = 0b01; pub struct Rtc { - pub regs: RTC, + rtc: RTC, } impl Rtc { @@ -40,7 +40,7 @@ impl Rtc { // TODO what to pass to prediv_s and prediv_a // TODO bypass to enum? pub fn new( - regs: RTC, + rtc: RTC, prediv_s: u16, prediv_a: u8, bypass: bool, @@ -48,7 +48,7 @@ impl Rtc { bdcr: &mut BDCR, pwr: &mut PWR, ) -> Self { - let mut result = Self { regs }; + let mut result = Self { rtc }; // TODO // These are one time used functions and not very @@ -60,7 +60,7 @@ impl Rtc { enable(bdcr); result.set_24h_fmt(); - result.regs.prer.modify(|_, w| { + result.rtc.prer.modify(|_, w| { w.prediv_s().bits(prediv_s); w.prediv_a().bits(prediv_a) }); @@ -70,16 +70,17 @@ impl Rtc { /// Sets calendar clock to 24 hr format pub fn set_24h_fmt(&mut self) { - self.regs.cr.modify(|_, w| w.fmt().set_bit()); + self.rtc.cr.modify(|_, w| w.fmt().set_bit()); } /// Sets calendar clock to 12 hr format pub fn set_12h_fmt(&mut self) { - self.regs.cr.modify(|_, w| w.fmt().clear_bit()); + self.rtc.cr.modify(|_, w| w.fmt().clear_bit()); } /// Reads current hour format selection pub fn is_24h_fmt(&self) -> bool { - self.regs.cr.read().fmt().bit() + self.rtc.cr.read().fmt().bit() + } } /// As described in Section 27.3.7 in RM0316, @@ -90,20 +91,20 @@ impl Rtc { F: FnMut(&mut RTC), { // Disable write protection - self.regs.wpr.write(|w| unsafe { w.bits(0xCA) }); - self.regs.wpr.write(|w| unsafe { w.bits(0x53) }); + self.rtc.wpr.write(|w| unsafe { w.bits(0xCA) }); + self.rtc.wpr.write(|w| unsafe { w.bits(0x53) }); // Enter init mode - let isr = self.regs.isr.read(); + let isr = self.rtc.isr.read(); if isr.initf().bit_is_clear() { - self.regs.isr.modify(|_, w| w.init().set_bit()); - while self.regs.isr.read().initf().bit_is_clear() {} + self.rtc.isr.modify(|_, w| w.init().set_bit()); + while self.rtc.isr.read().initf().bit_is_clear() {} } // Invoke closure - closure(&mut self.regs); + closure(&mut self.rtc); // Exit init mode - self.regs.isr.modify(|_, w| w.init().clear_bit()); + self.rtc.isr.modify(|_, w| w.init().clear_bit()); // wait for last write to be done - while !self.regs.isr.read().initf().bit_is_clear() {} + while !self.rtc.isr.read().initf().bit_is_clear() {} } } @@ -117,7 +118,7 @@ impl Rtcc for Rtc { let (ht, hu) = bcd2_encode(time.hour())?; let (mnt, mnu) = bcd2_encode(time.minute())?; let (st, su) = bcd2_encode(time.second())?; - self.regs.tr.write(|w| { + self.rtc.tr.write(|w| { w.ht().bits(ht); w.hu().bits(hu); w.mnt().bits(mnt); @@ -135,7 +136,7 @@ impl Rtcc for Rtc { return Err(Error::InvalidInputData); } let (st, su) = bcd2_encode(seconds as u32)?; - self.modify(|regs| regs.tr.modify(|_, w| w.st().bits(st).su().bits(su))); + self.modify(|rtc| rtc.tr.modify(|_, w| w.st().bits(st).su().bits(su))); Ok(()) } @@ -145,7 +146,7 @@ impl Rtcc for Rtc { return Err(Error::InvalidInputData); } let (mnt, mnu) = bcd2_encode(minutes as u32)?; - self.modify(|regs| regs.tr.modify(|_, w| w.mnt().bits(mnt).mnu().bits(mnu))); + self.modify(|rtc| rtc.tr.modify(|_, w| w.mnt().bits(mnt).mnu().bits(mnu))); Ok(()) } @@ -157,7 +158,7 @@ impl Rtcc for Rtc { Hours::AM(_h) | Hours::PM(_h) => self.set_12h_fmt(), } - self.regs.tr.modify(|_, w| w.ht().bits(ht).hu().bits(hu)); + self.rtc.tr.modify(|_, w| w.ht().bits(ht).hu().bits(hu)); Ok(()) } @@ -166,7 +167,7 @@ impl Rtcc for Rtc { if !(1..=7).contains(&weekday) { return Err(Error::InvalidInputData); } - self.modify(|regs| regs.dr.modify(|_, w| unsafe { w.wdu().bits(weekday) })); + self.modify(|rtc| rtc.dr.modify(|_, w| unsafe { w.wdu().bits(weekday) })); Ok(()) } @@ -176,7 +177,7 @@ impl Rtcc for Rtc { return Err(Error::InvalidInputData); } let (dt, du) = bcd2_encode(day as u32)?; - self.modify(|regs| regs.dr.modify(|_, w| w.dt().bits(dt).du().bits(du))); + self.modify(|rtc| rtc.dr.modify(|_, w| w.dt().bits(dt).du().bits(du))); Ok(()) } @@ -186,7 +187,7 @@ impl Rtcc for Rtc { return Err(Error::InvalidInputData); } let (mt, mu) = bcd2_encode(month as u32)?; - self.modify(|regs| regs.dr.modify(|_, w| w.mt().bit(mt > 0).mu().bits(mu))); + self.modify(|rtc| rtc.dr.modify(|_, w| w.mt().bit(mt > 0).mu().bits(mu))); Ok(()) } @@ -196,7 +197,7 @@ impl Rtcc for Rtc { return Err(Error::InvalidInputData); } let (yt, yu) = bcd2_encode(year as u32)?; - self.modify(|regs| regs.dr.modify(|_, w| w.yt().bits(yt).yu().bits(yu))); + self.modify(|rtc| rtc.dr.modify(|_, w| w.yt().bits(yt).yu().bits(yu))); Ok(()) } @@ -212,7 +213,7 @@ impl Rtcc for Rtc { let (mt, mu) = bcd2_encode(date.month())?; let (dt, du) = bcd2_encode(date.day())?; - self.regs.dr.write(|w| { + self.rtc.dr.write(|w| { w.dt().bits(dt); w.du().bits(du); w.mt().bit(mt > 0); @@ -238,7 +239,7 @@ impl Rtcc for Rtc { let (mnt, mnu) = bcd2_encode(date.minute())?; let (st, su) = bcd2_encode(date.second())?; - self.regs.dr.write(|w| { + self.rtc.dr.write(|w| { w.dt().bits(dt); w.du().bits(du); w.mt().bit(mt > 0); @@ -247,7 +248,7 @@ impl Rtcc for Rtc { w.yu().bits(yu) }); - self.regs.tr.write(|w| { + self.rtc.tr.write(|w| { w.ht().bits(ht); w.hu().bits(hu); w.mnt().bits(mnt); @@ -261,19 +262,19 @@ impl Rtcc for Rtc { } fn get_seconds(&mut self) -> Result { - let tr = self.regs.tr.read(); + let tr = self.rtc.tr.read(); let seconds = bcd2_decode(tr.st().bits(), tr.su().bits()); Ok(seconds as u8) } fn get_minutes(&mut self) -> Result { - let tr = self.regs.tr.read(); + let tr = self.rtc.tr.read(); let minutes = bcd2_decode(tr.mnt().bits(), tr.mnu().bits()); Ok(minutes as u8) } fn get_hours(&mut self) -> Result { - let tr = self.regs.tr.read(); + let tr = self.rtc.tr.read(); let hours = bcd2_decode(tr.ht().bits(), tr.hu().bits()); if self.is_24h_fmt() { return Ok(Hours::H24(hours as u8)); @@ -298,26 +299,26 @@ impl Rtcc for Rtc { } fn get_weekday(&mut self) -> Result { - let dr = self.regs.dr.read(); + let dr = self.rtc.dr.read(); let weekday = bcd2_decode(dr.wdu().bits(), 0x00); Ok(weekday as u8) } fn get_day(&mut self) -> Result { - let dr = self.regs.dr.read(); + let dr = self.rtc.dr.read(); let day = bcd2_decode(dr.dt().bits(), dr.du().bits()); Ok(day as u8) } fn get_month(&mut self) -> Result { - let dr = self.regs.dr.read(); + let dr = self.rtc.dr.read(); let mt: u8 = if dr.mt().bit() { 1 } else { 0 }; let month = bcd2_decode(mt, dr.mu().bits()); Ok(month as u8) } fn get_year(&mut self) -> Result { - let dr = self.regs.dr.read(); + let dr = self.rtc.dr.read(); let year = bcd2_decode(dr.yt().bits(), dr.yu().bits()); Ok(year as u16) } From b1c861ce2828d53de81df260b5f143999f79b982 Mon Sep 17 00:00:00 2001 From: Sh3Rm4n Date: Tue, 8 Dec 2020 15:34:30 +0100 Subject: [PATCH 3/4] Add free() function to rtc --- src/rtc.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/rtc.rs b/src/rtc.rs index 0465c11e6..851effa12 100644 --- a/src/rtc.rs +++ b/src/rtc.rs @@ -81,6 +81,10 @@ impl Rtc { pub fn is_24h_fmt(&self) -> bool { self.rtc.cr.read().fmt().bit() } + + /// Release the RTC peripheral + pub fn free(self) -> RTC { + self.rtc } /// As described in Section 27.3.7 in RM0316, From e370b4840480b83af9e592a1142204640f2c6465 Mon Sep 17 00:00:00 2001 From: Fabian Date: Wed, 9 Dec 2020 17:47:21 +0100 Subject: [PATCH 4/4] fixup! Add free() function to rtc --- src/rtc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rtc.rs b/src/rtc.rs index 851effa12..2c2a4bef0 100644 --- a/src/rtc.rs +++ b/src/rtc.rs @@ -84,7 +84,7 @@ impl Rtc { /// Release the RTC peripheral pub fn free(self) -> RTC { - self.rtc + self.rtc } /// As described in Section 27.3.7 in RM0316,