Ctx, SD
This commit is contained in:
parent
8dda09689d
commit
d8865488e3
12 changed files with 328 additions and 166 deletions
41
Cargo.lock
generated
41
Cargo.lock
generated
|
@ -42,7 +42,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "bcb2392079bf27198570d6af79ecbd9ec7d8f16d3ec6b60933922fdb66287127"
|
||||
dependencies = [
|
||||
"heapless",
|
||||
"nom 4.2.3",
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -74,6 +74,7 @@ dependencies = [
|
|||
"bitflags",
|
||||
"cortex-m",
|
||||
"embedded-hal",
|
||||
"embedded-sdmmc",
|
||||
"modular-bitfield",
|
||||
"nb 1.1.0",
|
||||
"num-traits",
|
||||
|
@ -341,12 +342,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "embedded-sdmmc"
|
||||
version = "0.5.0"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f4d14180a76a8af24a45a0e1a4f9c97491b05a3b962d59d5e4ce0e6ab103736"
|
||||
checksum = "6d3bf0a2b5becb87e9a329d9290f131e4d10fec39b56d129926826a7cbea1e7a"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"embedded-hal",
|
||||
"log",
|
||||
"nb 0.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -530,6 +533,7 @@ version = "0.10.0"
|
|||
dependencies = [
|
||||
"atsamd-hal",
|
||||
"cortex-m-rt",
|
||||
"embedded-sdmmc",
|
||||
"usb-device",
|
||||
]
|
||||
|
||||
|
@ -619,16 +623,6 @@ dependencies = [
|
|||
"version_check 0.1.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "6.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6a7a9657c84d5814c6196b68bb4429df09c18b1573806259fba397ea4ad0d44"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"version_check 0.9.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
|
@ -832,8 +826,6 @@ dependencies = [
|
|||
"epd-waveshare",
|
||||
"maduino_zero_4g",
|
||||
"panic-halt",
|
||||
"tinybmp",
|
||||
"tinytga",
|
||||
"tz-rs",
|
||||
"tzdb",
|
||||
]
|
||||
|
@ -939,25 +931,6 @@ dependencies = [
|
|||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinybmp"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e959c507975d768a226a08227d56791f6e60bddcf714ad7ef67ae2d20bae743"
|
||||
dependencies = [
|
||||
"embedded-graphics",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinytga"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "756dcc0078b35e5f8ab052f19a48225821fd046011342d31deef6b8d5c825d2b"
|
||||
dependencies = [
|
||||
"embedded-graphics",
|
||||
"nom 6.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.16.0"
|
||||
|
|
|
@ -12,12 +12,10 @@ atsamd-hal = { version = "0.15.1", default_features = false, features = ["samd21
|
|||
cfg-if = "1.0.0"
|
||||
embedded-graphics = "0.7.1"
|
||||
embedded-text = "0.5.0"
|
||||
embedded-sdmmc = { version = "0.5.0", default_features = false }
|
||||
embedded-sdmmc = { version = "0.3.0", default_features = false }
|
||||
epd-waveshare = "0.5.0"
|
||||
maduino_zero_4g = { git = "https://github.com/ZettaScript/atsamd", branch = "maduino-zero-4g", features = ["usb"] }
|
||||
panic-halt = "0.2.0"
|
||||
tinybmp = "0.4.0"
|
||||
tinytga = "0.4.1"
|
||||
tz-rs = { version = "0.6.14", default_features = false, features = ["const"] }
|
||||
tzdb = { version = "0.5.7", optional = true }
|
||||
|
||||
|
@ -31,6 +29,7 @@ simulator = ["embedded-graphics-simulator", "tzdb"]
|
|||
|
||||
[profile.release]
|
||||
lto = "fat"
|
||||
opt-level = 3
|
||||
|
||||
[patch."https://github.com/ZettaScript/atsamd"]
|
||||
maduino_zero_4g = { path = "../atsamd/boards/maduino_zero_4g" }
|
||||
|
|
|
@ -14,7 +14,7 @@ rustup target add thumbv6m-none-eabi
|
|||
## Run simulator
|
||||
|
||||
```bash
|
||||
cargo run
|
||||
cargo run --features simulator
|
||||
```
|
||||
|
||||
## Build
|
||||
|
@ -59,7 +59,7 @@ Note: at most 5 outputs of the 74HC565 may be used as GPO.
|
|||
https://www.makerfabs.com/maduino-zero-4g-lte-sim7600.html
|
||||
https://www.waveshare.com/1.54inch-e-Paper-Module.htm1
|
||||
https://bulkmemorycards.com/shop/microsd-cards/microsd-32gb/sd-32gb-class-10/32gb-microsd-ultra-sandisk-memory-card-2/
|
||||
Maybe an ESP for WIFI and Bluetooth.
|
||||
Maybe an ESP for WIFI and Bluetooth: https://www.sparkfun.com/products/18034
|
||||
|
||||
## crates
|
||||
bitmap-font ?
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
use crate::display::Display;
|
||||
use crate::{display::Display, keypad::KeyEvents, state::ModeState, Context};
|
||||
|
||||
pub mod clock;
|
||||
pub mod dial;
|
||||
|
||||
pub trait App {
|
||||
type State;
|
||||
type AppModeState;
|
||||
|
||||
fn update(display: &mut Display);
|
||||
/// Return Some if the mode should be changed
|
||||
fn update(context: &mut Context, mode_state: &mut Self::AppModeState) -> Option<ModeState>;
|
||||
}
|
||||
|
|
112
src/apps/clock.rs
Normal file
112
src/apps/clock.rs
Normal file
|
@ -0,0 +1,112 @@
|
|||
use crate::{
|
||||
apps,
|
||||
apps::App,
|
||||
display::Display,
|
||||
keypad::*,
|
||||
state::{self, ModeState},
|
||||
strf, Context,
|
||||
};
|
||||
|
||||
use arrayvec::ArrayString;
|
||||
use embedded_graphics::{
|
||||
mono_font::{ascii::FONT_10X20, MonoTextStyleBuilder},
|
||||
pixelcolor::BinaryColor,
|
||||
prelude::*,
|
||||
text::{Alignment, Text},
|
||||
};
|
||||
|
||||
pub struct Clock;
|
||||
|
||||
pub struct ClockState {
|
||||
year: i32,
|
||||
month: u8,
|
||||
day: u8,
|
||||
week_day: u8,
|
||||
}
|
||||
|
||||
impl Default for ClockState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
year: 0,
|
||||
month: 0,
|
||||
day: 0,
|
||||
week_day: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl App for Clock {
|
||||
type AppModeState = ClockState;
|
||||
|
||||
fn update(ctx: &mut Context, mode_state: &mut ClockState) -> Option<ModeState> {
|
||||
// TODO move at init
|
||||
let clock_text_style = MonoTextStyleBuilder::new()
|
||||
.font(&FONT_10X20)
|
||||
.text_color(BinaryColor::On)
|
||||
.background_color(BinaryColor::Off)
|
||||
.build();
|
||||
|
||||
for key_event in &ctx.key_events {
|
||||
if key_event.event_type != KeyEventType::Pressed {
|
||||
continue;
|
||||
}
|
||||
match key_event.key {
|
||||
_ => {
|
||||
if let Some(ch) = key_event.get_char(KeyInputMode::Digit) {
|
||||
let mut buf = [0; 4];
|
||||
return Some(ModeState::Dial(apps::dial::DialState {
|
||||
line: ArrayString::from(&*ch.encode_utf8(&mut buf)).unwrap(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ctx.hm_change {
|
||||
Text::with_alignment(
|
||||
unsafe {
|
||||
core::str::from_utf8_unchecked(&strf::fmt_time_hm(
|
||||
ctx.state.hour,
|
||||
ctx.state.minute,
|
||||
))
|
||||
},
|
||||
ctx.display.inner().bounding_box().center() + Point::new(0, 10),
|
||||
clock_text_style,
|
||||
Alignment::Center,
|
||||
)
|
||||
.draw(ctx.display.inner_mut())
|
||||
.unwrap();
|
||||
|
||||
let year_ = ctx.now.year();
|
||||
let month_ = ctx.now.month();
|
||||
let day_ = ctx.now.month_day();
|
||||
let week_day_ = ctx.now.week_day();
|
||||
if (year_, month_, day_, week_day_)
|
||||
!= (
|
||||
mode_state.year,
|
||||
mode_state.month,
|
||||
mode_state.day,
|
||||
mode_state.week_day,
|
||||
) {
|
||||
mode_state.year = year_;
|
||||
mode_state.month = month_;
|
||||
mode_state.day = day_;
|
||||
mode_state.week_day = week_day_;
|
||||
Text::with_alignment(
|
||||
unsafe {
|
||||
core::str::from_utf8_unchecked(&strf::fmt_time_ymdw(
|
||||
year_, month_, day_, week_day_,
|
||||
))
|
||||
},
|
||||
ctx.display.inner().bounding_box().center() + Point::new(0, -20),
|
||||
clock_text_style,
|
||||
Alignment::Center,
|
||||
)
|
||||
.draw(ctx.display.inner_mut())
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
|
@ -1 +1,45 @@
|
|||
use crate::{
|
||||
apps::App,
|
||||
display::Display,
|
||||
keypad::{Key, KeyEvent, KeyEventType, KeyEvents, KeyInputMode},
|
||||
state::{ModeState, State},
|
||||
Context,
|
||||
};
|
||||
|
||||
use arrayvec::ArrayString;
|
||||
|
||||
pub struct Dial;
|
||||
|
||||
pub struct DialState {
|
||||
// TODO what should max length be?
|
||||
pub line: ArrayString<255>,
|
||||
}
|
||||
|
||||
impl App for Dial {
|
||||
type AppModeState = DialState;
|
||||
|
||||
fn update(ctx: &mut Context, mode_state: &mut DialState) -> Option<ModeState> {
|
||||
for key_event in &ctx.key_events {
|
||||
if key_event.event_type != KeyEventType::Pressed {
|
||||
continue;
|
||||
}
|
||||
match key_event.key {
|
||||
Key::HangUp => {
|
||||
return Some(ModeState::Clock(Default::default()));
|
||||
}
|
||||
Key::PickUp => {
|
||||
// TODO
|
||||
}
|
||||
_ => {
|
||||
if let Some(ch) = key_event.get_char(KeyInputMode::Digit) {
|
||||
if mode_state.line.try_push(ch).is_err() {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
29
src/fs.rs
Normal file
29
src/fs.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
use atsamd_hal::{delay::Delay, pac::Peripherals, prelude::*, sercom::spi::EightBit};
|
||||
use embedded_sdmmc::{Controller, SdMmcSpi, VolumeIdx};
|
||||
|
||||
pub struct Fs {
|
||||
controller: Controller<SdMmcSpi<maduino_zero_4g::SdSpi, maduino_zero_4g::SdCs>, ClockMock>,
|
||||
}
|
||||
|
||||
impl Fs {
|
||||
pub fn new(spi: maduino_zero_4g::SdSpi, cs: maduino_zero_4g::SdCs) -> Self {
|
||||
let controller = Controller::new(SdMmcSpi::new(spi, cs), ClockMock);
|
||||
Self { controller }
|
||||
}
|
||||
}
|
||||
|
||||
struct ClockMock;
|
||||
|
||||
// TODO
|
||||
impl embedded_sdmmc::TimeSource for ClockMock {
|
||||
fn get_timestamp(&self) -> embedded_sdmmc::Timestamp {
|
||||
embedded_sdmmc::Timestamp {
|
||||
year_since_1970: 0,
|
||||
zero_indexed_month: 0,
|
||||
zero_indexed_day: 0,
|
||||
hours: 0,
|
||||
minutes: 0,
|
||||
seconds: 0,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1 +1 @@
|
|||
|
||||
pub trait Widget {}
|
||||
|
|
|
@ -4,6 +4,8 @@ const NB_KEYS: usize = 21;
|
|||
/// Key repeat max delay (ms)
|
||||
const REPEAT_DELAY: u64 = 500;
|
||||
|
||||
pub type KeyEvents = ArrayVec<KeyEvent, 4>;
|
||||
|
||||
pub struct Keypad {
|
||||
last_key: Option<(Key, u64, u8)>,
|
||||
pressed: [bool; NB_KEYS],
|
||||
|
@ -19,7 +21,7 @@ impl Default for Keypad {
|
|||
}
|
||||
|
||||
impl Keypad {
|
||||
pub fn update(&mut self) -> ArrayVec<KeyEvent, 4> {
|
||||
pub fn update(&mut self) -> KeyEvents {
|
||||
self.get_keys()
|
||||
.into_iter()
|
||||
.zip(self.pressed.iter_mut())
|
||||
|
@ -137,26 +139,41 @@ impl Key {
|
|||
}
|
||||
|
||||
pub struct KeyEvent {
|
||||
event_type: KeyEventType,
|
||||
key: Key,
|
||||
repeats: u8,
|
||||
pub event_type: KeyEventType,
|
||||
pub key: Key,
|
||||
pub repeats: u8,
|
||||
}
|
||||
|
||||
/*impl KeyEvent {
|
||||
impl KeyEvent {
|
||||
pub fn get_char(&self, key_input_mode: KeyInputMode) -> Option<char> {
|
||||
use Key::*;
|
||||
match key_input_mode {
|
||||
|
||||
KeyInputMode::Digit => match self.key {
|
||||
D0 =>
|
||||
D0 => Some('0'),
|
||||
D1 => Some('1'),
|
||||
D2 => Some('2'),
|
||||
D3 => Some('3'),
|
||||
D4 => Some('4'),
|
||||
D5 => Some('5'),
|
||||
D6 => Some('6'),
|
||||
D7 => Some('7'),
|
||||
D8 => Some('8'),
|
||||
D9 => Some('9'),
|
||||
Asterisk => Some('*'),
|
||||
Hash => Some('#'),
|
||||
_ => None,
|
||||
},
|
||||
_ => {
|
||||
None /* TODO */
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
//ncb1 upz2 tdk3
|
||||
//eow4 lqh5 age6
|
||||
//sfx7 rmj8 ivy9
|
||||
|
||||
#[derive(Eq, PartialEq)]
|
||||
pub enum KeyEventType {
|
||||
Pressed,
|
||||
Down,
|
||||
|
|
192
src/main.rs
192
src/main.rs
|
@ -5,25 +5,19 @@ mod apps;
|
|||
mod config;
|
||||
mod display;
|
||||
mod energy;
|
||||
mod fs;
|
||||
mod gui;
|
||||
mod keypad;
|
||||
mod state;
|
||||
mod strf;
|
||||
mod time;
|
||||
|
||||
use apps::App;
|
||||
use display::Display;
|
||||
use energy::EnergyStatus;
|
||||
use keypad::KeyEvents;
|
||||
use state::*;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(not(feature = "simulator"))] {
|
||||
use maduino_zero_4g as bsp;
|
||||
use bsp::hal;
|
||||
|
||||
use hal::pac::{CorePeripherals, Peripherals};
|
||||
use hal::prelude::*;
|
||||
}
|
||||
}
|
||||
|
||||
use arrayvec::ArrayString;
|
||||
use core::fmt::Write;
|
||||
use embedded_graphics::{
|
||||
|
@ -33,36 +27,55 @@ use embedded_graphics::{
|
|||
primitives::{Line, PrimitiveStyle, PrimitiveStyleBuilder, Rectangle, StrokeAlignment},
|
||||
text::{Alignment, Text},
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "simulator"))]
|
||||
use panic_halt as _;
|
||||
|
||||
static mut STATE: State = State {
|
||||
energy: EnergyStatus {
|
||||
battery: 255,
|
||||
charging: false,
|
||||
},
|
||||
hour: 0,
|
||||
minute: 0,
|
||||
mode: Mode::Clock {
|
||||
year: 0,
|
||||
month: 0,
|
||||
day: 0,
|
||||
week_day: 0,
|
||||
use maduino_zero_4g::{
|
||||
self as bsp,
|
||||
hal::{
|
||||
clock::GenericClockController,
|
||||
delay::Delay,
|
||||
pac::{CorePeripherals, Peripherals},
|
||||
prelude::*,
|
||||
},
|
||||
};
|
||||
|
||||
fn state() -> &'static State {
|
||||
unsafe { &STATE }
|
||||
}
|
||||
|
||||
fn state_mut() -> &'static mut State {
|
||||
unsafe { &mut STATE }
|
||||
}
|
||||
#[cfg(not(feature = "simulator"))]
|
||||
use panic_halt as _;
|
||||
use tz::DateTime;
|
||||
|
||||
#[cfg_attr(not(feature = "simulator"), bsp::entry)]
|
||||
fn main() -> ! {
|
||||
let mut display = display::Display::new();
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(not(feature = "simulator"))] {
|
||||
let mut peripherals = Peripherals::take().unwrap();
|
||||
let mut pins = maduino_zero_4g::Pins::new(peripherals.PORT);
|
||||
let core = CorePeripherals::take().unwrap();
|
||||
let mut clocks = GenericClockController::with_external_32kosc(
|
||||
peripherals.GCLK,
|
||||
&mut peripherals.PM,
|
||||
&mut peripherals.SYSCTRL,
|
||||
&mut peripherals.NVMCTRL,
|
||||
);
|
||||
let mut delay = Delay::new(core.SYST, &mut clocks);
|
||||
|
||||
let mut fs = fs::Fs::new(atsamd_hal::sercom::spi::Config::new(
|
||||
&peripherals.PM,
|
||||
peripherals.SERCOM4,
|
||||
atsamd_hal::sercom::spi::Pads::default().data_in(pins.sd_miso).data_out(pins.sd_mosi).sclk(pins.sd_sck),
|
||||
10_u32.mhz(),
|
||||
).enable(), pins.d4.into_push_pull_output());
|
||||
}
|
||||
}
|
||||
|
||||
let mut state = State {
|
||||
energy: EnergyStatus {
|
||||
battery: 255,
|
||||
charging: false,
|
||||
},
|
||||
hour: 0,
|
||||
minute: 0,
|
||||
};
|
||||
let mut mode_state = ModeState::Clock(Default::default());
|
||||
|
||||
let mut display = Display::new();
|
||||
let mut keypad = keypad::Keypad::default();
|
||||
|
||||
let thin_stroke = PrimitiveStyle::with_stroke(BinaryColor::On, 1);
|
||||
|
@ -73,11 +86,6 @@ fn main() -> ! {
|
|||
.text_color(BinaryColor::On)
|
||||
.background_color(BinaryColor::Off)
|
||||
.build();
|
||||
let clock_text_style = MonoTextStyleBuilder::new()
|
||||
.font(&FONT_10X20)
|
||||
.text_color(BinaryColor::On)
|
||||
.background_color(BinaryColor::Off)
|
||||
.build();
|
||||
|
||||
Line::new(Point::new(0, 13), Point::new(199, 13))
|
||||
.into_styled(thin_stroke)
|
||||
|
@ -87,13 +95,19 @@ fn main() -> ! {
|
|||
#[cfg(feature = "simulator")]
|
||||
display.update();
|
||||
|
||||
let mut update = true;
|
||||
let mut hm_change = true;
|
||||
let mut ctx = Context {
|
||||
display: &mut display,
|
||||
hm_change: true,
|
||||
key_events: Default::default(),
|
||||
now: DateTime::from_timespec(0, 0, tz::TimeZoneRef::utc()).unwrap(),
|
||||
update: true,
|
||||
state: &mut state,
|
||||
};
|
||||
loop {
|
||||
let energy_status = energy::get_energy_status();
|
||||
|
||||
if energy_status != state().energy {
|
||||
update = true;
|
||||
if energy_status != ctx.state.energy {
|
||||
ctx.update = true;
|
||||
|
||||
Text::with_alignment(
|
||||
unsafe { core::str::from_utf8_unchecked(&strf::fmt_energy(&energy_status)) },
|
||||
|
@ -101,21 +115,21 @@ fn main() -> ! {
|
|||
statusbar_text_style,
|
||||
Alignment::Left,
|
||||
)
|
||||
.draw(display.inner_mut())
|
||||
.draw(ctx.display.inner_mut())
|
||||
.unwrap();
|
||||
|
||||
state_mut().energy = energy_status;
|
||||
ctx.state.energy = energy_status;
|
||||
}
|
||||
|
||||
let now = time::now();
|
||||
ctx.now = time::now();
|
||||
|
||||
let hour = now.hour();
|
||||
let minute = now.minute();
|
||||
if (hour, minute) != (state().hour, state().minute) {
|
||||
update = true;
|
||||
hm_change = true;
|
||||
state_mut().hour = hour;
|
||||
state_mut().minute = minute;
|
||||
let hour = ctx.now.hour();
|
||||
let minute = ctx.now.minute();
|
||||
if (hour, minute) != (ctx.state.hour, ctx.state.minute) {
|
||||
ctx.update = true;
|
||||
ctx.hm_change = true;
|
||||
ctx.state.hour = hour;
|
||||
ctx.state.minute = minute;
|
||||
|
||||
Text::with_alignment(
|
||||
unsafe { core::str::from_utf8_unchecked(&strf::fmt_time_hm(hour, minute)) },
|
||||
|
@ -123,67 +137,41 @@ fn main() -> ! {
|
|||
statusbar_text_style,
|
||||
Alignment::Right,
|
||||
)
|
||||
.draw(display.inner_mut())
|
||||
.draw(ctx.display.inner_mut())
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let key_events = keypad.update();
|
||||
ctx.key_events = keypad.update();
|
||||
|
||||
match &mut state_mut().mode {
|
||||
Mode::Clock {
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
week_day,
|
||||
} => {
|
||||
if hm_change {
|
||||
Text::with_alignment(
|
||||
unsafe { core::str::from_utf8_unchecked(&strf::fmt_time_hm(hour, minute)) },
|
||||
display.inner().bounding_box().center() + Point::new(0, 10),
|
||||
clock_text_style,
|
||||
Alignment::Center,
|
||||
)
|
||||
.draw(display.inner_mut())
|
||||
.unwrap();
|
||||
|
||||
let year_ = now.year();
|
||||
let month_ = now.month();
|
||||
let day_ = now.month_day();
|
||||
let week_day_ = now.week_day();
|
||||
if (year_, month_, day_, week_day_) != (*year, *month, *day, *week_day) {
|
||||
*year = year_;
|
||||
*month = month_;
|
||||
*day = day_;
|
||||
*week_day = week_day_;
|
||||
Text::with_alignment(
|
||||
unsafe {
|
||||
core::str::from_utf8_unchecked(&strf::fmt_time_ymdw(
|
||||
year_, month_, day_, week_day_,
|
||||
))
|
||||
},
|
||||
display.inner().bounding_box().center() + Point::new(0, -20),
|
||||
clock_text_style,
|
||||
Alignment::Center,
|
||||
)
|
||||
.draw(display.inner_mut())
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(new_mode_state) = match &mut mode_state {
|
||||
ModeState::Clock(clock_state) => apps::clock::Clock::update(&mut ctx, clock_state),
|
||||
ModeState::Dial(dial_state) => apps::dial::Dial::update(&mut ctx, dial_state),
|
||||
} {
|
||||
mode_state = new_mode_state;
|
||||
}
|
||||
|
||||
#[cfg(feature = "simulator")]
|
||||
{
|
||||
display.update();
|
||||
ctx.display.update();
|
||||
std::thread::sleep(core::time::Duration::from_millis(50));
|
||||
}
|
||||
#[cfg(not(feature = "simulator"))]
|
||||
if update {
|
||||
display.update();
|
||||
if ctx.update {
|
||||
ctx.display.update();
|
||||
}
|
||||
// TODO sleep on samd
|
||||
#[cfg(not(feature = "simulator"))]
|
||||
delay.delay_ms(50_u8);
|
||||
|
||||
update = false;
|
||||
hm_change = false;
|
||||
ctx.update = false;
|
||||
ctx.hm_change = false;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Context<'a> {
|
||||
pub state: &'a mut State,
|
||||
pub display: &'a mut Display,
|
||||
pub hm_change: bool,
|
||||
pub now: DateTime,
|
||||
pub update: bool,
|
||||
pub key_events: KeyEvents,
|
||||
}
|
||||
|
|
20
src/state.rs
20
src/state.rs
|
@ -1,18 +1,18 @@
|
|||
use crate::energy::EnergyStatus;
|
||||
use crate::{apps, energy::EnergyStatus};
|
||||
|
||||
/*pub struct State {
|
||||
pub global: GlobalState,
|
||||
pub mode: ModeState,
|
||||
}*/
|
||||
|
||||
/// Global state
|
||||
pub struct State {
|
||||
pub energy: EnergyStatus,
|
||||
pub hour: u8,
|
||||
pub minute: u8,
|
||||
pub mode: Mode,
|
||||
}
|
||||
|
||||
pub enum Mode {
|
||||
Clock {
|
||||
year: i32,
|
||||
month: u8,
|
||||
day: u8,
|
||||
week_day: u8,
|
||||
},
|
||||
#[warn(clippy::large_enum_variant)]
|
||||
pub enum ModeState {
|
||||
Clock(apps::clock::ClockState),
|
||||
Dial(apps::dial::DialState),
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use tz::DateTime;
|
||||
|
||||
use crate::energy::EnergyStatus;
|
||||
|
||||
static WEEK_DAYS: [[u8; 3]; 7] = [
|
||||
|
|
Loading…
Reference in a new issue