Add State-system
This commit is contained in:
parent
d03b00e3f0
commit
3546cf62c6
@ -3,7 +3,7 @@ use core::ops::{Add, Mul};
|
||||
use embedded_hal::{delay::DelayNs, spi::SpiBus};
|
||||
use esp_hal::{DriverMode, gpio::Output, spi::master::Spi};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Rgb565(pub u8, pub u8, pub u8);
|
||||
|
||||
impl Rgb565 {
|
||||
@ -72,7 +72,7 @@ impl Add<Rgb565> for Rgb565 {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Copy, Debug)]
|
||||
#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Position {
|
||||
pub x: i16,
|
||||
pub y: i16,
|
||||
@ -84,7 +84,7 @@ impl Position {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Copy)]
|
||||
#[derive(Default, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct Color {
|
||||
pub bytes: [u8; 2],
|
||||
}
|
||||
@ -371,4 +371,8 @@ impl<'d, DM: DriverMode, T: DelayNs> Display<'d, DM, T> {
|
||||
self.write(Writeable::Data(&color.bytes));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear(&mut self, color: Color) {
|
||||
self.draw_rect(Position::new(0, 0), Position::new(240, 240), color);
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,12 +10,14 @@ use crate::display::{self, Color, Display, Position, Rgb565};
|
||||
|
||||
static OPEN_SANS: &'static [u8] = include_bytes!("./OpenSans_Condensed-Regular.ttf");
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
|
||||
pub enum HorizontalAlignment {
|
||||
RightToLeft,
|
||||
Center,
|
||||
LeftToRight,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
|
||||
pub enum VerticalAlignment {
|
||||
TopToBottom,
|
||||
Center,
|
||||
|
||||
34
src/main.rs
34
src/main.rs
@ -9,7 +9,7 @@
|
||||
|
||||
use core::fmt::Write;
|
||||
|
||||
use alloc::{borrow::ToOwned, str};
|
||||
use alloc::{borrow::ToOwned, boxed::Box, str};
|
||||
use embedded_hal::delay::DelayNs;
|
||||
use esp_alloc::export::enumset::EnumSet;
|
||||
use esp_hal::{
|
||||
@ -28,6 +28,7 @@ use crate::{
|
||||
at_commands::ATCommands,
|
||||
display::{Display, Position, Rgb565, SetAddressMode},
|
||||
font::{FontRenderer, HorizontalAlignment, VerticalAlignment},
|
||||
state::{HelloState, StateManager},
|
||||
};
|
||||
|
||||
extern crate alloc;
|
||||
@ -35,6 +36,7 @@ extern crate alloc;
|
||||
mod at_commands;
|
||||
mod display;
|
||||
mod font;
|
||||
mod state;
|
||||
|
||||
// This creates a default app-descriptor required by the esp-idf bootloader.
|
||||
// For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description>
|
||||
@ -156,13 +158,18 @@ fn main() -> ! {
|
||||
);
|
||||
};
|
||||
|
||||
at_commands.init();
|
||||
render_response(at_commands.raw_command("ATI".to_owned()));
|
||||
render_response(at_commands.raw_command("AT+CMGF?".to_owned()));
|
||||
render_response(at_commands.raw_command("AT+CPIN=1234".to_owned()));
|
||||
render_response(at_commands.raw_command("AT+CPIN?".to_owned()));
|
||||
render_response(at_commands.raw_command("AT+CMGF=1".to_owned()));
|
||||
render_response(at_commands.raw_command("AT+CSCS=?".to_owned()));
|
||||
// at_commands.init();
|
||||
// render_response(at_commands.raw_command("ATI".to_owned()));
|
||||
// render_response(at_commands.raw_command("AT+CMGF?".to_owned()));
|
||||
// render_response(at_commands.raw_command("AT+CPIN=1234".to_owned()));
|
||||
// render_response(at_commands.raw_command("AT+CPIN?".to_owned()));
|
||||
// render_response(at_commands.raw_command("AT+CMGF=1".to_owned()));
|
||||
// render_response(at_commands.raw_command("AT+CSCS=?".to_owned()));
|
||||
|
||||
let mut state_mgr = StateManager {
|
||||
data: state::StateData::from(display, at_commands),
|
||||
curr_state: Box::new(HelloState),
|
||||
};
|
||||
// render_response(
|
||||
// at_commands.raw_two_part_command("AT+CMGS=\"number\"".to_owned(), "hello".to_owned()),
|
||||
// );
|
||||
@ -187,15 +194,8 @@ fn main() -> ! {
|
||||
|
||||
let mut test_delay = Delay::new();
|
||||
loop {
|
||||
// log::info!("Input 1: {}", input_1.is_high());
|
||||
// log::info!("Input 2: {}", input_2.is_high());
|
||||
// log::info!("Input 3: {}", input_3.is_high());
|
||||
// log::info!("Input 4: {}", input_4.is_high());
|
||||
// log::info!("Input 5: {}", input_5.is_high());
|
||||
// log::info!("Input 6: {}", input_6.is_high());
|
||||
// log::info!("Input 7: {}", input_7.is_high());
|
||||
// input_7.toggle();
|
||||
test_delay.delay_millis(100);
|
||||
state_mgr.update();
|
||||
state_mgr.draw();
|
||||
}
|
||||
|
||||
// for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.1.0/examples
|
||||
|
||||
126
src/state.rs
Normal file
126
src/state.rs
Normal file
@ -0,0 +1,126 @@
|
||||
use alloc::{boxed::Box, string::String, vec::Vec};
|
||||
use esp_hal::{Blocking, delay::Delay};
|
||||
|
||||
use crate::{
|
||||
at_commands::ATCommands,
|
||||
display::{Color, Display, Position, Rgb565},
|
||||
font::{FontRenderer, HorizontalAlignment, VerticalAlignment},
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct TextSettings {
|
||||
h_align: HorizontalAlignment,
|
||||
v_align: VerticalAlignment,
|
||||
fg: Rgb565,
|
||||
bg: Rgb565,
|
||||
}
|
||||
|
||||
impl Default for TextSettings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
h_align: HorizontalAlignment::LeftToRight,
|
||||
v_align: VerticalAlignment::TopToBottom,
|
||||
fg: Rgb565::white(),
|
||||
bg: Rgb565::black(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub enum DrawCommands {
|
||||
Clear(Color),
|
||||
DrawText(String, Position, TextSettings),
|
||||
}
|
||||
|
||||
pub struct StateData<'a> {
|
||||
display: Display<'a, Blocking, Delay>,
|
||||
at_commands: ATCommands<'a, 'a>,
|
||||
font_renderer: FontRenderer<'a>,
|
||||
pub delay: Delay,
|
||||
|
||||
prev_commands: Vec<DrawCommands>,
|
||||
commands: Vec<DrawCommands>,
|
||||
}
|
||||
|
||||
impl<'a> StateData<'a> {
|
||||
pub fn from(
|
||||
display: Display<'a, Blocking, Delay>,
|
||||
at_commands: ATCommands<'a, 'a>,
|
||||
) -> StateData<'a> {
|
||||
StateData {
|
||||
display,
|
||||
at_commands,
|
||||
font_renderer: FontRenderer::create(30),
|
||||
delay: Delay::new(),
|
||||
|
||||
prev_commands: Vec::new(),
|
||||
commands: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_screen(&mut self, color: Color) {
|
||||
self.commands.push(DrawCommands::Clear(color));
|
||||
}
|
||||
|
||||
pub fn draw_text<T: Into<String>>(&mut self, text: T, pos: Position, settings: TextSettings) {
|
||||
self.commands
|
||||
.push(DrawCommands::DrawText(text.into(), pos, settings));
|
||||
}
|
||||
}
|
||||
|
||||
pub trait State {
|
||||
fn update(&self, data: &mut StateData) -> Option<Box<dyn State>>;
|
||||
fn draw(&self, data: &mut StateData);
|
||||
}
|
||||
|
||||
pub struct StateManager<'a> {
|
||||
pub data: StateData<'a>,
|
||||
pub curr_state: Box<dyn State>,
|
||||
}
|
||||
|
||||
impl<'a> StateManager<'a> {
|
||||
pub fn update(&mut self) {
|
||||
match self.curr_state.update(&mut self.data) {
|
||||
Some(next_state) => self.curr_state = next_state,
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw(&mut self) {
|
||||
self.data.commands.clear();
|
||||
self.curr_state.draw(&mut self.data);
|
||||
if self.data.commands != self.data.prev_commands {
|
||||
self.data.prev_commands = self.data.commands.clone();
|
||||
for command in &self.data.commands {
|
||||
match command {
|
||||
DrawCommands::Clear(color) => self.data.display.clear(*color),
|
||||
DrawCommands::DrawText(text, position, text_settings) => {
|
||||
self.data.font_renderer.render(
|
||||
&mut self.data.display,
|
||||
text,
|
||||
*position,
|
||||
text_settings.h_align,
|
||||
text_settings.v_align,
|
||||
text_settings.bg,
|
||||
text_settings.fg,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct HelloState;
|
||||
|
||||
impl State for HelloState {
|
||||
fn update(&self, data: &mut StateData) -> Option<Box<dyn State>> {
|
||||
data.delay.delay_millis(100);
|
||||
None
|
||||
}
|
||||
|
||||
fn draw(&self, data: &mut StateData) {
|
||||
data.clear_screen(Rgb565::black().as_color());
|
||||
data.draw_text("Hello World", Position::new(0, 0), TextSettings::default());
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user