#![no_std]
#![feature(asm)]
#![feature(const_cell_new)]
#![feature(const_refcell_new)]
#[macro_use] extern crate stm32f103xx;
extern crate cortex_m;
use stm32f103xx::{Interrupt, Peripherals, gpioa};
use core::cell::{Cell, RefCell, UnsafeCell, RefMut};
mod mutex;
mod i2c;
mod ds3231;
mod at24c;
mod tim;
#[inline]
fn digits2bcds(digs: &[u8]) -> u32 {
let mut res: u32 = 0;
for d in digs.iter().rev() {
res = (res << 4) | (*d as u32);
}
res
}
fn inc_rotate(n: &mut u8, reset: u8, limit: u8) {
*n += 1;
if *n == limit {
*n = reset;
}
}
#[inline]
fn countdown(n: u32) -> u32 {
if n > 0 { n - 1 } else { n }
}
fn render1(mut buff: RefMut<[u8; 6]>, mut n: u32) {
for i in 0..buff.len() {
buff[i] = (n % 10) as u8;
n /= 10;
}
}
fn render3(mut buff: RefMut<[u8; 6]>, n1: u8, n2: u8, n3: u8) {
buff[1] = n3 / 10; buff[0] = n3 - buff[1] * 10;
buff[3] = n2 / 10; buff[2] = n2 - buff[3] * 10;
buff[5] = n1 / 10; buff[4] = n1 - buff[5] * 10;
}
struct ShiftRegister<'a> {
gpioa: &'a gpioa::RegisterBlock,
width: u8,
}
#[derive(Clone, Copy)]
struct Time {
sec: u8,
min: u8,
hr: u8,
}
#[derive(PartialEq, Clone, Copy)]
enum DispState {
On,
Off,
TempOn
}
struct GlobalState<'a> {
perip: Option<Peripherals<'a>>,
disp: Option<ShiftRegister<'a>>,
btn1: Option<Button<'a>>,
btn2: Option<Button<'a>>,
events: Option<AlarmEventManager<'a>>,
i2c: Option<i2c::I2C<'a>>,
i2c_inited: bool,
sync_cnt: Cell<u8>,
buff: RefCell<[u8; 6]>,
disp_state: Cell<DispState>,
tempon_cycle: Cell<u16>,
tempon_peroid: Cell<u16>,
tempon_cnt: Cell<u16>,
blinky: RefCell<[bool; 6]>,
blink_state: Cell<bool>,
blinky_enabled: Cell<Option<u8>>,
pidx: usize,
panels: [&'a Panel; 6],
}
#[derive(PartialEq, Clone, Copy)]
enum ButtonState {
Idle,
PressedLock,
PressedUnlock,
ReleaseLock
}
struct Button<'