This commit is contained in:
Sofia 2026-05-28 23:10:38 +03:00
parent 7e4b2e3162
commit 3ba28b7915
3 changed files with 73 additions and 24 deletions

View File

@ -3,7 +3,7 @@ use core::{cell::RefCell, marker::PhantomData};
use alloc::{rc::Rc, string::String}; use alloc::{rc::Rc, string::String};
use critical_section::Mutex; use critical_section::Mutex;
use crate::at_commands::ATCommand; use crate::at_commands::{ATCommand, StubATCommand};
#[derive(Clone)] #[derive(Clone)]
pub struct Button { pub struct Button {
@ -97,13 +97,17 @@ impl<T: ATCommand> ATPromise<T> {
None => Some(None), None => Some(None),
} }
} }
pub fn downgrade(self) -> ATPromise<StubATCommand> {
ATPromise { _data: PhantomData }
}
} }
impl AsyncIO { impl AsyncIO {
pub fn send_at_command<Resp, T: ATCommand<Response = Resp>>( pub fn send_at_command<Resp, T: ATCommand<Response = Resp>>(
&self, &self,
command: T, command: T,
) -> Result<(), ()> { ) -> Result<ATPromise<T>, ()> {
critical_section::with(|cs| { critical_section::with(|cs| {
let mut borrow = self.at_command.borrow_ref_mut(cs); let mut borrow = self.at_command.borrow_ref_mut(cs);
if borrow.is_some() { if borrow.is_some() {
@ -112,7 +116,7 @@ impl AsyncIO {
*borrow = Some(command.execute()); *borrow = Some(command.execute());
Ok(()) Ok(ATPromise { _data: PhantomData })
}) })
} }
@ -132,7 +136,7 @@ impl AsyncIO {
}) })
} }
pub fn poll_at_response(&self) -> Option<Option<String>> { fn poll_at_response(&self) -> Option<Option<String>> {
critical_section::with(|cs| { critical_section::with(|cs| {
let command = self.at_command.borrow_ref(cs); let command = self.at_command.borrow_ref(cs);
let mut response = self.at_response.borrow_ref_mut(cs); let mut response = self.at_response.borrow_ref_mut(cs);

View File

@ -2,6 +2,7 @@ use alloc::string::{String, ToString};
use alloc::vec::Vec; use alloc::vec::Vec;
use alloc::{borrow::ToOwned, format}; use alloc::{borrow::ToOwned, format};
use core::fmt::Write; use core::fmt::Write;
use core::marker::PhantomData;
use esp_hal::{Blocking, delay::Delay, gpio::Output, uart::Uart}; use esp_hal::{Blocking, delay::Delay, gpio::Output, uart::Uart};
use crate::async_io::ConstructedATCommand; use crate::async_io::ConstructedATCommand;
@ -164,6 +165,19 @@ pub trait ATCommand: Send + Sync {
fn parse_response(text: String) -> Self::Response; fn parse_response(text: String) -> Self::Response;
} }
pub struct StubATCommand(());
impl ATCommand for StubATCommand {
type Response = String;
fn execute(&self) -> ConstructedATCommand {
panic!("Should never be called")
}
fn parse_response(text: String) -> Self::Response {
text
}
}
pub struct ATInformationCommand; pub struct ATInformationCommand;
impl ATCommand for ATInformationCommand { impl ATCommand for ATInformationCommand {
type Response = String; type Response = String;

View File

@ -9,9 +9,11 @@ use alloc::{
use esp_hal::time::{Duration, Instant}; use esp_hal::time::{Duration, Instant};
use crate::{ use crate::{
async_io::ATPromise,
at_commands::{ at_commands::{
ATInformationCommand, CheckPinCommand, EnterPinCommand, ListTECharacterSetsCommand, ATInformationCommand, CheckPinCommand, EnterPinCommand, ListTECharacterSetsCommand,
SMSFormat, SelectSMSFormatCommand, SendSMSCommand, SetTECharsetCommand, TECharset, SMSFormat, SelectSMSFormatCommand, SendSMSCommand, SetTECharsetCommand, StubATCommand,
TECharset,
}, },
display::{Position, Rgb565}, display::{Position, Rgb565},
font::{HorizontalAlignment, VerticalAlignment}, font::{HorizontalAlignment, VerticalAlignment},
@ -23,6 +25,7 @@ pub struct InitATState {
message: String, message: String,
dots: u8, dots: u8,
prev_dots: Instant, prev_dots: Instant,
promise: Option<ATPromise<StubATCommand>>,
} }
impl Default for InitATState { impl Default for InitATState {
@ -32,6 +35,7 @@ impl Default for InitATState {
message: "Initializing AT..".to_string(), message: "Initializing AT..".to_string(),
dots: 0, dots: 0,
prev_dots: Instant::now(), prev_dots: Instant::now(),
promise: None,
} }
} }
} }
@ -44,13 +48,16 @@ impl State for InitATState {
self.prev_dots = Instant::now(); self.prev_dots = Instant::now();
} }
// Wait for previous AT command to finish if let Some(promise) = &self.promise {
if let Some(response) = data.io.poll_at_response() { match promise.poll(&mut data.io) {
match response { Some(response) => match response {
Some(response) => { Some(response) => {
log::info!("Response: {}", response) log::info!("Response: {}", response);
} self.promise = None;
None => {} }
None => {}
},
None => self.promise = None,
} }
return None; return None;
} }
@ -58,37 +65,61 @@ impl State for InitATState {
// Send next AT command // Send next AT command
let res: Option<Box<dyn State>> = match self.inner_state { let res: Option<Box<dyn State>> = match self.inner_state {
0 => { 0 => {
data.io.send_at_command(ATInformationCommand).unwrap(); self.promise = Some(
data.io
.send_at_command(ATInformationCommand)
.unwrap()
.downgrade(),
);
self.message = "Checking info".to_owned(); self.message = "Checking info".to_owned();
None None
} }
1 => { 1 => {
data.io self.promise = Some(
.send_at_command(EnterPinCommand("1234".to_owned())) data.io
.unwrap(); .send_at_command(EnterPinCommand("1234".to_owned()))
.unwrap()
.downgrade(),
);
self.message = "Entering PIN".to_owned(); self.message = "Entering PIN".to_owned();
None None
} }
2 => { 2 => {
data.io.send_at_command(CheckPinCommand).unwrap(); self.promise = Some(
data.io
.send_at_command(CheckPinCommand)
.unwrap()
.downgrade(),
);
None None
} }
3 => { 3 => {
data.io.send_at_command(ListTECharacterSetsCommand).unwrap(); self.promise = Some(
data.io
.send_at_command(ListTECharacterSetsCommand)
.unwrap()
.downgrade(),
);
self.message = "Checking\ncharsets".to_owned(); self.message = "Checking\ncharsets".to_owned();
None None
} }
4 => { 4 => {
data.io self.promise = Some(
.send_at_command(SelectSMSFormatCommand(SMSFormat::TextMode)) data.io
.unwrap(); .send_at_command(SelectSMSFormatCommand(SMSFormat::TextMode))
.unwrap()
.downgrade(),
);
self.message = "Selecting SMS\nformat".to_owned(); self.message = "Selecting SMS\nformat".to_owned();
None None
} }
5 => { 5 => {
data.io self.promise = Some(
.send_at_command(SetTECharsetCommand(TECharset::IRA)) data.io
.unwrap(); .send_at_command(SetTECharsetCommand(TECharset::IRA))
.unwrap()
.downgrade(),
);
self.message = "Selecting SMS\nformat".to_owned(); self.message = "Selecting SMS\nformat".to_owned();
None None
} }