From 5418c1b23207160f15693e16305fc0aa1d925760 Mon Sep 17 00:00:00 2001 From: Joakim Hulthe Date: Fri, 7 May 2021 01:20:32 +0200 Subject: [PATCH] Read key inputs --- src/main.rs | 63 ++++++++++++++++++++++++++++++++++++++++++++-- src/ring_buffer.rs | 15 ++++++++++- src/usb_shell.rs | 2 +- src/util/mod.rs | 40 +++++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index a8a1280..9081967 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,10 @@ mod usb_shell; mod util; mod wait_delay; +use crate::ring_buffer::RingBuffer; +use crate::util::ByteStr; +use core::fmt::Write; +use embedded_hal::digital::v2::{InputPin, OutputPin}; use hal::clock::GenericClockController; use hal::entry; use hal::pac::{interrupt, CorePeripherals, Peripherals}; @@ -34,9 +38,16 @@ fn main() -> ! { ); let mut pins = hal::Pins::new(peripherals.PORT); let mut red_led = pins.d13.into_open_drain_output(&mut pins.port); - //let mut delay = Delay::new(core.SYST, &mut clocks); let mut delay = WaitDelay::new(core.SYST, &mut clocks); + let col0 = pins.d9.into_pull_up_input(&mut pins.port); + let col1 = pins.d12.into_pull_up_input(&mut pins.port); + let cols = [&col0 as &dyn InputPin, &col1]; + + let mut row0 = pins.d11.into_open_drain_output(&mut pins.port); + let mut row1 = pins.d7.into_open_drain_output(&mut pins.port); + let mut rows = [&mut row0 as &mut dyn OutputPin, &mut row1]; + let mut blip = || { red_led.set_low().ok(); delay.delay_ms(100u16); @@ -54,11 +65,59 @@ fn main() -> ! { &mut blip, ); + let mut matrix = [[false; 2]; 2]; + // Flash the LED in a spin loop to demonstrate that USB is // entirely interrupt driven. loop { - blip(); + let mut switched_buttons = RingBuffer::<(usize, usize, bool), 4>::new(); + + for (i, row) in rows.iter_mut().enumerate() { + row.set_low().ok(); + for (j, col) in cols.iter().enumerate() { + let state = col.is_low().unwrap_or(false); + if matrix[i][j] != state { + matrix[i][j] = state; + switched_buttons.push_back((i, j, state)).ok(); + } + } + row.set_high().ok(); + } + + if matrix.iter().flatten().any(|&f| f) { + red_led.set_high().ok(); + } else { + red_led.set_low().ok(); + } + + while let Some((i, j, pressed)) = switched_buttons.pop_front() { + let mut buf = ByteStr::<255>::new(); + write!( + &mut buf, + "button [{}, {}] {}", + i, + j, + if pressed { "pressed" } else { "released" } + ) + .ok(); + usb.println(&buf); + } + + /* + n += buf.write(b"buttons: ").unwrap_or(0); + for &pressed in matrix.iter().flatten() { + if pressed { + n += buf.write("DOWN").unwrap_or(0); + } else { + n += buf.write("UP").unwrap_or(0); + } + n += buf.write(" ").unwrap_or(0); + } + */ + + delay.delay_ms(50u16); usb.poll(); + //usb.println(b"woop"); } } diff --git a/src/ring_buffer.rs b/src/ring_buffer.rs index f02d9d6..f15ab0f 100644 --- a/src/ring_buffer.rs +++ b/src/ring_buffer.rs @@ -5,7 +5,7 @@ pub struct RingBuffer { } impl RingBuffer { - pub const fn new() -> Self { + pub const fn new_u8() -> Self { RingBuffer { buffer: [0; N], start: 0, @@ -14,6 +14,19 @@ impl RingBuffer { } } +impl RingBuffer +where + T: Default + Copy, +{ + pub fn new() -> Self { + RingBuffer { + buffer: [Default::default(); N], + start: 0, + end: 0, + } + } +} + impl RingBuffer where T: Copy, diff --git a/src/usb_shell.rs b/src/usb_shell.rs index 9e4dbda..a619166 100644 --- a/src/usb_shell.rs +++ b/src/usb_shell.rs @@ -28,7 +28,7 @@ static USB_READY: AtomicBool = AtomicBool::new(false); static mut USB_BUS: Option> = None; static mut USB_SERIAL: Option> = None; -static INPUT_BUFFER: RacyCell> = RacyCell::new(RingBuffer::new()); +static INPUT_BUFFER: RacyCell> = RacyCell::new(RingBuffer::new_u8()); const PROMPT: &[u8] = b"[neowatch]# "; diff --git a/src/util/mod.rs b/src/util/mod.rs index 48433da..46cf0de 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -1 +1,41 @@ pub mod cell; + +use core::fmt::{self, Write}; +use core::ops::Deref; + +pub struct ByteStr { + bytes: [u8; N], + len: usize, +} + +impl ByteStr { + pub fn new() -> Self { + ByteStr { + bytes: [0; N], + len: 0, + } + } +} + +impl Deref for ByteStr { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.bytes[..self.len] + } +} + +impl Write for ByteStr { + fn write_str(&mut self, s: &str) -> fmt::Result { + let b = s.as_bytes(); + + if (self.bytes.len() - self.len) < b.len() { + return Err(fmt::Error); + } + + self.bytes[self.len..self.len + b.len()].copy_from_slice(b); + self.len += b.len(); + + Ok(()) + } +}