Skip to content

Commit

Permalink
async/internal: Add clear_interrupt test
Browse files Browse the repository at this point in the history
  • Loading branch information
RobertZ2011 committed Jan 6, 2025
1 parent 1c519e0 commit 96f955f
Showing 1 changed file with 61 additions and 5 deletions.
66 changes: 61 additions & 5 deletions src/asynchronous/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ pub const ADDR0: [u8; 2] = [0x20, 0x24];
pub const ADDR1: [u8; 2] = [0x21, 0x25];

/// Wrapper to allow implementing device_driver traits on our I2C bus
struct Port<'a, B: I2c> {
pub struct Port<'a, B: I2c> {
bus: &'a mut B,
addr: u8,
}

impl<'a, B: I2c> Port<'a, B> {
fn into_registers(self) -> Registers<Port<'a, B>> {
pub fn into_registers(self) -> Registers<Port<'a, B>> {
Registers::new(self)
}
}
Expand Down Expand Up @@ -95,17 +95,22 @@ impl<B: I2c> Internal<B> {
}
}

fn borrow_port(&mut self, port: PortId) -> Result<Port<'_, B>, Error<B::Error>> {
pub fn borrow_port(&mut self, port: PortId) -> Result<Port<'_, B>, Error<B::Error>> {
let addr = self.port_addr(port)?;
Ok(Port { bus: &mut self.bus, addr })
}

/// Clear interrupts on a port, returns asserted interrupts
pub async fn clear_interrupt(&mut self, port: PortId) -> Result<registers::field_sets::IntEventBus1, Error<B::Error>> {
let mut registers = self.borrow_port(port)?.into_registers();
let p = self.borrow_port(port)?;
let mut registers = p.into_registers();

let flags = registers.int_event_bus_1().read_async().await?;
registers.int_clear_bus_1().write_async(|r| *r = flags).await?;
// Clear interrupt if anything is set
if flags != registers::field_sets::IntEventBus1::new_zero() {
registers.int_clear_bus_1().write_async(|r| *r = flags).await?;
}

Ok(flags)
}

Expand All @@ -128,6 +133,11 @@ mod test {
const PORT0: PortId = PortId(0);
const PORT1: PortId = PortId(1);

/// Default I2C addresse for testing
const PORT0_ADDR: u8 = 0x20;
/// Default I2C addresse for testing
const PORT1_ADDR: u8 = 0x24;

/// Test helper for reading successfully from a port
async fn test_read_port_success(port: &mut Port<'_, Mock>, reg: u8, expected_addr: u8, buf: &mut [u8], expected: &[u8]) -> Result<(), Error<ErrorKind>> {
let mut response = Vec::with_capacity(expected.len() + 1);
Expand Down Expand Up @@ -262,4 +272,50 @@ mod test {
test_write_ports_success(ADDR1).await;
test_write_ports_failure(ADDR1).await;
}

fn create_register_read<const N: usize, R: Into<[u8; N]>>(addr: u8, reg: u8, value: R) -> Vec<Transaction> {
// +1 for the length byte
let mut response = Vec::with_capacity(N + 1);
response.push(N as u8);
response.splice(1..1, value.into().iter().cloned());

vec![Transaction::write_read(addr, vec![reg], response)]
}

fn create_register_write<const N: usize, R: Into<[u8; N]>>(addr: u8, reg: u8, value: R) -> Vec<Transaction> {
// +1 for the register + length byte
let mut response = Vec::with_capacity(N + 2);
response.push(reg);
response.push(N as u8);
response.splice(2..2, value.into().iter().cloned());

std::eprintln!("create_register_write: {:#?}", response);
vec![Transaction::write(addr, response)]
}

async fn test_clear_interrupt_port(port: PortId, expected_addr: u8) {
use registers::field_sets::IntEventBus1;

// Create a fully asserted interrupt register
let int = !IntEventBus1::new_zero();
let mut transactions = Vec::new();
transactions.extend(create_register_read(expected_addr, 0x14, int).into_iter());
transactions.extend(create_register_write(expected_addr, 0x18, int).into_iter());

let mock = Mock::new(&transactions);
let mut tps6699x: Internal<Mock> = Internal::new(mock, ADDR0);

assert_eq!(tps6699x.clear_interrupt(port).await.unwrap(), int);
tps6699x.bus.done();
}

#[tokio::test]
async fn test_clear_interrupt_port0() {
test_clear_interrupt_port(PORT0, PORT0_ADDR).await;
}

#[tokio::test]
async fn test_clear_interrupt_port1() {
test_clear_interrupt_port(PORT1, PORT1_ADDR).await;
}
}

0 comments on commit 96f955f

Please sign in to comment.