tca9548_eh/
lib.rs

1#![doc = include_str!("../README.md")]
2#![no_std]
3
4use interface::Interface;
5
6mod interface;
7
8/// An error that occurs when communicating with the TCA9548.
9#[derive(Debug)]
10pub enum Error<EI2C> {
11    /// An error occurred on the I2C bus.
12    Io(EI2C),
13    /// The I2C bus is busy, ie used by another multiplexed bus at the same
14    /// time.
15    BusBusy,
16}
17
18impl<EI2C> embedded_hal::i2c::Error for Error<EI2C>
19where
20    EI2C: embedded_hal::i2c::Error,
21{
22    fn kind(&self) -> embedded_hal::i2c::ErrorKind {
23        match self {
24            Self::Io(e) => e.kind(),
25            Self::BusBusy => embedded_hal::i2c::ErrorKind::Other,
26        }
27    }
28}
29
30/// A driver for the TCA9548 I2C bus multiplexer.
31pub struct Tca9548<I2C> {
32    interface: Interface<I2C>,
33}
34
35impl<I2C, EI2C> Tca9548<I2C>
36where
37    I2C: embedded_hal::i2c::I2c<Error = EI2C>,
38{
39    /// Create a new instance of the TCA9548 driver. This performs a reset of
40    /// the device and may fail if the device is not present.
41    ///
42    /// # Errors
43    /// Returns `Err` if the I2C bus is not responding or the reset pin
44    /// operation fails.
45    pub fn new(mut i2c: I2C, address: u8) -> Result<Self, EI2C> {
46        // Select none of the I2C buses.
47        i2c.write(address, &[0x00])?;
48
49        Ok(Self {
50            interface: Interface::new(spin::Mutex::new(i2c), address),
51        })
52    }
53
54    /// Split the multiplexer into individual busses. This allows you to
55    /// use each bus independently. A mutable reference is used to ensure
56    /// multiple sets of busses cannot exist at the same time.
57    pub fn split(&mut self) -> Busses<'_, I2C> {
58        Busses {
59            bus0: MultiplexedBus {
60                interface: &self.interface,
61            },
62            bus1: MultiplexedBus {
63                interface: &self.interface,
64            },
65            bus2: MultiplexedBus {
66                interface: &self.interface,
67            },
68            bus3: MultiplexedBus {
69                interface: &self.interface,
70            },
71            bus4: MultiplexedBus {
72                interface: &self.interface,
73            },
74            bus5: MultiplexedBus {
75                interface: &self.interface,
76            },
77            bus6: MultiplexedBus {
78                interface: &self.interface,
79            },
80            bus7: MultiplexedBus {
81                interface: &self.interface,
82            },
83        }
84    }
85}
86
87/// The busses on the TCA9548.
88pub struct Busses<'a, I2C> {
89    /// Bus 0.
90    pub bus0: MultiplexedBus<'a, I2C, 0>,
91    /// Bus 1.
92    pub bus1: MultiplexedBus<'a, I2C, 1>,
93    /// Bus 2.
94    pub bus2: MultiplexedBus<'a, I2C, 2>,
95    /// Bus 3.
96    pub bus3: MultiplexedBus<'a, I2C, 3>,
97    /// Bus 4.
98    pub bus4: MultiplexedBus<'a, I2C, 4>,
99    /// Bus 5.
100    pub bus5: MultiplexedBus<'a, I2C, 5>,
101    /// Bus 6.
102    pub bus6: MultiplexedBus<'a, I2C, 6>,
103    /// Bus 7.
104    pub bus7: MultiplexedBus<'a, I2C, 7>,
105}
106
107/// A multiplexed I2C bus. Using this bus will briefly enable the selected
108/// channel on the TCA9548, then disable it again after the transaction is
109/// complete.
110pub struct MultiplexedBus<'a, I2C, const NUM: u8> {
111    interface: &'a Interface<I2C>,
112}
113
114impl<'a, I2C, E, const NUM: u8> embedded_hal::i2c::ErrorType for MultiplexedBus<'a, I2C, NUM>
115where
116    I2C: embedded_hal::i2c::I2c<Error = E>,
117    E: embedded_hal::i2c::Error,
118{
119    type Error = Error<E>;
120}
121
122impl<'a, I2C, E, const NUM: u8> embedded_hal::i2c::I2c for MultiplexedBus<'a, I2C, NUM>
123where
124    I2C: embedded_hal::i2c::I2c<Error = E>,
125    E: embedded_hal::i2c::Error,
126{
127    fn transaction(
128        &mut self,
129        address: u8,
130        operations: &mut [embedded_hal::i2c::Operation<'_>],
131    ) -> Result<(), Error<E>> {
132        self.interface
133            .enable_to_run::<NUM>(|i2c| i2c.transaction(address, operations))
134    }
135}