#![no_std] #![feature(asm)] #![feature(const_fn)] #[macro_use] extern crate stm32f103xx; extern crate cortex_m; use stm32f103xx::{Interrupt, Peripherals, gpioa}; use core::cell::{Cell, RefCell, UnsafeCell}; 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; } } struct ShiftRegister<'a> { gpioa: &'a gpioa::RegisterBlock, width: u8, } #[derive(Clone, Copy)] struct Time { sec: u8, min: u8, hr: u8, } struct GlobalState<'a> { perip: Option>, disp: Option>, btn1: Option>, btn2: Option>, events: Option>, i2c: Option>, i2c_inited: bool, sync_cnt: Cell, buff: RefCell<[u8; 6]>, disp_on: bool, blinky: RefCell<[bool; 6]>, blink_state: Cell, blinky_enabled: Cell>, pidx: usize, panels: [&'a Panel; 5], } #[derive(PartialEq, Clone, Copy)] enum ButtonState { Idle, PressedLock, PressedUnlock, ReleaseLock } struct Button<'a> { state: Cell, long: Cell, events: &'a AlarmEventManager<'a>, ev_id: Cell } enum ButtonResult { FalseAlarm, ShortPress, LongPress } trait Panel { fn btn1_short(&self) -> bool {false} fn btn1_long(&self) -> bool {false} fn btn2_short(&self) -> bool {false} fn btn2_long(&self) -> bool {false} fn update_output(&self); } trait Timeoutable<'a> { fn timeout(&'a self); } #[derive(PartialEq, Clone, Copy)] enum TimePanelState { Inactive, View, EditHr, EditMin, EditSec, } struct TimePanel<'a> { gs: &'a GlobalState<'a>, state: Cell, time: RefCell