diff --git a/Cargo.lock b/Cargo.lock index dc289e6..ce740b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "embedded-hal" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" - [[package]] name = "zel-tca8418" version = "0.1.0" -dependencies = [ - "embedded-hal", -] diff --git a/Cargo.toml b/Cargo.toml index 210a175..d9191de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,3 @@ version = "0.1.0" edition = "2024" [dependencies] -embedded-hal = "1.0.0" diff --git a/src/lib.rs b/src/lib.rs index 69650c1..1ef6109 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,159 +1,2 @@ #![no_std] -use embedded_hal::i2c::SevenBitAddress; - -pub const I2C_ADDR: SevenBitAddress = 0b0_0110100; - -pub struct TCA8418 { - i2c: I2C, -} - -#[derive(Clone, Copy)] -pub struct MatrixConfig { - rows: u8, - columns: u16, -} - -impl MatrixConfig { - /// A new config where the matrix has no rows or columns and all of the pins are - /// allocated for GPIO. - pub const fn new_empty() -> Self { - MatrixConfig { - rows: 0, - columns: 0, - } - } - - /// Add a row to the keyboard matrix, meaning its pin will not be available for GPIO. - /// - /// `row_number` must be in the range `0..=7` - pub const fn with_row(self, row_number: u8) -> Self { - if row_number >= 8 { - panic!("row_number out of bounds"); - } - MatrixConfig { - rows: self.rows | (1 << row_number), - columns: self.columns, - } - } - - /// Add a column to the keyboard matrix, meaning its pin will not be available for GPIO. - /// - /// `column_number` must be in the range `0..=9` - pub const fn with_column(self, column_number: u8) -> Self { - if column_number >= 10 { - panic!("column_number out of bounds"); - } - MatrixConfig { - rows: self.rows, - columns: self.columns | (1 << column_number), - } - } -} - -#[derive(Clone, Copy)] -pub struct InterruptConfig(u8); - -impl InterruptConfig { - /// A new interrupt with the following configuration: - /// - GPI events are tracked when keypad is locked - /// - Overflow data is lost - /// - Processor interrupt remains asserted (or low) if host tries to clear - /// interrupt while there is still a pending key press, key release or - /// GPI interrupt - /// - ~INT is not asserted if the FIFO overflows - /// - ~INT is not asserted after a correct unlock key sequence - /// - ~INT is not asserted for a change on a GPI - /// - ~INT is not asserted when a key event occurs - pub const fn new() -> Self { - Self(0) - } - - pub const fn without_gpi_event_tracking_when_locked(self) -> Self { - InterruptConfig(self.0 | 0b0100_0000) - } - - pub const fn with_overflow_data_shifting(self) -> Self { - InterruptConfig(self.0 | 0b0010_0000) - } - - pub const fn with_temporary_interrupt_deassertion(self) -> Self { - InterruptConfig(self.0 | 0b0001_0000) - } -} - -#[derive(Clone, Copy)] -pub struct KeySet(u128); - -impl KeySet { - fn contains(&self, key_number: u8) -> bool { - (self.0 & (1 << key_number)) != 0 - } -} - -impl core::ops::Not for KeySet { - type Output = KeySet; - - fn not(self) -> Self::Output { - KeySet(!self.0) - } -} - -pub struct KeySetIter { - key_set: KeySet, - shift: u8, -} - -impl core::iter::Iterator for KeySetIter { - type Item = u8; - - fn next(&mut self) -> Option { - let next_shift = self.key_set.0.trailing_zeros() as u8 + 1; - if next_shift >= 128 { - return None; - } - - self.key_set.0 >>= next_shift; - self.shift += next_shift; - - Some(self.shift - 1) - } -} - -impl core::iter::IntoIterator for KeySet { - type Item = u8; - - type IntoIter = KeySetIter; - - fn into_iter(self) -> Self::IntoIter { - KeySetIter { - key_set: self, - shift: 0 - } - } -} - -impl TCA8418 { - pub fn new( - i2c: I2C, - matrix_config: MatrixConfig, - interrupt_config: InterruptConfig, - ) -> Self { - let mut self_ = Self { i2c }; - self_.init(matrix_config, interrupt_config); - self_ - } - - fn init(&mut self, matrix_config: MatrixConfig, interrupt_config: InterruptConfig) { - self.i2c.write(I2C_ADDR, &[0x1D, matrix_config.rows]); - self.i2c - .write(I2C_ADDR, &[0x1E, matrix_config.columns as u8]); - self.i2c - .write(I2C_ADDR, &[0x1F, (matrix_config.columns >> 8) as u8]); - self.i2c.write(I2C_ADDR, &[0x01, interrupt_config.0]); - self.i2c.write(I2C_ADDR, &[0x0F, 0]); - self.i2c.write(I2C_ADDR, &[0x10, 0]); - self.i2c.write(I2C_ADDR, &[0x0E, 0]); - } -} -