|
@@ -1,4 +1,9 @@
|
|
|
-use core::future::pending;
|
|
|
+use stm32l4xx_hal::prelude::{
|
|
|
+ _embedded_hal_blocking_i2c_Read, _embedded_hal_blocking_i2c_Write,
|
|
|
+ _embedded_hal_blocking_i2c_WriteRead,
|
|
|
+};
|
|
|
+
|
|
|
+use crate::ds3231;
|
|
|
|
|
|
pub const DS3231_ADDR: u8 = 0x68;
|
|
|
pub const TUSB322_ADDR: u8 = 0x47;
|
|
@@ -362,7 +367,7 @@ pub fn refresh_frame() {
|
|
|
}
|
|
|
d.updated = true;
|
|
|
pending_refresh = true;
|
|
|
- },
|
|
|
+ }
|
|
|
DigitState::Decrementing => {
|
|
|
d.value = d.value.saturating_sub(steps);
|
|
|
if d.value <= DIGIT_MIN_BRIGHTNESS {
|
|
@@ -371,8 +376,7 @@ pub fn refresh_frame() {
|
|
|
}
|
|
|
d.updated = true;
|
|
|
pending_refresh = true;
|
|
|
-
|
|
|
- },
|
|
|
+ }
|
|
|
DigitState::Idle => (),
|
|
|
}
|
|
|
}
|
|
@@ -388,7 +392,7 @@ pub fn refresh_frame() {
|
|
|
}
|
|
|
CLOCK.dot.updated = true;
|
|
|
pending_refresh = true;
|
|
|
- },
|
|
|
+ }
|
|
|
DigitState::Decrementing => {
|
|
|
CLOCK.dot.value = CLOCK.dot.value.saturating_sub(steps);
|
|
|
if CLOCK.dot.value >= DIGIT_MIN_BRIGHTNESS {
|
|
@@ -397,7 +401,7 @@ pub fn refresh_frame() {
|
|
|
}
|
|
|
CLOCK.dot.updated = true;
|
|
|
pending_refresh = true;
|
|
|
- },
|
|
|
+ }
|
|
|
DigitState::Idle => (),
|
|
|
}
|
|
|
}
|
|
@@ -406,3 +410,85 @@ pub fn refresh_frame() {
|
|
|
// TODO! trigger refresh timer
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+pub fn rtc_tick<T>(i2c: &mut T)
|
|
|
+where
|
|
|
+ T: _embedded_hal_blocking_i2c_WriteRead
|
|
|
+ + _embedded_hal_blocking_i2c_Read
|
|
|
+ + _embedded_hal_blocking_i2c_Write,
|
|
|
+{
|
|
|
+ static mut STARTUP: bool = true;
|
|
|
+ static mut PREV_MINUTE: u32 = 0;
|
|
|
+ static mut PREV_HOUR: u32 = 0;
|
|
|
+
|
|
|
+ let (second, minute, hour) = ds3231::get_time(DS3231_ADDR, i2c);
|
|
|
+ let (weekday, day, month, _, _) = ds3231::get_date(DS3231_ADDR, i2c);
|
|
|
+
|
|
|
+ let hour = if ds3231::in_dst(weekday, day, month, hour) {
|
|
|
+ (hour + 1) % 12
|
|
|
+ } else {
|
|
|
+ hour % 12
|
|
|
+ };
|
|
|
+ let hour = if hour == 0 { 12 } else { hour };
|
|
|
+
|
|
|
+ unsafe {
|
|
|
+ if STARTUP || PREV_HOUR / 10 != hour / 10 {
|
|
|
+ fade_in_out_digit(
|
|
|
+ 0,
|
|
|
+ if hour / 10 != 0 {
|
|
|
+ Some((hour / 10) as usize)
|
|
|
+ } else {
|
|
|
+ None
|
|
|
+ },
|
|
|
+ DIGIT_FADE_DURATION_US,
|
|
|
+ false,
|
|
|
+ )
|
|
|
+ }
|
|
|
+ if STARTUP || PREV_HOUR % 10 != hour % 10 {
|
|
|
+ fade_in_out_digit(1, Some((hour % 10) as usize), DIGIT_FADE_DURATION_US, false);
|
|
|
+ }
|
|
|
+ if STARTUP || PREV_MINUTE / 10 != minute / 10 {
|
|
|
+ fade_in_out_digit(
|
|
|
+ 2,
|
|
|
+ Some((minute / 10) as usize),
|
|
|
+ DIGIT_FADE_DURATION_US,
|
|
|
+ false,
|
|
|
+ );
|
|
|
+ }
|
|
|
+ if STARTUP || PREV_MINUTE % 10 != minute % 10 {
|
|
|
+ fade_in_out_digit(
|
|
|
+ 3,
|
|
|
+ Some((minute % 10) as usize),
|
|
|
+ DIGIT_FADE_DURATION_US,
|
|
|
+ false,
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ CLOCK.dot.current_state = match second % 2 {
|
|
|
+ 0 => DigitState::Incrementing,
|
|
|
+ 1 => DigitState::Decrementing,
|
|
|
+ _ => DigitState::Idle,
|
|
|
+ };
|
|
|
+
|
|
|
+ PREV_MINUTE = minute;
|
|
|
+ PREV_HOUR = hour;
|
|
|
+
|
|
|
+ STARTUP = false;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+pub fn refresh_tick<T>(i2c: &mut T)
|
|
|
+where
|
|
|
+ T: _embedded_hal_blocking_i2c_WriteRead
|
|
|
+ + _embedded_hal_blocking_i2c_Read
|
|
|
+ + _embedded_hal_blocking_i2c_Write,
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+pub fn rng_tick<T>(i2c: &mut T)
|
|
|
+where
|
|
|
+ T: _embedded_hal_blocking_i2c_WriteRead
|
|
|
+ + _embedded_hal_blocking_i2c_Read
|
|
|
+ + _embedded_hal_blocking_i2c_Write,
|
|
|
+{
|
|
|
+}
|