rsiot/drivers_i2c/
rsiot_i2c_driver_base.rs

1use std::{marker::Send, time::Duration};
2
3use async_trait::async_trait;
4use tracing::{trace, warn};
5
6// TODO - добавить тип ошибки вместо String
7
8#[async_trait]
9pub trait RsiotI2cDriverBase
10where
11    Self: Send,
12{
13    async fn mux_control(&mut self, address: I2cSlaveAddress) -> Result<u8, String> {
14        match address {
15            I2cSlaveAddress::Direct { slave_address } => Ok(slave_address),
16            I2cSlaveAddress::Mux {
17                mux_address,
18                channel,
19                slave_address,
20            } => {
21                let request = [2_u8.pow(channel as u32)];
22                self.write_platform(mux_address, &request, Duration::from_secs(2))
23                    .await?;
24                Ok(slave_address)
25            }
26        }
27    }
28
29    async fn read(
30        &mut self,
31        address: I2cSlaveAddress,
32        response_size: usize,
33        timeout: Duration,
34    ) -> Result<Vec<u8>, String> {
35        let address = self.mux_control(address).await?;
36        let response = self.read_platform(address, response_size, timeout).await;
37        match response {
38            Ok(response) => {
39                trace!("I2C success response");
40                Ok(response)
41            }
42            Err(err) => {
43                warn!("I2C error response: {err:?}");
44                Err(err.to_string())
45            }
46        }
47    }
48
49    async fn write(
50        &mut self,
51        address: I2cSlaveAddress,
52        request: &[u8],
53        timeout: Duration,
54    ) -> Result<(), String> {
55        let address = self.mux_control(address).await?;
56        let response = self.write_platform(address, request, timeout).await;
57        match response {
58            Ok(_) => {
59                trace!("I2C success response");
60                Ok(())
61            }
62            Err(err) => {
63                warn!("I2C error response: {err:?}");
64                Err(err.to_string())
65            }
66        }
67    }
68
69    async fn write_read(
70        &mut self,
71        address: I2cSlaveAddress,
72        request: &[u8],
73        response_size: usize,
74        timeout: Duration,
75    ) -> Result<Vec<u8>, String> {
76        let address = self.mux_control(address).await?;
77        let response = self
78            .write_read_platform(address, request, response_size, timeout)
79            .await;
80        match response {
81            Ok(response) => {
82                trace!("I2C success response");
83                Ok(response)
84            }
85            Err(err) => {
86                warn!("I2C error response: {err:?}");
87                Err(err.to_string())
88            }
89        }
90    }
91
92    async fn read_platform(
93        &mut self,
94        address: u8,
95        response_size: usize,
96        timeout: Duration,
97    ) -> Result<Vec<u8>, String>;
98
99    async fn write_platform(
100        &mut self,
101        address: u8,
102        request: &[u8],
103        timeout: Duration,
104    ) -> Result<(), String>;
105
106    async fn write_read_platform(
107        &mut self,
108        address: u8,
109        request: &[u8],
110        response_size: usize,
111        timeout: Duration,
112    ) -> Result<Vec<u8>, String>;
113}
114
115/// Адрес подчиненного устройства
116#[derive(Clone, Copy)]
117pub enum I2cSlaveAddress {
118    /// Прямое подключение
119    Direct {
120        /// Адрес подчиненного устройства
121        slave_address: u8,
122    },
123    /// Через мультиплексор
124    Mux {
125        /// Адрес мультиплексора
126        mux_address: u8,
127        /// Канал на мультиплексоре. 0..7
128        channel: u8,
129        /// Адрес подчиненного устройства
130        slave_address: u8,
131    },
132}