untested statemachine for handling the UART protocol of the nextion stuff

This commit is contained in:
Robert Schauklies 2026-01-06 22:12:45 +01:00
parent afd1a61bfe
commit b130c8575b
3 changed files with 147 additions and 37 deletions

View file

@ -6,7 +6,7 @@
holding buffers for the duration of a data transfer." holding buffers for the duration of a data transfer."
)] )]
use core::fmt::Write; use core::fmt::Write;
use esp_hal::uart::{Config, Uart}; use esp_hal::uart::{self, Config, Uart};
use esp_hal::clock::CpuClock; use esp_hal::clock::CpuClock;
use esp_hal::delay::Delay; use esp_hal::delay::Delay;
@ -27,14 +27,16 @@ use esp_hal::timer::timg::TimerGroup;
use critical_section::Mutex; use critical_section::Mutex;
use rtt_target::rprintln; use rtt_target::rprintln;
mod dc_driver; mod dc_driver;
mod peripherals;
use dc_driver::afroesc::AfroEsc; use dc_driver::afroesc::AfroEsc;
use peripherals::nextion::Nextion;
#[panic_handler] #[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! { fn panic(_: &core::panic::PanicInfo) -> ! {
rprintln!("PANIC!");
loop {} loop {}
} }
// //
static BUTTON: Mutex<RefCell<Option<Input>>> = Mutex::new(RefCell::new(None)); static EMERGENCY_BUTTON: Mutex<RefCell<Option<Input>>> = Mutex::new(RefCell::new(None));
extern crate alloc; extern crate alloc;
// This creates a default app-descriptor required by the esp-idf bootloader. // This creates a default app-descriptor required by the esp-idf bootloader.
@ -57,10 +59,10 @@ fn main() -> ! {
esp_hal::mcpwm::PeripheralClockConfig::with_frequency(Rate::from_mhz(32)).unwrap(); esp_hal::mcpwm::PeripheralClockConfig::with_frequency(Rate::from_mhz(32)).unwrap();
let mut mcpwm = esp_hal::mcpwm::McPwm::new(peripherals.MCPWM0, clock_config); let mut mcpwm = esp_hal::mcpwm::McPwm::new(peripherals.MCPWM0, clock_config);
mcpwm.operator0.set_timer(&mcpwm.timer0); mcpwm.operator0.set_timer(&mcpwm.timer0);
let pin = peripherals.GPIO18;
let mut pwm_pin = mcpwm let mut pwm_pin = mcpwm
.operator0 .operator0
.with_pin_a(pin, PwmPinConfig::UP_ACTIVE_HIGH); .with_pin_a(peripherals.GPIO18, PwmPinConfig::UP_ACTIVE_HIGH);
let timer_clock_cfg = clock_config let timer_clock_cfg = clock_config
.timer_clock_with_frequency(19_999, PwmWorkingMode::Increase, Rate::from_hz(50)) .timer_clock_with_frequency(19_999, PwmWorkingMode::Increase, Rate::from_hz(50))
.unwrap(); .unwrap();
@ -79,21 +81,42 @@ fn main() -> ! {
let mut emergency_button = Input::new(peripherals.GPIO9, input_config); let mut emergency_button = Input::new(peripherals.GPIO9, input_config);
critical_section::with(|cs| { critical_section::with(|cs| {
emergency_button.listen(Event::FallingEdge); emergency_button.listen(Event::FallingEdge);
BUTTON.borrow_ref_mut(cs).replace(emergency_button) EMERGENCY_BUTTON
.borrow_ref_mut(cs)
.replace(emergency_button)
}); });
let mut io = esp_hal::gpio::Io::new(peripherals.IO_MUX); let mut io = esp_hal::gpio::Io::new(peripherals.IO_MUX);
io.set_interrupt_handler(handler); io.set_interrupt_handler(handler);
let mut uart0 = Uart::new(
let mut uart0 = Uart::new(peripherals.UART0, Config::default().with_baudrate(9600)) peripherals.UART0,
Config::default()
.with_baudrate(115200)
.with_data_bits(esp_hal::uart::DataBits::_8)
.with_stop_bits(esp_hal::uart::StopBits::_1)
.with_parity(esp_hal::uart::Parity::None),
)
.unwrap() .unwrap()
.with_rx(peripherals.GPIO10) .with_rx(peripherals.GPIO5)
.with_tx(peripherals.GPIO11); .with_tx(peripherals.GPIO7);
uart0.write(b"page page1"); // uart0.write(b"page page0");
uart0.write(b"\xff"); // uart0.write(b"\xff");
uart0.write(b"\xff"); // uart0.write(b"\xff");
uart0.write(b"\xff"); // uart0.write(b"\xff");
uart0.write(b"\xff"); // uart0.write(b"\xff");
rprintln!("WRITE HAPPENED!"); // rprintln!("WRITE HAPPENED!");
let mut display = Nextion::new(&mut uart0);
display.send_command(b"page page0");
loop {
let mut buf:[u8;20] = [0;20];
if display.read_ready(){
display.read_command(&mut buf);
display.send_command(b"page page0");
rprintln!("RECV BUF:{:?}",buf);
rprintln!("WTF");
}
//display.send_command(b"page page0");
//uart0.write(b"page page0\xff\xff\xff");
}
// Example: Ramp from 0% to 50% throttle // Example: Ramp from 0% to 50% throttle
//the afro esc starts turning at roughly setup gets a PWM at //the afro esc starts turning at roughly setup gets a PWM at
//loop{ //loop{
@ -121,25 +144,14 @@ fn main() -> ! {
#[handler] #[handler]
// #[ram] // #[ram]
fn handler() { fn handler() {
if critical_section::with(|cs| {
BUTTON
.borrow_ref_mut(cs)
.as_mut()
.unwrap()
.is_interrupt_set()
}) {
rprintln!("Button was the source of the interrupt");
} else {
rprintln!("Button was not the source of the interrupt");
}
critical_section::with(|cs| { critical_section::with(|cs| {
BUTTON let mut binding = EMERGENCY_BUTTON.borrow_ref_mut(cs);
.borrow_ref_mut(cs) let mut button = binding.as_mut().unwrap();
.as_mut() if button.is_interrupt_set() {
.unwrap() // do the thing
.clear_interrupt() rprintln!("BUTTON1 WAS PRESSED!");
button.clear_interrupt();
return;
}
}); });
} }

View file

@ -0,0 +1 @@
pub mod nextion;

View file

@ -0,0 +1,97 @@
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<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 {
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)
}
}
self.state = UART_STATEMACHINE::Reading;
if self.idx < buf.len() {
buf[self.idx] = byte;
self.idx += 1;
} else {
self.reset();
return Err(RxError::FifoOverflowed);
}
}
}
}
}
pub fn read_ready(&mut self) -> bool {
self.interface.read_ready()
}
fn reset(&mut self) {
self.state = UART_STATEMACHINE::WaitingP;
self.idx = 0;
}
}