diff --git a/src/async_io.rs b/src/async_io.rs index 6998d2a..8cb9344 100644 --- a/src/async_io.rs +++ b/src/async_io.rs @@ -25,10 +25,18 @@ pub enum SMSFormat { TextMode = 1, } +#[derive(Clone, Default)] +pub struct Button { + was_pressed: bool, + is_pressed: bool, + presses: u32, +} + #[derive(Clone)] pub struct AsyncIO { at_command: Rc>>>, at_response: Rc>>>, + button: Rc>>, } impl Default for AsyncIO { @@ -36,6 +44,7 @@ impl Default for AsyncIO { Self { at_command: Rc::new(Mutex::new(RefCell::new(None))), at_response: Rc::new(Mutex::new(RefCell::new(None))), + button: Rc::new(Mutex::new(RefCell::new(Default::default()))), } } } @@ -86,4 +95,29 @@ impl AsyncIO { None }) } + + pub unsafe fn set_button_pressed(&self, pressed: bool) { + critical_section::with(|cs| { + let mut button = self.button.borrow_ref_mut(cs); + button.was_pressed = button.is_pressed; + button.is_pressed = pressed; + if !button.was_pressed && button.is_pressed { + button.presses += 1; + } + }) + } + + pub fn get_button_presses(&self) -> u32 { + critical_section::with(|cs| { + let button = self.button.borrow_ref(cs); + button.presses + }) + } + + pub fn clear_button_presses(&self) { + critical_section::with(|cs| { + let mut button = self.button.borrow_ref_mut(cs); + button.presses = 0; + }) + } } diff --git a/src/main.rs b/src/main.rs index d40c9bd..6a567dd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,7 +24,7 @@ use critical_section::Mutex; use esp_hal::{ clock::CpuClock, delay::Delay, - gpio::{InputConfig, Level, Output, OutputConfig}, + gpio::{Input, InputConfig, Level, Output, OutputConfig}, interrupt::software::SoftwareInterruptControl, main, spi::master::{Config, Spi}, @@ -39,7 +39,8 @@ use esp_backtrace as _; use crate::{ async_io::AsyncIO, at_commands::ATCommands, - display::{Display, SetAddressMode}, + display::{Display, Position, Rgb565, SetAddressMode}, + font::FontRenderer, state::StateManager, states::InitATState, }; @@ -142,6 +143,18 @@ fn main() -> ! { delay: Delay::new(), }; + let font_renderer = FontRenderer::create(30); + display.clear(Rgb565::black().as_color()); + font_renderer.render( + &mut display, + "Please wait", + Position::new(120, 120), + font::HorizontalAlignment::Center, + font::VerticalAlignment::Center, + Rgb565::black(), + Rgb565::white(), + ); + at_commands.init(); let async_io = AsyncIO::default(); @@ -169,6 +182,11 @@ fn main() -> ! { // let input_6 = Input::new(peripherals.GPIO26, pull_up_cfg); // let input_7 = Input::new(peripherals.GPIO27, pull_up_cfg); + let button = Input::new( + peripherals.GPIO13, + InputConfig::default().with_pull(esp_hal::gpio::Pull::Up), + ); + static mut THREAD_2_STACK: Stack<{ 30 * 1024 }> = esp_hal::system::Stack { mem: MaybeUninit::new([0u8; 30 * 1024]), }; @@ -185,11 +203,10 @@ fn main() -> ! { }, { let io = async_io.clone(); - || thread_2_main(io, at_commands) + || thread_2_main(io, at_commands, button) }, ); - let mut test_delay = Delay::new(); loop { state_mgr.update(); state_mgr.draw(); @@ -198,7 +215,7 @@ fn main() -> ! { // for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.1.0/examples } -fn thread_2_main(async_io: AsyncIO, mut at_commands: ATCommands<'static, 'static>) { +fn thread_2_main(async_io: AsyncIO, mut at_commands: ATCommands<'static, 'static>, button: Input) { loop { if let Some(command) = unsafe { async_io.check_at_command() } { let response = match command { @@ -219,5 +236,7 @@ fn thread_2_main(async_io: AsyncIO, mut at_commands: ATCommands<'static, 'static }; unsafe { async_io.set_at_response(response) }; } + + unsafe { async_io.set_button_pressed(button.is_low()) }; } } diff --git a/src/state.rs b/src/state.rs index 2f42725..a12fe3b 100644 --- a/src/state.rs +++ b/src/state.rs @@ -10,10 +10,10 @@ use crate::{ #[derive(PartialEq, Eq, Clone)] pub struct TextSettings { - h_align: HorizontalAlignment, - v_align: VerticalAlignment, - fg: Rgb565, - bg: Rgb565, + pub h_align: HorizontalAlignment, + pub v_align: VerticalAlignment, + pub fg: Rgb565, + pub bg: Rgb565, } impl Default for TextSettings { @@ -82,6 +82,7 @@ impl<'a> StateManager<'a> { Some(next_state) => self.curr_state = next_state, None => {} } + self.data.io.clear_button_presses(); } pub fn draw(&mut self) { diff --git a/src/states.rs b/src/states.rs index 8349318..2e02040 100644 --- a/src/states.rs +++ b/src/states.rs @@ -11,6 +11,7 @@ use esp_hal::time::{Duration, Instant}; use crate::{ async_io::{ATCommand, SMSFormat}, display::{Position, Rgb565}, + font::{HorizontalAlignment, VerticalAlignment}, state::{State, StateData, TextSettings}, }; @@ -110,12 +111,44 @@ pub struct TextState { impl State for TextState { fn update(&mut self, data: &mut StateData) -> Option> { - data.delay.delay_millis(100); - None + if data.io.get_button_presses() > 0 { + Some(Box::new(ButtonTestState { presses: 0 })) + } else { + None + } } fn draw(&self, data: &mut StateData) { data.clear_screen(Rgb565::black().as_color()); data.draw_text(&self.text, Position::new(0, 0), TextSettings::default()); + data.draw_text( + "OK", + Position::new(120, 240), + TextSettings { + h_align: HorizontalAlignment::Center, + v_align: VerticalAlignment::BottomToTop, + ..Default::default() + }, + ); + } +} + +pub struct ButtonTestState { + presses: u32, +} + +impl State for ButtonTestState { + fn update(&mut self, data: &mut StateData) -> Option> { + self.presses += data.io.get_button_presses(); + None + } + + fn draw(&self, data: &mut StateData) { + data.clear_screen(Rgb565::black().as_color()); + data.draw_text( + format!("Presses: {}", self.presses), + Position::new(0, 0), + TextSettings::default(), + ); } }