use core::iter::repeat; use alloc::{ borrow::ToOwned, boxed::Box, format, string::{String, ToString}, }; use esp_hal::time::{Duration, Instant}; use crate::{ async_io::{ATCommand, Charset, SMSFormat}, display::{Position, Rgb565}, font::{HorizontalAlignment, VerticalAlignment}, state::{State, StateData, TextSettings}, }; pub struct InitATState { inner_state: u8, message: String, dots: u8, prev_dots: Instant, } impl Default for InitATState { fn default() -> Self { Self { inner_state: 0, message: "Initializing AT..".to_string(), dots: 0, prev_dots: Instant::now(), } } } impl State for InitATState { fn update(&mut self, data: &mut StateData) -> Option> { // Update dots if self.prev_dots.elapsed() > Duration::from_millis(200) { self.dots = (self.dots + 1) % 3; self.prev_dots = Instant::now(); } // Wait for previous AT command to finish if let Some(response) = data.io.poll_at_response() { match response { Some(_) => {} None => {} } return None; } // Send next AT command let res: Option> = match self.inner_state { 0 => { data.io.send_at_command(ATCommand::ATInformation).unwrap(); self.message = "Checking info".to_owned(); None } 1 => { data.io .send_at_command(ATCommand::EnterPin("1234".to_owned())) .unwrap(); self.message = "Entering PIN".to_owned(); None } 2 => { data.io.send_at_command(ATCommand::CheckPin).unwrap(); None } 3 => { data.io .send_at_command(ATCommand::ListTECharacterSets) .unwrap(); self.message = "Checking\ncharsets".to_owned(); None } 4 => { data.io .send_at_command(ATCommand::SelectSMSFormat(SMSFormat::TextMode)) .unwrap(); self.message = "Selecting SMS\nformat".to_owned(); None } 5 => { data.io .send_at_command(ATCommand::SetTECharSet(Charset::IRA)) .unwrap(); self.message = "Selecting SMS\nformat".to_owned(); None } _ => { data.delay.delay_millis(1000); Some(Box::new(TextState { text: "AT init done!".to_owned(), })) } }; self.inner_state = (self.inner_state + 1).min(200); res } fn draw(&self, data: &mut StateData) { data.clear_screen(Rgb565::black().as_color()); let dots = repeat(".").take(self.dots as usize).collect::(); data.draw_text( format!("{}{}", self.message, dots), Position::new(0, 0), TextSettings::default(), ); } } pub struct TextState { text: String, } impl State for TextState { fn update(&mut self, data: &mut StateData) -> Option> { if data.io.button.get_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.button.get_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(), ); } }