summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeterminant <[email protected]>2017-10-18 15:52:06 -0400
committerDeterminant <[email protected]>2017-10-18 15:52:06 -0400
commitd09fadccb157c47c10a2edfbb3b229dda53a0ee1 (patch)
treed23ea4eade859a2a1594fefda4e96a46b1c67430
parent6e0b5539fd440208edd9ec995ca35a93413843ba (diff)
reduce unsafe blocks
-rw-r--r--src/at24c.rs4
-rw-r--r--src/ds3231.rs6
-rw-r--r--src/i2c.rs6
-rw-r--r--src/main.rs144
4 files changed, 79 insertions, 81 deletions
diff --git a/src/at24c.rs b/src/at24c.rs
index 169c048..44ae3b4 100644
--- a/src/at24c.rs
+++ b/src/at24c.rs
@@ -5,10 +5,6 @@ const AT24C_ADDR: u8 = 0b1010111; /* suppose A0, A1, A2 = 1 */
pub struct AT24C<'a>(&'a I2C<'a>);
impl<'a> AT24C<'a> {
- pub fn new(i2c: &'a I2C<'a>) -> AT24C<'a> {
- AT24C(i2c)
- }
-
pub fn read(&self, start: u16, size: usize, buf: &mut [u8]) {
let &AT24C(ref i2c) = self;
i2c.conf_ack(true); /* enable ack */
diff --git a/src/ds3231.rs b/src/ds3231.rs
index 07e99f1..bd23fdd 100644
--- a/src/ds3231.rs
+++ b/src/ds3231.rs
@@ -5,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>(&'a I2C<'a>);
+pub struct DS3231<'a>(pub &'a I2C<'a>);
pub struct Date {
pub second: u8,
@@ -25,10 +25,6 @@ pub struct Temp {
}
impl<'a> DS3231<'a> {
- pub fn new(i2c: &'a I2C<'a>) -> DS3231<'a> {
- DS3231(i2c)
- }
-
fn bcd2dec(bcd: u8) -> u8 {
(bcd >> 4) * 10 + (bcd & 0x0f)
}
diff --git a/src/i2c.rs b/src/i2c.rs
index 2647ffb..e275140 100644
--- a/src/i2c.rs
+++ b/src/i2c.rs
@@ -15,7 +15,7 @@ const FLAGS_MASK: u32 = 0x00ffffff;
const HSI_VALUE: u32 = 8000000;
const HSE_VALUE: u32 = 8000000;
-pub struct I2C<'a> (&'a i2c1::RegisterBlock);
+pub struct I2C<'a> (pub &'a i2c1::RegisterBlock);
pub enum TransDir {
TRANSMITTER,
@@ -29,10 +29,6 @@ pub enum DutyType {
impl<'a> I2C<'a> {
#[inline(always)]
- pub fn new(i2c: &'a i2c1::RegisterBlock) -> I2C<'a> {
- I2C(i2c)
- }
-
fn get_pclk1(rcc: &RCC) -> u32 {
use stm32f103xx::rcc::cfgr::{SWSR, PLLSRCR, PLLXTPRER};
let cfgr = rcc.cfgr.read();
diff --git a/src/main.rs b/src/main.rs
index 8de0ba5..a98b250 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -13,6 +13,8 @@ mod i2c;
mod ds3231;
mod at24c;
+const SYNC_PERIOD: u8 = 10;
+
struct ShiftRegister<'a> {
gpioa: &'a gpioa::RegisterBlock,
width: u8,
@@ -25,14 +27,28 @@ struct Clock {
reset: u8
}
-const RESET_PERIOD: u8 = 10;
-static mut SR: Option<ShiftRegister> = None;
-static mut I2C: Option<i2c::I2C> = None;
-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;
+struct GlobalState {
+ disp: Option<ShiftRegister<'static>>,
+ i2c: Option<i2c::I2C<'static>>,
+ i2c_inited: bool,
+ buff: [u8; 6],
+ time: Clock,
+ perip: Option<Peripherals<'static>>,
+ bs: bool
+}
+
+static mut GS: GlobalState =
+ GlobalState{disp: None,
+ i2c: None,
+ i2c_inited: false,
+ buff: [0; 6],
+ time: Clock{sec: 0, min: 0, hr: 0, reset: 0},
+ perip: None,
+ bs: false};
+
+fn get_gs() -> &'static mut GlobalState {
+ unsafe {&mut GS}
+}
fn digits2bcds(digs: &[u8]) -> u32 {
let mut res: u32 = 0;
@@ -42,53 +58,53 @@ fn digits2bcds(digs: &[u8]) -> u32 {
res
}
-fn digits_countup() {
- unsafe {
- SR.as_ref().unwrap().output_bits(digits2bcds(&DIGITS[..]));
- let mut i = 0;
- let mut carry = 1;
- while carry > 0 && i < DIGITS.len() {
- DIGITS[i] += carry;
- carry = if DIGITS[i] > 9 {DIGITS[i] = 0; 1} else {0};
- i += 1;
- }
- }
+fn display() {
+ let gs = get_gs();
+ gs.disp.as_ref().unwrap().output_bits(digits2bcds(&gs.buff[..]));
}
-fn refresh_clock() {
- unsafe {
- SR.as_ref().unwrap().output_bits(digits2bcds(&DIGITS[..]));
+fn digits_countup() {
+ let gs = get_gs();
+ let mut digits = gs.buff;
+ gs.disp.as_ref().unwrap().output_bits(digits2bcds(&digits[..]));
+ let mut i = 0;
+ let mut carry = 1;
+ while carry > 0 && i < digits.len() {
+ digits[i] += carry;
+ carry = if digits[i] > 9 {digits[i] = 0; 1} else {0};
+ i += 1;
}
}
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;
- }
+ let gs = get_gs();
+ let mut digits = 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 {
+ *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_ref().unwrap()
- .read_fulldate();
- TIME = Clock{sec, min, hr,
- reset: RESET_PERIOD};
- }
+ let gs = get_gs();
+ let p = gs.perip.as_ref().unwrap();
+ let rtc = ds3231::DS3231(gs.i2c.as_ref().unwrap());
+ if !gs.i2c_inited {return}
+ if !gs.time.tick() {
+ let ds3231::Date{second: sec,
+ minute: min,
+ hour: hr, ..} = rtc.read_fulldate();
+ gs.time = Clock{sec, min, hr,
+ reset: SYNC_PERIOD};
}
render_clock();
- refresh_clock();
+ display();
}
fn systick_handler() {
@@ -96,21 +112,18 @@ fn systick_handler() {
update_clock();
}
-static mut bs: bool = false;
-
fn exti3_handler() {
- let p = unsafe {PERIP.as_ref().unwrap()};
+ let gs = get_gs();
+ let p = gs.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;
- }
+ if !x && !gs.bs {
+ gs.bs = true;
+ } else if x && gs.bs {
+ gs.bs = false;
}
render_clock();
- refresh_clock();
+ display();
}
exception!(SYS_TICK, systick_handler);
@@ -168,9 +181,10 @@ impl Clock {
}
fn init() {
- let p = unsafe {
- PERIP = Some(Peripherals::all());
- PERIP.as_ref().unwrap()
+ let gs = get_gs();
+ let p = {
+ gs.perip = Some(unsafe {Peripherals::all()});
+ gs.perip.as_ref().unwrap()
};
p.SYST.set_clock_source(SystClkSource::Core);
@@ -211,21 +225,17 @@ fn init() {
p.EXTI.ftsr.write(|w| w.tr3().set_bit());
- unsafe {
- 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(p.GPIOA, 24));
-
- i2c.init(p.RCC, 0x01, 400_000, i2c::DutyType::DUTY1, true);
- //i2c.init(0x01, 100_000, i2c::DutyType::DUTY1, false);
- SR.as_ref().unwrap().output_bits(0);
- }
+ gs.i2c = Some(i2c::I2C(p.I2C1));
+ gs.disp = Some(ShiftRegister::new(p.GPIOA, 24));
+ gs.i2c.as_ref().unwrap().init(p.RCC, 0x01, 400_000, i2c::DutyType::DUTY1, true);
+ //i2c.init(0x01, 100_000, i2c::DutyType::DUTY1, false);
+ gs.disp.as_ref().unwrap().output_bits(0);
}
fn set_clock() {
- let rtc = unsafe {RTC.as_ref().unwrap()};
+ let gs = get_gs();
+ let p = gs.perip.as_ref().unwrap();
+ let rtc = ds3231::DS3231(gs.i2c.as_ref().unwrap());
rtc.write_fulldate(&ds3231::Date{second: 30,
minute: 23,
hour: 18,