1use crate::{clock::Clocks, time::Bps};
14use core::ops::Deref;
15use e310x::{i2c0, I2c0};
16use embedded_hal::i2c::{self, ErrorKind, ErrorType, NoAcknowledgeSource, Operation};
17
18pub trait SdaPin<I2C>: private::Sealed {}
20
21pub trait SclPin<I2C>: private::Sealed {}
23
24pub trait I2cX: Deref<Target = i2c0::RegisterBlock> + private::Sealed {}
26
27mod i2c_impl {
28 use super::{I2c0, I2cX, SclPin, SdaPin};
29 use crate::gpio::{gpio0, IOF0};
30
31 impl I2cX for I2c0 {}
33 impl<T> SdaPin<I2c0> for gpio0::Pin12<IOF0<T>> {}
34 impl<T> SclPin<I2c0> for gpio0::Pin13<IOF0<T>> {}
35}
36
37pub enum Speed {
39 Normal,
41
42 Fast,
44
45 Custom(Bps),
47}
48
49pub struct I2c<I2C, PINS> {
51 i2c: I2C,
52 pins: PINS,
53}
54
55impl<I2C: I2cX, SDA, SCL> I2c<I2C, (SDA, SCL)> {
56 pub fn new(i2c: I2C, sda: SDA, scl: SCL, speed: Speed, clocks: Clocks) -> Self
58 where
59 SDA: SdaPin<I2C>,
60 SCL: SclPin<I2C>,
61 {
62 let desired_speed = match speed {
64 Speed::Normal => 100_000,
65 Speed::Fast => 400_000,
66 Speed::Custom(bps) => bps.0,
67 };
68 let clock = clocks.tlclk().0;
69 assert!(desired_speed * 5 <= clock);
70 let prescaler = clock / (5 * desired_speed) - 1;
71 assert!(prescaler < (1 << 16));
72
73 i2c.ctr().write(|w| w.en().clear_bit().ien().clear_bit());
75
76 let prescaler_lo = (prescaler & 0xff) as u8;
78 let prescaler_hi = ((prescaler >> 8) & 0xff) as u8;
79 i2c.prer_lo()
80 .write(|w| unsafe { w.value().bits(prescaler_lo) });
81 i2c.prer_hi()
82 .write(|w| unsafe { w.value().bits(prescaler_hi) });
83
84 i2c.ctr().write(|w| w.en().set_bit());
86
87 Self {
88 i2c,
89 pins: (sda, scl),
90 }
91 }
92}
93
94impl<I2C, PINS> I2c<I2C, PINS> {
95 pub fn free(self) -> (I2C, PINS) {
97 (self.i2c, self.pins)
98 }
99}
100
101impl<I2C: I2cX, PINS> I2c<I2C, PINS> {
102 fn read_sr(&self) -> i2c0::sr::R {
104 self.i2c.sr().read()
105 }
106
107 fn clear_interrupt(&self) {
109 self.i2c.cr().write(|w| w.iack().set_bit());
110 }
111
112 fn reset(&self) {
114 self.clear_interrupt();
115 }
116
117 fn set_stop(&self) {
120 self.i2c.cr().write(|w| w.sto().set_bit());
121 }
122
123 fn write_txr(&self, byte: u8) {
130 self.i2c.txr_rxr().write(|w| unsafe { w.data().bits(byte) });
131 }
132
133 fn read_rxr(&self) -> u8 {
135 self.i2c.txr_rxr().read().data().bits()
136 }
137
138 fn trigger_write(&self, start: bool, stop: bool) {
146 self.i2c
147 .cr()
148 .write(|w| w.sta().bit(start).wr().set_bit().sto().bit(stop));
149 }
150
151 fn trigger_read(&self, ack: bool, stop: bool) {
159 self.i2c
160 .cr()
161 .write(|w| w.rd().set_bit().ack().bit(ack).sto().bit(stop));
162 }
163
164 fn is_idle(&self) -> bool {
166 !self.read_sr().busy().bit_is_set()
167 }
168
169 fn wait_idle(&self) {
171 while !self.is_idle() {}
172 }
173
174 fn ack_interrupt(&self) -> nb::Result<(), ErrorKind> {
181 let sr = self.read_sr();
182 if sr.if_().bit_is_set() {
183 self.clear_interrupt();
184 if sr.al().bit_is_set() {
185 self.set_stop();
186 Err(nb::Error::Other(ErrorKind::ArbitrationLoss))
187 } else {
188 Ok(())
189 }
190 } else {
191 Err(nb::Error::WouldBlock)
192 }
193 }
194
195 fn wait_for_read(&self) -> Result<(), ErrorKind> {
202 nb::block!(self.ack_interrupt())
203 }
204
205 fn wait_for_write(&self, source: NoAcknowledgeSource) -> Result<(), ErrorKind> {
215 nb::block!(self.ack_interrupt())?;
216 if self.read_sr().rx_ack().bit_is_set() {
217 self.set_stop();
218 Err(ErrorKind::NoAcknowledge(source))
219 } else {
220 Ok(())
221 }
222 }
223}
224
225const FLAG_READ: u8 = 1;
226const FLAG_WRITE: u8 = 0;
227
228impl<I2C: I2cX, PINS> ErrorType for I2c<I2C, PINS> {
229 type Error = ErrorKind;
230}
231
232impl<I2C: I2cX, PINS> i2c::I2c for I2c<I2C, PINS> {
233 fn transaction(
234 &mut self,
235 address: u8,
236 operations: &mut [Operation<'_>],
237 ) -> Result<(), Self::Error> {
238 let n_ops = operations.len();
239 if n_ops == 0 {
240 return Ok(());
241 }
242
243 self.wait_idle();
244 self.reset();
245
246 let mut last_op_was_read = match &operations[0] {
248 Operation::Read(_) => false,
249 Operation::Write(_) => true,
250 };
251
252 for (i, operation) in operations.iter_mut().enumerate() {
253 match operation {
254 Operation::Write(bytes) => {
255 self.write_txr((address << 1) + FLAG_WRITE);
257 self.trigger_write(last_op_was_read, false);
258 self.wait_for_write(NoAcknowledgeSource::Address)?;
259 last_op_was_read = false;
260
261 let n_bytes = bytes.len();
263 for (j, byte) in bytes.iter().enumerate() {
264 self.write_txr(*byte);
265 self.trigger_write(false, (i == n_ops - 1) && (j == n_bytes - 1));
266 self.wait_for_write(NoAcknowledgeSource::Data)?;
267 }
268 }
269 Operation::Read(buffer) => {
270 self.write_txr((address << 1) + FLAG_READ);
272 self.trigger_write(!last_op_was_read, false);
273 self.wait_for_write(NoAcknowledgeSource::Address)?;
274 last_op_was_read = true;
275
276 let n_bytes = buffer.len();
278 for (j, byte) in buffer.iter_mut().enumerate() {
279 self.trigger_read(j == n_bytes - 1, (i == n_ops - 1) && (j == n_bytes - 1));
280 self.wait_for_read()?;
281 *byte = self.read_rxr();
282 }
283 }
284 }
285 }
286 self.wait_idle();
287
288 Ok(())
289 }
290}
291
292mod private {
293 use super::I2c0;
294 use crate::gpio::{gpio0, IOF0};
295
296 pub trait Sealed {}
297
298 impl Sealed for I2c0 {}
300 impl<T> Sealed for gpio0::Pin12<IOF0<T>> {}
301 impl<T> Sealed for gpio0::Pin13<IOF0<T>> {}
302}