rsiot/drivers_i2c/pcf8575/
device.rs1use std::sync::Arc;
2
3use tokio::{sync::Mutex, task::JoinSet};
4use tracing::warn;
5
6use crate::{executor::CmpInOut, message::MsgDataBound};
7
8use super::{
9 super::{I2cSlaveAddress, RsiotI2cDriverBase},
10 state::State,
11 task_read_inputs::TaskReadInputs,
12 task_write_output::TaskWriteOutput,
13 PCF8575PinMode, TPinFnOutput,
14};
15
16pub struct PCF8575<TMsg>
17where
18 TMsg: MsgDataBound,
19{
20 pub address: I2cSlaveAddress,
21 pub pins: Vec<PCF8575PinMode<TMsg>>,
22}
23
24impl<TMsg> PCF8575<TMsg>
25where
26 TMsg: MsgDataBound + 'static,
27{
28 pub async fn fn_process(
29 &self,
30 in_out: CmpInOut<TMsg>,
31 driver: Arc<Mutex<impl RsiotI2cDriverBase + 'static>>,
32 ) {
33 loop {
34 let mut state = State::new();
35 let mut task_set: JoinSet<Result<(), String>> = JoinSet::new();
36
37 let mut input_pins: TPinFnOutput<TMsg> = vec![];
39 for (index, pin) in self.pins.iter().enumerate() {
40 match pin {
41 PCF8575PinMode::Disabled => {}
42
43 PCF8575PinMode::Input { fn_output } => {
44 state.set_input(index).await;
45 input_pins.push((index, *fn_output))
46 }
47
48 PCF8575PinMode::Output { fn_input } => {
49 state.set_output_low(index).await;
50 let mut task_output = TaskWriteOutput {
51 in_out: in_out.clone(),
52 fn_input: *fn_input,
53 state: state.clone(),
54 driver: driver.clone(),
55 address: self.address,
56 pin: index,
57 };
58 task_set.spawn(async move { task_output.spawn().await });
59 }
60 }
61 }
62
63 let task_input = TaskReadInputs {
64 in_out: in_out.clone(),
65 driver: driver.clone(),
66 address: self.address,
67 pin_and_fn_output: input_pins,
68 state: state.clone(),
69 };
70 task_set.spawn(async move { task_input.spawn().await });
71
72 while let Some(res) = task_set.join_next().await {
75 warn!("{res:?}");
76 task_set.abort_all()
77 }
78 }
79 }
80}