maasier/spinnyboy_rust/src/bin/peripherals/nextion.rs
Robert Schauklies 443da0edcf safety commit
2026-01-11 00:14:58 +01:00

146 lines
4.6 KiB
Rust

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<usize, RxError> {
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<Command,ErrCommand>{
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;
}
}