summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeterminant <ted.sybil@gmail.com>2017-09-21 23:04:45 -0400
committerDeterminant <ted.sybil@gmail.com>2017-09-21 23:04:45 -0400
commita459ddf4bfe00f956bf0ffffe70d57585e889501 (patch)
tree23449bf61263976102b028154dbb630ffeb25e3d
parent561887acffccb8d4757d931eedfa2e494946efd1 (diff)
sync with ds3231 every 10s
-rw-r--r--src/ds3231.rs5
-rw-r--r--src/i2c.rs69
-rw-r--r--src/main.rs70
3 files changed, 94 insertions, 50 deletions
diff --git a/src/ds3231.rs b/src/ds3231.rs
index 6b20958..0e1d561 100644
--- a/src/ds3231.rs
+++ b/src/ds3231.rs
@@ -22,8 +22,9 @@ pub struct Date {
}
impl<'a> DS3231<'a> {
- pub fn new(i2c_reg: &'a stm32f103xx::i2c1::RegisterBlock) -> DS3231<'a> {
- DS3231{i2c: I2C::new(i2c_reg)}
+ pub fn new(i2c_reg: &'a stm32f103xx::i2c1::RegisterBlock,
+ rcc_reg: &'a stm32f103xx::rcc::RegisterBlock) -> DS3231<'a> {
+ DS3231{i2c: I2C::new(i2c_reg, rcc_reg)}
}
fn bcd2dec(bcd: u8) -> u8 {
diff --git a/src/i2c.rs b/src/i2c.rs
index 6a8d7a4..8904730 100644
--- a/src/i2c.rs
+++ b/src/i2c.rs
@@ -20,6 +20,7 @@ const I2C_ACK_ENABLE: u16 = 0x0400;
pub struct I2C<'a> {
i2c: &'a stm32f103xx::i2c1::RegisterBlock,
+ rcc: &'a stm32f103xx::rcc::RegisterBlock,
}
pub enum TransDir {
@@ -28,52 +29,50 @@ pub enum TransDir {
}
impl<'a> I2C<'a> {
- pub fn new(reg: &'a stm32f103xx::i2c1::RegisterBlock) -> I2C<'a> {
- I2C{i2c: reg}
+ pub fn new(i2c_reg: &'a stm32f103xx::i2c1::RegisterBlock,
+ rcc_reg: &'a stm32f103xx::rcc::RegisterBlock) -> I2C<'a> {
+ I2C{i2c: i2c_reg, rcc: rcc_reg}
}
- fn get_pclk1() -> u32 {
- unsafe {
- use stm32f103xx::rcc::cfgr::{SWSR, PLLSRCR, PLLXTPRER};
- let rcc: &stm32f103xx::rcc::RegisterBlock = &*RCC.get();
- let cfgr = rcc.cfgr.read();
- let sysclk_freq = match cfgr.sws() {
- SWSR::HSI => HSI_VALUE,
- SWSR::HSE => HSE_VALUE,
- SWSR::PLL => {
- let pllmull = cfgr.pllmul().bits();
- let pllsource = cfgr.pllsrc();
- let pllmull = (pllmull as u32 >> 18) + 2;
- match pllsource {
- PLLSRCR::INTERNAL => {
- (HSI_VALUE >> 1) * pllmull
- },
- PLLSRCR::EXTERNAL => {
- match cfgr.pllxtpre() {
- PLLXTPRER::DIV2 => (HSE_VALUE >> 1) * pllmull,
- PLLXTPRER::DIV1 => HSE_VALUE * pllmull
- }
+ fn get_pclk1(&self) -> u32 {
+ use stm32f103xx::rcc::cfgr::{SWSR, PLLSRCR, PLLXTPRER};
+ let cfgr = self.rcc.cfgr.read();
+ let sysclk_freq = match cfgr.sws() {
+ SWSR::HSI => HSI_VALUE,
+ SWSR::HSE => HSE_VALUE,
+ SWSR::PLL => {
+ let pllmull = cfgr.pllmul().bits();
+ let pllsource = cfgr.pllsrc();
+ let pllmull = (pllmull as u32 >> 18) + 2;
+ match pllsource {
+ PLLSRCR::INTERNAL => {
+ (HSI_VALUE >> 1) * pllmull
+ },
+ PLLSRCR::EXTERNAL => {
+ match cfgr.pllxtpre() {
+ PLLXTPRER::DIV2 => (HSE_VALUE >> 1) * pllmull,
+ PLLXTPRER::DIV1 => HSE_VALUE * pllmull
}
}
}
- _ => HSI_VALUE
- };
- let div_table: [u8; 16] = [0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9];
- let hclk_freq = sysclk_freq >> div_table[cfgr.hpre().bits() as usize];
- let pclk1_freq = hclk_freq >> div_table[cfgr.ppre1().bits() as usize];
- pclk1_freq
- }
+ }
+ _ => HSI_VALUE
+ };
+ let div_table: [u8; 16] = [0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9];
+ let hclk_freq = sysclk_freq >> div_table[cfgr.hpre().bits() as usize];
+ let pclk1_freq = hclk_freq >> div_table[cfgr.ppre1().bits() as usize];
+ pclk1_freq
}
+ /// TODO: support for standard mode (100khz)
pub fn init(&self) {
let i2c = &self.i2c;
unsafe {
- let rcc: &stm32f103xx::rcc::RegisterBlock = &*RCC.get();
- rcc.apb1rstr.modify(|_, w| w.i2c1rst().set_bit());
- rcc.apb1rstr.modify(|_, w| w.i2c1rst().clear_bit());
+ 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 = I2C::get_pclk1();
+ let pclk1 = self.get_pclk1();
let freq_range: u16 = (pclk1 / 1000000) as u16;
i2c.cr2.modify(|r, w| w.bits(r.bits()).freq().bits(freq_range as u8));
/* CCR configuration */
@@ -84,7 +83,7 @@ impl<'a> I2C<'a> {
}
/* TRISE configuration */
i2c.trise.write(|w| w.bits(((freq_range * 300) / 1000 + 1) as u32));
- i2c.ccr.modify(|r, w| w.bits((res | CCR_FS_SET) as u32));
+ i2c.ccr.write(|w| w.bits((res | CCR_FS_SET) as u32));
self.pe(true); /* PE = 1, enable I2C */
/* CR1 configuration */
i2c.cr1.modify(|r, w| w.bits(((r.bits() as u16 & CR1_CLEAR_MASK) | I2C_ACK_ENABLE) as u32));
diff --git a/src/main.rs b/src/main.rs
index 6690828..219764f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -12,18 +12,22 @@ struct ShiftRegister<'a> {
width: u8,
}
+struct Clock {
+ sec: u8,
+ min: u8,
+ hr: u8,
+ reset: u8
+}
+
+const RESET_PERIOD: u8 = 10;
static mut SR: Option<ShiftRegister> = None;
static mut RTC: Option<ds3231::DS3231> = None;
-static mut N: u16 = 0;
static mut DIGITS: [u8; 6] = [0; 6];
+static mut TIME: Clock = Clock{sec: 0, min: 0, hr: 0, reset: 0};
-fn systick_handler() {
+fn update_clock() {
unsafe {
/*
- SR.as_mut().unwrap().output_bits(N as u32);
- N += 1;
- */
- /*
SR.as_mut().unwrap().output_bits(digits2bcds(&DIGITS[..]));
let mut i = 0;
let mut carry = 1;
@@ -33,14 +37,28 @@ fn systick_handler() {
i += 1;
}
*/
- let ds3231::Date{second: sec, minute: min, hour: hr, ..} = RTC.as_mut().unwrap().read_fulldate();
- DIGITS[4] = sec / 10; DIGITS[5] = sec % 10;
- DIGITS[2] = min / 10; DIGITS[3] = min % 10;
- DIGITS[0] = hr / 10; DIGITS[1] = hr % 10;
+ if !TIME.tick() {
+ let ds3231::Date{second: sec,
+ minute: min,
+ hour: hr, ..} = RTC.as_mut().unwrap()
+ .read_fulldate();
+ TIME = Clock{sec: sec,
+ min: min,
+ hr: hr,
+ reset: RESET_PERIOD};
+ }
+
+ DIGITS[4] = TIME.sec / 10; DIGITS[5] = TIME.sec - DIGITS[4] * 10;
+ DIGITS[2] = TIME.min / 10; DIGITS[3] = TIME.min - DIGITS[2] * 10;
+ DIGITS[0] = TIME.hr / 10; DIGITS[1] = TIME.hr - DIGITS[0] * 10;
SR.as_mut().unwrap().output_bits(digits2bcds(&DIGITS[..]));
}
}
+fn systick_handler() {
+ update_clock();
+}
+
exception!(SYS_TICK, systick_handler);
impl<'a> ShiftRegister<'a> {
@@ -77,6 +95,31 @@ fn digits2bcds(digs: &[u8]) -> u32 {
res
}
+impl Clock {
+ fn tick(&mut self) -> bool {
+ if self.reset == 0 {
+ return false;
+ }
+
+ self.sec += 1;
+ if self.sec == 60 {
+ self.min += 1;
+ self.sec = 0;
+ }
+
+ if self.min == 60 {
+ self.hr += 1;
+ self.min = 0;
+ }
+
+ if self.hr == 24 {
+ self.hr = 0;
+ }
+ self.reset -= 1;
+ true
+ }
+}
+
fn main() {
let gpioa: &stm32f103xx::gpioa::RegisterBlock = unsafe { &*GPIOA.get() };
@@ -86,7 +129,7 @@ fn main() {
let syst: &cortex_m::peripheral::SYST = unsafe { &*SYST.get() };
syst.set_clock_source(SystClkSource::Core);
- syst.set_reload(100_000);
+ syst.set_reload(8_000_000);
syst.enable_interrupt();
syst.enable_counter();
rcc.apb2enr.modify(|_, w| w.iopaen().enabled()
@@ -104,12 +147,11 @@ fn main() {
rcc.apb1enr.modify(|_, w| w.i2c1en().enabled());
unsafe {
- RTC = Some(ds3231::DS3231::new(i2c));
+ 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();
rtc.init();
- let x = rtc.read_fulldate();
/*
rtc.write_fulldate(&ds3231::Date{second: 30,
minute: 48,
@@ -122,4 +164,6 @@ fn main() {
am_enable: false});
*/
}
+
+ update_clock();
}