use esp_hal::uart::RxError; use esp_hal::uart::{Uart}; use esp_hal::{Blocking }; use rtt_target::rprintln; use crate::peripherals::{ErrCommand,Command}; enum UartStatemachine { WaitingP, WaitingE, Reading, Terminator(u8), } pub struct Nextion<'a> { interface: &'a mut Uart<'static, Blocking>, state: UartStatemachine, idx: usize, } impl<'a> Nextion<'a> { pub fn new<'b>(uart: &'a mut Uart<'static, Blocking>) -> Self { Nextion { interface: uart, state: UartStatemachine::WaitingP, idx: 0, } } pub fn send_command(&mut self, cmd: &[u8]) { let _ = &self.interface.write(cmd); let _ = &self.interface.write(b"\xff\xff\xff"); } fn read_frame(&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 { UartStatemachine::WaitingP => { if byte == b'P' { self.state = UartStatemachine::WaitingE; } } UartStatemachine::WaitingE => { if byte == b'E' { self.state = UartStatemachine::Reading; self.idx = 0; } } UartStatemachine::Reading => { if byte == b'\xff' { self.state = UartStatemachine::Terminator(1); } else { if self.idx < buf.len() { buf[self.idx] = byte; self.idx += 1; } else { self.reset(); return Err(RxError::FifoOverflowed); } } } UartStatemachine::Terminator(n) => { if byte == b'\xff' { if n >= 2 { rprintln!("SENDING {:?}",buf); let idx = self.idx; self.reset(); return Ok(idx); } else { self.state = UartStatemachine::Terminator(n + 1) } } else { self.state = UartStatemachine::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_command(&mut self) -> Result{ let mut buf:[u8;8] = [0;8]; let _read_bytes = match self.read_frame(&mut buf){ Ok(x) => x, Err(e) => {rprintln!("ERROR while reading"); return Err(ErrCommand::NoValidCmd); } }; rprintln!("READ SUCCESS!:{:?}",buf); match buf[0]{ 01 => {Ok(Command::Start)}, 02 =>{Ok(Command::Stop)}, 03 => { let rpm = u32::from_le_bytes(buf[1..5].try_into().expect("failed to parse rpm!")); Ok(Command::SetRpm(rpm)) }, 04 => { let time = u32::from_le_bytes(buf[1..5].try_into().expect("failed to parse time!")); Ok(Command::SetTimer(time)) } 05 =>{ Ok(Command::SendConfig) } 00 => { Ok(Command::CommandSuccess) }, _ => { Err(ErrCommand::NoValidCmd) } } } pub fn read_ready(&mut self) -> bool { self.interface.read_ready() } fn reset(&mut self) { self.state = UartStatemachine::WaitingP; self.idx = 0; } }