rsiot/drivers_i2c/ds3231/
task_output.rs1use std::{sync::Arc, time::Duration};
2
3use tokio::{sync::Mutex, time::sleep};
4use tracing::debug;
5
6use crate::{
7 drivers_i2c::{I2cSlaveAddress, RsiotI2cDriverBase},
8 executor::CmpInOut,
9 message::{Message, MsgDataBound},
10};
11
12use super::data_models;
13
14pub struct OutputData {
16 pub year: u8,
18 pub month: u8,
20 pub day: u8,
22 pub hour: u8,
24 pub minute: u8,
26 pub second: u8,
28}
29pub struct TaskOutput<TMsg, Driver>
31where
32 Driver: RsiotI2cDriverBase,
33 TMsg: MsgDataBound,
34{
35 pub address: I2cSlaveAddress,
36 pub period: Duration,
37 pub driver: Arc<Mutex<Driver>>,
38 pub fn_output: fn(OutputData) -> Option<Vec<Message<TMsg>>>,
39 pub in_out: CmpInOut<TMsg>,
40}
41
42impl<TMsg, Driver> TaskOutput<TMsg, Driver>
43where
44 Driver: RsiotI2cDriverBase,
45 TMsg: MsgDataBound,
46{
47 pub async fn spawn(self) -> Result<(), String> {
48 loop {
49 let mut driver = self.driver.lock().await;
50 let res = driver
51 .write_read(self.address, &[0x00], 19, Duration::from_secs(2))
52 .await?;
53
54 let second = data_models::Second::new_from_bcd(res[0]);
55 let minute = data_models::Minute::new_from_bcd(res[1]);
56 let hour = data_models::Hour::new_from_bcd(res[2]);
57 let day = data_models::Day::new_from_bcd(res[4]);
58 let month = data_models::Month::new_from_bcd(res[5]);
59 let year = data_models::Year::new_from_bcd(res[6]);
60
61 let res = driver
62 .write_read(self.address, &[0x0E], 2, Duration::from_secs(2))
63 .await?;
64 debug!("Control: {:?}", res[0]);
65 debug!("Status: {:?}", res[1]);
66
67 let output = OutputData {
68 year: year.get_dec(),
69 month: month.get_dec(),
70 day: day.get_dec(),
71 hour: hour.get_dec(),
72 minute: minute.get_dec(),
73 second: second.get_dec(),
74 };
75
76 let msgs = (self.fn_output)(output);
77 let Some(msgs) = msgs else { continue };
78 for msg in msgs {
79 self.in_out
80 .send_output(msg)
81 .await
82 .map_err(|e| e.to_string())?;
83 }
84 sleep(self.period).await;
85 }
86 }
87}