embassy_stm32/i2c/
v2.rs

1use core::cmp;
2use core::future::poll_fn;
3use core::task::Poll;
4
5use embassy_embedded_hal::SetConfig;
6use embassy_hal_internal::drop::OnDrop;
7use embedded_hal_1::i2c::Operation;
8
9use super::*;
10use crate::pac::i2c;
11
12pub(crate) unsafe fn on_interrupt<T: Instance>() {
13    let regs = T::info().regs;
14    let isr = regs.isr().read();
15
16    if isr.tcr() || isr.tc() {
17        T::state().waker.wake();
18    }
19    // The flag can only be cleared by writting to nbytes, we won't do that here, so disable
20    // the interrupt
21    critical_section::with(|_| {
22        regs.cr1().modify(|w| w.set_tcie(false));
23    });
24}
25
26impl<'d, M: Mode> I2c<'d, M> {
27    pub(crate) fn init(&mut self, freq: Hertz, _config: Config) {
28        self.info.regs.cr1().modify(|reg| {
29            reg.set_pe(false);
30            reg.set_anfoff(false);
31        });
32
33        let timings = Timings::new(self.kernel_clock, freq.into());
34
35        self.info.regs.timingr().write(|reg| {
36            reg.set_presc(timings.prescale);
37            reg.set_scll(timings.scll);
38            reg.set_sclh(timings.sclh);
39            reg.set_sdadel(timings.sdadel);
40            reg.set_scldel(timings.scldel);
41        });
42
43        self.info.regs.cr1().modify(|reg| {
44            reg.set_pe(true);
45        });
46    }
47
48    fn master_stop(&mut self) {
49        self.info.regs.cr2().write(|w| w.set_stop(true));
50    }
51
52    fn master_read(
53        info: &'static Info,
54        address: u8,
55        length: usize,
56        stop: Stop,
57        reload: bool,
58        restart: bool,
59        timeout: Timeout,
60    ) -> Result<(), Error> {
61        assert!(length < 256);
62
63        if !restart {
64            // Wait for any previous address sequence to end
65            // automatically. This could be up to 50% of a bus
66            // cycle (ie. up to 0.5/freq)
67            while info.regs.cr2().read().start() {
68                timeout.check()?;
69            }
70        }
71
72        // Set START and prepare to receive bytes into
73        // `buffer`. The START bit can be set even if the bus
74        // is BUSY or I2C is in slave mode.
75
76        let reload = if reload {
77            i2c::vals::Reload::NOT_COMPLETED
78        } else {
79            i2c::vals::Reload::COMPLETED
80        };
81
82        info.regs.cr2().modify(|w| {
83            w.set_sadd((address << 1 | 0) as u16);
84            w.set_add10(i2c::vals::Addmode::BIT7);
85            w.set_dir(i2c::vals::Dir::READ);
86            w.set_nbytes(length as u8);
87            w.set_start(true);
88            w.set_autoend(stop.autoend());
89            w.set_reload(reload);
90        });
91
92        Ok(())
93    }
94
95    fn master_write(
96        info: &'static Info,
97        address: u8,
98        length: usize,
99        stop: Stop,
100        reload: bool,
101        timeout: Timeout,
102    ) -> Result<(), Error> {
103        assert!(length < 256);
104
105        // Wait for any previous address sequence to end
106        // automatically. This could be up to 50% of a bus
107        // cycle (ie. up to 0.5/freq)
108        while info.regs.cr2().read().start() {
109            timeout.check()?;
110        }
111
112        // Wait for the bus to be free
113        while info.regs.isr().read().busy() {
114            timeout.check()?;
115        }
116
117        let reload = if reload {
118            i2c::vals::Reload::NOT_COMPLETED
119        } else {
120            i2c::vals::Reload::COMPLETED
121        };
122
123        // Set START and prepare to send `bytes`. The
124        // START bit can be set even if the bus is BUSY or
125        // I2C is in slave mode.
126        info.regs.cr2().modify(|w| {
127            w.set_sadd((address << 1 | 0) as u16);
128            w.set_add10(i2c::vals::Addmode::BIT7);
129            w.set_dir(i2c::vals::Dir::WRITE);
130            w.set_nbytes(length as u8);
131            w.set_start(true);
132            w.set_autoend(stop.autoend());
133            w.set_reload(reload);
134        });
135
136        Ok(())
137    }
138
139    fn master_continue(info: &'static Info, length: usize, reload: bool, timeout: Timeout) -> Result<(), Error> {
140        assert!(length < 256 && length > 0);
141
142        while !info.regs.isr().read().tcr() {
143            timeout.check()?;
144        }
145
146        let reload = if reload {
147            i2c::vals::Reload::NOT_COMPLETED
148        } else {
149            i2c::vals::Reload::COMPLETED
150        };
151
152        info.regs.cr2().modify(|w| {
153            w.set_nbytes(length as u8);
154            w.set_reload(reload);
155        });
156
157        Ok(())
158    }
159
160    fn flush_txdr(&self) {
161        if self.info.regs.isr().read().txis() {
162            self.info.regs.txdr().write(|w| w.set_txdata(0));
163        }
164        if !self.info.regs.isr().read().txe() {
165            self.info.regs.isr().modify(|w| w.set_txe(true))
166        }
167    }
168
169    fn wait_txe(&self, timeout: Timeout) -> Result<(), Error> {
170        loop {
171            let isr = self.info.regs.isr().read();
172            if isr.txe() {
173                return Ok(());
174            } else if isr.berr() {
175                self.info.regs.icr().write(|reg| reg.set_berrcf(true));
176                return Err(Error::Bus);
177            } else if isr.arlo() {
178                self.info.regs.icr().write(|reg| reg.set_arlocf(true));
179                return Err(Error::Arbitration);
180            } else if isr.nackf() {
181                self.info.regs.icr().write(|reg| reg.set_nackcf(true));
182                self.flush_txdr();
183                return Err(Error::Nack);
184            }
185
186            timeout.check()?;
187        }
188    }
189
190    fn wait_rxne(&self, timeout: Timeout) -> Result<(), Error> {
191        loop {
192            let isr = self.info.regs.isr().read();
193            if isr.rxne() {
194                return Ok(());
195            } else if isr.berr() {
196                self.info.regs.icr().write(|reg| reg.set_berrcf(true));
197                return Err(Error::Bus);
198            } else if isr.arlo() {
199                self.info.regs.icr().write(|reg| reg.set_arlocf(true));
200                return Err(Error::Arbitration);
201            } else if isr.nackf() {
202                self.info.regs.icr().write(|reg| reg.set_nackcf(true));
203                self.flush_txdr();
204                return Err(Error::Nack);
205            }
206
207            timeout.check()?;
208        }
209    }
210
211    fn wait_tc(&self, timeout: Timeout) -> Result<(), Error> {
212        loop {
213            let isr = self.info.regs.isr().read();
214            if isr.tc() {
215                return Ok(());
216            } else if isr.berr() {
217                self.info.regs.icr().write(|reg| reg.set_berrcf(true));
218                return Err(Error::Bus);
219            } else if isr.arlo() {
220                self.info.regs.icr().write(|reg| reg.set_arlocf(true));
221                return Err(Error::Arbitration);
222            } else if isr.nackf() {
223                self.info.regs.icr().write(|reg| reg.set_nackcf(true));
224                self.flush_txdr();
225                return Err(Error::Nack);
226            }
227
228            timeout.check()?;
229        }
230    }
231
232    fn read_internal(&mut self, address: u8, read: &mut [u8], restart: bool, timeout: Timeout) -> Result<(), Error> {
233        let completed_chunks = read.len() / 255;
234        let total_chunks = if completed_chunks * 255 == read.len() {
235            completed_chunks
236        } else {
237            completed_chunks + 1
238        };
239        let last_chunk_idx = total_chunks.saturating_sub(1);
240
241        Self::master_read(
242            self.info,
243            address,
244            read.len().min(255),
245            Stop::Automatic,
246            last_chunk_idx != 0,
247            restart,
248            timeout,
249        )?;
250
251        for (number, chunk) in read.chunks_mut(255).enumerate() {
252            if number != 0 {
253                Self::master_continue(self.info, chunk.len(), number != last_chunk_idx, timeout)?;
254            }
255
256            for byte in chunk {
257                // Wait until we have received something
258                self.wait_rxne(timeout)?;
259
260                *byte = self.info.regs.rxdr().read().rxdata();
261            }
262        }
263        Ok(())
264    }
265
266    fn write_internal(&mut self, address: u8, write: &[u8], send_stop: bool, timeout: Timeout) -> Result<(), Error> {
267        let completed_chunks = write.len() / 255;
268        let total_chunks = if completed_chunks * 255 == write.len() {
269            completed_chunks
270        } else {
271            completed_chunks + 1
272        };
273        let last_chunk_idx = total_chunks.saturating_sub(1);
274
275        // I2C start
276        //
277        // ST SAD+W
278        if let Err(err) = Self::master_write(
279            self.info,
280            address,
281            write.len().min(255),
282            Stop::Software,
283            last_chunk_idx != 0,
284            timeout,
285        ) {
286            if send_stop {
287                self.master_stop();
288            }
289            return Err(err);
290        }
291
292        for (number, chunk) in write.chunks(255).enumerate() {
293            if number != 0 {
294                Self::master_continue(self.info, chunk.len(), number != last_chunk_idx, timeout)?;
295            }
296
297            for byte in chunk {
298                // Wait until we are allowed to send data
299                // (START has been ACKed or last byte when
300                // through)
301                if let Err(err) = self.wait_txe(timeout) {
302                    if send_stop {
303                        self.master_stop();
304                    }
305                    return Err(err);
306                }
307
308                self.info.regs.txdr().write(|w| w.set_txdata(*byte));
309            }
310        }
311        // Wait until the write finishes
312        let result = self.wait_tc(timeout);
313        if send_stop {
314            self.master_stop();
315        }
316        result
317    }
318
319    // =========================
320    //  Blocking public API
321
322    /// Blocking read.
323    pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
324        self.read_internal(address, read, false, self.timeout())
325        // Automatic Stop
326    }
327
328    /// Blocking write.
329    pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
330        self.write_internal(address, write, true, self.timeout())
331    }
332
333    /// Blocking write, restart, read.
334    pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
335        let timeout = self.timeout();
336        self.write_internal(address, write, false, timeout)?;
337        self.read_internal(address, read, true, timeout)
338        // Automatic Stop
339    }
340
341    /// Blocking transaction with operations.
342    ///
343    /// Consecutive operations of same type are merged. See [transaction contract] for details.
344    ///
345    /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction
346    pub fn blocking_transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> {
347        let _ = addr;
348        let _ = operations;
349        todo!()
350    }
351
352    /// Blocking write multiple buffers.
353    ///
354    /// The buffers are concatenated in a single write transaction.
355    pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> {
356        if write.is_empty() {
357            return Err(Error::ZeroLengthTransfer);
358        }
359
360        let timeout = self.timeout();
361
362        let first_length = write[0].len();
363        let last_slice_index = write.len() - 1;
364
365        if let Err(err) = Self::master_write(
366            self.info,
367            address,
368            first_length.min(255),
369            Stop::Software,
370            (first_length > 255) || (last_slice_index != 0),
371            timeout,
372        ) {
373            self.master_stop();
374            return Err(err);
375        }
376
377        for (idx, slice) in write.iter().enumerate() {
378            let slice_len = slice.len();
379            let completed_chunks = slice_len / 255;
380            let total_chunks = if completed_chunks * 255 == slice_len {
381                completed_chunks
382            } else {
383                completed_chunks + 1
384            };
385            let last_chunk_idx = total_chunks.saturating_sub(1);
386
387            if idx != 0 {
388                if let Err(err) = Self::master_continue(
389                    self.info,
390                    slice_len.min(255),
391                    (idx != last_slice_index) || (slice_len > 255),
392                    timeout,
393                ) {
394                    self.master_stop();
395                    return Err(err);
396                }
397            }
398
399            for (number, chunk) in slice.chunks(255).enumerate() {
400                if number != 0 {
401                    if let Err(err) = Self::master_continue(
402                        self.info,
403                        chunk.len(),
404                        (number != last_chunk_idx) || (idx != last_slice_index),
405                        timeout,
406                    ) {
407                        self.master_stop();
408                        return Err(err);
409                    }
410                }
411
412                for byte in chunk {
413                    // Wait until we are allowed to send data
414                    // (START has been ACKed or last byte when
415                    // through)
416                    if let Err(err) = self.wait_txe(timeout) {
417                        self.master_stop();
418                        return Err(err);
419                    }
420
421                    // Put byte on the wire
422                    //self.i2c.txdr.write(|w| w.txdata().bits(*byte));
423                    self.info.regs.txdr().write(|w| w.set_txdata(*byte));
424                }
425            }
426        }
427        // Wait until the write finishes
428        let result = self.wait_tc(timeout);
429        self.master_stop();
430        result
431    }
432}
433
434impl<'d> I2c<'d, Async> {
435    async fn write_dma_internal(
436        &mut self,
437        address: u8,
438        write: &[u8],
439        first_slice: bool,
440        last_slice: bool,
441        timeout: Timeout,
442    ) -> Result<(), Error> {
443        let total_len = write.len();
444
445        let dma_transfer = unsafe {
446            let regs = self.info.regs;
447            regs.cr1().modify(|w| {
448                w.set_txdmaen(true);
449                if first_slice {
450                    w.set_tcie(true);
451                }
452            });
453            let dst = regs.txdr().as_ptr() as *mut u8;
454
455            self.tx_dma.as_mut().unwrap().write(write, dst, Default::default())
456        };
457
458        let mut remaining_len = total_len;
459
460        let on_drop = OnDrop::new(|| {
461            let regs = self.info.regs;
462            regs.cr1().modify(|w| {
463                if last_slice {
464                    w.set_txdmaen(false);
465                }
466                w.set_tcie(false);
467            })
468        });
469
470        poll_fn(|cx| {
471            self.state.waker.register(cx.waker());
472
473            let isr = self.info.regs.isr().read();
474            if remaining_len == total_len {
475                if first_slice {
476                    Self::master_write(
477                        self.info,
478                        address,
479                        total_len.min(255),
480                        Stop::Software,
481                        (total_len > 255) || !last_slice,
482                        timeout,
483                    )?;
484                } else {
485                    Self::master_continue(self.info, total_len.min(255), (total_len > 255) || !last_slice, timeout)?;
486                    self.info.regs.cr1().modify(|w| w.set_tcie(true));
487                }
488            } else if !(isr.tcr() || isr.tc()) {
489                // poll_fn was woken without an interrupt present
490                return Poll::Pending;
491            } else if remaining_len == 0 {
492                return Poll::Ready(Ok(()));
493            } else {
494                let last_piece = (remaining_len <= 255) && last_slice;
495
496                if let Err(e) = Self::master_continue(self.info, remaining_len.min(255), !last_piece, timeout) {
497                    return Poll::Ready(Err(e));
498                }
499                self.info.regs.cr1().modify(|w| w.set_tcie(true));
500            }
501
502            remaining_len = remaining_len.saturating_sub(255);
503            Poll::Pending
504        })
505        .await?;
506
507        dma_transfer.await;
508
509        if last_slice {
510            // This should be done already
511            self.wait_tc(timeout)?;
512            self.master_stop();
513        }
514
515        drop(on_drop);
516
517        Ok(())
518    }
519
520    async fn read_dma_internal(
521        &mut self,
522        address: u8,
523        buffer: &mut [u8],
524        restart: bool,
525        timeout: Timeout,
526    ) -> Result<(), Error> {
527        let total_len = buffer.len();
528
529        let dma_transfer = unsafe {
530            let regs = self.info.regs;
531            regs.cr1().modify(|w| {
532                w.set_rxdmaen(true);
533                w.set_tcie(true);
534            });
535            let src = regs.rxdr().as_ptr() as *mut u8;
536
537            self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default())
538        };
539
540        let mut remaining_len = total_len;
541
542        let on_drop = OnDrop::new(|| {
543            let regs = self.info.regs;
544            regs.cr1().modify(|w| {
545                w.set_rxdmaen(false);
546                w.set_tcie(false);
547            })
548        });
549
550        poll_fn(|cx| {
551            self.state.waker.register(cx.waker());
552
553            let isr = self.info.regs.isr().read();
554            if remaining_len == total_len {
555                Self::master_read(
556                    self.info,
557                    address,
558                    total_len.min(255),
559                    Stop::Software,
560                    total_len > 255,
561                    restart,
562                    timeout,
563                )?;
564            } else if !(isr.tcr() || isr.tc()) {
565                // poll_fn was woken without an interrupt present
566                return Poll::Pending;
567            } else if remaining_len == 0 {
568                return Poll::Ready(Ok(()));
569            } else {
570                let last_piece = remaining_len <= 255;
571
572                if let Err(e) = Self::master_continue(self.info, remaining_len.min(255), !last_piece, timeout) {
573                    return Poll::Ready(Err(e));
574                }
575                self.info.regs.cr1().modify(|w| w.set_tcie(true));
576            }
577
578            remaining_len = remaining_len.saturating_sub(255);
579            Poll::Pending
580        })
581        .await?;
582
583        dma_transfer.await;
584
585        // This should be done already
586        self.wait_tc(timeout)?;
587        self.master_stop();
588
589        drop(on_drop);
590
591        Ok(())
592    }
593
594    // =========================
595    //  Async public API
596
597    /// Write.
598    pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
599        let timeout = self.timeout();
600        if write.is_empty() {
601            self.write_internal(address, write, true, timeout)
602        } else {
603            timeout
604                .with(self.write_dma_internal(address, write, true, true, timeout))
605                .await
606        }
607    }
608
609    /// Write multiple buffers.
610    ///
611    /// The buffers are concatenated in a single write transaction.
612    pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> {
613        let timeout = self.timeout();
614
615        if write.is_empty() {
616            return Err(Error::ZeroLengthTransfer);
617        }
618        let mut iter = write.iter();
619
620        let mut first = true;
621        let mut current = iter.next();
622        while let Some(c) = current {
623            let next = iter.next();
624            let is_last = next.is_none();
625
626            let fut = self.write_dma_internal(address, c, first, is_last, timeout);
627            timeout.with(fut).await?;
628            first = false;
629            current = next;
630        }
631        Ok(())
632    }
633
634    /// Read.
635    pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> {
636        let timeout = self.timeout();
637
638        if buffer.is_empty() {
639            self.read_internal(address, buffer, false, timeout)
640        } else {
641            let fut = self.read_dma_internal(address, buffer, false, timeout);
642            timeout.with(fut).await
643        }
644    }
645
646    /// Write, restart, read.
647    pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
648        let timeout = self.timeout();
649
650        if write.is_empty() {
651            self.write_internal(address, write, false, timeout)?;
652        } else {
653            let fut = self.write_dma_internal(address, write, true, true, timeout);
654            timeout.with(fut).await?;
655        }
656
657        if read.is_empty() {
658            self.read_internal(address, read, true, timeout)?;
659        } else {
660            let fut = self.read_dma_internal(address, read, true, timeout);
661            timeout.with(fut).await?;
662        }
663
664        Ok(())
665    }
666
667    /// Transaction with operations.
668    ///
669    /// Consecutive operations of same type are merged. See [transaction contract] for details.
670    ///
671    /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction
672    pub async fn transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> {
673        let _ = addr;
674        let _ = operations;
675        todo!()
676    }
677}
678
679/// I2C Stop Configuration
680///
681/// Peripheral options for generating the STOP condition
682#[derive(Copy, Clone, PartialEq)]
683enum Stop {
684    /// Software end mode: Must write register to generate STOP condition
685    Software,
686    /// Automatic end mode: A STOP condition is automatically generated once the
687    /// configured number of bytes have been transferred
688    Automatic,
689}
690
691impl Stop {
692    fn autoend(&self) -> i2c::vals::Autoend {
693        match self {
694            Stop::Software => i2c::vals::Autoend::SOFTWARE,
695            Stop::Automatic => i2c::vals::Autoend::AUTOMATIC,
696        }
697    }
698}
699
700struct Timings {
701    prescale: u8,
702    scll: u8,
703    sclh: u8,
704    sdadel: u8,
705    scldel: u8,
706}
707
708impl Timings {
709    fn new(i2cclk: Hertz, freq: Hertz) -> Self {
710        let i2cclk = i2cclk.0;
711        let freq = freq.0;
712        // Refer to RM0433 Rev 7 Figure 539 for setup and hold timing:
713        //
714        // t_I2CCLK = 1 / PCLK1
715        // t_PRESC  = (PRESC + 1) * t_I2CCLK
716        // t_SCLL   = (SCLL + 1) * t_PRESC
717        // t_SCLH   = (SCLH + 1) * t_PRESC
718        //
719        // t_SYNC1 + t_SYNC2 > 4 * t_I2CCLK
720        // t_SCL ~= t_SYNC1 + t_SYNC2 + t_SCLL + t_SCLH
721        let ratio = i2cclk / freq;
722
723        // For the standard-mode configuration method, we must have a ratio of 4
724        // or higher
725        assert!(ratio >= 4, "The I2C PCLK must be at least 4 times the bus frequency!");
726
727        let (presc_reg, scll, sclh, sdadel, scldel) = if freq > 100_000 {
728            // Fast-mode (Fm) or Fast-mode Plus (Fm+)
729            // here we pick SCLL + 1 = 2 * (SCLH + 1)
730
731            // Prescaler, 384 ticks for sclh/scll. Round up then subtract 1
732            let presc_reg = ((ratio - 1) / 384) as u8;
733            // ratio < 1200 by pclk 120MHz max., therefore presc < 16
734
735            // Actual precale value selected
736            let presc = (presc_reg + 1) as u32;
737
738            let sclh = ((ratio / presc) - 3) / 3;
739            let scll = (2 * (sclh + 1)) - 1;
740
741            let (sdadel, scldel) = if freq > 400_000 {
742                // Fast-mode Plus (Fm+)
743                assert!(i2cclk >= 17_000_000); // See table in datsheet
744
745                let sdadel = i2cclk / 8_000_000 / presc;
746                let scldel = i2cclk / 4_000_000 / presc - 1;
747
748                (sdadel, scldel)
749            } else {
750                // Fast-mode (Fm)
751                assert!(i2cclk >= 8_000_000); // See table in datsheet
752
753                let sdadel = i2cclk / 4_000_000 / presc;
754                let scldel = i2cclk / 2_000_000 / presc - 1;
755
756                (sdadel, scldel)
757            };
758
759            (presc_reg, scll as u8, sclh as u8, sdadel as u8, scldel as u8)
760        } else {
761            // Standard-mode (Sm)
762            // here we pick SCLL = SCLH
763            assert!(i2cclk >= 2_000_000); // See table in datsheet
764
765            // Prescaler, 512 ticks for sclh/scll. Round up then
766            // subtract 1
767            let presc = (ratio - 1) / 512;
768            let presc_reg = cmp::min(presc, 15) as u8;
769
770            // Actual prescale value selected
771            let presc = (presc_reg + 1) as u32;
772
773            let sclh = ((ratio / presc) - 2) / 2;
774            let scll = sclh;
775
776            // Speed check
777            assert!(sclh < 256, "The I2C PCLK is too fast for this bus frequency!");
778
779            let sdadel = i2cclk / 2_000_000 / presc;
780            let scldel = i2cclk / 500_000 / presc - 1;
781
782            (presc_reg, scll as u8, sclh as u8, sdadel as u8, scldel as u8)
783        };
784
785        // Sanity check
786        assert!(presc_reg < 16);
787
788        // Keep values within reasonable limits for fast per_ck
789        let sdadel = cmp::max(sdadel, 2);
790        let scldel = cmp::max(scldel, 4);
791
792        //(presc_reg, scll, sclh, sdadel, scldel)
793        Self {
794            prescale: presc_reg,
795            scll,
796            sclh,
797            sdadel,
798            scldel,
799        }
800    }
801}
802
803impl<'d, M: Mode> SetConfig for I2c<'d, M> {
804    type Config = Hertz;
805    type ConfigError = ();
806    fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
807        let timings = Timings::new(self.kernel_clock, *config);
808        self.info.regs.timingr().write(|reg| {
809            reg.set_presc(timings.prescale);
810            reg.set_scll(timings.scll);
811            reg.set_sclh(timings.sclh);
812            reg.set_sdadel(timings.sdadel);
813            reg.set_scldel(timings.scldel);
814        });
815
816        Ok(())
817    }
818}