xca9548a 0.2.0

Platform-agnostic Rust driver for the TCA9548A and PCA9548A I2C switches/multiplexers.
Documentation
extern crate embedded_hal;
extern crate embedded_hal_mock as hal;
use hal::i2c::{Mock as I2cMock, Transaction as I2cTrans};
extern crate xca9548a;
use xca9548a::{SlaveAddr, Xca9548a};

const DEV_ADDR: u8 = 0b111_0000;

fn new(transactions: &[I2cTrans]) -> Xca9548a<I2cMock> {
    Xca9548a::new(I2cMock::new(&transactions), SlaveAddr::default())
}

use embedded_hal::prelude::*;
const SLAVE_ADDR: u8 = 0b010_0000;
const SLAVE_WRITE_DATA: [u8; 2] = [0b0101_0101, 0b1010_1010];
const SLAVE_READ_DATA: [u8; 2] = [0b1001_1001, 0b0110_0110];

#[test]
fn can_select_channels() {
    let transactions = [I2cTrans::write(DEV_ADDR, vec![0x01])];
    let mut switch = new(&transactions);
    switch.select_channels(0x01).unwrap();
    switch.destroy().done();
}

#[test]
fn can_get_channel_status() {
    let transactions = [I2cTrans::read(DEV_ADDR, vec![0b0101_0101])];
    let mut switch = new(&transactions);
    let read_status = switch.get_channel_status().unwrap();
    assert_eq!(0b0101_0101, read_status);
    switch.destroy().done();
}

#[test]
fn can_write_to_slave() {
    let transactions = [
        I2cTrans::write(DEV_ADDR, vec![0x01]),
        I2cTrans::write(SLAVE_ADDR, SLAVE_WRITE_DATA.to_vec()),
    ];
    let mut switch = new(&transactions);
    switch.select_channels(0b0000_0001).unwrap();
    switch.write(SLAVE_ADDR, &SLAVE_WRITE_DATA).unwrap();
    switch.destroy().done();
}

#[test]
fn can_read_from_slave() {
    let transactions = [
        I2cTrans::write(DEV_ADDR, vec![0x01]),
        I2cTrans::read(SLAVE_ADDR, SLAVE_READ_DATA.to_vec()),
    ];
    let mut switch = new(&transactions);
    switch.select_channels(0b0000_0001).unwrap();

    let mut read_data = [0; 2];
    switch.read(SLAVE_ADDR, &mut read_data).unwrap();
    assert_eq!(read_data, SLAVE_READ_DATA);
    switch.destroy().done();
}
#[test]
fn can_write_read_from_slave() {
    let transactions = [
        I2cTrans::write(DEV_ADDR, vec![0x01]),
        I2cTrans::write_read(
            SLAVE_ADDR,
            SLAVE_WRITE_DATA.to_vec(),
            SLAVE_READ_DATA.to_vec(),
        ),
    ];
    let mut switch = new(&transactions);
    switch.select_channels(0b0000_0001).unwrap();

    let mut read_data = [0; 2];
    switch
        .write_read(SLAVE_ADDR, &SLAVE_WRITE_DATA, &mut read_data)
        .unwrap();
    assert_eq!(read_data, SLAVE_READ_DATA);
    switch.destroy().done();
}

#[test]
fn can_split_and_communicate_with_slave() {
    let slave_read_data_2 = [0xAB, 0xCD];
    let transactions = [
        I2cTrans::write(DEV_ADDR, vec![0x01]),
        I2cTrans::write(SLAVE_ADDR, SLAVE_WRITE_DATA.to_vec()),
        I2cTrans::write(DEV_ADDR, vec![0x02]),
        I2cTrans::read(SLAVE_ADDR, SLAVE_READ_DATA.to_vec()),
        I2cTrans::write(DEV_ADDR, vec![0x04]),
        I2cTrans::write_read(
            SLAVE_ADDR,
            SLAVE_WRITE_DATA.to_vec(),
            slave_read_data_2.to_vec(),
        ),
    ];
    let switch = new(&transactions);
    {
        let mut read_data_1 = [0; 2];
        let mut read_data_2 = [0; 2];
        let mut parts = switch.split();
        parts.i2c0.write(SLAVE_ADDR, &SLAVE_WRITE_DATA).unwrap();
        parts.i2c1.read(SLAVE_ADDR, &mut read_data_1).unwrap();
        parts
            .i2c2
            .write_read(SLAVE_ADDR, &SLAVE_WRITE_DATA, &mut read_data_2)
            .unwrap();
        assert_eq!(read_data_1, SLAVE_READ_DATA);
        assert_eq!(read_data_2, slave_read_data_2);
    }
    switch.destroy().done();
}

#[test]
fn when_split_only_change_channel_if_necessary() {
    let transactions = [
        I2cTrans::write(DEV_ADDR, vec![0x01]),
        I2cTrans::write(SLAVE_ADDR, SLAVE_WRITE_DATA.to_vec()),
        I2cTrans::read(SLAVE_ADDR, SLAVE_READ_DATA.to_vec()),
    ];
    let switch = new(&transactions);
    {
        let mut read_data = [0; 2];
        let mut parts = switch.split();
        parts.i2c0.write(SLAVE_ADDR, &SLAVE_WRITE_DATA).unwrap();
        parts.i2c0.read(SLAVE_ADDR, &mut read_data).unwrap();
        assert_eq!(read_data, SLAVE_READ_DATA);
    }
    switch.destroy().done();
}