M source/src/calendar.rs => source/src/calendar.rs +3 -3
@@ 1,4 1,4 @@
-use core::cmp::{max, min};
+use core::cmp::max;
#[derive(Clone, PartialEq, Eq)]
pub struct Calendar {
@@ 46,7 46,7 @@ impl Calendar {
/// Calculate current date based off of the seconds elapsed since
/// a base date
- pub fn from_ticks(base_year: u16, mut seconds: u32) -> Self {
+ pub fn from_ticks(base_year: u16, seconds: u32) -> Self {
let total_seconds = seconds;
let seconds = total_seconds % 60;
@@ 255,7 255,7 @@ impl Calendar {
}
pub fn unfreeze(&mut self) {
- self.frozen = true;
+ self.frozen = false;
}
fn days_in_month(month: u8, leap_year: bool) -> u8 {
M source/src/clock_app.rs => source/src/clock_app.rs +42 -107
@@ 1,43 1,28 @@
-use core::marker::PhantomData;
-
use alloc::boxed::Box;
use stm32f1xx_hal::rtc::Rtc;
use crate::{
brightness_manager::BrightnessManager,
button::ButtonState,
- clock_display_viewer::{ClockDisplayViewer, DisplayView},
- clock_state::ClockState,
+ clock_display_viewer::ClockDisplayViewer,
+ clock_state::ClockState, app_mode::{ClockAppMode, ClockAppModes, default_app_mode::DefaultAppMode, edit_app_mode::EditAppMode},
};
pub struct ClockApp {
rtc: Rtc,
display: ClockDisplayViewer,
state: ClockState,
- buttons: [Box<dyn ClockButton + Send>; 4],
+ modes: [Box<dyn ClockAppMode + Send>; core::mem::variant_count::<ClockAppModes>()],
brightness: BrightnessManager,
- current_view: DisplayView,
-}
-
-struct AppState<'a> {
- rtc: &'a mut Rtc,
- display: &'a mut ClockDisplayViewer,
- state: &'a mut ClockState,
- brightness: &'a mut BrightnessManager,
- current_view: &'a mut DisplayView,
-}
-
-trait ClockButton {
- fn handle(&self, state: ButtonState, state: AppState);
+ current_mode: ClockAppModes,
}
-struct ButtonSwitchView;
-struct ButtonChangeTime;
-
-struct Up;
-struct Down;
-struct ButtonBrightness<Direction> {
- direction: PhantomData<Direction>,
+pub struct AppState<'a> {
+ pub rtc: &'a mut Rtc,
+ pub display: &'a mut ClockDisplayViewer,
+ pub state: &'a mut ClockState,
+ pub brightness: &'a mut BrightnessManager,
+ pub current_mode: &'a mut ClockAppModes,
}
pub enum ClockInterrupt {
@@ 51,16 36,10 @@ impl ClockApp {
rtc,
display,
state,
- current_view: DisplayView::ClockView,
- buttons: [
- Box::new(ButtonSwitchView),
- Box::new(ButtonChangeTime),
- Box::new(ButtonBrightness::<Down> {
- direction: PhantomData::<Down>,
- }),
- Box::new(ButtonBrightness::<Up> {
- direction: PhantomData::<Up>,
- }),
+ current_mode: ClockAppModes::NormalMode,
+ modes: [
+ Box::new(DefaultAppMode::new()),
+ Box::new(EditAppMode::new())
],
brightness: BrightnessManager::new(),
}
@@ 74,96 53,52 @@ impl ClockApp {
}
ClockInterrupt::DisplayTimer => {
let _ = self.display.update(&self.state);
- self.brightness.update(&self.state);
self.brightness.apply_brightness(&mut self.display);
+
+ let mut mode = self.current_mode;
+ let app_state = AppState {
+ rtc: &mut self.rtc,
+ display: &mut self.display,
+ state: &mut self.state,
+ brightness: &mut self.brightness,
+ current_mode: &mut mode,
+ };
+ self.modes[self.current_mode as usize].update(app_state);
}
}
}
pub fn handle_button(&mut self, index: usize, state: ButtonState) {
- self.buttons[index].handle(
- state,
- AppState {
+ let mut mode = self.current_mode;
+ let current_mode = self.modes[self.current_mode as usize].as_mut();
+
+ {
+ let app_state = AppState {
rtc: &mut self.rtc,
display: &mut self.display,
state: &mut self.state,
brightness: &mut self.brightness,
- current_view: &mut self.current_view,
- },
- );
- }
-
- pub fn display(&mut self) -> &mut ClockDisplayViewer {
- &mut self.display
- }
-}
+ current_mode: &mut mode,
+ };
-impl ClockButton for ButtonSwitchView {
- fn handle(&self, state: ButtonState, app: AppState) {
- match state {
- ButtonState::JustPressed => {
- let display = app.display;
- let current_view = *app.current_view as usize;
- let new_view = ((current_view + 1) % core::mem::variant_count::<DisplayView>())
- .try_into()
- .unwrap();
- display.set_current_view(new_view);
- *app.current_view = new_view;
- }
- _ => (),
+ current_mode.handle_button(app_state, index, state);
}
- }
-}
-
-// How long to turn off the brightness adjustment on user brightness change, in seconds
-const BRIGHT_OFF_FOR: u32 = 30 * 60;
-const BRIGHT_CHANGE: i8 = 10; // How much to change the brightness on press
-impl ClockButton for ButtonBrightness<Down> {
- fn handle(&self, state: ButtonState, app: AppState) {
- match state {
- ButtonState::JustPressed | ButtonState::LongPress => {
- app.brightness.turn_off_for(&app.state, BRIGHT_OFF_FOR);
- app.brightness
- .set_brightness(app.brightness.brightness() as i8 - BRIGHT_CHANGE);
+ if self.current_mode != mode {
+ let mut temp_mode = mode;
+ {
+ current_mode.stop(AppState { rtc: &mut self.rtc, display: &mut self.display, state: &mut self.state, brightness: &mut self.brightness, current_mode: &mut temp_mode });
}
- _ => (),
- }
- }
-}
-impl ClockButton for ButtonBrightness<Up> {
- fn handle(&self, state: ButtonState, app: AppState) {
- match state {
- ButtonState::JustPressed | ButtonState::LongPress => {
- app.brightness.turn_off_for(&app.state, BRIGHT_OFF_FOR);
- app.brightness
- .set_brightness(app.brightness.brightness() as i8 + BRIGHT_CHANGE);
- }
- _ => (),
+ self.current_mode = temp_mode;
+
+ let current_mode = self.modes[self.current_mode as usize].as_mut();
+ current_mode.run(AppState { rtc: &mut self.rtc, display: &mut self.display, state: &mut self.state, brightness: &mut self.brightness, current_mode: &mut temp_mode });
}
}
-}
-impl ClockButton for ButtonChangeTime {
- fn handle(&self, state: ButtonState, app: AppState) {
- match state {
- ButtonState::JustPressed => {
- app.rtc.set_time(app.rtc.current_time() + 2);
- }
- _ => (),
- }
+ pub fn display(&mut self) -> &mut ClockDisplayViewer {
+ &mut self.display
}
}
-// to edit date, second button can be used
-// to enter edit mode
-// DateEditMode
-// editing_field
-// 1. Hours, 2. Minutes, 3. Seconds,
-// 4. Year, 5. Month, 6. Day
-// button functions:
-// 1. next field
-// 2. current_field++
-// 3. current_field--
-// 4. set
M source/src/clock_display.rs => source/src/clock_display.rs +5 -0
@@ 124,6 124,11 @@ impl ClockDisplay {
let offset = Self::get_part_offset(part);
let size = Self::get_part_size(part);
+ self.hide_at(offset, size);
+ }
+
+ pub fn hide_at(&mut self, offset: usize, size: usize) {
+
let mut data = self.display.data();
for current_data in data.iter_mut().skip(offset).take(size) {
*current_data = 0;
M source/src/clock_display_viewer.rs => source/src/clock_display_viewer.rs +17 -6
@@ 1,5 1,3 @@
-use core::mem;
-
use crate::{
clock_display::{ClockDisplay, DisplayPart},
clock_state::ClockState,
@@ 29,6 27,7 @@ impl TryFrom<usize> for DisplayView {
#[derive(Copy, Clone, PartialEq, Eq)]
#[repr(usize)]
+#[derive(core::marker::ConstParamTy)]
pub enum ClockPart {
Hours = 0,
Minutes = 1,
@@ 75,10 74,6 @@ impl ClockDisplayViewer {
for part in self.parts.iter_mut() {
*part = false;
}
-
- self.clock_display.hide(DisplayPart::MainDisplay);
- self.clock_display.hide(DisplayPart::SideDisplay1);
- self.clock_display.hide(DisplayPart::SideDisplay2);
}
pub fn clock_display(&mut self) -> &mut ClockDisplay {
@@ 180,6 175,22 @@ impl ClockDisplayViewer {
}
}
+ if !self.parts[ClockPart::Day as usize] {
+ self.clock_display.hide(DisplayPart::SideDisplay1);
+ }
+
+ if !self.parts[ClockPart::Month as usize] && !self.parts[ClockPart::Seconds as usize] {
+ self.clock_display.hide(DisplayPart::SideDisplay2);
+ }
+
+ if !self.parts[ClockPart::Hours as usize] && !self.parts[ClockPart::Year as usize] {
+ self.clock_display.hide_at(ClockDisplay::get_part_offset(DisplayPart::MainDisplay), 2);
+ }
+
+ if !self.parts[ClockPart::Minutes as usize] && !self.parts[ClockPart::Year as usize] {
+ self.clock_display.hide_at(ClockDisplay::get_part_offset(DisplayPart::MainDisplay) + 2, 2);
+ }
+
if self.parts[ClockPart::Hours as usize] && self.parts[ClockPart::Minutes as usize] {
self.clock_display
.set_colon(state.calendar().seconds() % 2 == 0);
M source/src/clock_state.rs => source/src/clock_state.rs +4 -0
@@ 20,6 20,10 @@ impl ClockState {
&self.calendar
}
+ pub fn mut_calendar(&mut self) -> &mut Calendar {
+ &mut self.calendar
+ }
+
pub fn second_elapsed(&mut self) {
self.calendar.second_elapsed()
}
M source/src/lib.rs => source/src/lib.rs +2 -0
@@ 1,6 1,7 @@
#![cfg_attr(test, no_main)]
#![no_std]
#![feature(variant_count)]
+#![feature(adt_const_params)]
use defmt_rtt as _; // global logger
@@ 21,6 22,7 @@ pub mod linear_interpolation;
pub mod mono_timer;
pub mod number_digits;
pub mod seven_segments;
+pub mod app_mode;
extern crate alloc;
M source/src/main.rs => source/src/main.rs +2 -0
@@ 2,6 2,7 @@
#![no_main]
#![feature(alloc_error_handler)]
#![feature(variant_count)]
+#![feature(adt_const_params)]
extern crate alloc;
@@ 18,6 19,7 @@ pub mod linear_interpolation;
pub mod mono_timer;
pub mod number_digits;
pub mod seven_segments;
+pub mod app_mode;
use alloc::boxed::Box;
use button::{ActiveHigh, Button, ButtonState};