rsiot/components/cmp_esp_uart_slave/tasks/
uart_comm.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
74
75
76
77
78
79
80
81
82
83
84
use esp_idf_svc::{
    hal::{
        io::asynch::Write,
        uart::{AsyncUartDriver, UartDriver},
    },
    sys::uart_flush_input,
};
use tracing::{trace, warn};

use crate::components_config::uart_general::{UartRequest, UartResponse};

use super::super::TFnUartComm;
use super::Buffer;

pub struct UartComm<TBufferData> {
    pub address: u8,
    pub uart: AsyncUartDriver<'static, UartDriver<'static>>,
    pub fn_uart_comm: TFnUartComm<UartRequest, UartResponse, TBufferData>,
    pub buffer_data: Buffer<TBufferData>,
}

const READ_BUFFER_LEN: usize = 100;

impl<TBufferData> UartComm<TBufferData> {
    pub async fn spawn(mut self) -> super::Result<()> {
        let port = self.uart.driver().port();

        loop {
            let mut read_buffer = [0_u8; READ_BUFFER_LEN];

            // Очистка буфера чтения
            // Используется unsafe функция, поскольку AsyncUartDriver не содержит метода clear_rx()
            unsafe { uart_flush_input(port) };

            let res = self.uart.read(&mut read_buffer).await;
            let _read_len = match res {
                Ok(val) => val,
                Err(err) => {
                    warn!("Error reading from uart: {:?}", err);
                    continue;
                }
            };

            trace!("Read UART buffer: {:?}", read_buffer);

            let request = match UartRequest::from_read_buffer(&mut read_buffer) {
                Ok(val) => val,
                Err(err) => {
                    warn!("Deserialization error: {:?}", err);
                    continue;
                }
            };

            if request.address != self.address {
                continue;
            }

            trace!("Request: {:?}", request);
            let address = request.address;

            let response = {
                let mut buffer_data = self.buffer_data.lock().await;
                (self.fn_uart_comm)(request, &mut buffer_data)
            };

            let mut response = match response {
                Ok(val) => val,
                Err(err) => {
                    let err = format!("fn_uart_comm error: {err}");
                    warn!("{err}");
                    continue;
                }
            };
            response.address = address;

            trace!("Response: {:?}", response);

            let write_buffer = response.to_write_buffer()?;

            self.uart.write_all(&write_buffer).await.unwrap();
            self.uart.flush().await.unwrap();
        }
    }
}