rsiot/drivers_i2c/ds3231/
task_input.rs

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
use std::{sync::Arc, time::Duration};

use tokio::sync::Mutex;

use crate::{
    drivers_i2c::{I2cSlaveAddress, RsiotI2cDriverBase},
    executor::CmpInOut,
    message::{Message, MsgDataBound, ServiceBound},
};

use super::data_models;

/// Структура входных данных для задания времени
pub struct InputData {
    /// Год
    pub year: u8,
    /// Месяц
    pub month: u8,
    /// День
    pub day: u8,
    /// Час
    pub hour: u8,
    /// Минуты
    pub minute: u8,
    /// Секунды
    pub second: u8,
}

pub struct TaskInput<TMsg, TService, Driver>
where
    Driver: RsiotI2cDriverBase,
    TMsg: MsgDataBound,
    TService: ServiceBound,
{
    pub address: I2cSlaveAddress,
    pub driver: Arc<Mutex<Driver>>,
    pub fn_input: fn(Message<TMsg>) -> Option<InputData>,
    pub in_out: CmpInOut<TMsg, TService>,
}

impl<TMsg, TService, Driver> TaskInput<TMsg, TService, Driver>
where
    Driver: RsiotI2cDriverBase,
    TMsg: MsgDataBound,
    TService: ServiceBound,
{
    pub async fn spawn(mut self) -> Result<(), String> {
        while let Ok(msg) = self.in_out.recv_input().await {
            let input_data = (self.fn_input)(msg);
            let Some(input_data) = input_data else {
                continue;
            };

            let mut driver = self.driver.lock().await;

            let request: Vec<u8> = vec![
                0x00,
                data_models::Second::new_from_dec(input_data.second).get_bcd(),
                data_models::Minute::new_from_dec(input_data.minute).get_bcd(),
                data_models::Hour::new_from_dec(input_data.hour).get_bcd(),
                0x01, // день ненели
                data_models::Day::new_from_dec(input_data.day).get_bcd(),
                data_models::Month::new_from_dec(input_data.month).get_bcd(),
                data_models::Year::new_from_dec(input_data.year).get_bcd(),
            ];
            driver
                .write(self.address, &request, Duration::from_secs(2))
                .await
                .unwrap();
        }
        Ok(())
    }
}