pub fn write_multiple<PD, MUTEX, MODE: crate::mode::HasOutput, const N: usize>(
pins: [&mut crate::Pin<'_, MODE, MUTEX>; N],
states: [bool; N],
) -> Result<(), PD::Error>
where
PD: crate::PortDriver,
MUTEX: crate::PortMutex<Port = PD>,
{
let mut mask_set_high = 0x00;
let mut mask_set_low = 0x00;
let port_driver = pins[0].port_driver();
for (pin, state) in pins.iter().zip(states.iter()) {
assert!(core::ptr::eq(pin.port_driver(), port_driver));
if *state {
mask_set_high |= pin.pin_mask();
} else {
mask_set_low |= pin.pin_mask();
}
}
pins[0].port_driver().lock(|drv| {
drv.set(mask_set_high, mask_set_low)?;
Ok(())
})
}
pub fn read_multiple<PD, MUTEX, MODE: crate::mode::HasInput, const N: usize>(
pins: [&crate::Pin<'_, MODE, MUTEX>; N],
) -> Result<[bool; N], PD::Error>
where
PD: crate::PortDriver,
MUTEX: crate::PortMutex<Port = PD>,
{
let mask = pins.iter().map(|p| p.pin_mask()).fold(0, |m, p| m | p);
let port_driver = pins[0].port_driver();
let mask_in = port_driver.lock(|drv| drv.get(mask, 0))?;
let mut ret = [false; N];
for (pin, state) in pins.iter().zip(ret.iter_mut()) {
assert!(core::ptr::eq(pin.port_driver(), port_driver));
*state = mask_in & pin.pin_mask() != 0;
}
Ok(ret)
}
#[cfg(test)]
mod tests {
use embedded_hal_mock::eh1::i2c as mock_i2c;
use embedded_hal_mock::eh1::spi as mock_spi;
#[test]
fn pcf8574_write_multiple() {
let expectations = [
mock_i2c::Transaction::write(0x21, vec![0b10111011]),
mock_i2c::Transaction::write(0x21, vec![0b10101111]),
];
let mut bus = mock_i2c::Mock::new(&expectations);
let mut pcf = crate::Pcf8574::new(bus.clone(), true, false, false);
let mut pcf_pins = pcf.split();
super::write_multiple(
[&mut pcf_pins.p2, &mut pcf_pins.p4, &mut pcf_pins.p6],
[false, true, false],
)
.unwrap();
super::write_multiple([&mut pcf_pins.p2, &mut pcf_pins.p4], [true, false]).unwrap();
bus.done();
}
#[test]
fn pcf8575_write_multiple() {
let expectations = [
mock_i2c::Transaction::write(0x21, vec![0b10111011, 0b11011101]),
mock_i2c::Transaction::write(0x21, vec![0b10101111, 0b11010111]),
];
let mut bus = mock_i2c::Mock::new(&expectations);
let mut pcf = crate::Pcf8575::new(bus.clone(), true, false, false);
let mut pcf_pins = pcf.split();
super::write_multiple(
[
&mut pcf_pins.p02,
&mut pcf_pins.p04,
&mut pcf_pins.p06,
&mut pcf_pins.p11,
&mut pcf_pins.p13,
&mut pcf_pins.p15,
],
[false, true, false, false, true, false],
)
.unwrap();
super::write_multiple(
[
&mut pcf_pins.p02,
&mut pcf_pins.p04,
&mut pcf_pins.p11,
&mut pcf_pins.p13,
],
[true, false, true, false],
)
.unwrap();
bus.done();
}
#[test]
fn pca9536_read_multiple() {
let expectations = [
mock_i2c::Transaction::write_read(0x41, vec![0x00], vec![0b00000101]),
mock_i2c::Transaction::write_read(0x41, vec![0x00], vec![0b00001010]),
];
let mut bus = mock_i2c::Mock::new(&expectations);
let mut pca = crate::Pca9536::new(bus.clone());
let pca_pins = pca.split();
let res = super::read_multiple([&pca_pins.io0, &pca_pins.io1, &pca_pins.io2]).unwrap();
assert_eq!(res, [true, false, true]);
let res = super::read_multiple([&pca_pins.io1, &pca_pins.io0, &pca_pins.io3]).unwrap();
assert_eq!(res, [true, false, true]);
bus.done();
}
#[test]
fn pca9702_read_multiple() {
let expectations = [
mock_spi::Transaction::transaction_start(),
mock_spi::Transaction::transfer_in_place(vec![0], vec![0b10101010]),
mock_spi::Transaction::transaction_end(),
mock_spi::Transaction::transaction_start(),
mock_spi::Transaction::transfer_in_place(vec![0], vec![0b10101010]),
mock_spi::Transaction::transaction_end(),
];
let mut bus = mock_spi::Mock::new(&expectations);
let mut pca = crate::Pca9702::new(bus.clone());
let pca_pins = pca.split();
let res = super::read_multiple([&pca_pins.in0, &pca_pins.in1, &pca_pins.in2]).unwrap();
assert_eq!(res, [false, true, false]);
let res = super::read_multiple([&pca_pins.in1, &pca_pins.in0, &pca_pins.in3]).unwrap();
assert_eq!(res, [true, false, true]);
bus.done();
}
#[test]
#[should_panic]
fn pca9538_multiple_assert_same_chip() {
let expectations = [
mock_i2c::Transaction::write_read(0x70, vec![0x00], vec![0b00000101]),
];
let mut bus = mock_i2c::Mock::new(&expectations);
let mut pca0 = crate::Pca9538::new(bus.clone(), false, false);
let pca0_pins = pca0.split();
let mut pca1 = crate::Pca9538::new(bus.clone(), false, true);
let pca1_pins = pca1.split();
let _ = super::read_multiple([&pca0_pins.io0, &pca1_pins.io1]);
bus.done();
}
}