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 embedded_hal::{delay::DelayNs, spi::SpiBus};
|
||||||
use esp_hal::{DriverMode, gpio::Output, spi::master::Spi};
|
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);
|
pub struct Rgb565(pub u8, pub u8, pub u8);
|
||||||
|
|
||||||
impl Rgb565 {
|
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 struct Position {
|
||||||
pub x: i16,
|
pub x: i16,
|
||||||
pub y: i16,
|
pub y: i16,
|
||||||
@ -84,7 +84,7 @@ impl Position {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone, Copy)]
|
#[derive(Default, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct Color {
|
pub struct Color {
|
||||||
pub bytes: [u8; 2],
|
pub bytes: [u8; 2],
|
||||||
}
|
}
|
||||||
@ -371,4 +371,8 @@ impl<'d, DM: DriverMode, T: DelayNs> Display<'d, DM, T> {
|
|||||||
self.write(Writeable::Data(&color.bytes));
|
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");
|
static OPEN_SANS: &'static [u8] = include_bytes!("./OpenSans_Condensed-Regular.ttf");
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
|
||||||
pub enum HorizontalAlignment {
|
pub enum HorizontalAlignment {
|
||||||
RightToLeft,
|
RightToLeft,
|
||||||
Center,
|
Center,
|
||||||
LeftToRight,
|
LeftToRight,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
|
||||||
pub enum VerticalAlignment {
|
pub enum VerticalAlignment {
|
||||||
TopToBottom,
|
TopToBottom,
|
||||||
Center,
|
Center,
|
||||||
|
|||||||
34
src/main.rs
34
src/main.rs
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
|
|
||||||
use alloc::{borrow::ToOwned, str};
|
use alloc::{borrow::ToOwned, boxed::Box, str};
|
||||||
use embedded_hal::delay::DelayNs;
|
use embedded_hal::delay::DelayNs;
|
||||||
use esp_alloc::export::enumset::EnumSet;
|
use esp_alloc::export::enumset::EnumSet;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
@ -28,6 +28,7 @@ use crate::{
|
|||||||
at_commands::ATCommands,
|
at_commands::ATCommands,
|
||||||
display::{Display, Position, Rgb565, SetAddressMode},
|
display::{Display, Position, Rgb565, SetAddressMode},
|
||||||
font::{FontRenderer, HorizontalAlignment, VerticalAlignment},
|
font::{FontRenderer, HorizontalAlignment, VerticalAlignment},
|
||||||
|
state::{HelloState, StateManager},
|
||||||
};
|
};
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
@ -35,6 +36,7 @@ extern crate alloc;
|
|||||||
mod at_commands;
|
mod at_commands;
|
||||||
mod display;
|
mod display;
|
||||||
mod font;
|
mod font;
|
||||||
|
mod state;
|
||||||
|
|
||||||
// This creates a default app-descriptor required by the esp-idf bootloader.
|
// 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>
|
// 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();
|
// at_commands.init();
|
||||||
render_response(at_commands.raw_command("ATI".to_owned()));
|
// 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+CMGF?".to_owned()));
|
||||||
render_response(at_commands.raw_command("AT+CPIN=1234".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+CPIN?".to_owned()));
|
||||||
render_response(at_commands.raw_command("AT+CMGF=1".to_owned()));
|
// render_response(at_commands.raw_command("AT+CMGF=1".to_owned()));
|
||||||
render_response(at_commands.raw_command("AT+CSCS=?".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(
|
// render_response(
|
||||||
// at_commands.raw_two_part_command("AT+CMGS=\"number\"".to_owned(), "hello".to_owned()),
|
// 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();
|
let mut test_delay = Delay::new();
|
||||||
loop {
|
loop {
|
||||||
// log::info!("Input 1: {}", input_1.is_high());
|
state_mgr.update();
|
||||||
// log::info!("Input 2: {}", input_2.is_high());
|
state_mgr.draw();
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.1.0/examples
|
// 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