rsiot/drivers_i2c/pm_di16/tasks/
output.rs

1use std::{sync::Arc, time::Duration};
2
3// use pm_firmware_lib::pm_di16_dc24sink_v0_0_2::{I2cRequest, I2cResponse};
4use serde::{Deserialize, Serialize};
5use tokio::{
6    sync::{mpsc::Sender, Mutex},
7    time::sleep,
8};
9use tracing::warn;
10
11#[derive(Debug, Deserialize, Serialize)]
12pub enum I2cRequest {
13    GetInput,
14}
15
16#[derive(Debug, Deserialize, Serialize)]
17pub enum I2cResponse {
18    InputsState {
19        a0: bool,
20        a1: bool,
21        a2: bool,
22        a3: bool,
23        a4: bool,
24        a5: bool,
25        a6: bool,
26        a7: bool,
27        b0: bool,
28        b1: bool,
29        b2: bool,
30        b3: bool,
31        b4: bool,
32        b5: bool,
33        b6: bool,
34        b7: bool,
35    },
36}
37
38use crate::{
39    drivers_i2c::{I2cSlaveAddress, RsiotI2cDriverBase},
40    message::{Message, MsgDataBound},
41    serde_utils::postcard_serde,
42};
43
44use super::super::config::FnOutput;
45
46pub struct Output<TMsg, TDriver>
47where
48    TMsg: MsgDataBound,
49    TDriver: RsiotI2cDriverBase,
50{
51    pub output: Sender<Message<TMsg>>,
52    pub address: I2cSlaveAddress,
53    pub fn_output_a_0: FnOutput<TMsg>,
54    pub fn_output_a_1: FnOutput<TMsg>,
55    pub fn_output_a_2: FnOutput<TMsg>,
56    pub fn_output_a_3: FnOutput<TMsg>,
57    pub fn_output_a_4: FnOutput<TMsg>,
58    pub fn_output_a_5: FnOutput<TMsg>,
59    pub fn_output_a_6: FnOutput<TMsg>,
60    pub fn_output_a_7: FnOutput<TMsg>,
61
62    pub fn_output_b_0: FnOutput<TMsg>,
63    pub fn_output_b_1: FnOutput<TMsg>,
64    pub fn_output_b_2: FnOutput<TMsg>,
65    pub fn_output_b_3: FnOutput<TMsg>,
66    pub fn_output_b_4: FnOutput<TMsg>,
67    pub fn_output_b_5: FnOutput<TMsg>,
68    pub fn_output_b_6: FnOutput<TMsg>,
69    pub fn_output_b_7: FnOutput<TMsg>,
70    pub fn_output_period: Duration,
71    pub driver: Arc<Mutex<TDriver>>,
72}
73
74impl<TMsg, TDriver> Output<TMsg, TDriver>
75where
76    TMsg: MsgDataBound,
77    TDriver: RsiotI2cDriverBase,
78{
79    pub async fn spawn(self) -> super::Result<()> {
80        loop {
81            sleep(self.fn_output_period).await;
82            let result = self.request().await;
83            if let Err(err) = result {
84                warn!("I2c request error: {err}");
85            }
86        }
87    }
88
89    async fn request(&self) -> super::Result<()> {
90        let req = I2cRequest::GetInput;
91        let req = postcard_serde::serialize_crc_deprecated(&req)?;
92
93        let mut response = {
94            let mut driver = self.driver.lock().await;
95            driver
96                .write_read(
97                    self.address,
98                    &req,
99                    postcard_serde::MESSAGE_LEN,
100                    Duration::from_millis(100),
101                )
102                .await
103                .map_err(super::Error::I2c)?
104        };
105
106        let response: I2cResponse = postcard_serde::deserialize(&mut response)?;
107
108        match response {
109            I2cResponse::InputsState {
110                a0,
111                a1,
112                a2,
113                a3,
114                a4,
115                a5,
116                a6,
117                a7,
118                b0,
119                b1,
120                b2,
121                b3,
122                b4,
123                b5,
124                b6,
125                b7,
126            } => {
127                let mut msgs = vec![];
128                msgs.push((self.fn_output_a_0)(a0));
129                msgs.push((self.fn_output_a_1)(a1));
130                msgs.push((self.fn_output_a_2)(a2));
131                msgs.push((self.fn_output_a_3)(a3));
132                msgs.push((self.fn_output_a_4)(a4));
133                msgs.push((self.fn_output_a_5)(a5));
134                msgs.push((self.fn_output_a_6)(a6));
135                msgs.push((self.fn_output_a_7)(a7));
136                msgs.push((self.fn_output_b_0)(b0));
137                msgs.push((self.fn_output_b_1)(b1));
138                msgs.push((self.fn_output_b_2)(b2));
139                msgs.push((self.fn_output_b_3)(b3));
140                msgs.push((self.fn_output_b_4)(b4));
141                msgs.push((self.fn_output_b_5)(b5));
142                msgs.push((self.fn_output_b_6)(b6));
143                msgs.push((self.fn_output_b_7)(b7));
144
145                for msg in msgs {
146                    let Some(msg) = msg else { continue };
147                    self.output
148                        .send(msg)
149                        .await
150                        .map_err(|e| super::Error::TokioSyncMpscSender(e.to_string()))?;
151                }
152            }
153        }
154
155        Ok(())
156    }
157}