use esp_hal::uart::RxError; #[no_std] use esp_hal::uart::{self, Config, Uart}; use esp_hal::{Blocking, riscv::register::hpmcounter13h::read}; use rtt_target::{rprint, rprintln}; enum UART_STATEMACHINE { WaitingP, WaitingE, Reading, Terminator(u8), } pub struct Nextion<'a> { interface: &'a mut Uart<'static, Blocking>, state: UART_STATEMACHINE, idx: usize, } impl<'a> Nextion<'a> { pub fn new<'b>(uart: &'a mut Uart<'static, Blocking>) -> Self { Nextion { interface: uart, state: UART_STATEMACHINE::WaitingP, idx: 0, } } pub fn send_command(&mut self, cmd: &[u8]) { let _ = &self.interface.write(cmd); let _ = &self.interface.write(b"\xff\xff\xff"); } pub fn read_command(&mut self, buf: &mut [u8]) -> Result { let size: usize = 0; let mut tmp_buf: [u8; 20] = [0; 20]; let mut cmd_end_ctr = 0; let mut i = 0; let mut read_header = false; loop { if !self.interface.read_ready() { continue; } let mut char: [u8; 1] = [0; 1]; self.interface.read(&mut char)?; let byte = char[0]; match self.state { UART_STATEMACHINE::WaitingP => { if byte == b'P' { self.state = UART_STATEMACHINE::WaitingE; } } UART_STATEMACHINE::WaitingE => { if byte == b'E' { self.state = UART_STATEMACHINE::Reading; self.idx = 0; } } UART_STATEMACHINE::Reading => { if byte == b'\xff' { self.state = UART_STATEMACHINE::Terminator(1); } else { if self.idx < buf.len() { buf[self.idx] = byte; self.idx += 1; } else { self.reset(); return Err(RxError::FifoOverflowed); } } } UART_STATEMACHINE::Terminator(n) => { if byte == b'\xff' { if n >= 2 { let idx = self.idx; self.reset(); return Ok(idx); } else { self.state = UART_STATEMACHINE::Terminator(n + 1) } } else { self.state = UART_STATEMACHINE::Reading; let needed: usize = (n + 1).into(); // number of bytes to reinsert (FFs + current byte) if self.idx + needed > buf.len() { self.reset(); return Err(RxError::FifoOverflowed); } for _ in 0..n { buf[self.idx] = 0xff; self.idx += 1; } buf[self.idx] = byte; self.idx += 1; } } } } } pub fn read_ready(&mut self) -> bool { self.interface.read_ready() } fn reset(&mut self) { self.state = UART_STATEMACHINE::WaitingP; self.idx = 0; } }