rsiot/drivers_i2c/ds3231/
device.rs

1use std::{sync::Arc, time::Duration};
2
3use tokio::{sync::Mutex, task::JoinSet};
4use tracing::warn;
5
6use crate::{
7    executor::CmpInOut,
8    message::{Message, MsgDataBound},
9};
10
11use super::{
12    super::{I2cSlaveAddress, RsiotI2cDriverBase},
13    task_input::{InputData, TaskInput},
14    task_output::{OutputData, TaskOutput},
15};
16
17/// Часы реального времени
18pub struct DS3231<TMsg>
19where
20    TMsg: MsgDataBound,
21{
22    /// Адрес. По-умолчанию 0x68
23    pub address: I2cSlaveAddress,
24    /// Функция преобразования входящих сообщений в данные для записи в модуль
25    pub fn_input: fn(Message<TMsg>) -> Option<InputData>,
26    /// Функция преобразования данных с модуля в исходящие сообщения
27    pub fn_output: fn(OutputData) -> Option<Vec<Message<TMsg>>>,
28    /// Период чтения данных с часов
29    pub fn_output_period: Duration,
30    /// Внутренняя шина сообщений
31    pub in_out: CmpInOut<TMsg>,
32}
33
34impl<TMsg> DS3231<TMsg>
35where
36    TMsg: MsgDataBound + 'static,
37{
38    /// Запустить опрос датчика
39    pub async fn spawn(&self, driver: Arc<Mutex<impl RsiotI2cDriverBase + 'static>>) {
40        loop {
41            let mut task_set: JoinSet<Result<(), String>> = JoinSet::new();
42
43            let task_input = TaskInput {
44                address: self.address,
45                driver: driver.clone(),
46                fn_input: self.fn_input,
47                in_out: self.in_out.clone(),
48            };
49            task_set.spawn(async move { task_input.spawn().await });
50
51            let task_output = TaskOutput {
52                address: self.address,
53                period: self.fn_output_period,
54                driver: driver.clone(),
55                fn_output: self.fn_output,
56                in_out: self.in_out.clone(),
57            };
58            task_set.spawn(async move { task_output.spawn().await });
59
60            while let Some(res) = task_set.join_next().await {
61                warn!("{res:?}");
62                task_set.shutdown().await;
63            }
64        }
65    }
66}