Add Keypad to AsyncIO
This commit is contained in:
parent
f3e0080f8e
commit
2380fbee6d
@ -1,18 +1,42 @@
|
|||||||
use core::{cell::RefCell, marker::PhantomData};
|
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 critical_section::Mutex;
|
||||||
|
|
||||||
use crate::at_commands::{ATCommand, StubATCommand};
|
use crate::at_commands::{ATCommand, StubATCommand};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct Button {
|
pub enum KeypadButton {
|
||||||
was_pressed: Rc<Mutex<RefCell<bool>>>,
|
Keypad1,
|
||||||
is_pressed: Rc<Mutex<RefCell<bool>>>,
|
Keypad2,
|
||||||
presses: Rc<Mutex<RefCell<u32>>>,
|
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<Mutex<RefCell<BTreeSet<KeypadButton>>>>,
|
||||||
|
is_pressed: Rc<Mutex<RefCell<BTreeSet<KeypadButton>>>>,
|
||||||
|
presses: Rc<Mutex<RefCell<BTreeMap<KeypadButton, u32>>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Keypad {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
was_pressed: Rc::new(Mutex::new(RefCell::new(Default::default()))),
|
was_pressed: Rc::new(Mutex::new(RefCell::new(Default::default()))),
|
||||||
@ -22,31 +46,49 @@ impl Default for Button {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Button {
|
impl Keypad {
|
||||||
pub unsafe fn set_pressed(&self, pressed: bool) {
|
pub fn handle_presses(&self, presses: BTreeSet<KeypadButton>) {
|
||||||
critical_section::with(|cs| {
|
critical_section::with(|cs| {
|
||||||
let mut was_pressed = self.was_pressed.borrow_ref_mut(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 is_pressed = self.is_pressed.borrow_ref_mut(cs);
|
||||||
let mut presses = self.presses.borrow_ref_mut(cs);
|
let mut num_presses = self.presses.borrow_ref_mut(cs);
|
||||||
*was_pressed = *is_pressed;
|
|
||||||
*is_pressed = pressed;
|
*was_pressed = is_pressed.clone();
|
||||||
if !*was_pressed && *is_pressed {
|
*is_pressed = presses;
|
||||||
*presses += 1;
|
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| {
|
critical_section::with(|cs| {
|
||||||
let presses = self.presses.borrow_ref(cs);
|
let is_pressed = self.is_pressed.borrow_ref(cs);
|
||||||
*presses
|
is_pressed.contains(&button)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pressed_buttons(&self) -> BTreeSet<KeypadButton> {
|
||||||
|
critical_section::with(|cs| {
|
||||||
|
let is_pressed = self.is_pressed.borrow_ref(cs);
|
||||||
|
is_pressed.clone()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&self) {
|
pub fn clear(&self) {
|
||||||
critical_section::with(|cs| {
|
critical_section::with(|cs| {
|
||||||
let mut presses = self.presses.borrow_ref_mut(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 {
|
pub struct AsyncIO {
|
||||||
at_command: Rc<Mutex<RefCell<Option<ConstructedATCommand>>>>,
|
at_command: Rc<Mutex<RefCell<Option<ConstructedATCommand>>>>,
|
||||||
at_response: Rc<Mutex<RefCell<Option<String>>>>,
|
at_response: Rc<Mutex<RefCell<Option<String>>>>,
|
||||||
pub button: Button,
|
pub keypad: Keypad,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AsyncIO {
|
impl Default for AsyncIO {
|
||||||
@ -74,7 +116,7 @@ impl Default for AsyncIO {
|
|||||||
Self {
|
Self {
|
||||||
at_command: Rc::new(Mutex::new(RefCell::new(None))),
|
at_command: Rc::new(Mutex::new(RefCell::new(None))),
|
||||||
at_response: Rc::new(Mutex::new(RefCell::new(None))),
|
at_response: Rc::new(Mutex::new(RefCell::new(None))),
|
||||||
button: Default::default(),
|
keypad: Keypad::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
29
src/main.rs
29
src/main.rs
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
use core::mem::MaybeUninit;
|
use core::mem::MaybeUninit;
|
||||||
|
|
||||||
use alloc::{boxed::Box, vec::Vec};
|
use alloc::{boxed::Box, collections::btree_set::BTreeSet, vec::Vec};
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::CpuClock,
|
clock::CpuClock,
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
@ -28,7 +28,7 @@ use esp_hal::{
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
async_io::AsyncIO,
|
async_io::{AsyncIO, KeypadButton},
|
||||||
at_commands::ATCommands,
|
at_commands::ATCommands,
|
||||||
display::{Display, Position, Rgb565, SetAddressMode},
|
display::{Display, Position, Rgb565, SetAddressMode},
|
||||||
font::FontRenderer,
|
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] = [
|
static KEYPAD_BUTTONS: [[KeypadButton; 4]; 4] = [
|
||||||
[
|
[
|
||||||
KeypadButton::Keypad1,
|
KeypadButton::Keypad1,
|
||||||
@ -260,7 +241,7 @@ fn thread_2_main(
|
|||||||
log::info!("Event: {}", event);
|
log::info!("Event: {}", event);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut buttons_pressed = Vec::new();
|
let mut buttons_pressed = BTreeSet::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let keypad_data = sx1509.read_keypad();
|
let keypad_data = sx1509.read_keypad();
|
||||||
@ -276,11 +257,11 @@ fn thread_2_main(
|
|||||||
if buttons_pressed.contains(&button) {
|
if buttons_pressed.contains(&button) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buttons_pressed.push(button);
|
buttons_pressed.insert(button);
|
||||||
delay.delay_millis(5);
|
delay.delay_millis(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
log::info!("Pressed: {:?}", buttons_pressed);
|
async_io.keypad.handle_presses(buttons_pressed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -85,7 +85,7 @@ impl<'a> StateManager<'a> {
|
|||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
self.data.io.button.clear();
|
self.data.io.keypad.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(&mut self) {
|
pub fn draw(&mut self) {
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use alloc::{borrow::ToOwned, boxed::Box, format, string::String};
|
|||||||
use esp_hal::time::{Duration, Instant};
|
use esp_hal::time::{Duration, Instant};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
async_io::ATPromise,
|
async_io::{ATPromise, KeypadButton},
|
||||||
at_commands::{
|
at_commands::{
|
||||||
ATCommand, ATInformationCommand, CheckPinCommand, EnterPinCommand, SMSFormat,
|
ATCommand, ATInformationCommand, CheckPinCommand, EnterPinCommand, SMSFormat,
|
||||||
SelectSMSFormatCommand, SetTECharsetCommand, TECharset,
|
SelectSMSFormatCommand, SetTECharsetCommand, TECharset,
|
||||||
@ -124,7 +124,7 @@ pub struct TextState {
|
|||||||
|
|
||||||
impl State for TextState {
|
impl State for TextState {
|
||||||
fn update(&mut self, data: &mut StateData) -> Option<Box<dyn State>> {
|
fn update(&mut self, data: &mut StateData) -> Option<Box<dyn State>> {
|
||||||
if data.io.button.get_presses() > 0 {
|
if data.io.keypad.get_presses(KeypadButton::KeypadA) > 0 {
|
||||||
Some(Box::new(ButtonTestState { presses: 0 }))
|
Some(Box::new(ButtonTestState { presses: 0 }))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -152,7 +152,7 @@ pub struct ButtonTestState {
|
|||||||
|
|
||||||
impl State for ButtonTestState {
|
impl State for ButtonTestState {
|
||||||
fn update(&mut self, data: &mut StateData) -> Option<Box<dyn State>> {
|
fn update(&mut self, data: &mut StateData) -> Option<Box<dyn State>> {
|
||||||
self.presses += data.io.button.get_presses();
|
self.presses += data.io.keypad.get_presses(KeypadButton::KeypadA);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user