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
55pub trait Driver: I2c + DelayNs {}
57impl<T> Driver for T where T: I2c + DelayNs {}
58
59macro_rules! impl_integer_write {
60 ($fn:ident $fn_with_delay: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 fn $fn_with_delay(
71 &mut self,
72 addr: SevenBitAddress,
73 reg: &Reg,
74 value: $nty,
75 delay: u32,
76 ) -> Result<(), Self::Error> {
77 self.register_write_with_delay(addr, reg, &<$nty>::to_be_bytes(value), delay)
78 }
79 };
80}
81
82macro_rules! impl_integer_read {
83 ($fn:ident $fn_with_delay:ident $nty:tt) => {
84 fn $fn(&mut self, addr: SevenBitAddress, reg: &Reg) -> Result<$nty, Self::Error> {
85 self.register_read::<{ ($nty::BITS / 8) as usize }>(addr, reg)
86 .map($nty::from_be_bytes)
87 }
88
89 fn $fn_with_delay(
90 &mut self,
91 addr: SevenBitAddress,
92 reg: &Reg,
93 delay: u32,
94 ) -> Result<$nty, Self::Error> {
95 self.register_read_with_delay::<{ ($nty::BITS / 8) as usize }>(addr, reg, delay)
96 .map($nty::from_be_bytes)
97 }
98 };
99}
100
101pub trait DriverExt {
102 type Error;
103
104 fn register_read_with_delay<const N: usize>(
105 &mut self,
106 addr: SevenBitAddress,
107 reg: &Reg,
108 delay: u32,
109 ) -> Result<[u8; N], Self::Error>;
110
111 fn register_write_with_delay(
112 &mut self,
113 addr: SevenBitAddress,
114 reg: &Reg,
115 bytes: &[u8],
116 delay: u32,
117 ) -> Result<(), Self::Error>;
118
119 impl_integer_read! { read_u8 read_u8_with_delay u8 }
120 impl_integer_read! { read_u16 read_u16_with_delay u16 }
121 impl_integer_read! { read_u32 read_u32_with_delay u32 }
122 impl_integer_read! { read_u64 read_u64_with_delay u64 }
123 impl_integer_read! { read_i8 read_i8_with_delay i8 }
124 impl_integer_read! { read_i16 read_i16_with_delay i16 }
125 impl_integer_read! { read_i32 read_i32_with_delay i32 }
126 impl_integer_read! { read_i64 read_i64_with_delay i64 }
127 impl_integer_write! { write_u8 write_u8_with_delay u8 }
128 impl_integer_write! { write_u16 write_u16_with_delay u16 }
129 impl_integer_write! { write_u32 write_u32_with_delay u32 }
130 impl_integer_write! { write_u64 write_u64_with_delay u64 }
131 impl_integer_write! { write_i8 write_i8_with_delay i8 }
132 impl_integer_write! { write_i16 write_i16_with_delay i16 }
133 impl_integer_write! { write_i32 write_i32_with_delay i32 }
134 impl_integer_write! { write_i64 write_i64_with_delay i64 }
135
136 fn register_read<const N: usize>(
137 &mut self,
138 addr: SevenBitAddress,
139 reg: &Reg,
140 ) -> Result<[u8; N], Self::Error> {
141 self.register_read_with_delay(addr, reg, DELAY_TIME)
142 }
143
144 fn register_write(
145 &mut self,
146 addr: SevenBitAddress,
147 reg: &Reg,
148 bytes: &[u8],
149 ) -> Result<(), Self::Error> {
150 self.register_write_with_delay(addr, reg, bytes, DELAY_TIME)
151 }
152}
153
154impl<T: Driver> DriverExt for T {
155 type Error = T::Error;
156
157 fn register_read_with_delay<const N: usize>(
158 &mut self,
159 addr: SevenBitAddress,
160 reg: &Reg,
161 delay: u32,
162 ) -> Result<[u8; N], Self::Error> {
163 let mut buffer = [0u8; N];
164 self.write(addr, reg)?;
165 self.delay_us(delay);
166 self.read(addr, &mut buffer)?;
167 Ok(buffer)
168 }
169
170 fn register_write_with_delay(
171 &mut self,
172 addr: SevenBitAddress,
173 reg: &Reg,
174 bytes: &[u8],
175 delay: u32,
176 ) -> Result<(), Self::Error> {
177 self.transaction(addr, &mut [Operation::Write(reg), Operation::Write(bytes)])?;
178 self.delay_us(delay);
179 Ok(())
180 }
181}