use embedded_hal::digital::v2::{InputPin, OutputPin};
pub struct Matrix<C, R, const CS: usize, const RS: usize>
where
C: InputPin,
R: OutputPin,
{
cols: [C; CS],
rows: [R; RS],
}
impl<C, R, const CS: usize, const RS: usize> Matrix<C, R, CS, RS>
where
C: InputPin,
R: OutputPin,
{
pub fn new<E>(cols: [C; CS], rows: [R; RS]) -> Result<Self, E>
where
C: InputPin<Error = E>,
R: OutputPin<Error = E>,
{
let mut res = Self { cols, rows };
res.clear()?;
Ok(res)
}
fn clear<E>(&mut self) -> Result<(), E>
where
C: InputPin<Error = E>,
R: OutputPin<Error = E>,
{
for r in self.rows.iter_mut() {
r.set_high()?;
}
Ok(())
}
pub fn get<E>(&mut self) -> Result<[[bool; CS]; RS], E>
where
C: InputPin<Error = E>,
R: OutputPin<Error = E>,
{
let mut keys = [[false; CS]; RS];
for (ri, row) in (&mut self.rows).iter_mut().enumerate() {
row.set_low()?;
for (ci, col) in (&self.cols).iter().enumerate() {
if col.is_low()? {
keys[ri][ci] = true;
}
}
row.set_high()?;
}
Ok(keys)
}
}
pub struct DirectPinMatrix<P, const CS: usize, const RS: usize>
where
P: InputPin,
{
pins: [[Option<P>; CS]; RS],
}
impl<P, const CS: usize, const RS: usize> DirectPinMatrix<P, CS, RS>
where
P: InputPin,
{
pub fn new<E>(pins: [[Option<P>; CS]; RS]) -> Result<Self, E>
where
P: InputPin<Error = E>,
{
let res = Self { pins };
Ok(res)
}
pub fn get<E>(&mut self) -> Result<[[bool; CS]; RS], E>
where
P: InputPin<Error = E>,
{
let mut keys = [[false; CS]; RS];
for (ri, row) in (&mut self.pins).iter_mut().enumerate() {
for (ci, col_option) in row.iter().enumerate() {
if let Some(col) = col_option {
if col.is_low()? {
keys[ri][ci] = true;
}
}
}
}
Ok(keys)
}
}