diff options
-rw-r--r-- | src/i2c.rs | 1 | ||||
-rw-r--r-- | src/main.rs | 25 | ||||
-rw-r--r-- | src/tim.rs | 34 |
3 files changed, 56 insertions, 4 deletions
@@ -3,7 +3,6 @@ extern crate stm32f103xx; use core::cmp::max; use stm32f103xx::{i2c1, rcc, RCC}; - pub const EVENT_MASTER_STARTED: u32 = 0x00030001; /* BUSY, MSL and SB flag */ pub const EVENT_MASTER_TRANSMITTER_MODE_SELECTED: u32 = 0x00070082; /* BUSY, MSL, ADDR, TXE and TRA flags */ pub const EVENT_MASTER_RECEIVER_MODE_SELECTED: u32 = 0x00030002; /* BUSY, MSL and ADDR flags */ diff --git a/src/main.rs b/src/main.rs index a98b250..9df73cf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,7 @@ mod mutex; mod i2c; mod ds3231; mod at24c; +mod tim; const SYNC_PERIOD: u8 = 10; @@ -30,6 +31,7 @@ struct Clock { struct GlobalState { disp: Option<ShiftRegister<'static>>, i2c: Option<i2c::I2C<'static>>, + tim: Option<tim::Timer<'static>>, i2c_inited: bool, buff: [u8; 6], time: Clock, @@ -40,6 +42,7 @@ struct GlobalState { static mut GS: GlobalState = GlobalState{disp: None, i2c: None, + tim: None, i2c_inited: false, buff: [0; 6], time: Clock{sec: 0, min: 0, hr: 0, reset: 0}, @@ -65,7 +68,7 @@ fn display() { fn digits_countup() { let gs = get_gs(); - let mut digits = gs.buff; + let mut digits = &mut gs.buff; gs.disp.as_ref().unwrap().output_bits(digits2bcds(&digits[..])); let mut i = 0; let mut carry = 1; @@ -78,14 +81,14 @@ fn digits_countup() { fn render_clock() { let gs = get_gs(); - let mut digits = gs.buff; + let mut digits = &mut gs.buff; let time = &gs.time; if gs.bs { digits[1] = time.sec / 10; digits[0] = time.sec - digits[1] * 10; digits[3] = time.min / 10; digits[2] = time.min - digits[3] * 10; digits[5] = time.hr / 10; digits[4] = time.hr - digits[5] * 10; } else { - for i in &mut digits { + for i in digits { *i = 0xf; } } @@ -126,8 +129,18 @@ fn exti3_handler() { display(); } +fn tim2_handler() { + let gs = get_gs(); + let p = gs.perip.as_ref().unwrap(); + p.TIM2.sr.modify(|_, w| w.uif().clear()); + gs.bs = !gs.bs; + render_clock(); + display(); +} + exception!(SYS_TICK, systick_handler); interrupt!(EXTI3, exti3_handler); +interrupt!(TIM2, tim2_handler); impl<'a> ShiftRegister<'a> { fn new(gpioa: &'a gpioa::RegisterBlock, @@ -196,6 +209,7 @@ fn init() { p.RCC.apb2enr.modify(|_, w| w.iopaen().enabled() .iopben().enabled() .afioen().enabled()); + p.RCC.apb1enr.modify(|_, w| w.tim2en().enabled()); /* GPIO */ /* enable PA0-2 for manipulating shift register */ @@ -220,6 +234,7 @@ fn init() { /* NVIC & EXTI */ p.AFIO.exticr1.write(|w| unsafe { w.exti3().bits(0b0000) }); p.NVIC.enable(Interrupt::EXTI3); + p.NVIC.enable(Interrupt::TIM2); p.EXTI.imr.write(|w| w.mr3().set_bit()); p.EXTI.rtsr.write(|w| w.tr3().set_bit()); p.EXTI.ftsr.write(|w| w.tr3().set_bit()); @@ -227,9 +242,13 @@ fn init() { gs.i2c = Some(i2c::I2C(p.I2C1)); gs.disp = Some(ShiftRegister::new(p.GPIOA, 24)); + gs.tim = Some(tim::Timer(p.TIM2)); gs.i2c.as_ref().unwrap().init(p.RCC, 0x01, 400_000, i2c::DutyType::DUTY1, true); + gs.tim.as_ref().unwrap().init(16_000_000); + gs.tim.as_ref().unwrap().go(); //i2c.init(0x01, 100_000, i2c::DutyType::DUTY1, false); gs.disp.as_ref().unwrap().output_bits(0); + gs.i2c_inited = true; } fn set_clock() { diff --git a/src/tim.rs b/src/tim.rs new file mode 100644 index 0000000..efbd786 --- /dev/null +++ b/src/tim.rs @@ -0,0 +1,34 @@ +use stm32f103xx::{tim2, TIM2}; + +pub struct Timer<'a> (pub &'a tim2::RegisterBlock); + +impl<'a> Timer<'a> { + pub fn init(&self, timeout: u32) { + let tim = self.0; + self.set_timeout(timeout); + tim.cr1.write(|w| unsafe { + w.opm().continuous() + .cms().bits(0b00) + .dir().up()}); + tim.dier.modify(|_, w| w.uie().set_bit()); + } + + pub fn set_timeout(&self, timeout: u32) { + let psc: u16 = (timeout / (1 << 16)) as u16; + let arr: u16 = (timeout / (psc + 1) as u32) as u16; + self.0.psc.write(|w| w.psc().bits(psc)); + self.0.arr.write(|w| w.arr().bits(arr)); + } + + pub fn reset(&self) { + self.0.cnt.write(|w| w.cnt().bits(0)); + } + + pub fn go(&self) { + self.0.cr1.modify(|_, w| w.cen().enabled()); + } + + pub fn stop(&self) { + self.0.cr1.modify(|_, w| w.cen().disabled()); + } +} |