rsiot/drivers_i2c/pm_di16/tasks/
output.rs1use std::{sync::Arc, time::Duration};
2
3use 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}