summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDeterminant <[email protected]>2017-10-30 00:42:00 -0400
committerDeterminant <[email protected]>2017-10-30 00:42:00 -0400
commitd944ac11ebf76d37b9588362a573324c7878842d (patch)
tree48b9c93339fe0c37f12f0cb348dea74eb43cc191 /src
parent296a044ec94bd18b8fa6a9d279fc76363cee9132 (diff)
support auto display on/off
Diffstat (limited to 'src')
-rw-r--r--src/main.rs76
1 files changed, 63 insertions, 13 deletions
diff --git a/src/main.rs b/src/main.rs
index 41bcafc..8bf97b0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,7 @@
#![no_std]
#![feature(asm)]
-#![feature(const_fn)]
+#![feature(const_cell_new)]
+#![feature(const_refcell_new)]
#[macro_use] extern crate stm32f103xx;
extern crate cortex_m;
@@ -30,6 +31,10 @@ fn inc_rotate(n: &mut u8, reset: u8, limit: u8) {
}
}
+fn countdown(n: u32) -> u32 {
+ if n > 0 { n - 1 } else { n }
+}
+
struct ShiftRegister<'a> {
gpioa: &'a gpioa::RegisterBlock,
width: u8,
@@ -42,6 +47,13 @@ struct Time {
hr: u8,
}
+#[derive(PartialEq, Clone, Copy)]
+enum DispState {
+ On,
+ Off,
+ TempOn
+}
+
struct GlobalState<'a> {
perip: Option<Peripherals<'a>>,
disp: Option<ShiftRegister<'a>>,
@@ -52,7 +64,10 @@ struct GlobalState<'a> {
i2c_inited: bool,
sync_cnt: Cell<u8>,
buff: RefCell<[u8; 6]>,
- disp_on: bool,
+ 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>>,
@@ -616,14 +631,14 @@ impl<'a> CountdownPanel<'a> {
if self.state.get() == CountdownPanelState::Inactive {
return
}
- let x = self.counter.get();
+ let x = countdown(self.counter.get());
if x == 0 {
let tim = self.gs.perip.as_ref().unwrap().TIM3;
let timer = tim::Timer(tim);
timer.stop();
self.state.set(CountdownPanelState::TimeUp);
} else {
- self.counter.set(x - 1);
+ self.counter.set(x);
}
self.update_output();
}
@@ -726,7 +741,7 @@ impl<'a> AlarmEventManager<'a> {
unsafe {
for v in &mut *self.events.get() {
if v.free {continue;}
- v.cnt -= 1;
+ v.cnt = countdown(v.cnt);
if v.cnt == 0 {
v.cb.timeout();
v.free = true;
@@ -760,12 +775,12 @@ impl<'a> GlobalState<'a> {
let mut buff = *self.buff.borrow();
let b = self.blink_state.get();
let bs = self.blinky.borrow();
- if self.disp_on {
- for (i, v) in buff.iter_mut().enumerate() {
- if b && bs[i] { *v = 0xf; }
- }
- } else {
- for i in buff.iter_mut() { *i = 0xf; }
+ match self.disp_state.get() {
+ DispState::On | DispState::TempOn =>
+ for (i, v) in buff.iter_mut().enumerate() {
+ if b && bs[i] { *v = 0xf; }
+ },
+ DispState::Off => for i in buff.iter_mut() { *i = 0xf; }
}
self.disp.as_ref().unwrap().output_bits(digits2bcds(&buff[..]));
}
@@ -823,6 +838,26 @@ impl<'a> GlobalState<'a> {
} else {
self.sync_cnt.set(self.sync_cnt.get() - 1);
}
+ let tcnt = countdown(self.tempon_cnt.get() as u32) as u16;
+ match self.disp_state.get() {
+ DispState::Off => {
+ if tcnt == 0 {
+ self.disp_state.set(DispState::TempOn);
+ self.tempon_cnt.set(self.tempon_peroid.get());
+ } else {
+ self.tempon_cnt.set(tcnt);
+ }
+ },
+ DispState::TempOn => {
+ if tcnt == 0 {
+ self.disp_state.set(DispState::Off);
+ self.tempon_cnt.set(self.tempon_cycle.get());
+ } else {
+ self.tempon_cnt.set(tcnt);
+ }
+ },
+ _ => ()
+ }
unsafe {
TIME_PANEL.update_clock(clk);
DATE_PANEL.update_clock(d);
@@ -893,6 +928,15 @@ fn exti3_handler() {
match btn1.release() {
ButtonResult::FalseAlarm => (),
ButtonResult::ShortPress => {
+ match gs.disp_state.get() {
+ DispState::Off => {
+ gs.disp_state.set(DispState::On);
+ gs.display();
+ return;
+ },
+ DispState::TempOn => gs.disp_state.set(DispState::On),
+ _ => ()
+ }
if !gs.panels[gs.pidx].btn1_short() {
gs.pidx += 1;
if gs.pidx == gs.panels.len() {
@@ -901,7 +945,10 @@ fn exti3_handler() {
gs.panels[gs.pidx].btn1_short();
}
},
- ButtonResult::LongPress => { }
+ ButtonResult::LongPress => {
+ gs.disp_state.set(DispState::Off);
+ gs.tempon_cnt.set(gs.tempon_cycle.get());
+ }
}
gs.display();
}
@@ -966,7 +1013,10 @@ static mut GS: GlobalState =
i2c_inited: false,
sync_cnt: Cell::new(0),
buff: RefCell::new([0; 6]),
- disp_on: true,
+ disp_state: Cell::new(DispState::On),
+ tempon_cycle: Cell::new(20),
+ tempon_peroid: Cell::new(5),
+ tempon_cnt: Cell::new(0),
blinky: RefCell::new([false; 6]),
blink_state: Cell::new(false),
blinky_enabled: Cell::new(None),