A personal rust firmware for the Badger 2040 W
1use super::{BitFlags, Control, DEVICE_ADDRESS, Error, PCF85063, Register, decode_bcd, encode_bcd};
2use embedded_hal_1::i2c::I2c;
3use time::Time;
4
5impl<I2C, E> PCF85063<I2C>
6where
7 I2C: I2c<Error = E>,
8{
9 /// Set the alarm seconds, minutes and hours, keeping the AE bit unchanged.
10 pub fn set_alarm_time(&mut self, time: Time) -> Result<(), Error<E>> {
11 self.set_alarm_seconds(time.second())?;
12 self.set_alarm_minutes(time.minute())?;
13 self.set_alarm_hours(time.hour())?;
14 Ok(())
15 }
16
17 /// Set the alarm seconds [0-59], keeping the AE bit unchanged.
18 pub fn set_alarm_seconds(&mut self, seconds: u8) -> Result<(), Error<E>> {
19 if seconds > 59 {
20 return Err(Error::InvalidInputData);
21 }
22 let data: u8 = self.read_register(Register::SECOND_ALARM)?; // read current value
23 let data: u8 = data & BitFlags::AE; // keep the AE bit as is
24 let setting: u8 = encode_bcd(seconds);
25 let data: u8 = data | setting;
26 self.write_register(Register::SECOND_ALARM, data)
27 }
28
29 /// Set the alarm minutes [0-59], keeping the AE bit unchanged.
30 pub fn set_alarm_minutes(&mut self, minutes: u8) -> Result<(), Error<E>> {
31 if minutes > 59 {
32 return Err(Error::InvalidInputData);
33 }
34 let data: u8 = self.read_register(Register::MINUTE_ALARM)?; // read current value
35 let data: u8 = data & BitFlags::AE; // keep the AE bit as is
36 let setting: u8 = encode_bcd(minutes);
37 let data: u8 = data | setting;
38 self.write_register(Register::MINUTE_ALARM, data)
39 }
40
41 /// Set the alarm hours [0-23], keeping the AE bit unchanged.
42 pub fn set_alarm_hours(&mut self, hours: u8) -> Result<(), Error<E>> {
43 if hours > 23 {
44 return Err(Error::InvalidInputData);
45 }
46 let data: u8 = self.read_register(Register::HOUR_ALARM)?; // read current value
47 let data: u8 = data & BitFlags::AE; // keep the AE bit as is
48 let setting: u8 = encode_bcd(hours);
49 let data: u8 = data | setting;
50 self.write_register(Register::HOUR_ALARM, data)
51 }
52
53 /// Set the alarm day [1-31], keeping the AE bit unchanged.
54 pub fn set_alarm_day(&mut self, day: u8) -> Result<(), Error<E>> {
55 if !(1..=31).contains(&day) {
56 return Err(Error::InvalidInputData);
57 }
58 let data: u8 = self.read_register(Register::DAY_ALARM)?; // read current value
59 let data: u8 = data & BitFlags::AE; // keep the AE bit as is
60 let setting: u8 = encode_bcd(day);
61 let data: u8 = data | setting;
62 self.write_register(Register::DAY_ALARM, data)
63 }
64
65 /// Set the alarm weekday [0-6], keeping the AE bit unchanged.
66 pub fn set_alarm_weekday(&mut self, weekday: u8) -> Result<(), Error<E>> {
67 if weekday > 6 {
68 return Err(Error::InvalidInputData);
69 }
70 let data: u8 = self.read_register(Register::WEEKDAY_ALARM)?; // read current value
71 let data: u8 = data & BitFlags::AE; // keep the AE bit as is
72 let setting: u8 = encode_bcd(weekday);
73 let data: u8 = data | setting;
74 self.write_register(Register::WEEKDAY_ALARM, data)
75 }
76
77 /// Control alarm seconds (On: alarm enabled, Off: alarm disabled).
78 pub fn control_alarm_seconds(&mut self, status: Control) -> Result<(), Error<E>> {
79 match status {
80 Control::Off => self.set_register_bit_flag(Register::SECOND_ALARM, BitFlags::AE),
81 Control::On => self.clear_register_bit_flag(Register::SECOND_ALARM, BitFlags::AE),
82 }
83 }
84
85 /// Is alarm seconds enabled?
86 pub fn is_alarm_seconds_enabled(&mut self) -> Result<bool, Error<E>> {
87 Ok(!self.is_register_bit_flag_high(Register::SECOND_ALARM, BitFlags::AE)?)
88 }
89
90 /// Control alarm minutes (On: alarm enabled, Off: alarm disabled).
91 pub fn control_alarm_minutes(&mut self, status: Control) -> Result<(), Error<E>> {
92 match status {
93 Control::Off => self.set_register_bit_flag(Register::MINUTE_ALARM, BitFlags::AE),
94 Control::On => self.clear_register_bit_flag(Register::MINUTE_ALARM, BitFlags::AE),
95 }
96 }
97
98 /// Is alarm minutes enabled?
99 pub fn is_alarm_minutes_enabled(&mut self) -> Result<bool, Error<E>> {
100 Ok(!self.is_register_bit_flag_high(Register::MINUTE_ALARM, BitFlags::AE)?)
101 }
102
103 /// Control alarm hours (On: alarm enabled, Off: alarm disabled).
104 pub fn control_alarm_hours(&mut self, status: Control) -> Result<(), Error<E>> {
105 match status {
106 Control::Off => self.set_register_bit_flag(Register::HOUR_ALARM, BitFlags::AE),
107 Control::On => self.clear_register_bit_flag(Register::HOUR_ALARM, BitFlags::AE),
108 }
109 }
110
111 /// Is alarm hours enabled?
112 pub fn is_alarm_hours_enabled(&mut self) -> Result<bool, Error<E>> {
113 Ok(!self.is_register_bit_flag_high(Register::HOUR_ALARM, BitFlags::AE)?)
114 }
115
116 /// Control alarm day (On: alarm enabled, Off: alarm disabled).
117 pub fn control_alarm_day(&mut self, status: Control) -> Result<(), Error<E>> {
118 match status {
119 Control::Off => self.set_register_bit_flag(Register::DAY_ALARM, BitFlags::AE),
120 Control::On => self.clear_register_bit_flag(Register::DAY_ALARM, BitFlags::AE),
121 }
122 }
123
124 /// Is alarm day enabled?
125 pub fn is_alarm_day_enabled(&mut self) -> Result<bool, Error<E>> {
126 Ok(!self.is_register_bit_flag_high(Register::DAY_ALARM, BitFlags::AE)?)
127 }
128
129 /// Control alarm weekday (On: alarm enabled, Off: alarm disabled).
130 pub fn control_alarm_weekday(&mut self, status: Control) -> Result<(), Error<E>> {
131 match status {
132 Control::Off => self.set_register_bit_flag(Register::WEEKDAY_ALARM, BitFlags::AE),
133 Control::On => self.clear_register_bit_flag(Register::WEEKDAY_ALARM, BitFlags::AE),
134 }
135 }
136
137 /// Is alarm weekday enabled?
138 pub fn is_alarm_weekday_enabled(&mut self) -> Result<bool, Error<E>> {
139 Ok(!self.is_register_bit_flag_high(Register::WEEKDAY_ALARM, BitFlags::AE)?)
140 }
141
142 /// Enable or disable alarm interrupt.
143 pub fn control_alarm_interrupt(&mut self, status: Control) -> Result<(), Error<E>> {
144 match status {
145 Control::On => self.set_register_bit_flag(Register::CONTROL_2, BitFlags::AIE),
146 Control::Off => self.clear_register_bit_flag(Register::CONTROL_2, BitFlags::AIE),
147 }
148 }
149
150 pub fn get_alarm_time(&mut self) -> Result<Time, Error<E>> {
151 Ok(Time::from_hms(
152 self.get_alarm_hours()?,
153 self.get_alarm_minutes()?,
154 self.get_alarm_seconds()?,
155 )?)
156 }
157
158 /// Read the alarm seconds setting.
159 pub fn get_alarm_seconds(&mut self) -> Result<u8, Error<E>> {
160 let mut data = [0];
161 self.i2c
162 .write_read(DEVICE_ADDRESS, &[Register::SECOND_ALARM], &mut data)
163 .map_err(Error::I2C)?;
164 Ok(decode_bcd(data[0]))
165 }
166
167 /// Read the alarm minutes setting.
168 pub fn get_alarm_minutes(&mut self) -> Result<u8, Error<E>> {
169 let mut data = [0];
170 self.i2c
171 .write_read(DEVICE_ADDRESS, &[Register::MINUTE_ALARM], &mut data)
172 .map_err(Error::I2C)?;
173 Ok(decode_bcd(data[0]))
174 }
175
176 /// Read the alarm hours setting.
177 pub fn get_alarm_hours(&mut self) -> Result<u8, Error<E>> {
178 let mut data = [0];
179 self.i2c
180 .write_read(DEVICE_ADDRESS, &[Register::HOUR_ALARM], &mut data)
181 .map_err(Error::I2C)?;
182 Ok(decode_bcd(data[0]))
183 }
184
185 /// Read the alarm day setting.
186 pub fn get_alarm_day(&mut self) -> Result<u8, Error<E>> {
187 let mut data = [0];
188 self.i2c
189 .write_read(DEVICE_ADDRESS, &[Register::DAY_ALARM], &mut data)
190 .map_err(Error::I2C)?;
191 Ok(decode_bcd(data[0]))
192 }
193
194 /// Read the alarm weekday setting.
195 pub fn get_alarm_weekday(&mut self) -> Result<u8, Error<E>> {
196 let mut data = [0];
197 self.i2c
198 .write_read(DEVICE_ADDRESS, &[Register::WEEKDAY_ALARM], &mut data)
199 .map_err(Error::I2C)?;
200 Ok(decode_bcd(data[0]))
201 }
202
203 /// Get the alarm flag (if true, alarm event happened).
204 pub fn get_alarm_flag(&mut self) -> Result<bool, Error<E>> {
205 self.is_register_bit_flag_high(Register::CONTROL_2, BitFlags::AF)
206 }
207
208 /// Clear the alarm flag.
209 pub fn clear_alarm_flag(&mut self) -> Result<(), Error<E>> {
210 self.clear_register_bit_flag(Register::CONTROL_2, BitFlags::AF)
211 }
212
213 /// Check if alarm interrupt is enabled.
214 pub fn is_alarm_interrupt_enabled(&mut self) -> Result<bool, Error<E>> {
215 self.is_register_bit_flag_high(Register::CONTROL_2, BitFlags::AIE)
216 }
217
218 /// Shut off the alarms at once.
219 pub fn disable_all_alarms(&mut self) -> Result<(), Error<E>> {
220 self.control_alarm_seconds(Control::Off)?;
221 self.control_alarm_minutes(Control::Off)?;
222 self.control_alarm_hours(Control::Off)?;
223 self.control_alarm_day(Control::Off)?;
224 self.control_alarm_weekday(Control::Off)?;
225 Ok(())
226 }
227}