summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeterminant <ted.sybil@gmail.com>2017-10-18 14:35:48 -0400
committerDeterminant <ted.sybil@gmail.com>2017-10-18 14:35:48 -0400
commit177667b7034ec09bb0d7146077bb3c0b7ba28336 (patch)
tree392855183e96c36e0ad870d5770a6e3c2504857b
parentb27ebb9f07d7ee0b60abe84738db712c8fbcb3f1 (diff)
code refactoring
-rw-r--r--src/at24c.rs9
-rw-r--r--src/ds3231.rs7
-rw-r--r--src/i2c.rs44
-rw-r--r--src/main.rs172
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)
}
diff --git a/src/i2c.rs b/src/i2c.rs
index 1f8a57f..2647ffb 100644
--- a/src/i2c.rs
+++ b/src/i2c.rs
@@ -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();
}