1use crate::{
2 async_hal::interrupts::{Binding, Handler, InterruptSource},
3 sercom::{
4 Sercom,
5 i2c::{self, AnyConfig, Flags, I2c, impl_ehal::chunk_operations},
6 },
7 typelevel::NoneT,
8};
9use core::{marker::PhantomData, task::Poll};
10
11use embedded_hal_async::i2c::{ErrorType, I2c as I2cTrait, Operation};
12
13pub struct InterruptHandler<S: Sercom> {
15 _private: (),
16 _sercom: PhantomData<S>,
17}
18
19impl<S: Sercom> crate::typelevel::Sealed for InterruptHandler<S> {}
20
21impl<S: Sercom> Handler<S::Interrupt> for InterruptHandler<S> {
22 #[inline]
24 unsafe fn on_interrupt() {
25 let mut peripherals = unsafe { crate::pac::Peripherals::steal() };
26 let i2cm = S::reg_block(&mut peripherals).i2cm();
27 let flags_to_check = Flags::all();
28 let flags_pending = Flags::from_bits_truncate(i2cm.intflag().read().bits());
29
30 if flags_to_check.intersects(flags_pending) {
33 i2cm.intenclr()
34 .write(|w| unsafe { w.bits(flags_pending.bits()) });
35 S::rx_waker().wake();
36 }
37 }
38}
39
40impl<C, S> I2c<C>
41where
42 C: AnyConfig<Sercom = S>,
43 S: Sercom,
44{
45 #[inline]
47 pub fn into_future<I>(self, _interrupts: I) -> I2cFuture<C>
48 where
49 I: Binding<S::Interrupt, InterruptHandler<S>>,
50 {
51 S::Interrupt::unpend();
52 unsafe { S::Interrupt::enable() };
53
54 I2cFuture { i2c: self }
55 }
56}
57
58pub struct I2cFuture<C, D = NoneT>
62where
63 C: AnyConfig,
64{
65 i2c: I2c<C, D>,
66}
67
68impl<C, S, D> I2cFuture<C, D>
69where
70 C: AnyConfig<Sercom = S>,
71 S: Sercom,
72{
73 async fn wait_flags(&mut self, flags_to_wait: Flags) {
74 core::future::poll_fn(|cx| {
75 {
77 let maybe_pending = self.i2c.config.as_ref().registers.read_flags();
78 if flags_to_wait.intersects(maybe_pending) {
79 return Poll::Ready(());
80 }
81 }
82
83 self.i2c.disable_interrupts(Flags::all());
84 S::rx_waker().register(cx.waker());
86 self.i2c.enable_interrupts(flags_to_wait);
87 let maybe_pending = self.i2c.config.as_ref().registers.read_flags();
88
89 if !flags_to_wait.intersects(maybe_pending) {
90 Poll::Pending
91 } else {
92 Poll::Ready(())
93 }
94 })
95 .await;
96 }
97}
98
99impl<C, S> I2cFuture<C, NoneT>
100where
101 C: AnyConfig<Sercom = S>,
102 S: Sercom,
103{
104 pub fn free(self) -> I2c<C> {
106 self.i2c
107 }
108
109 #[cfg(feature = "dma")]
111 pub fn with_dma_channel<D: crate::dmac::AnyChannel<Status = crate::dmac::ReadyFuture>>(
112 self,
113 dma_channel: D,
114 ) -> I2cFuture<C, D> {
115 I2cFuture {
116 i2c: I2c {
117 config: self.i2c.config,
118 _dma_channel: dma_channel,
119 },
120 }
121 }
122
123 async fn write_one(&mut self, byte: u8) -> Result<(), i2c::Error> {
124 self.wait_flags(Flags::MB | Flags::ERROR).await;
125 self.i2c.read_status().check_bus_error()?;
126 self.i2c.config.as_mut().registers.write_one(byte);
127 Ok(())
128 }
129
130 async fn read_one(&mut self) -> Result<u8, i2c::Error> {
131 self.wait_flags(Flags::SB | Flags::ERROR).await;
132 self.i2c.read_status().check_bus_error()?;
133 Ok(self.i2c.config.as_mut().registers.read_one())
134 }
135}
136
137impl<C: AnyConfig, D> AsRef<I2c<C, D>> for I2cFuture<C, D> {
138 #[inline]
139 fn as_ref(&self) -> &I2c<C, D> {
140 &self.i2c
141 }
142}
143
144impl<C: AnyConfig, D> AsMut<I2c<C, D>> for I2cFuture<C, D> {
145 #[inline]
146 fn as_mut(&mut self) -> &mut I2c<C, D> {
147 &mut self.i2c
148 }
149}
150
151impl<C, D> ErrorType for I2cFuture<C, D>
152where
153 C: AnyConfig,
154{
155 type Error = i2c::Error;
156}
157
158impl<C: AnyConfig> I2cFuture<C> {
159 #[inline]
160 async fn do_read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), i2c::Error> {
161 self.i2c.config.as_mut().registers.start_read(addr)?;
162
163 let mut iter = buffer.iter_mut();
165 *iter.next().expect("buffer len is at least 1") = self.read_one().await?;
166
167 for byte in iter {
168 self.i2c.config.as_mut().registers.cmd_read();
170 *byte = self.read_one().await?;
171 }
172
173 Ok(())
174 }
175
176 #[inline]
177 async fn continue_read(&mut self, buffer: &mut [u8]) -> Result<(), i2c::Error> {
178 for byte in buffer.iter_mut() {
179 self.i2c.config.as_mut().registers.cmd_read();
180 *byte = self.read_one().await?;
181 }
182 Ok(())
183 }
184
185 #[inline]
186 async fn do_write(&mut self, address: u8, buffer: &[u8]) -> Result<(), i2c::Error> {
187 self.i2c.config.as_mut().registers.start_write(address)?;
188
189 for byte in buffer {
190 self.write_one(*byte).await?;
191 }
192 Ok(())
193 }
194
195 #[inline]
196 async fn continue_write(&mut self, buffer: &[u8]) -> Result<(), i2c::Error> {
197 for byte in buffer {
198 self.write_one(*byte).await?;
199 }
200 Ok(())
201 }
202}
203
204impl<C: AnyConfig> I2cTrait for I2cFuture<C> {
205 #[inline]
206 async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
207 self.do_read(address, buffer).await?;
208 self.i2c.config.as_mut().registers.cmd_stop();
209 Ok(())
210 }
211
212 #[inline]
213 async fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
214 self.do_write(address, bytes).await?;
215 self.i2c.cmd_stop();
216 Ok(())
217 }
218
219 #[inline]
220 async fn write_read(
221 &mut self,
222 address: u8,
223 write_buf: &[u8],
224 read_buf: &mut [u8],
225 ) -> Result<(), Self::Error> {
226 self.do_write(address, write_buf).await?;
227 self.i2c.config.as_mut().registers.cmd_repeated_start();
228 self.do_read(address, read_buf).await?;
229 Ok(())
230 }
231
232 #[inline]
233 async fn transaction(
234 &mut self,
235 address: u8,
236 operations: &mut [Operation<'_>],
237 ) -> Result<(), Self::Error> {
238 let mut op_groups = chunk_operations(operations).peekable();
239
240 while let Some(group) = op_groups.next() {
241 let mut group = group.iter_mut();
242 let op = group.next().unwrap();
245
246 match op {
249 Operation::Read(buf) => self.do_read(address, buf).await?,
250 Operation::Write(buf) => self.do_write(address, buf).await?,
251 }
252
253 for op in group {
256 match op {
257 Operation::Read(buf) => self.continue_read(buf).await?,
258 Operation::Write(buf) => self.continue_write(buf).await?,
259 }
260 }
261
262 let regs = &mut self.i2c.config.as_mut().registers;
263 if op_groups.peek().is_some() {
264 regs.cmd_repeated_start();
266 } else {
267 regs.cmd_stop();
269 }
270 }
271
272 Ok(())
273 }
274}
275
276#[cfg(feature = "dma")]
277mod dma {
278 use embedded_hal_1::i2c::Operation;
279 use embedded_hal_async::i2c::I2c as I2cTrait;
280
281 use super::*;
282 use crate::dmac::sram::DmacDescriptor;
283 use crate::dmac::{AnyChannel, Channel, ReadyFuture};
284 use crate::sercom::dma::SharedSliceBuffer;
285 use crate::sercom::dma::async_dma::{read_dma_linked, write_dma_linked};
286
287 #[cfg(feature = "dma")]
288 pub type I2cFutureDma<C, I> = I2cFuture<C, Channel<I, ReadyFuture>>;
292
293 impl<C, D> I2cFuture<C, D>
294 where
295 C: AnyConfig,
296 D: AnyChannel<Status = ReadyFuture>,
297 {
298 pub fn take_dma_channel(self) -> (I2cFuture<C, crate::typelevel::NoneT>, D) {
301 let (i2c, channel) = self.i2c.take_dma_channel();
302 (I2cFuture { i2c }, channel)
303 }
304 }
305
306 impl<C, S, D> I2cFuture<C, D>
307 where
308 C: AnyConfig<Sercom = S>,
309 S: Sercom,
310 D: AnyChannel<Status = ReadyFuture>,
311 {
312 #[inline]
324 pub(super) async unsafe fn write_linked(
325 &mut self,
326 address: u8,
327 bytes: &[u8],
328 next: Option<&mut DmacDescriptor>,
329 ) -> Result<(), i2c::Error> {
330 unsafe {
331 self.i2c.prepare_write_linked(address, bytes, &next)?;
332
333 let sercom_ptr = self.i2c.sercom_ptr();
334 let mut bytes = SharedSliceBuffer::from_slice(bytes);
335
336 write_dma_linked::<_, _, S>(
337 &mut self.i2c._dma_channel,
338 sercom_ptr,
339 &mut bytes,
340 next,
341 )
342 .await?;
343 }
344
345 while !self.i2c.read_status().is_idle() {
349 core::hint::spin_loop();
350 }
351 self.i2c.read_status().check_bus_error()?;
352 Ok(())
353 }
354
355 #[inline]
357 pub(super) async unsafe fn read_linked(
358 &mut self,
359 address: u8,
360 mut buffer: &mut [u8],
361 next: Option<&mut DmacDescriptor>,
362 ) -> Result<(), i2c::Error> {
363 unsafe {
364 self.i2c.prepare_read_linked(address, buffer, &next)?;
365 let i2c_ptr = self.i2c.sercom_ptr();
366
367 read_dma_linked::<_, _, S>(&mut self.i2c._dma_channel, i2c_ptr, &mut buffer, next)
368 .await?;
369 }
370
371 while !self.i2c.read_status().is_idle() {
375 core::hint::spin_loop();
376 }
377 self.i2c.read_status().check_bus_error()?;
378
379 Ok(())
380 }
381
382 #[inline]
388 pub async fn write_read(
389 &mut self,
390 addr: u8,
391 write_buf: &[u8],
392 read_buf: &mut [u8],
393 ) -> Result<(), i2c::Error> {
394 unsafe {
395 self.write_linked(addr, write_buf, None).await?;
396 self.read_linked(addr, read_buf, None).await?;
397 }
398 Ok(())
399 }
400 }
401
402 impl<C, D> I2cTrait for I2cFuture<C, D>
403 where
404 C: AnyConfig,
405 D: AnyChannel<Status = ReadyFuture>,
406 {
407 #[inline]
408 async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
409 unsafe { self.read_linked(address, buffer, None).await }
410 }
411
412 #[inline]
413 async fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
414 unsafe { self.write_linked(address, bytes, None).await }
415 }
416
417 #[inline]
418 async fn write_read(
419 &mut self,
420 address: u8,
421 wr_buffer: &[u8],
422 rd_buffer: &mut [u8],
423 ) -> Result<(), Self::Error> {
424 self.write_read(address, wr_buffer, rd_buffer).await?;
425 Ok(())
426 }
427
428 #[inline]
429 async fn transaction(
430 &mut self,
431 address: u8,
432 operations: &mut [Operation<'_>],
433 ) -> Result<(), Self::Error> {
434 use crate::dmac::{channel, sram::DmacDescriptor};
435 use crate::sercom::dma::SharedSliceBuffer;
436 use Operation::{Read, Write};
437
438 const NUM_LINKED_TRANSFERS: usize = 16;
439
440 if operations.is_empty() {
441 return Ok(());
442 }
443
444 let mut sercom_ptr = self.i2c.sercom_ptr();
445
446 let mut descriptors = heapless::Vec::<DmacDescriptor, NUM_LINKED_TRANSFERS>::new();
457
458 let op_groups = operations.chunk_by_mut(|this, next| {
460 matches!((this, next), (Write(_), Write(_)) | (Read(_), Read(_)))
461 });
462
463 for group in op_groups {
464 descriptors.clear();
465
466 if group.len() > NUM_LINKED_TRANSFERS {
469 self.i2c.transaction_byte_by_byte(address, group)?;
470 } else {
471 for op in group.iter_mut().skip(1) {
477 match op {
478 Read(buffer) => {
479 if buffer.is_empty() {
480 continue;
481 }
482 descriptors
484 .push(DmacDescriptor::default())
485 .unwrap_or_else(|_| panic!("BUG: DMAC descriptors overflow"));
486 let last_descriptor = descriptors.last_mut().unwrap();
487 let next_ptr =
488 (last_descriptor as *mut DmacDescriptor).wrapping_add(1);
489
490 unsafe {
491 channel::write_descriptor(
492 last_descriptor,
493 &mut sercom_ptr,
494 buffer,
495 next_ptr,
498 );
499 }
500 }
501
502 Write(bytes) => {
503 if bytes.is_empty() {
504 continue;
505 }
506 descriptors
508 .push(DmacDescriptor::default())
509 .unwrap_or_else(|_| panic!("BUG: DMAC descriptors overflow"));
510 let last_descriptor = descriptors.last_mut().unwrap();
511 let next_ptr =
512 (last_descriptor as *mut DmacDescriptor).wrapping_add(1);
513
514 let mut bytes = SharedSliceBuffer::from_slice(bytes);
515 unsafe {
516 channel::write_descriptor(
517 last_descriptor,
518 &mut bytes,
519 &mut sercom_ptr,
520 next_ptr,
523 );
524 }
525 }
526 }
527 }
528
529 if let Some(d) = descriptors.last_mut() {
532 d.set_next_descriptor(core::ptr::null_mut());
533 }
534
535 match group.first_mut().unwrap() {
537 Read(buffer) => unsafe {
538 self.read_linked(address, buffer, descriptors.first_mut())
539 .await?;
540 },
541 Write(bytes) => unsafe {
542 self.write_linked(address, bytes, descriptors.first_mut())
543 .await?;
544 },
545 }
546 }
547 }
548
549 Ok(())
550 }
551 }
552}
553
554#[cfg(feature = "dma")]
555pub use dma::*;