#![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};
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;
}
}
fn countdown(n: u32) -> u32 {
if n > 0 { n - 1 } else { n }
}
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; 5],
}
#[derive(PartialEq, Clone, Copy)]
enum ButtonState {
Idle,
PressedLock,
PressedUnlock,
ReleaseLock
}
struct Button<'a> {
state: Cell<ButtonState>,
long: Cell<bool>,
events: &'a AlarmEventManager<'a>,
ev_id: Cell<u8>
}
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<TimePanelState>,
time: RefCell<Time>,
tmp: RefCell<Time>
}
#[derive(Clone, Copy)]
struct Date {
yr: u8,
mon: u8,
day: u8
}
#[derive(PartialEq, Clone, Copy)]
enum DatePanelState {
Inactive,
View,
EditYr,
EditMon,
EditDay
}
struct DatePanel<'a> {
gs: &'a GlobalState<'a>,
state: Cell<DatePanelState>,
date: RefCell<Date>,
tmp: RefCell<Date>
}
#[derive(PartialEq, Clone, Copy)]
enum TempPanelState {
Inactive,
View
}
struct TempPanel<'a> {
state: Cell<TempPanelState>,
temp: Cell<ds3231::Temp>,
gs: &'a GlobalState<'a>,
}
#[derive(PartialEq, Clone, Copy)]
enum CountdownPanelState {
Inactive,
View,
EditWhole,
Edit3,
Edit2,
Edit1,
Edit0,
Edit2m,
Edit1m,
OnGoing,
OnGoingPaused,
TimeUp
}
struct CountdownPanel<'a> {
state: Cell<CountdownPanelState>,
presets: RefCell<[[u8; 6]; 2]>,
counter: Cell<u32>,
didx: