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
8use core::future::Future;
9use core::iter;
10use core::marker::PhantomData;
11
12use embassy_hal_internal::{Peripheral, PeripheralRef};
13use embassy_sync::waitqueue::AtomicWaker;
14#[cfg(feature = "time")]
15use embassy_time::{Duration, Instant};
16
17use crate::dma::ChannelAndRequest;
18#[cfg(gpio_v2)]
19use crate::gpio::Pull;
20use crate::gpio::{AfType, AnyPin, OutputType, SealedPin as _, Speed};
21use crate::interrupt::typelevel::Interrupt;
22use crate::mode::{Async, Blocking, Mode};
23use crate::rcc::{RccInfo, SealedRccPeripheral};
24use crate::time::Hertz;
25use crate::{interrupt, peripherals};
26
27#[derive(Debug, PartialEq, Eq, Copy, Clone)]
29#[cfg_attr(feature = "defmt", derive(defmt::Format))]
30pub enum Error {
31 Bus,
33 Arbitration,
35 Nack,
37 Timeout,
39 Crc,
41 Overrun,
43 ZeroLengthTransfer,
45}
46
47#[non_exhaustive]
49#[derive(Copy, Clone)]
50pub struct Config {
51 #[cfg(gpio_v2)]
56 pub sda_pullup: bool,
57 #[cfg(gpio_v2)]
62 pub scl_pullup: bool,
63 #[cfg(feature = "time")]
65 pub timeout: embassy_time::Duration,
66}
67
68impl Default for Config {
69 fn default() -> Self {
70 Self {
71 #[cfg(gpio_v2)]
72 sda_pullup: false,
73 #[cfg(gpio_v2)]
74 scl_pullup: false,
75 #[cfg(feature = "time")]
76 timeout: embassy_time::Duration::from_millis(1000),
77 }
78 }
79}
80
81impl Config {
82 fn scl_af(&self) -> AfType {
83 #[cfg(gpio_v1)]
84 return AfType::output(OutputType::OpenDrain, Speed::Medium);
85 #[cfg(gpio_v2)]
86 return AfType::output_pull(
87 OutputType::OpenDrain,
88 Speed::Medium,
89 match self.scl_pullup {
90 true => Pull::Up,
91 false => Pull::None,
92 },
93 );
94 }
95
96 fn sda_af(&self) -> AfType {
97 #[cfg(gpio_v1)]
98 return AfType::output(OutputType::OpenDrain, Speed::Medium);
99 #[cfg(gpio_v2)]
100 return AfType::output_pull(
101 OutputType::OpenDrain,
102 Speed::Medium,
103 match self.sda_pullup {
104 true => Pull::Up,
105 false => Pull::None,
106 },
107 );
108 }
109}
110
111pub struct I2c<'d, M: Mode> {
113 info: &'static Info,
114 state: &'static State,
115 kernel_clock: Hertz,
116 scl: Option<PeripheralRef<'d, AnyPin>>,
117 sda: Option<PeripheralRef<'d, AnyPin>>,
118 tx_dma: Option<ChannelAndRequest<'d>>,
119 rx_dma: Option<ChannelAndRequest<'d>>,
120 #[cfg(feature = "time")]
121 timeout: Duration,
122 _phantom: PhantomData<M>,
123}
124
125impl<'d> I2c<'d, Async> {
126 pub fn new<T: Instance>(
128 peri: impl Peripheral<P = T> + 'd,
129 scl: impl Peripheral<P = impl SclPin<T>> + 'd,
130 sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
131 _irq: impl interrupt::typelevel::Binding<T::EventInterrupt, EventInterruptHandler<T>>
132 + interrupt::typelevel::Binding<T::ErrorInterrupt, ErrorInterruptHandler<T>>
133 + 'd,
134 tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd,
135 rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd,
136 freq: Hertz,
137 config: Config,
138 ) -> Self {
139 Self::new_inner(
140 peri,
141 new_pin!(scl, config.scl_af()),
142 new_pin!(sda, config.sda_af()),
143 new_dma!(tx_dma),
144 new_dma!(rx_dma),
145 freq,
146 config,
147 )
148 }
149}
150
151impl<'d> I2c<'d, Blocking> {
152 pub fn new_blocking<T: Instance>(
154 peri: impl Peripheral<P = T> + 'd,
155 scl: impl Peripheral<P = impl SclPin<T>> + 'd,
156 sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
157 freq: Hertz,
158 config: Config,
159 ) -> Self {
160 Self::new_inner(
161 peri,
162 new_pin!(scl, config.scl_af()),
163 new_pin!(sda, config.sda_af()),
164 None,
165 None,
166 freq,
167 config,
168 )
169 }
170}
171
172impl<'d, M: Mode> I2c<'d, M> {
173 fn new_inner<T: Instance>(
175 _peri: impl Peripheral<P = T> + 'd,
176 scl: Option<PeripheralRef<'d, AnyPin>>,
177 sda: Option<PeripheralRef<'d, AnyPin>>,
178 tx_dma: Option<ChannelAndRequest<'d>>,
179 rx_dma: Option<ChannelAndRequest<'d>>,
180 freq: Hertz,
181 config: Config,
182 ) -> Self {
183 unsafe { T::EventInterrupt::enable() };
184 unsafe { T::ErrorInterrupt::enable() };
185
186 let mut this = Self {
187 info: T::info(),
188 state: T::state(),
189 kernel_clock: T::frequency(),
190 scl,
191 sda,
192 tx_dma,
193 rx_dma,
194 #[cfg(feature = "time")]
195 timeout: config.timeout,
196 _phantom: PhantomData,
197 };
198 this.enable_and_init(freq, config);
199 this
200 }
201
202 fn enable_and_init(&mut self, freq: Hertz, config: Config) {
203 self.info.rcc.enable_and_reset();
204 self.init(freq, config);
205 }
206
207 fn timeout(&self) -> Timeout {
208 Timeout {
209 #[cfg(feature = "time")]
210 deadline: Instant::now() + self.timeout,
211 }
212 }
213}
214
215impl<'d, M: Mode> Drop for I2c<'d, M> {
216 fn drop(&mut self) {
217 self.scl.as_ref().map(|x| x.set_as_disconnected());
218 self.sda.as_ref().map(|x| x.set_as_disconnected());
219
220 self.info.rcc.disable()
221 }
222}
223
224#[derive(Copy, Clone)]
225struct Timeout {
226 #[cfg(feature = "time")]
227 deadline: Instant,
228}
229
230#[allow(dead_code)]
231impl Timeout {
232 #[inline]
233 fn check(self) -> Result<(), Error> {
234 #[cfg(feature = "time")]
235 if Instant::now() > self.deadline {
236 return Err(Error::Timeout);
237 }
238
239 Ok(())
240 }
241
242 #[inline]
243 fn with<R>(self, fut: impl Future<Output = Result<R, Error>>) -> impl Future<Output = Result<R, Error>> {
244 #[cfg(feature = "time")]
245 {
246 use futures_util::FutureExt;
247
248 embassy_futures::select::select(embassy_time::Timer::at(self.deadline), fut).map(|r| match r {
249 embassy_futures::select::Either::First(_) => Err(Error::Timeout),
250 embassy_futures::select::Either::Second(r) => r,
251 })
252 }
253
254 #[cfg(not(feature = "time"))]
255 fut
256 }
257}
258
259struct State {
260 #[allow(unused)]
261 waker: AtomicWaker,
262}
263
264impl State {
265 const fn new() -> Self {
266 Self {
267 waker: AtomicWaker::new(),
268 }
269 }
270}
271
272struct Info {
273 regs: crate::pac::i2c::I2c,
274 rcc: RccInfo,
275}
276
277peri_trait!(
278 irqs: [EventInterrupt, ErrorInterrupt],
279);
280
281pin_trait!(SclPin, Instance);
282pin_trait!(SdaPin, Instance);
283dma_trait!(RxDma, Instance);
284dma_trait!(TxDma, Instance);
285
286pub struct EventInterruptHandler<T: Instance> {
288 _phantom: PhantomData<T>,
289}
290
291impl<T: Instance> interrupt::typelevel::Handler<T::EventInterrupt> for EventInterruptHandler<T> {
292 unsafe fn on_interrupt() {
293 _version::on_interrupt::<T>()
294 }
295}
296
297pub struct ErrorInterruptHandler<T: Instance> {
299 _phantom: PhantomData<T>,
300}
301
302impl<T: Instance> interrupt::typelevel::Handler<T::ErrorInterrupt> for ErrorInterruptHandler<T> {
303 unsafe fn on_interrupt() {
304 _version::on_interrupt::<T>()
305 }
306}
307
308foreach_peripheral!(
309 (i2c, $inst:ident) => {
310 #[allow(private_interfaces)]
311 impl SealedInstance for peripherals::$inst {
312 fn info() -> &'static Info {
313 static INFO: Info = Info{
314 regs: crate::pac::$inst,
315 rcc: crate::peripherals::$inst::RCC_INFO,
316 };
317 &INFO
318 }
319 fn state() -> &'static State {
320 static STATE: State = State::new();
321 &STATE
322 }
323 }
324
325 impl Instance for peripherals::$inst {
326 type EventInterrupt = crate::_generated::peripheral_interrupts::$inst::EV;
327 type ErrorInterrupt = crate::_generated::peripheral_interrupts::$inst::ER;
328 }
329 };
330);
331
332impl<'d, M: Mode> embedded_hal_02::blocking::i2c::Read for I2c<'d, M> {
333 type Error = Error;
334
335 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
336 self.blocking_read(address, buffer)
337 }
338}
339
340impl<'d, M: Mode> embedded_hal_02::blocking::i2c::Write for I2c<'d, M> {
341 type Error = Error;
342
343 fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
344 self.blocking_write(address, write)
345 }
346}
347
348impl<'d, M: Mode> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, M> {
349 type Error = Error;
350
351 fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
352 self.blocking_write_read(address, write, read)
353 }
354}
355
356impl embedded_hal_1::i2c::Error for Error {
357 fn kind(&self) -> embedded_hal_1::i2c::ErrorKind {
358 match *self {
359 Self::Bus => embedded_hal_1::i2c::ErrorKind::Bus,
360 Self::Arbitration => embedded_hal_1::i2c::ErrorKind::ArbitrationLoss,
361 Self::Nack => {
362 embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Unknown)
363 }
364 Self::Timeout => embedded_hal_1::i2c::ErrorKind::Other,
365 Self::Crc => embedded_hal_1::i2c::ErrorKind::Other,
366 Self::Overrun => embedded_hal_1::i2c::ErrorKind::Overrun,
367 Self::ZeroLengthTransfer => embedded_hal_1::i2c::ErrorKind::Other,
368 }
369 }
370}
371
372impl<'d, M: Mode> embedded_hal_1::i2c::ErrorType for I2c<'d, M> {
373 type Error = Error;
374}
375
376impl<'d, M: Mode> embedded_hal_1::i2c::I2c for I2c<'d, M> {
377 fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
378 self.blocking_read(address, read)
379 }
380
381 fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
382 self.blocking_write(address, write)
383 }
384
385 fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
386 self.blocking_write_read(address, write, read)
387 }
388
389 fn transaction(
390 &mut self,
391 address: u8,
392 operations: &mut [embedded_hal_1::i2c::Operation<'_>],
393 ) -> Result<(), Self::Error> {
394 self.blocking_transaction(address, operations)
395 }
396}
397
398impl<'d> embedded_hal_async::i2c::I2c for I2c<'d, Async> {
399 async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
400 self.read(address, read).await
401 }
402
403 async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
404 self.write(address, write).await
405 }
406
407 async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
408 self.write_read(address, write, read).await
409 }
410
411 async fn transaction(
412 &mut self,
413 address: u8,
414 operations: &mut [embedded_hal_1::i2c::Operation<'_>],
415 ) -> Result<(), Self::Error> {
416 self.transaction(address, operations).await
417 }
418}
419
420#[derive(Copy, Clone)]
439#[allow(dead_code)]
440enum FrameOptions {
441 FirstAndLastFrame,
443 FirstFrame,
446 FirstAndNextFrame,
449 NextFrame,
451 LastFrame,
453 LastFrameNoStop,
455}
456
457#[allow(dead_code)]
458impl FrameOptions {
459 fn send_start(self) -> bool {
461 match self {
462 Self::FirstAndLastFrame | Self::FirstFrame | Self::FirstAndNextFrame => true,
463 Self::NextFrame | Self::LastFrame | Self::LastFrameNoStop => false,
464 }
465 }
466
467 fn send_stop(self) -> bool {
469 match self {
470 Self::FirstAndLastFrame | Self::LastFrame => true,
471 Self::FirstFrame | Self::FirstAndNextFrame | Self::NextFrame | Self::LastFrameNoStop => false,
472 }
473 }
474
475 fn send_nack(self) -> bool {
477 match self {
478 Self::FirstAndLastFrame | Self::FirstFrame | Self::LastFrame | Self::LastFrameNoStop => true,
479 Self::FirstAndNextFrame | Self::NextFrame => false,
480 }
481 }
482}
483
484#[allow(dead_code)]
491fn operation_frames<'a, 'b: 'a>(
492 operations: &'a mut [embedded_hal_1::i2c::Operation<'b>],
493) -> Result<impl IntoIterator<Item = (&'a mut embedded_hal_1::i2c::Operation<'b>, FrameOptions)>, Error> {
494 use embedded_hal_1::i2c::Operation::{Read, Write};
495
496 if operations.iter().any(|op| match op {
503 Read(read) => read.is_empty(),
504 Write(_) => false,
505 }) {
506 return Err(Error::Overrun);
507 }
508
509 let mut operations = operations.iter_mut().peekable();
510
511 let mut next_first_frame = true;
512
513 Ok(iter::from_fn(move || {
514 let Some(op) = operations.next() else {
515 return None;
516 };
517
518 let first_frame = next_first_frame;
520 let next_op = operations.peek();
521
522 let frame = match (first_frame, next_op) {
534 (true, None) => FrameOptions::FirstAndLastFrame,
535 (true, Some(Read(_))) => FrameOptions::FirstAndNextFrame,
536 (true, Some(Write(_))) => FrameOptions::FirstFrame,
537 (false, None) => FrameOptions::LastFrame,
539 (false, Some(Read(_))) => FrameOptions::NextFrame,
540 (false, Some(Write(_))) => FrameOptions::LastFrameNoStop,
541 };
542
543 next_first_frame = match (&op, next_op) {
547 (_, None) => false,
548 (Read(_), Some(Write(_))) | (Write(_), Some(Read(_))) => true,
549 (Read(_), Some(Read(_))) | (Write(_), Some(Write(_))) => false,
550 };
551
552 Some((op, frame))
553 }))
554}