adafruit_seesaw/
driver.rs

1use crate::modules::Reg;
2use embedded_hal::{
3    delay::DelayNs,
4    i2c::{ErrorType, I2c, Operation, SevenBitAddress},
5};
6
7const DELAY_TIME: u32 = 125;
8
9#[cfg_attr(feature = "defmt", derive(defmt::Format))]
10#[derive(Debug)]
11pub struct SeesawDriver<I2C, DELAY>(DELAY, I2C);
12
13impl<I2C, DELAY> SeesawDriver<I2C, DELAY>
14where
15    DELAY: DelayNs,
16    I2C: I2c,
17{
18    pub fn new(delay: DELAY, i2c: I2C) -> Self {
19        SeesawDriver(delay, i2c)
20    }
21}
22
23impl<DELAY, I2C> ErrorType for SeesawDriver<I2C, DELAY>
24where
25    DELAY: DelayNs,
26    I2C: I2c,
27{
28    type Error = I2C::Error;
29}
30
31impl<I2C, DELAY> I2c for SeesawDriver<I2C, DELAY>
32where
33    DELAY: DelayNs,
34    I2C: I2c,
35{
36    fn transaction(
37        &mut self,
38        address: u8,
39        operations: &mut [Operation<'_>],
40    ) -> Result<(), Self::Error> {
41        self.1.transaction(address, operations)
42    }
43}
44
45impl<DELAY, I2C> DelayNs for SeesawDriver<I2C, DELAY>
46where
47    DELAY: DelayNs,
48    I2C: I2c,
49{
50    fn delay_ns(&mut self, ns: u32) {
51        self.0.delay_ns(ns)
52    }
53}
54
55/// Blanket trait for anything that implements I2C and a delay
56pub trait Driver: I2c + DelayNs {}
57impl<T> Driver for T where T: I2c + DelayNs {}
58
59macro_rules! impl_integer_write {
60    ($fn:ident $nty:tt) => {
61        fn $fn(
62            &mut self,
63            addr: SevenBitAddress,
64            reg: &Reg,
65            value: $nty,
66        ) -> Result<(), Self::Error> {
67            self.register_write(addr, reg, &<$nty>::to_be_bytes(value))
68        }
69    };
70}
71
72macro_rules! impl_integer_read {
73    ($fn:ident $nty:tt) => {
74        fn $fn(&mut self, addr: SevenBitAddress, reg: &Reg) -> Result<$nty, Self::Error> {
75            self.register_read::<{ ($nty::BITS / 8) as usize }>(addr, reg)
76                .map($nty::from_be_bytes)
77        }
78    };
79}
80
81pub trait DriverExt {
82    type Error;
83
84    fn register_read<const N: usize>(
85        &mut self,
86        addr: SevenBitAddress,
87        reg: &Reg,
88    ) -> Result<[u8; N], Self::Error>;
89
90    fn register_write(
91        &mut self,
92        addr: SevenBitAddress,
93        reg: &Reg,
94        bytes: &[u8],
95    ) -> Result<(), Self::Error>;
96
97    impl_integer_read! { read_u8 u8 }
98    impl_integer_read! { read_u16 u16 }
99    impl_integer_read! { read_u32 u32 }
100    impl_integer_read! { read_u64 u64 }
101    impl_integer_read! { read_i8 i8 }
102    impl_integer_read! { read_i16 i16 }
103    impl_integer_read! { read_i32 i32 }
104    impl_integer_read! { read_i64 i64 }
105    impl_integer_write! { write_u8 u8 }
106    impl_integer_write! { write_u16 u16 }
107    impl_integer_write! { write_u32 u32 }
108    impl_integer_write! { write_u64 u64 }
109    impl_integer_write! { write_i8 i8 }
110    impl_integer_write! { write_i16 i16 }
111    impl_integer_write! { write_i32 i32 }
112    impl_integer_write! { write_i64 i64 }
113}
114
115impl<T: Driver> DriverExt for T {
116    type Error = T::Error;
117
118    fn register_read<const N: usize>(
119        &mut self,
120        addr: SevenBitAddress,
121        reg: &Reg,
122    ) -> Result<[u8; N], Self::Error> {
123        let mut buffer = [0u8; N];
124        self.write(addr, reg)?;
125        self.delay_us(DELAY_TIME);
126        self.read(addr, &mut buffer)?;
127        Ok(buffer)
128    }
129
130    fn register_write(
131        &mut self,
132        addr: SevenBitAddress,
133        reg: &Reg,
134        bytes: &[u8],
135    ) -> Result<(), Self::Error> {
136        self.transaction(addr, &mut [Operation::Write(reg), Operation::Write(bytes)])?;
137        self.delay_us(DELAY_TIME);
138        Ok(())
139    }
140}