diff options
-rw-r--r-- | Cargo.toml | 4 | ||||
-rw-r--r-- | src/ds3231.rs | 2 | ||||
-rw-r--r-- | src/i2c.rs | 12 | ||||
-rw-r--r-- | src/main.rs | 11 |
4 files changed, 21 insertions, 8 deletions
@@ -1,6 +1,6 @@ [package] -name = "bluepill-ds3231" -description = "Test the communication with DS3231" +name = "bluepill-bcdclock" +description = "A BCD clock using DS3231" authors = ["Ted Yin <[email protected]>"] keywords = ["no-std", "arm", "cortex-m", "stm32"] license = "GPL-3.0" diff --git a/src/ds3231.rs b/src/ds3231.rs index 0e1d561..2ebc31d 100644 --- a/src/ds3231.rs +++ b/src/ds3231.rs @@ -37,7 +37,7 @@ impl<'a> DS3231<'a> { pub fn init(&self) { let i2c = &self.i2c; - i2c.init(); + i2c.init(400_000, true); i2c.start(true, true); i2c.send_addr(DS3231_ADDR, TransDir::TRANSMITTER, true); i2c.send(DS3231_REG_CTL, true); @@ -15,6 +15,7 @@ const HSI_VALUE: u32 = 8000000; const HSE_VALUE: u32 = 8000000; const CCR_CCR_SET: u16 = 0x0FFF; const CCR_FS_SET: u16 = 0x8000; +const CCR_DUTY_SET: u16 = 0x4000; const CR1_CLEAR_MASK: u16 = 0xFBF5; const I2C_ACK_ENABLE: u16 = 0x0400; @@ -64,12 +65,10 @@ impl<'a> I2C<'a> { pclk1_freq } - /// TODO: support for standard mode (100khz) - pub fn init(&self) { + /// TODO: support for standard mode + pub fn init(&self, freq: u32, duty: bool) { let i2c = &self.i2c; unsafe { - self.rcc.apb1rstr.modify(|_, w| w.i2c1rst().set_bit()); - self.rcc.apb1rstr.modify(|_, w| w.i2c1rst().clear_bit()); self.pe(true); /* PE = 1, enable I2C */ /* CR2 configuration */ let pclk1 = self.get_pclk1(); @@ -77,7 +76,10 @@ impl<'a> I2C<'a> { i2c.cr2.modify(|r, w| w.bits(r.bits()).freq().bits(freq_range as u8)); /* CCR configuration */ self.pe(false); - let mut res = (pclk1 / (400000 * 3)) as u16; + let mut res = match duty { + true => (pclk1 / (freq * (16 + 9))) as u16 | CCR_DUTY_SET, + false => (pclk1 / (freq * (2 + 1))) as u16 + }; if (res & CCR_CCR_SET) == 0 { res |= 0x0001; } diff --git a/src/main.rs b/src/main.rs index 219764f..ce4c2b6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -132,25 +132,36 @@ fn main() { syst.set_reload(8_000_000); syst.enable_interrupt(); syst.enable_counter(); + + /* enable GPIOA, GPIOB and AFIO */ rcc.apb2enr.modify(|_, w| w.iopaen().enabled() .iopben().enabled() .afioen().enabled()); + + /* GPIO */ + /* enable PA0-2 for manipulating shift register */ gpioa.crl.modify(|_, w| w.mode0().output().cnf0().push() .mode1().output().cnf1().push() .mode2().output().cnf2().push()); + /* enable PB6 and PB7 for I2C1 */ gpiob.crl.modify(|_, w| w.mode6().output50().cnf6().alt_open() .mode7().output50().cnf7().alt_open()); + /* I2C */ + /* enable and reset I2C1 */ rcc.apb1enr.modify(|_, w| w.i2c1en().enabled()); + rcc.apb1rstr.modify(|_, w| w.i2c1rst().set_bit()); + rcc.apb1rstr.modify(|_, w| w.i2c1rst().clear_bit()); unsafe { RTC = Some(ds3231::DS3231::new(i2c, rcc)); SR = Some(ShiftRegister::new(gpioa, 24)); SR.as_mut().unwrap().output_bits(0); let rtc = RTC.as_mut().unwrap(); + /* initialize the ds3231 */ rtc.init(); /* rtc.write_fulldate(&ds3231::Date{second: 30, |