From 33063316e02911b1d2e0d02b53043b89ce87dea1 Mon Sep 17 00:00:00 2001 From: Determinant Date: Fri, 22 Sep 2017 20:15:23 -0400 Subject: code refactor --- src/ds3231.rs | 18 +++++++++--------- src/i2c.rs | 48 +++++++++++++++++++++++++----------------------- src/main.rs | 28 ++++++++++++++++------------ 3 files changed, 50 insertions(+), 44 deletions(-) diff --git a/src/ds3231.rs b/src/ds3231.rs index 2ebc31d..caf4825 100644 --- a/src/ds3231.rs +++ b/src/ds3231.rs @@ -1,5 +1,5 @@ extern crate stm32f103xx; -use ::i2c::{I2C, TransDir}; +use ::i2c::{I2C, TransDir, DutyType}; const DS3231_ADDR: u8 = 0b1101000; const DS3231_REG_SEC: u8 = 0x00; @@ -18,7 +18,7 @@ pub struct Date { pub month: u8, pub year: u8, pub am: bool, - pub am_enable: bool + pub am_enabled: bool } impl<'a> DS3231<'a> { @@ -37,7 +37,7 @@ impl<'a> DS3231<'a> { pub fn init(&self) { let i2c = &self.i2c; - i2c.init(400_000, true); + i2c.init(0x01, 400_000, DutyType::DUTY1); i2c.start(true, true); i2c.send_addr(DS3231_ADDR, TransDir::TRANSMITTER, true); i2c.send(DS3231_REG_CTL, true); @@ -62,13 +62,13 @@ impl<'a> DS3231<'a> { i2c.conf_ack(false); /* disable ack (send nack) */ buf[6] = i2c.recv(true); i2c.stop(true); - let am_enable = (buf[2] >> 6) & 1 == 1; - let hour = if am_enable { + let am_enabled = (buf[2] >> 6) & 1 == 1; + let hour = if am_enabled { (buf[2] & 0x0f) + ((buf[2] >> 4) & 1) * 10 } else { DS3231::bcd2dec(buf[2]) }; - let am = if am_enable {(buf[2] >> 5) & 1 == 0} else {hour < 12}; + let am = if am_enabled {(buf[2] >> 5) & 1 == 0} else {hour < 12}; Date{second: DS3231::bcd2dec(buf[0]), minute: DS3231::bcd2dec(buf[1]), hour: hour, @@ -77,14 +77,14 @@ impl<'a> DS3231<'a> { month: DS3231::bcd2dec(buf[5]), year: DS3231::bcd2dec(buf[6]), am: am, - am_enable: am_enable} + am_enabled: am_enabled} } pub fn write_fulldate(&self, date: &Date) { let i2c = &self.i2c; - let hour = if date.am_enable { + let hour = if date.am_enabled { (1 << 6) | ((if date.am {0} else {1}) << 5) | - ((date.hour % 10) << 4) | (date.hour & 0x0f) + ((date.hour / 10) << 4) | (date.hour % 10) } else { DS3231::dec2bcd(date.hour) }; diff --git a/src/i2c.rs b/src/i2c.rs index f6ff8e3..73a8f3b 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -1,6 +1,6 @@ #![allow(dead_code)] extern crate stm32f103xx; -use stm32f103xx::RCC; +use core::cmp::max; pub const EVENT_MASTER_STARTED: u32 = 0x00030001; /* BUSY, MSL and SB flag */ @@ -13,11 +13,6 @@ pub const EVENT_MASTER_BYTE_TRANSMITTED: u32 = 0x00070084; /* TRA, BUSY, MSL, T const FLAGS_MASK: u32 = 0x00ffffff; 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; pub struct I2C<'a> { i2c: &'a stm32f103xx::i2c1::RegisterBlock, @@ -29,6 +24,11 @@ pub enum TransDir { RECEIVER } +pub enum DutyType { + DUTY0, + DUTY1 +} + impl<'a> I2C<'a> { pub fn new(i2c_reg: &'a stm32f103xx::i2c1::RegisterBlock, rcc_reg: &'a stm32f103xx::rcc::RegisterBlock) -> I2C<'a> { @@ -66,31 +66,33 @@ impl<'a> I2C<'a> { } /// TODO: support for standard mode - pub fn init(&self, freq: u32, duty: bool) { + pub fn init(&self, + addr: u8, + scl_freq: u32, + duty_type: DutyType) { let i2c = &self.i2c; unsafe { - self.pe(true); /* PE = 1, enable I2C */ - /* CR2 configuration */ 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 */ + let freq_range: u16 = (pclk1 / 1_000_000) as u16; self.pe(false); - 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; - } - /* TRISE configuration */ + /* TRISE configuration (in Fm mode, max rise interval is 300) */ i2c.trise.write(|w| w.bits(((freq_range * 300) / 1000 + 1) as u32)); - i2c.ccr.write(|w| w.bits((res | CCR_FS_SET) as u32)); + /* CCR configuration */ + i2c.ccr.write(|w| match duty_type { + DutyType::DUTY0 => w.ccr().bits(max(pclk1 / (scl_freq * (2 + 1)), 0x1) as u16), + DutyType::DUTY1 => w.ccr().bits(max(pclk1 / (scl_freq * (16 + 9)), 0x1) as u16) + .duty().set_bit(), + }.f_s().set_bit()); 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)); + i2c.cr1.modify(|r, w| w.bits(r.bits()) + .smbus().clear_bit() + .smbtype().clear_bit() + .ack().set_bit()); + /* CR2 configuration */ + i2c.cr2.modify(|r, w| w.bits(r.bits()).freq().bits(freq_range as u8)); /* OAR1 configuration */ - i2c.oar1.write(|w| w.addmode().clear_bit().add7().bits(0x01)); + i2c.oar1.write(|w| w.addmode().clear_bit().add7().bits(addr)); while i2c.sr2.read().busy().bit() {} /* wait until the bus is free */ } } diff --git a/src/main.rs b/src/main.rs index ce4c2b6..a79107c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,9 +25,16 @@ static mut RTC: Option = None; static mut DIGITS: [u8; 6] = [0; 6]; static mut TIME: Clock = Clock{sec: 0, min: 0, hr: 0, reset: 0}; -fn update_clock() { +fn digits2bcds(digs: &[u8]) -> u32 { + let mut res: u32 = 0; + for d in digs.iter().rev() { + res = (res << 4) | (*d as u32); + } + res +} + +fn digits_countup() { unsafe { - /* SR.as_mut().unwrap().output_bits(digits2bcds(&DIGITS[..])); let mut i = 0; let mut carry = 1; @@ -36,7 +43,11 @@ fn update_clock() { carry = if DIGITS[i] > 9 {DIGITS[i] = 0; 1} else {0}; i += 1; } - */ + } +} + +fn update_clock() { + unsafe { if !TIME.tick() { let ds3231::Date{second: sec, minute: min, @@ -56,6 +67,7 @@ fn update_clock() { } fn systick_handler() { + // digits_countup(); update_clock(); } @@ -87,14 +99,6 @@ impl<'a> ShiftRegister<'a> { } } -fn digits2bcds(digs: &[u8]) -> u32 { - let mut res: u32 = 0; - for d in digs.iter().rev() { - res = (res << 4) | (*d as u32); - } - res -} - impl Clock { fn tick(&mut self) -> bool { if self.reset == 0 { @@ -172,7 +176,7 @@ fn main() { month: 9, year: 17, am: false, - am_enable: false}); + am_enabled: false}); */ } -- cgit v1.2.3