diff options
author | Determinant <[email protected]> | 2017-10-18 14:35:48 -0400 |
---|---|---|
committer | Determinant <[email protected]> | 2017-10-18 14:35:48 -0400 |
commit | 177667b7034ec09bb0d7146077bb3c0b7ba28336 (patch) | |
tree | 392855183e96c36e0ad870d5770a6e3c2504857b /src | |
parent | b27ebb9f07d7ee0b60abe84738db712c8fbcb3f1 (diff) |
code refactoring
Diffstat (limited to 'src')
-rw-r--r-- | src/at24c.rs | 9 | ||||
-rw-r--r-- | src/ds3231.rs | 7 | ||||
-rw-r--r-- | src/i2c.rs | 44 | ||||
-rw-r--r-- | src/main.rs | 172 |
4 files changed, 144 insertions, 88 deletions
diff --git a/src/at24c.rs b/src/at24c.rs index 569f04a..169c048 100644 --- a/src/at24c.rs +++ b/src/at24c.rs @@ -1,12 +1,11 @@ -extern crate stm32f103xx; -use i2c::{I2C, TransDir, DutyType}; +use i2c::{I2C, TransDir}; const AT24C_ADDR: u8 = 0b1010111; /* suppose A0, A1, A2 = 1 */ -pub struct AT24C<'a, 'b: 'a>(&'a I2C<'a, 'b>); +pub struct AT24C<'a>(&'a I2C<'a>); -impl<'a, 'b> AT24C<'a, 'b> { - pub fn new(i2c: &'a I2C<'a, 'b>) -> AT24C<'a, 'b> { +impl<'a> AT24C<'a> { + pub fn new(i2c: &'a I2C<'a>) -> AT24C<'a> { AT24C(i2c) } diff --git a/src/ds3231.rs b/src/ds3231.rs index 375ce21..07e99f1 100644 --- a/src/ds3231.rs +++ b/src/ds3231.rs @@ -1,4 +1,3 @@ -extern crate stm32f103xx; use i2c::{I2C, TransDir, DutyType}; const DS3231_ADDR: u8 = 0b1101000; @@ -6,7 +5,7 @@ const DS3231_REG_SEC: u8 = 0x00; const DS3231_REG_CTL: u8 = 0x0e; const DS3231_REG_TEMP: u8 = 0x11; -pub struct DS3231<'a, 'b: 'a>(&'a I2C<'a, 'b>); +pub struct DS3231<'a>(&'a I2C<'a>); pub struct Date { pub second: u8, @@ -25,8 +24,8 @@ pub struct Temp { pub quarter: u8 } -impl<'a, 'b> DS3231<'a, 'b> { - pub fn new(i2c: &'a I2C<'a, 'b>) -> DS3231<'a, 'b> { +impl<'a> DS3231<'a> { + pub fn new(i2c: &'a I2C<'a>) -> DS3231<'a> { DS3231(i2c) } @@ -1,6 +1,7 @@ #![allow(dead_code)] extern crate stm32f103xx; use core::cmp::max; +use stm32f103xx::{i2c1, rcc, RCC}; pub const EVENT_MASTER_STARTED: u32 = 0x00030001; /* BUSY, MSL and SB flag */ @@ -14,10 +15,7 @@ const FLAGS_MASK: u32 = 0x00ffffff; const HSI_VALUE: u32 = 8000000; const HSE_VALUE: u32 = 8000000; -pub struct I2C<'a, 'b: 'a> { - i2c: &'a stm32f103xx::i2c1::RegisterBlock, - rcc: &'b stm32f103xx::rcc::RegisterBlock, -} +pub struct I2C<'a> (&'a i2c1::RegisterBlock); pub enum TransDir { TRANSMITTER, @@ -29,16 +27,15 @@ pub enum DutyType { DUTY1 } -impl<'a, 'b> I2C<'a, 'b> { +impl<'a> I2C<'a> { #[inline(always)] - pub fn new(i2c: &'a stm32f103xx::i2c1::RegisterBlock, - rcc: &'b stm32f103xx::rcc::RegisterBlock) -> I2C<'a, 'b> { - I2C{i2c, rcc} + pub fn new(i2c: &'a i2c1::RegisterBlock) -> I2C<'a> { + I2C(i2c) } - fn get_pclk1(&self) -> u32 { + fn get_pclk1(rcc: &RCC) -> u32 { use stm32f103xx::rcc::cfgr::{SWSR, PLLSRCR, PLLXTPRER}; - let cfgr = self.rcc.cfgr.read(); + let cfgr = rcc.cfgr.read(); let sysclk_freq = match cfgr.sws() { SWSR::HSI => HSI_VALUE, SWSR::HSE => HSE_VALUE, @@ -68,13 +65,14 @@ impl<'a, 'b> I2C<'a, 'b> { /// TODO: support for standard mode pub fn init(&self, + rcc: &RCC, addr: u8, scl_freq: u32, duty_type: DutyType, fast_mode: bool) { - let i2c = &self.i2c; + let &I2C(ref i2c) = self; unsafe { - let pclk1 = self.get_pclk1(); + let pclk1 = I2C::get_pclk1(rcc); let freq_range: u16 = (pclk1 / 1_000_000) as u16; self.pe(false); /* TRISE configuration (in Fm mode, max rise interval is 300) */ @@ -107,7 +105,7 @@ impl<'a, 'b> I2C<'a, 'b> { } pub fn pe(&self, enable: bool) { - let i2c = &self.i2c; + let &I2C(ref i2c) = self; unsafe { match enable { true => i2c.cr1.modify(|r, w| w.bits(r.bits()).pe().set_bit()), @@ -117,11 +115,11 @@ impl<'a, 'b> I2C<'a, 'b> { } pub fn is_ack_fail(&self) -> bool { - self.i2c.sr1.read().af().bit_is_set() + self.0.sr1.read().af().bit_is_set() } pub fn start(&self, enable: bool, synced: bool) { - let i2c = &self.i2c; + let &I2C(ref i2c) = self; unsafe { match enable { true => i2c.cr1.modify(|r, w| w.bits(r.bits()).start().set_bit()), @@ -137,7 +135,7 @@ impl<'a, 'b> I2C<'a, 'b> { } pub fn stop(&self, enable: bool) { - let i2c = &self.i2c; + let &I2C(ref i2c) = self; unsafe { match enable { true => i2c.cr1.modify(|r, w| w.bits(r.bits()).stop().set_bit()), @@ -147,7 +145,7 @@ impl<'a, 'b> I2C<'a, 'b> { } pub fn conf_ack(&self, enable: bool) { - let i2c = &self.i2c; + let &I2C(ref i2c) = self; unsafe { match enable { true => i2c.cr1.modify(|r, w| w.bits(r.bits()).ack().set_bit()), @@ -162,8 +160,8 @@ impl<'a, 'b> I2C<'a, 'b> { TransDir::RECEIVER => 1 }; unsafe { - self.i2c.sr1.write(|w| w.af().clear_bit()); - self.i2c.dr.write(|w| w.dr().bits(addr)); + self.0.sr1.write(|w| w.af().clear_bit()); + self.0.dr.write(|w| w.dr().bits(addr)); } if synced { match d { @@ -186,7 +184,7 @@ impl<'a, 'b> I2C<'a, 'b> { pub fn send(&self, data: u8, synced: bool) { unsafe { - self.i2c.dr.write(|w| w.dr().bits(data)); + self.0.dr.write(|w| w.dr().bits(data)); } if synced { while !self.check_event(EVENT_MASTER_BYTE_TRANSMITTED) {} @@ -197,12 +195,12 @@ impl<'a, 'b> I2C<'a, 'b> { if synced { while !self.check_event(EVENT_MASTER_BYTE_RECEIVED) {} } - self.i2c.dr.read().dr().bits() + self.0.dr.read().dr().bits() } pub fn check_event(&self, ev_mask: u32) -> bool { - let flags = self.i2c.sr1.read().bits() & 0xffff | - ((self.i2c.sr2.read().bits() & 0xffff) << 16) & FLAGS_MASK; + let flags = self.0.sr1.read().bits() & 0xffff | + ((self.0.sr2.read().bits() & 0xffff) << 16) & FLAGS_MASK; (flags & ev_mask) == ev_mask } } diff --git a/src/main.rs b/src/main.rs index d5fdef9..8de0ba5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,20 @@ #![no_std] +#![feature(asm)] #[macro_use] extern crate stm32f103xx; extern crate cortex_m; -use stm32f103xx::{GPIOA, GPIOB, RCC, SYST, I2C1}; + +use stm32f103xx::{GPIOA, GPIOB, RCC, SYST, I2C1, EXTI, NVIC, Interrupt, AFIO, Peripherals}; +use stm32f103xx::{gpioa}; use cortex_m::peripheral::SystClkSource; + +mod mutex; mod i2c; mod ds3231; mod at24c; struct ShiftRegister<'a> { - gpioa: &'a stm32f103xx::gpioa::RegisterBlock, + gpioa: &'a gpioa::RegisterBlock, width: u8, } @@ -27,6 +32,7 @@ static mut RTC: Option<ds3231::DS3231> = None; static mut ROM: Option<at24c::AT24C> = None; static mut DIGITS: [u8; 6] = [0; 6]; static mut TIME: Clock = Clock{sec: 0, min: 0, hr: 0, reset: 0}; +static mut PERIP: Option<Peripherals> = None; fn digits2bcds(digs: &[u8]) -> u32 { let mut res: u32 = 0; @@ -38,7 +44,7 @@ fn digits2bcds(digs: &[u8]) -> u32 { fn digits_countup() { unsafe { - SR.as_mut().unwrap().output_bits(digits2bcds(&DIGITS[..])); + SR.as_ref().unwrap().output_bits(digits2bcds(&DIGITS[..])); let mut i = 0; let mut carry = 1; while carry > 0 && i < DIGITS.len() { @@ -49,23 +55,40 @@ fn digits_countup() { } } +fn refresh_clock() { + unsafe { + SR.as_ref().unwrap().output_bits(digits2bcds(&DIGITS[..])); + } +} + +fn render_clock() { + unsafe { + if 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 { + *i = 0xf; + } + } + } +} + fn update_clock() { unsafe { if RTC.is_none() {return} if !TIME.tick() { let ds3231::Date{second: sec, minute: min, - hour: hr, ..} = RTC.as_mut().unwrap() + hour: hr, ..} = RTC.as_ref().unwrap() .read_fulldate(); TIME = Clock{sec, min, 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[..])); } + render_clock(); + refresh_clock(); } fn systick_handler() { @@ -73,16 +96,34 @@ fn systick_handler() { update_clock(); } +static mut bs: bool = false; + +fn exti3_handler() { + let p = unsafe {PERIP.as_ref().unwrap()}; + p.EXTI.pr.write(|w| w.pr3().set_bit()); + let x = p.GPIOA.idr.read().idr3().bit(); + unsafe { + if !x && !bs { + bs = true; + } else if x && bs { + bs = false; + } + } + render_clock(); + refresh_clock(); +} + exception!(SYS_TICK, systick_handler); +interrupt!(EXTI3, exti3_handler); impl<'a> ShiftRegister<'a> { - fn new(gpioa: &'a stm32f103xx::gpioa::RegisterBlock, + fn new(gpioa: &'a gpioa::RegisterBlock, width: u8) -> ShiftRegister<'a> { let this = ShiftRegister{gpioa, width}; this } - fn output_bits(&mut self, bits: u32) { + fn output_bits(&self, bits: u32) { let bsrr = &self.gpioa.bsrr; for i in (0..self.width).rev() { bsrr.write(|w| w.br1().reset()); @@ -126,74 +167,93 @@ impl Clock { } } -fn main() { - - let gpioa: &stm32f103xx::gpioa::RegisterBlock = unsafe { &*GPIOA.get() }; - let gpiob: &stm32f103xx::gpioa::RegisterBlock = unsafe { &*GPIOB.get() }; - let rcc: &stm32f103xx::rcc::RegisterBlock = unsafe { &*RCC.get() }; - let i2c: &stm32f103xx::i2c1::RegisterBlock = unsafe { &*I2C1.get() }; - let syst: &cortex_m::peripheral::SYST = unsafe { &*SYST.get() }; +fn init() { + let p = unsafe { + PERIP = Some(Peripherals::all()); + PERIP.as_ref().unwrap() + }; - syst.set_clock_source(SystClkSource::Core); - syst.set_reload(8_000_000); - syst.enable_interrupt(); - syst.enable_counter(); + p.SYST.set_clock_source(SystClkSource::Core); + p.SYST.set_reload(8_000_000); + p.SYST.enable_interrupt(); + p.SYST.enable_counter(); /* enable GPIOA, GPIOB and AFIO */ - rcc.apb2enr.modify(|_, w| w.iopaen().enabled() + p.RCC.apb2enr.modify(|_, w| w.iopaen().enabled() .iopben().enabled() .afioen().enabled()); /* GPIO */ /* enable PA0-2 for manipulating shift register */ - gpioa.crl.modify(|_, w| + p.GPIOA.odr.modify(|_, w| w.odr3().set_bit()); + p.GPIOA.crl.modify(|_, w| w.mode0().output().cnf0().push() .mode1().output().cnf1().push() - .mode2().output().cnf2().push()); + .mode2().output().cnf2().push() + .mode3().input().cnf3().bits(0b10)); /* enable PB6 and PB7 for I2C1 */ - gpiob.crl.modify(|_, w| + p.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()); + p.RCC.apb1enr.modify(|_, w| w.i2c1en().enabled()); + p.RCC.apb1rstr.modify(|_, w| w.i2c1rst().set_bit()); + p.RCC.apb1rstr.modify(|_, w| w.i2c1rst().clear_bit()); + + /* NVIC & EXTI */ + p.AFIO.exticr1.write(|w| unsafe { w.exti3().bits(0b0000) }); + p.NVIC.enable(Interrupt::EXTI3); + 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()); + unsafe { - I2C = Some(i2c::I2C::new(i2c, rcc)); - let i2c = I2C.as_mut().unwrap(); - let rtc = ds3231::DS3231::new(i2c); + I2C = Some(i2c::I2C::new(p.I2C1)); + let i2c = I2C.as_ref().unwrap(); + RTC = Some(ds3231::DS3231::new(i2c)); ROM = Some(at24c::AT24C::new(i2c)); - SR = Some(ShiftRegister::new(gpioa, 24)); + SR = Some(ShiftRegister::new(p.GPIOA, 24)); - i2c.init(0x01, 400_000, i2c::DutyType::DUTY1, true); + i2c.init(p.RCC, 0x01, 400_000, i2c::DutyType::DUTY1, true); //i2c.init(0x01, 100_000, i2c::DutyType::DUTY1, false); - SR.as_mut().unwrap().output_bits(0); - - /* initialize the ds3231 */ - /* - rtc.write_fulldate(&ds3231::Date{second: 30, - minute: 48, - hour: 21, - day: 4, - date: 21, - month: 9, - year: 17, - am: false, - am_enabled: false}); - */ - /* - let rom = ROM.as_mut().unwrap(); - let mut buf: [u8; 64] = [23; 64]; - rom.write(23, 64, &buf); - let mut buf2: [u8; 80] = [0; 80]; - rom.read(20, 80, &mut buf2); - */ - RTC = Some(rtc); + SR.as_ref().unwrap().output_bits(0); } +} +fn set_clock() { + let rtc = unsafe {RTC.as_ref().unwrap()}; + rtc.write_fulldate(&ds3231::Date{second: 30, + minute: 23, + hour: 18, + day: 2, + date: 10, + month: 10, + year: 17, + am: false, + am_enabled: false}); + /* + let rom = ROM.as_ref().unwrap(); + let mut buf: [u8; 64] = [23; 64]; + rom.write(23, 64, &buf); + let mut buf2: [u8; 80] = [0; 80]; + rom.read(20, 80, &mut buf2); + */ +} + +fn main() { + init(); + //set_clock(); + /* + let x = mutex::Mutex::new(42); + { + let y = x.lock(); + let z = *y + 1; + let w = z; + } + */ update_clock(); } |