1#![macro_use]
3
4#[cfg_attr(i2c_v1, path = "v1.rs")]
5#[cfg_attr(any(i2c_v2, i2c_v3), path = "v2.rs")]
6mod _version;
7
8mod config;
9
10use core::future::Future;
11use core::iter;
12use core::marker::PhantomData;
13
14pub use config::*;
15use embassy_hal_internal::Peri;
16use embassy_sync::waitqueue::AtomicWaker;
17#[cfg(feature = "time")]
18use embassy_time::{Duration, Instant};
19use mode::MasterMode;
20pub use mode::{Master, MultiMaster};
21
22use crate::dma::ChannelAndRequest;
23use crate::gpio::{AnyPin, SealedPin as _};
24use crate::interrupt::typelevel::Interrupt;
25use crate::mode::{Async, Blocking, Mode};
26use crate::rcc::{RccInfo, SealedRccPeripheral};
27use crate::time::Hertz;
28use crate::{interrupt, peripherals};
29
30#[derive(Debug, PartialEq, Eq, Copy, Clone)]
32#[cfg_attr(feature = "defmt", derive(defmt::Format))]
33pub enum Error {
34 Bus,
36 Arbitration,
38 Nack,
40 Timeout,
42 Crc,
44 Overrun,
46 ZeroLengthTransfer,
48}
49
50impl core::fmt::Display for Error {
51 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
52 let message = match self {
53 Self::Bus => "Bus Error",
54 Self::Arbitration => "Arbitration Lost",
55 Self::Nack => "ACK Not Received",
56 Self::Timeout => "Request Timed Out",
57 Self::Crc => "CRC Mismatch",
58 Self::Overrun => "Buffer Overrun",
59 Self::ZeroLengthTransfer => "Zero-Length Transfers are not allowed",
60 };
61
62 write!(f, "{}", message)
63 }
64}
65
66impl core::error::Error for Error {}
67
68pub mod mode {
70 trait SealedMode {}
71
72 #[allow(private_bounds)]
74 pub trait MasterMode: SealedMode {}
75
76 pub struct Master;
78 pub struct MultiMaster;
80
81 impl SealedMode for Master {}
82 impl MasterMode for Master {}
83
84 impl SealedMode for MultiMaster {}
85 impl MasterMode for MultiMaster {}
86}
87
88#[derive(Debug, Clone, PartialEq, Eq)]
89#[cfg_attr(feature = "defmt", derive(defmt::Format))]
90pub enum SlaveCommandKind {
92 Write,
94 Read,
96}
97
98#[derive(Debug, Clone, PartialEq, Eq)]
99#[cfg_attr(feature = "defmt", derive(defmt::Format))]
100pub struct SlaveCommand {
102 pub kind: SlaveCommandKind,
104 pub address: Address,
106}
107
108#[derive(Debug, Clone, PartialEq, Eq)]
109#[cfg_attr(feature = "defmt", derive(defmt::Format))]
110pub enum SendStatus {
112 Done,
114 LeftoverBytes(usize),
116}
117
118struct I2CDropGuard<'d> {
119 info: &'static Info,
120 scl: Option<Peri<'d, AnyPin>>,
121 sda: Option<Peri<'d, AnyPin>>,
122}
123impl<'d> Drop for I2CDropGuard<'d> {
124 fn drop(&mut self) {
125 if let Some(x) = self.scl.as_ref() {
126 x.set_as_disconnected()
127 }
128 if let Some(x) = self.sda.as_ref() {
129 x.set_as_disconnected()
130 }
131
132 self.info.rcc.disable();
133 }
134}
135
136pub struct I2c<'d, M: Mode, IM: MasterMode> {
138 info: &'static Info,
139 state: &'static State,
140 kernel_clock: Hertz,
141 tx_dma: Option<ChannelAndRequest<'d>>,
142 rx_dma: Option<ChannelAndRequest<'d>>,
143 #[cfg(feature = "time")]
144 timeout: Duration,
145 _phantom: PhantomData<M>,
146 _phantom2: PhantomData<IM>,
147 _drop_guard: I2CDropGuard<'d>,
148}
149
150impl<'d> I2c<'d, Async, Master> {
151 pub fn new<T: Instance>(
153 peri: Peri<'d, T>,
154 scl: Peri<'d, impl SclPin<T>>,
155 sda: Peri<'d, impl SdaPin<T>>,
156 _irq: impl interrupt::typelevel::Binding<T::EventInterrupt, EventInterruptHandler<T>>
157 + interrupt::typelevel::Binding<T::ErrorInterrupt, ErrorInterruptHandler<T>>
158 + 'd,
159 tx_dma: Peri<'d, impl TxDma<T>>,
160 rx_dma: Peri<'d, impl RxDma<T>>,
161 config: Config,
162 ) -> Self {
163 Self::new_inner(
164 peri,
165 new_pin!(scl, config.scl_af()),
166 new_pin!(sda, config.sda_af()),
167 new_dma!(tx_dma),
168 new_dma!(rx_dma),
169 config,
170 )
171 }
172}
173
174impl<'d> I2c<'d, Blocking, Master> {
175 pub fn new_blocking<T: Instance>(
177 peri: Peri<'d, T>,
178 scl: Peri<'d, impl SclPin<T>>,
179 sda: Peri<'d, impl SdaPin<T>>,
180 config: Config,
181 ) -> Self {
182 Self::new_inner(
183 peri,
184 new_pin!(scl, config.scl_af()),
185 new_pin!(sda, config.sda_af()),
186 None,
187 None,
188 config,
189 )
190 }
191}
192
193impl<'d, M: Mode> I2c<'d, M, Master> {
194 fn new_inner<T: Instance>(
196 _peri: Peri<'d, T>,
197 scl: Option<Peri<'d, AnyPin>>,
198 sda: Option<Peri<'d, AnyPin>>,
199 tx_dma: Option<ChannelAndRequest<'d>>,
200 rx_dma: Option<ChannelAndRequest<'d>>,
201 config: Config,
202 ) -> Self {
203 unsafe { T::EventInterrupt::enable() };
204 unsafe { T::ErrorInterrupt::enable() };
205
206 let mut this = Self {
207 info: T::info(),
208 state: T::state(),
209 kernel_clock: T::frequency(),
210 tx_dma,
211 rx_dma,
212 #[cfg(feature = "time")]
213 timeout: config.timeout,
214 _phantom: PhantomData,
215 _phantom2: PhantomData,
216 _drop_guard: I2CDropGuard {
217 info: T::info(),
218 scl,
219 sda,
220 },
221 };
222 this.enable_and_init(config);
223
224 this
225 }
226
227 fn enable_and_init(&mut self, config: Config) {
228 self.info.rcc.enable_and_reset();
229 self.init(config);
230 }
231}
232
233impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
234 fn timeout(&self) -> Timeout {
235 Timeout {
236 #[cfg(feature = "time")]
237 deadline: Instant::now() + self.timeout,
238 }
239 }
240}
241
242#[derive(Copy, Clone)]
243struct Timeout {
244 #[cfg(feature = "time")]
245 deadline: Instant,
246}
247
248#[allow(dead_code)]
249impl Timeout {
250 #[inline]
251 fn check(self) -> Result<(), Error> {
252 #[cfg(feature = "time")]
253 if Instant::now() > self.deadline {
254 return Err(Error::Timeout);
255 }
256
257 Ok(())
258 }
259
260 #[inline]
261 fn with<R>(self, fut: impl Future<Output = Result<R, Error>>) -> impl Future<Output = Result<R, Error>> {
262 #[cfg(feature = "time")]
263 {
264 use futures_util::FutureExt;
265
266 embassy_futures::select::select(embassy_time::Timer::at(self.deadline), fut).map(|r| match r {
267 embassy_futures::select::Either::First(_) => Err(Error::Timeout),
268 embassy_futures::select::Either::Second(r) => r,
269 })
270 }
271
272 #[cfg(not(feature = "time"))]
273 fut
274 }
275}
276
277struct State {
278 #[allow(unused)]
279 waker: AtomicWaker,
280}
281
282impl State {
283 const fn new() -> Self {
284 Self {
285 waker: AtomicWaker::new(),
286 }
287 }
288}
289
290struct Info {
291 regs: crate::pac::i2c::I2c,
292 rcc: RccInfo,
293}
294
295peri_trait!(
296 irqs: [EventInterrupt, ErrorInterrupt],
297);
298
299pin_trait!(SclPin, Instance);
300pin_trait!(SdaPin, Instance);
301dma_trait!(RxDma, Instance);
302dma_trait!(TxDma, Instance);
303
304pub struct EventInterruptHandler<T: Instance> {
306 _phantom: PhantomData<T>,
307}
308
309impl<T: Instance> interrupt::typelevel::Handler<T::EventInterrupt> for EventInterruptHandler<T> {
310 unsafe fn on_interrupt() {
311 _version::on_interrupt::<T>()
312 }
313}
314
315pub struct ErrorInterruptHandler<T: Instance> {
317 _phantom: PhantomData<T>,
318}
319
320impl<T: Instance> interrupt::typelevel::Handler<T::ErrorInterrupt> for ErrorInterruptHandler<T> {
321 unsafe fn on_interrupt() {
322 _version::on_interrupt::<T>()
323 }
324}
325
326foreach_peripheral!(
327 (i2c, $inst:ident) => {
328 #[allow(private_interfaces)]
329 impl SealedInstance for peripherals::$inst {
330 fn info() -> &'static Info {
331 static INFO: Info = Info{
332 regs: crate::pac::$inst,
333 rcc: crate::peripherals::$inst::RCC_INFO,
334 };
335 &INFO
336 }
337 fn state() -> &'static State {
338 static STATE: State = State::new();
339 &STATE
340 }
341 }
342
343 impl Instance for peripherals::$inst {
344 type EventInterrupt = crate::_generated::peripheral_interrupts::$inst::EV;
345 type ErrorInterrupt = crate::_generated::peripheral_interrupts::$inst::ER;
346 }
347 };
348);
349
350impl<'d, M: Mode, IM: MasterMode> embedded_hal_02::blocking::i2c::Read for I2c<'d, M, IM> {
351 type Error = Error;
352
353 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
354 self.blocking_read(address, buffer)
355 }
356}
357
358impl<'d, M: Mode, IM: MasterMode> embedded_hal_02::blocking::i2c::Write for I2c<'d, M, IM> {
359 type Error = Error;
360
361 fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
362 self.blocking_write(address, write)
363 }
364}
365
366impl<'d, M: Mode, IM: MasterMode> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, M, IM> {
367 type Error = Error;
368
369 fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
370 self.blocking_write_read(address, write, read)
371 }
372}
373
374impl embedded_hal_1::i2c::Error for Error {
375 fn kind(&self) -> embedded_hal_1::i2c::ErrorKind {
376 match *self {
377 Self::Bus => embedded_hal_1::i2c::ErrorKind::Bus,
378 Self::Arbitration => embedded_hal_1::i2c::ErrorKind::ArbitrationLoss,
379 Self::Nack => {
380 embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Unknown)
381 }
382 Self::Timeout => embedded_hal_1::i2c::ErrorKind::Other,
383 Self::Crc => embedded_hal_1::i2c::ErrorKind::Other,
384 Self::Overrun => embedded_hal_1::i2c::ErrorKind::Overrun,
385 Self::ZeroLengthTransfer => embedded_hal_1::i2c::ErrorKind::Other,
386 }
387 }
388}
389
390impl<'d, M: Mode, IM: MasterMode> embedded_hal_1::i2c::ErrorType for I2c<'d, M, IM> {
391 type Error = Error;
392}
393
394impl<'d, M: Mode, IM: MasterMode> embedded_hal_1::i2c::I2c for I2c<'d, M, IM> {
395 fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
396 self.blocking_read(address, read)
397 }
398
399 fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
400 self.blocking_write(address, write)
401 }
402
403 fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
404 self.blocking_write_read(address, write, read)
405 }
406
407 fn transaction(
408 &mut self,
409 address: u8,
410 operations: &mut [embedded_hal_1::i2c::Operation<'_>],
411 ) -> Result<(), Self::Error> {
412 self.blocking_transaction(address, operations)
413 }
414}
415
416impl<'d, IM: MasterMode> embedded_hal_async::i2c::I2c for I2c<'d, Async, IM> {
417 async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
418 self.read(address, read).await
419 }
420
421 async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
422 self.write(address, write).await
423 }
424
425 async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
426 self.write_read(address, write, read).await
427 }
428
429 async fn transaction(
430 &mut self,
431 address: u8,
432 operations: &mut [embedded_hal_1::i2c::Operation<'_>],
433 ) -> Result<(), Self::Error> {
434 self.transaction(address, operations).await
435 }
436}
437
438#[derive(Copy, Clone)]
457#[allow(dead_code)]
458enum FrameOptions {
459 FirstAndLastFrame,
461 FirstFrame,
464 FirstAndNextFrame,
467 NextFrame,
469 LastFrame,
471 LastFrameNoStop,
473}
474
475#[allow(dead_code)]
476impl FrameOptions {
477 fn send_start(self) -> bool {
479 match self {
480 Self::FirstAndLastFrame | Self::FirstFrame | Self::FirstAndNextFrame => true,
481 Self::NextFrame | Self::LastFrame | Self::LastFrameNoStop => false,
482 }
483 }
484
485 fn send_stop(self) -> bool {
487 match self {
488 Self::FirstAndLastFrame | Self::LastFrame => true,
489 Self::FirstFrame | Self::FirstAndNextFrame | Self::NextFrame | Self::LastFrameNoStop => false,
490 }
491 }
492
493 fn send_nack(self) -> bool {
495 match self {
496 Self::FirstAndLastFrame | Self::FirstFrame | Self::LastFrame | Self::LastFrameNoStop => true,
497 Self::FirstAndNextFrame | Self::NextFrame => false,
498 }
499 }
500}
501
502#[allow(dead_code)]
509fn operation_frames<'a, 'b: 'a>(
510 operations: &'a mut [embedded_hal_1::i2c::Operation<'b>],
511) -> Result<impl IntoIterator<Item = (&'a mut embedded_hal_1::i2c::Operation<'b>, FrameOptions)>, Error> {
512 use embedded_hal_1::i2c::Operation::{Read, Write};
513
514 if operations.iter().any(|op| match op {
521 Read(read) => read.is_empty(),
522 Write(_) => false,
523 }) {
524 return Err(Error::Overrun);
525 }
526
527 let mut operations = operations.iter_mut().peekable();
528
529 let mut next_first_frame = true;
530
531 Ok(iter::from_fn(move || {
532 let op = operations.next()?;
533
534 let first_frame = next_first_frame;
536 let next_op = operations.peek();
537
538 let frame = match (first_frame, next_op) {
550 (true, None) => FrameOptions::FirstAndLastFrame,
551 (true, Some(Read(_))) => FrameOptions::FirstAndNextFrame,
552 (true, Some(Write(_))) => FrameOptions::FirstFrame,
553 (false, None) => FrameOptions::LastFrame,
555 (false, Some(Read(_))) => FrameOptions::NextFrame,
556 (false, Some(Write(_))) => FrameOptions::LastFrameNoStop,
557 };
558
559 next_first_frame = match (&op, next_op) {
563 (_, None) => false,
564 (Read(_), Some(Write(_))) | (Write(_), Some(Read(_))) => true,
565 (Read(_), Some(Read(_))) | (Write(_), Some(Write(_))) => false,
566 };
567
568 Some((op, frame))
569 }))
570}