From 2380fbee6d5b9bb8b919a01e3e20774a2dde5dd7 Mon Sep 17 00:00:00 2001 From: Sofia Date: Fri, 29 May 2026 21:55:18 +0300 Subject: [PATCH] Add Keypad to AsyncIO --- src/async_io.rs | 82 +++++++++++++++++++++++++++++++++++++------------ src/main.rs | 29 +++-------------- src/state.rs | 2 +- src/states.rs | 6 ++-- 4 files changed, 71 insertions(+), 48 deletions(-) diff --git a/src/async_io.rs b/src/async_io.rs index c9285bd..c2d6f40 100644 --- a/src/async_io.rs +++ b/src/async_io.rs @@ -1,18 +1,42 @@ use core::{cell::RefCell, marker::PhantomData}; -use alloc::{rc::Rc, string::String}; +use alloc::{ + collections::{btree_map::BTreeMap, btree_set::BTreeSet}, + rc::Rc, + string::String, + vec::Vec, +}; use critical_section::Mutex; use crate::at_commands::{ATCommand, StubATCommand}; -#[derive(Clone)] -pub struct Button { - was_pressed: Rc>>, - is_pressed: Rc>>, - presses: Rc>>, +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum KeypadButton { + Keypad1, + Keypad2, + Keypad3, + Keypad4, + Keypad5, + Keypad6, + Keypad7, + Keypad8, + Keypad9, + KeypadStar, + KeypadHash, + KeypadA, + KeypadB, + KeypadC, + KeypadD, } -impl Default for Button { +#[derive(Clone)] +pub struct Keypad { + was_pressed: Rc>>>, + is_pressed: Rc>>>, + presses: Rc>>>, +} + +impl Default for Keypad { fn default() -> Self { Self { was_pressed: Rc::new(Mutex::new(RefCell::new(Default::default()))), @@ -22,31 +46,49 @@ impl Default for Button { } } -impl Button { - pub unsafe fn set_pressed(&self, pressed: bool) { +impl Keypad { + pub fn handle_presses(&self, presses: BTreeSet) { critical_section::with(|cs| { let mut was_pressed = self.was_pressed.borrow_ref_mut(cs); let mut is_pressed = self.is_pressed.borrow_ref_mut(cs); - let mut presses = self.presses.borrow_ref_mut(cs); - *was_pressed = *is_pressed; - *is_pressed = pressed; - if !*was_pressed && *is_pressed { - *presses += 1; + let mut num_presses = self.presses.borrow_ref_mut(cs); + + *was_pressed = is_pressed.clone(); + *is_pressed = presses; + for button in is_pressed.iter() { + if !was_pressed.contains(button) { + let num = num_presses.get(button).copied().unwrap_or(0); + num_presses.insert(*button, num + 1); + } } + }); + } + + pub fn get_presses(&self, button: KeypadButton) -> u32 { + critical_section::with(|cs| { + let presses = self.presses.borrow_ref(cs); + presses.get(&button).copied().unwrap_or(0) }) } - pub fn get_presses(&self) -> u32 { + pub fn is_pressed(&self, button: KeypadButton) -> bool { critical_section::with(|cs| { - let presses = self.presses.borrow_ref(cs); - *presses + let is_pressed = self.is_pressed.borrow_ref(cs); + is_pressed.contains(&button) + }) + } + + pub fn pressed_buttons(&self) -> BTreeSet { + critical_section::with(|cs| { + let is_pressed = self.is_pressed.borrow_ref(cs); + is_pressed.clone() }) } pub fn clear(&self) { critical_section::with(|cs| { let mut presses = self.presses.borrow_ref_mut(cs); - *presses = 0; + presses.clear(); }) } } @@ -66,7 +108,7 @@ unsafe impl Sync for ConstructedATCommand {} pub struct AsyncIO { at_command: Rc>>>, at_response: Rc>>>, - pub button: Button, + pub keypad: Keypad, } impl Default for AsyncIO { @@ -74,7 +116,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: Default::default(), + keypad: Keypad::default(), } } } diff --git a/src/main.rs b/src/main.rs index bbf9f92..c91fc5d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,7 @@ use core::mem::MaybeUninit; -use alloc::{boxed::Box, vec::Vec}; +use alloc::{boxed::Box, collections::btree_set::BTreeSet, vec::Vec}; use esp_hal::{ clock::CpuClock, delay::Delay, @@ -28,7 +28,7 @@ use esp_hal::{ use esp_backtrace as _; use crate::{ - async_io::AsyncIO, + async_io::{AsyncIO, KeypadButton}, at_commands::ATCommands, display::{Display, Position, Rgb565, SetAddressMode}, font::FontRenderer, @@ -192,25 +192,6 @@ fn main() -> ! { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub enum KeypadButton { - Keypad1, - Keypad2, - Keypad3, - Keypad4, - Keypad5, - Keypad6, - Keypad7, - Keypad8, - Keypad9, - KeypadStar, - KeypadHash, - KeypadA, - KeypadB, - KeypadC, - KeypadD, -} - static KEYPAD_BUTTONS: [[KeypadButton; 4]; 4] = [ [ KeypadButton::Keypad1, @@ -260,7 +241,7 @@ fn thread_2_main( log::info!("Event: {}", event); } - let mut buttons_pressed = Vec::new(); + let mut buttons_pressed = BTreeSet::new(); loop { let keypad_data = sx1509.read_keypad(); @@ -276,11 +257,11 @@ fn thread_2_main( if buttons_pressed.contains(&button) { break; } - buttons_pressed.push(button); + buttons_pressed.insert(button); delay.delay_millis(5); } - log::info!("Pressed: {:?}", buttons_pressed); + async_io.keypad.handle_presses(buttons_pressed); } } diff --git a/src/state.rs b/src/state.rs index f0b145a..c01f674 100644 --- a/src/state.rs +++ b/src/state.rs @@ -85,7 +85,7 @@ impl<'a> StateManager<'a> { } None => {} } - self.data.io.button.clear(); + self.data.io.keypad.clear(); } pub fn draw(&mut self) { diff --git a/src/states.rs b/src/states.rs index e0d18a6..d5408aa 100644 --- a/src/states.rs +++ b/src/states.rs @@ -4,7 +4,7 @@ use alloc::{borrow::ToOwned, boxed::Box, format, string::String}; use esp_hal::time::{Duration, Instant}; use crate::{ - async_io::ATPromise, + async_io::{ATPromise, KeypadButton}, at_commands::{ ATCommand, ATInformationCommand, CheckPinCommand, EnterPinCommand, SMSFormat, SelectSMSFormatCommand, SetTECharsetCommand, TECharset, @@ -124,7 +124,7 @@ pub struct TextState { impl State for TextState { fn update(&mut self, data: &mut StateData) -> Option> { - if data.io.button.get_presses() > 0 { + if data.io.keypad.get_presses(KeypadButton::KeypadA) > 0 { Some(Box::new(ButtonTestState { presses: 0 })) } else { None @@ -152,7 +152,7 @@ pub struct ButtonTestState { impl State for ButtonTestState { fn update(&mut self, data: &mut StateData) -> Option> { - self.presses += data.io.button.get_presses(); + self.presses += data.io.keypad.get_presses(KeypadButton::KeypadA); None }