#![no_std]
#![feature(asm)]
#[macro_use] extern crate stm32f103xx;
extern crate cortex_m;
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;
const SYNC_PERIOD: u8 = 10;
struct ShiftRegister<'a> {
gpioa: &'a gpioa::RegisterBlock,
width: u8,
}
struct Clock {
sec: u8,
min: u8,
hr: u8,
reset: u8
}
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;
for d in digs.iter().rev() {
res = (res << 4) | (*d as u32);
}
res
}
fn display() {
let gs = get_gs();
gs.disp.as_ref().unwrap().output_bits(digits2bcds(&gs.buff[..]));
}
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() {
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;
}