1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
use std::time::{Duration, Instant};
macro_rules! to_ticks { ($dur:expr) => {($dur.as_millis() / 4) as u16}; }
macro_rules! from_ticks { ($ticks:expr) => {Duration::from_millis(($ticks * 4).into())}; }
macro_rules! now { () => {
time::OffsetDateTime::now_local().unwrap_or_else(|_| time::OffsetDateTime::now_utc())};}
/// Create a method to set the instant of a timer.
macro_rules! generate_set_timer_method {
($i:tt) => { mini_paste::item!{
pub fn [< set_timer_ $i >] (&mut self) {
let ticks = &mut self. [< timer_ $i >];
let instant = &mut self. [< timer_ $i _end >];
*instant = Instant::now() + from_ticks!(*ticks);
}
}};
}
/// Create a method to update the value of a timer.
macro_rules! generate_update_timer_method {
($i:tt) => { mini_paste::item!{
pub fn [< update_timer_ $i >] (&mut self) -> u16 {
let ticks = &mut self. [< timer_ $i >];
let instant = &mut self. [< timer_ $i _end >];
if *ticks > 0 {
*ticks = to_ticks!(instant.duration_since(Instant::now()));
if *ticks == 0 { self.wake_flag = true; }
}
return *ticks;
}
}};
}
pub struct ClockDevice {
pub wake_flag: bool,
pub program_start: Instant,
pub uptime: u16,
pub timer_1_end: Instant,
pub timer_2_end: Instant,
pub timer_3_end: Instant,
pub timer_4_end: Instant,
pub timer_1: u16,
pub timer_2: u16,
pub timer_3: u16,
pub timer_4: u16,
}
impl ClockDevice {
pub fn new() -> Self {
Self {
wake_flag: false,
program_start: Instant::now(),
uptime: 0,
timer_1_end: Instant::now(),
timer_2_end: Instant::now(),
timer_3_end: Instant::now(),
timer_4_end: Instant::now(),
timer_1: 0,
timer_2: 0,
timer_3: 0,
timer_4: 0,
}
}
generate_set_timer_method!{1}
generate_set_timer_method!{2}
generate_set_timer_method!{3}
generate_set_timer_method!{4}
generate_update_timer_method!{1}
generate_update_timer_method!{2}
generate_update_timer_method!{3}
generate_update_timer_method!{4}
pub fn update_timers(&mut self) {
self.update_timer_1();
self.update_timer_2();
self.update_timer_3();
self.update_timer_4();
}
pub fn update_uptime(&mut self) -> u16 {
self.uptime = to_ticks!(self.program_start.elapsed());
return self.uptime;
}
pub fn year(&self) -> u8 {
now!().year().saturating_sub(2000).try_into().unwrap_or(u8::MAX)
}
pub fn month(&self) -> u8 {
now!().month() as u8 - 1
}
pub fn day(&self) -> u8 {
now!().day() as u8 - 1
}
pub fn hour(&self) -> u8 {
now!().hour()
}
pub fn minute(&self) -> u8 {
now!().minute()
}
pub fn second(&self) -> u8 {
now!().second()
}
pub fn time_to_next_wake(&self) -> Option<Duration> {
[self.timer_1, self.timer_2, self.timer_3, self.timer_4]
.iter()
.filter(|t| **t > 0)
.min()
.and_then(|t| Some(from_ticks!(t)))
}
}
|