rsiot/drivers_i2c/ds3231/
task_output.rs

1use 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
14/// Структура выходных данных
15pub struct OutputData {
16    /// Год
17    pub year: u8,
18    /// Месяц
19    pub month: u8,
20    /// День
21    pub day: u8,
22    /// Час
23    pub hour: u8,
24    /// Минуты
25    pub minute: u8,
26    /// Секунды
27    pub second: u8,
28}
29/// Задача чтения данных с модуля
30pub 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}