pub struct Matrix<C: OutputPin, R: InputPin, const CSIZE: usize, const RSIZE: usize, const MSIZE: usize, const SCAN_PERIOD_US: u32, const DEBOUNCE_US: u32, const IDLE_MS: u32> { /* private fields */ }
Expand description

This struct handles scanning and strobing of the key matrix.

It also handles the debouncing of key input to ensure acurate keypresses are being read. OutputPin’s are passed as columns (cols) which are strobed. IoPins are functionally InputPins (rows) which are read. Rows are IoPins in order to drain the row/sense between strobes to prevent stray capacitance.

const CSIZE: usize = 18; // Number of columns
const RSIZE: usize = 6; // Number of rows
const MSIZE: usize = RSIZE * CSIZE; // Total matrix size
// Period of time it takes to re-scan a column (everything must be constant time!)
const SCAN_PERIOD_US = 40;
// Debounce timer in us. Can only be as precise as a multiple of SCAN_PERIOD_US.
// Per-key timer is reset if the raw gpio reading changes for any reason.
const DEBOUNCE_US = 5000; // 5 ms
// Idle timer in ms. Only valid if the switch is in the off state.
const IDLE_MS = 600_0000; // 600 seconds or 10 minutes

let cols = [
    pins.strobe1.downgrade(),
    pins.strobe2.downgrade(),
    pins.strobe3.downgrade(),
    pins.strobe4.downgrade(),
    pins.strobe5.downgrade(),
    pins.strobe6.downgrade(),
    pins.strobe7.downgrade(),
    pins.strobe8.downgrade(),
    pins.strobe9.downgrade(),
    pins.strobe10.downgrade(),
    pins.strobe11.downgrade(),
    pins.strobe12.downgrade(),
    pins.strobe13.downgrade(),
    pins.strobe14.downgrade(),
    pins.strobe15.downgrade(),
    pins.strobe16.downgrade(),
    pins.strobe17.downgrade(),
    pins.strobe18.downgrade(),
];

let rows = [
    pins.sense1.downgrade(),
    pins.sense2.downgrade(),
    pins.sense3.downgrade(),
    pins.sense4.downgrade(),
    pins.sense5.downgrade(),
    pins.sense6.downgrade(),
];

let mut matrix = Matrix::<OutputPin, InputPin, CSIZE, RSIZE, MSIZE, SCAN_PERIOD_US, DEBOUNCE_US,
IDLE_MS>::new(cols, rows);

// Prepare first strobe
matrix.next_strobe().unwrap();

// --> This next part must be done in constant time (SCAN_PERIOD_US) <--
let state = matrix.sense().unwrap();
matrix.next_strobe().unwrap();

Implementations§

source§

impl<C: OutputPin, R: InputPin, const CSIZE: usize, const RSIZE: usize, const MSIZE: usize, const SCAN_PERIOD_US: u32, const DEBOUNCE_US: u32, const IDLE_MS: u32> Matrix<C, R, CSIZE, RSIZE, MSIZE, SCAN_PERIOD_US, DEBOUNCE_US, IDLE_MS>

source

pub fn new<'a, E>(cols: [C; CSIZE], rows: [R; RSIZE]) -> Result<Self, E>where C: OutputPin<Error = E>, E: From<<C as OutputPin>::Error> + 'a,

source

pub fn clear<'a, E: 'a>(&'a mut self) -> Result<(), E>where C: OutputPin<Error = E>,

Clears strobes Resets strobe counter to the last element (so next_strobe starts at 0)

source

pub fn next_strobe<'a, E>(&'a mut self) -> Result<usize, E>where C: OutputPin<Error = E> + IoPin<R, C>, R: InputPin<Error = E> + IoPin<R, C>, E: From<<R as IoPin<R, C>>::Error> + From<<C as IoPin<R, C>>::Error> + 'a,

Next strobe

source

pub fn strobe(&self) -> usize

Current strobe

source

pub fn sense<'a, E>(&'a mut self) -> Result<([KeyEvent; RSIZE], usize), E>where E: From<<R as InputPin>::Error> + 'a,

Sense a column of switches

Returns the results of each row for the currently strobed column and the measured strobe

source

pub fn state( &self, index: usize ) -> Option<KeyState<CSIZE, SCAN_PERIOD_US, DEBOUNCE_US, IDLE_MS>>

Return the KeyState for a given index

source

pub fn generate_key_event(&self, index: usize) -> Option<KeyEvent>

Generate event from KeyState Useful when trying to determine if a key has not been pressed

Auto Trait Implementations§

§

impl<C, R, const CSIZE: usize, const RSIZE: usize, const MSIZE: usize, const SCAN_PERIOD_US: u32, const DEBOUNCE_US: u32, const IDLE_MS: u32> RefUnwindSafe for Matrix<C, R, CSIZE, RSIZE, MSIZE, SCAN_PERIOD_US, DEBOUNCE_US, IDLE_MS>where C: RefUnwindSafe, R: RefUnwindSafe,

§

impl<C, R, const CSIZE: usize, const RSIZE: usize, const MSIZE: usize, const SCAN_PERIOD_US: u32, const DEBOUNCE_US: u32, const IDLE_MS: u32> Send for Matrix<C, R, CSIZE, RSIZE, MSIZE, SCAN_PERIOD_US, DEBOUNCE_US, IDLE_MS>where C: Send, R: Send,

§

impl<C, R, const CSIZE: usize, const RSIZE: usize, const MSIZE: usize, const SCAN_PERIOD_US: u32, const DEBOUNCE_US: u32, const IDLE_MS: u32> Sync for Matrix<C, R, CSIZE, RSIZE, MSIZE, SCAN_PERIOD_US, DEBOUNCE_US, IDLE_MS>where C: Sync, R: Sync,

§

impl<C, R, const CSIZE: usize, const RSIZE: usize, const MSIZE: usize, const SCAN_PERIOD_US: u32, const DEBOUNCE_US: u32, const IDLE_MS: u32> Unpin for Matrix<C, R, CSIZE, RSIZE, MSIZE, SCAN_PERIOD_US, DEBOUNCE_US, IDLE_MS>where C: Unpin, R: Unpin,

§

impl<C, R, const CSIZE: usize, const RSIZE: usize, const MSIZE: usize, const SCAN_PERIOD_US: u32, const DEBOUNCE_US: u32, const IDLE_MS: u32> UnwindSafe for Matrix<C, R, CSIZE, RSIZE, MSIZE, SCAN_PERIOD_US, DEBOUNCE_US, IDLE_MS>where C: UnwindSafe, R: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.