#![no_std] #![feature(asm)] #![feature(const_fn)] #[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; use core::cell::{Cell, RefCell}; mod mutex; mod i2c; mod ds3231; mod at24c; mod tim; const SYNC_PERIOD: u8 = 10; const BLINK_PERIOD: u32 = 500; fn digits2bcds(digs: &[u8]) -> u32 { let mut res: u32 = 0; for d in digs.iter().rev() { res = (res << 4) | (*d as u32); } res } struct ShiftRegister<'a> { gpioa: &'a gpioa::RegisterBlock, width: u8, } #[derive(Copy, Clone)] struct Time { sec: u8, min: u8, hr: u8, } struct GlobalState { disp: Option>, i2c: Option>, btn1: Option>, //tim: Option>, i2c_inited: bool, sync_cnt: u8, buff: RefCell<[u8; 6]>, blinky: RefCell<[bool; 6]>, blink_state: Cell, perip: Option>, disp_on: bool, pidx: usize, panels: [&'static Panel; 2], } struct Button<'a> { state: Cell, long: Cell, timer: tim::Timer<'a> } enum ButtonResult { FALSE_ALARM, SHORT_PRESS, LONG_PRSSS } impl<'a> Button<'a> { fn new(timer: tim::Timer<'a>, thres: u32) -> Self { /* in milliseconds */ timer.init(thres * (8_000_000 / 1000)); Button {state: Cell::new(false), long: Cell::new(false), timer} } fn press(&self) { if !self.state.get() { self.state.set(true); self.long.set(false); self.timer.reset(); self.timer.go(); } } fn release(&self) -> ButtonResult { if self.state.get() { self.timer.stop(); self.state.set(false); if self.long.get() { ButtonResult::LONG_PRSSS } else { ButtonResult::SHORT_PRESS } } else { ButtonResult::FALSE_ALARM } } fn timeout(&self) { self.timer.stop(); self.long.set(true); } } 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); } #[derive(PartialEq, Clone, Copy)] enum TimePanelState { VIEW, EDIT_HR, EDIT_MIN, EDIT_SEC } struct TimePanel<'a> { gs: &'a GlobalState, state: Cell, time: RefCell