py32_hal/i2c/
v1.rs

1//! # I2Cv1
2
3// The following code is modified from embassy-stm32
4// https://github.com/embassy-rs/embassy/tree/main/embassy-stm32
5// Special thanks to the Embassy Project and its contributors for their work!
6
7#[cfg(dma)]
8use core::future::poll_fn;
9#[cfg(dma)]
10use core::task::Poll;
11
12use embassy_embedded_hal::SetConfig;
13#[cfg(dma)]
14use embassy_futures::select::{select, Either};
15#[cfg(dma)]
16use embassy_hal_internal::drop::OnDrop;
17use embedded_hal_1::i2c::Operation;
18
19use super::*;
20use crate::mode::Mode as PeriMode;
21use crate::pac::i2c;
22
23// /!\                      /!\
24// /!\ Implementation note! /!\
25// /!\                      /!\
26//
27// It's somewhat unclear whether using interrupts here in a *strictly* one-shot style is actually
28// what we want! If you are looking in this file because you are doing async I2C and your code is
29// just totally hanging (sometimes), maybe swing by this issue:
30// <https://github.com/embassy-rs/embassy/issues/2372>.
31//
32// There's some more details there, and we might have a fix for you. But please let us know if you
33// hit a case like this!
34pub unsafe fn on_interrupt<T: Instance>() {
35    let regs = T::info().regs;
36    // i2c v2 only woke the task on transfer complete interrupts. v1 uses interrupts for a bunch of
37    // other stuff, so we wake the task on every interrupt.
38    T::state().waker.wake();
39    critical_section::with(|_| {
40        // Clear event interrupt flag.
41        regs.cr2().modify(|w| {
42            w.set_itevten(false);
43            w.set_iterren(false);
44        });
45    });
46}
47
48impl<'d, M: PeriMode> I2c<'d, M> {
49    pub(crate) fn init(&mut self, freq: Hertz, _config: Config) {
50        self.info.regs.cr1().modify(|reg| {
51            reg.set_pe(false);
52            //reg.set_anfoff(false);
53        });
54
55        // Errata: "Start cannot be generated after a misplaced Stop"
56        //
57        // > If a master generates a misplaced Stop on the bus (bus error)
58        // > while the microcontroller I2C peripheral attempts to switch to
59        // > Master mode by setting the START bit, the Start condition is
60        // > not properly generated.
61        //
62        // This also can occur with falsely detected STOP events, for example
63        // if the SDA line is shorted to low.
64        //
65        // The workaround for this is to trigger the SWRST line AFTER power is
66        // enabled, AFTER PE is disabled and BEFORE making any other configuration.
67        //
68        // It COULD be possible to apply this workaround at runtime, instead of
69        // only on initialization, however this would require detecting the timeout
70        // or BUSY lockup condition, and re-configuring the peripheral after reset.
71        //
72        // This presents as an ~infinite hang on read or write, as the START condition
73        // is never generated, meaning the start event is never generated.
74        self.info.regs.cr1().modify(|reg| {
75            reg.set_swrst(true);
76        });
77        self.info.regs.cr1().modify(|reg| {
78            reg.set_swrst(false);
79        });
80
81        let timings = Timings::new(self.kernel_clock, freq);
82
83        self.info.regs.cr2().modify(|reg| {
84            reg.set_freq(timings.freq);
85        });
86        self.info.regs.ccr().modify(|reg| {
87            reg.set_f_s(timings.mode.f_s());
88            reg.set_duty(timings.duty.duty());
89            reg.set_ccr(timings.ccr);
90        });
91        self.info.regs.trise().modify(|reg| {
92            reg.set_trise(timings.trise);
93        });
94
95        self.info.regs.cr1().modify(|reg| {
96            reg.set_pe(true);
97        });
98    }
99
100    fn check_and_clear_error_flags(info: &'static Info) -> Result<i2c::regs::Sr1, Error> {
101        // Note that flags should only be cleared once they have been registered. If flags are
102        // cleared otherwise, there may be an inherent race condition and flags may be missed.
103        let sr1 = info.regs.sr1().read();
104
105        // if sr1.timeout() {
106        //     info.regs.sr1().write(|reg| {
107        //         reg.0 = !0;
108        //         reg.set_timeout(false);
109        //     });
110        //     return Err(Error::Timeout);
111        // }
112
113        if sr1.pecerr() {
114            info.regs.sr1().write(|reg| {
115                reg.0 = !0;
116                reg.set_pecerr(false);
117            });
118            return Err(Error::Crc);
119        }
120
121        if sr1.ovr() {
122            info.regs.sr1().write(|reg| {
123                reg.0 = !0;
124                reg.set_ovr(false);
125            });
126            return Err(Error::Overrun);
127        }
128
129        if sr1.af() {
130            info.regs.sr1().write(|reg| {
131                reg.0 = !0;
132                reg.set_af(false);
133            });
134            return Err(Error::Nack);
135        }
136
137        if sr1.arlo() {
138            info.regs.sr1().write(|reg| {
139                reg.0 = !0;
140                reg.set_arlo(false);
141            });
142            return Err(Error::Arbitration);
143        }
144
145        // The errata indicates that BERR may be incorrectly detected. It recommends ignoring and
146        // clearing the BERR bit instead.
147        if sr1.berr() {
148            info.regs.sr1().write(|reg| {
149                reg.0 = !0;
150                reg.set_berr(false);
151            });
152        }
153
154        Ok(sr1)
155    }
156
157    fn write_bytes(
158        &mut self,
159        addr: u8,
160        bytes: &[u8],
161        timeout: Timeout,
162        frame: FrameOptions,
163    ) -> Result<(), Error> {
164        if frame.send_start() {
165            // Send a START condition
166
167            self.info.regs.cr1().modify(|reg| {
168                reg.set_start(true);
169            });
170
171            // Wait until START condition was generated
172            while !Self::check_and_clear_error_flags(self.info)?.start() {
173                timeout.check()?;
174            }
175
176            // Check if we were the ones to generate START
177            if self.info.regs.cr1().read().start() || !self.info.regs.sr2().read().msl() {
178                return Err(Error::Arbitration);
179            }
180
181            // Set up current address we're trying to talk to
182            self.info.regs.dr().write(|reg| reg.set_dr(addr << 1));
183
184            // Wait until address was sent
185            // Wait for the address to be acknowledged
186            // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set.
187            while !Self::check_and_clear_error_flags(self.info)?.addr() {
188                timeout.check()?;
189            }
190
191            // Clear condition by reading SR2
192            let _ = self.info.regs.sr2().read();
193        }
194
195        // Send bytes
196        for c in bytes {
197            self.send_byte(*c, timeout)?;
198        }
199
200        if frame.send_stop() {
201            // Send a STOP condition
202            self.info.regs.cr1().modify(|reg| reg.set_stop(true));
203        }
204
205        // Fallthrough is success
206        Ok(())
207    }
208
209    fn send_byte(&self, byte: u8, timeout: Timeout) -> Result<(), Error> {
210        // Wait until we're ready for sending
211        while {
212            // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set.
213            !Self::check_and_clear_error_flags(self.info)?.txe()
214        } {
215            timeout.check()?;
216        }
217
218        // Push out a byte of data
219        self.info.regs.dr().write(|reg| reg.set_dr(byte));
220
221        // Wait until byte is transferred
222        while {
223            // Check for any potential error conditions.
224            !Self::check_and_clear_error_flags(self.info)?.btf()
225        } {
226            timeout.check()?;
227        }
228
229        Ok(())
230    }
231
232    fn recv_byte(&self, timeout: Timeout) -> Result<u8, Error> {
233        while {
234            // Check for any potential error conditions.
235            Self::check_and_clear_error_flags(self.info)?;
236
237            !self.info.regs.sr1().read().rxne()
238        } {
239            timeout.check()?;
240        }
241
242        let value = self.info.regs.dr().read().dr();
243        Ok(value)
244    }
245
246    fn blocking_read_timeout(
247        &mut self,
248        addr: u8,
249        buffer: &mut [u8],
250        timeout: Timeout,
251        frame: FrameOptions,
252    ) -> Result<(), Error> {
253        let Some((last, buffer)) = buffer.split_last_mut() else {
254            return Err(Error::Overrun);
255        };
256
257        if frame.send_start() {
258            // Send a START condition and set ACK bit
259            self.info.regs.cr1().modify(|reg| {
260                reg.set_start(true);
261                reg.set_ack(true);
262            });
263
264            // Wait until START condition was generated
265            while !Self::check_and_clear_error_flags(self.info)?.start() {
266                timeout.check()?;
267            }
268
269            // Check if we were the ones to generate START
270            if self.info.regs.cr1().read().start() || !self.info.regs.sr2().read().msl() {
271                return Err(Error::Arbitration);
272            }
273
274            // Set up current address we're trying to talk to
275            self.info.regs.dr().write(|reg| reg.set_dr((addr << 1) + 1));
276
277            // Wait until address was sent
278            // Wait for the address to be acknowledged
279            while !Self::check_and_clear_error_flags(self.info)?.addr() {
280                timeout.check()?;
281            }
282
283            // Clear condition by reading SR2
284            let _ = self.info.regs.sr2().read();
285        }
286
287        // Receive bytes into buffer
288        for c in buffer {
289            *c = self.recv_byte(timeout)?;
290        }
291
292        // Prepare to send NACK then STOP after next byte
293        self.info.regs.cr1().modify(|reg| {
294            if frame.send_nack() {
295                reg.set_ack(false);
296            }
297            if frame.send_stop() {
298                reg.set_stop(true);
299            }
300        });
301
302        // Receive last byte
303        *last = self.recv_byte(timeout)?;
304
305        // Fallthrough is success
306        Ok(())
307    }
308
309    /// Blocking read.
310    pub fn blocking_read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Error> {
311        self.blocking_read_timeout(addr, read, self.timeout(), FrameOptions::FirstAndLastFrame)
312    }
313
314    /// Blocking write.
315    pub fn blocking_write(&mut self, addr: u8, write: &[u8]) -> Result<(), Error> {
316        self.write_bytes(addr, write, self.timeout(), FrameOptions::FirstAndLastFrame)?;
317
318        // Fallthrough is success
319        Ok(())
320    }
321
322    /// Blocking write, restart, read.
323    pub fn blocking_write_read(
324        &mut self,
325        addr: u8,
326        write: &[u8],
327        read: &mut [u8],
328    ) -> Result<(), Error> {
329        // Check empty read buffer before starting transaction. Otherwise, we would not generate the
330        // stop condition below.
331        if read.is_empty() {
332            return Err(Error::Overrun);
333        }
334
335        let timeout = self.timeout();
336
337        self.write_bytes(addr, write, timeout, FrameOptions::FirstFrame)?;
338        self.blocking_read_timeout(addr, read, timeout, FrameOptions::FirstAndLastFrame)?;
339
340        Ok(())
341    }
342
343    /// Blocking transaction with operations.
344    ///
345    /// Consecutive operations of same type are merged. See [transaction contract] for details.
346    ///
347    /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction
348    pub fn blocking_transaction(
349        &mut self,
350        addr: u8,
351        operations: &mut [Operation<'_>],
352    ) -> Result<(), Error> {
353        let timeout = self.timeout();
354
355        for (op, frame) in operation_frames(operations)? {
356            match op {
357                Operation::Read(read) => self.blocking_read_timeout(addr, read, timeout, frame)?,
358                Operation::Write(write) => self.write_bytes(addr, write, timeout, frame)?,
359            }
360        }
361
362        Ok(())
363    }
364
365    // Async
366    #[cfg(dma)]
367    #[inline] // pretty sure this should always be inlined
368    fn enable_interrupts(info: &'static Info) -> () {
369        info.regs.cr2().modify(|w| {
370            w.set_iterren(true);
371            w.set_itevten(true);
372        });
373    }
374}
375
376#[cfg(dma)] 
377impl<'d> I2c<'d, Async> {
378    async fn write_frame(
379        &mut self,
380        address: u8,
381        write: &[u8],
382        frame: FrameOptions,
383    ) -> Result<(), Error> {
384        self.info.regs.cr2().modify(|w| {
385            // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for
386            // reception.
387            w.set_itbufen(false);
388            // DMA mode can be enabled for transmission by setting the DMAEN bit in the I2C_CR2
389            // register.
390            w.set_dmaen(true);
391            // Sending NACK is not necessary (nor possible) for write transfer.
392            w.set_last(false);
393        });
394
395        // Sentinel to disable transfer when an error occurs or future is canceled.
396        // TODO: Generate STOP condition on cancel?
397        let on_drop = OnDrop::new(|| {
398            self.info.regs.cr2().modify(|w| {
399                w.set_dmaen(false);
400                w.set_iterren(false);
401                w.set_itevten(false);
402            })
403        });
404
405        if frame.send_start() {
406            // Send a START condition
407            self.info.regs.cr1().modify(|reg| {
408                reg.set_start(true);
409            });
410
411            // Wait until START condition was generated
412            poll_fn(|cx| {
413                self.state.waker.register(cx.waker());
414
415                match Self::check_and_clear_error_flags(self.info) {
416                    Err(e) => Poll::Ready(Err(e)),
417                    Ok(sr1) => {
418                        if sr1.start() {
419                            Poll::Ready(Ok(()))
420                        } else {
421                            // When pending, (re-)enable interrupts to wake us up.
422                            Self::enable_interrupts(self.info);
423                            Poll::Pending
424                        }
425                    }
426                }
427            })
428            .await?;
429
430            // Check if we were the ones to generate START
431            if self.info.regs.cr1().read().start() || !self.info.regs.sr2().read().msl() {
432                return Err(Error::Arbitration);
433            }
434
435            // Set up current address we're trying to talk to
436            self.info.regs.dr().write(|reg| reg.set_dr(address << 1));
437
438            // Wait for the address to be acknowledged
439            poll_fn(|cx| {
440                self.state.waker.register(cx.waker());
441
442                match Self::check_and_clear_error_flags(self.info) {
443                    Err(e) => Poll::Ready(Err(e)),
444                    Ok(sr1) => {
445                        if sr1.addr() {
446                            Poll::Ready(Ok(()))
447                        } else {
448                            // When pending, (re-)enable interrupts to wake us up.
449                            Self::enable_interrupts(self.info);
450                            Poll::Pending
451                        }
452                    }
453                }
454            })
455            .await?;
456
457            // Clear condition by reading SR2
458            self.info.regs.sr2().read();
459        }
460
461        let dma_transfer = unsafe {
462            // Set the I2C_DR register address in the DMA_SxPAR register. The data will be moved to
463            // this address from the memory after each TxE event.
464            let dst = self.info.regs.dr().as_ptr() as *mut u8;
465
466            self.tx_dma
467                .as_mut()
468                .unwrap()
469                .write(write, dst, Default::default())
470        };
471
472        // Wait for bytes to be sent, or an error to occur.
473        let poll_error = poll_fn(|cx| {
474            self.state.waker.register(cx.waker());
475
476            match Self::check_and_clear_error_flags(self.info) {
477                Err(e) => Poll::Ready(Err::<(), Error>(e)),
478                Ok(_) => {
479                    // When pending, (re-)enable interrupts to wake us up.
480                    Self::enable_interrupts(self.info);
481                    Poll::Pending
482                }
483            }
484        });
485
486        // Wait for either the DMA transfer to successfully finish, or an I2C error to occur.
487        match select(dma_transfer, poll_error).await {
488            Either::Second(Err(e)) => Err(e),
489            _ => Ok(()),
490        }?;
491
492        self.info.regs.cr2().modify(|w| {
493            w.set_dmaen(false);
494        });
495
496        if frame.send_stop() {
497            // The I2C transfer itself will take longer than the DMA transfer, so wait for that to finish too.
498
499            // 18.3.8 “Master transmitter: In the interrupt routine after the EOT interrupt, disable DMA
500            // requests then wait for a BTF event before programming the Stop condition.”
501            poll_fn(|cx| {
502                self.state.waker.register(cx.waker());
503
504                match Self::check_and_clear_error_flags(self.info) {
505                    Err(e) => Poll::Ready(Err(e)),
506                    Ok(sr1) => {
507                        if sr1.btf() {
508                            Poll::Ready(Ok(()))
509                        } else {
510                            // When pending, (re-)enable interrupts to wake us up.
511                            Self::enable_interrupts(self.info);
512                            Poll::Pending
513                        }
514                    }
515                }
516            })
517            .await?;
518
519            self.info.regs.cr1().modify(|w| {
520                w.set_stop(true);
521            });
522        }
523
524        drop(on_drop);
525
526        // Fallthrough is success
527        Ok(())
528    }
529
530    /// Write.
531    pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
532        self.write_frame(address, write, FrameOptions::FirstAndLastFrame)
533            .await?;
534
535        Ok(())
536    }
537
538    /// Read.
539    pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> {
540        self.read_frame(address, buffer, FrameOptions::FirstAndLastFrame)
541            .await?;
542
543        Ok(())
544    }
545
546    async fn read_frame(
547        &mut self,
548        address: u8,
549        buffer: &mut [u8],
550        frame: FrameOptions,
551    ) -> Result<(), Error> {
552        if buffer.is_empty() {
553            return Err(Error::Overrun);
554        }
555
556        // Some branches below depend on whether the buffer contains only a single byte.
557        let single_byte = buffer.len() == 1;
558
559        self.info.regs.cr2().modify(|w| {
560            // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for
561            // reception.
562            w.set_itbufen(false);
563            // DMA mode can be enabled for transmission by setting the DMAEN bit in the I2C_CR2
564            // register.
565            w.set_dmaen(true);
566            // If, in the I2C_CR2 register, the LAST bit is set, I2C automatically sends a NACK
567            // after the next byte following EOT_1. The user can generate a Stop condition in
568            // the DMA Transfer Complete interrupt routine if enabled.
569            w.set_last(frame.send_nack() && !single_byte);
570        });
571
572        // Sentinel to disable transfer when an error occurs or future is canceled.
573        // TODO: Generate STOP condition on cancel?
574        let on_drop = OnDrop::new(|| {
575            self.info.regs.cr2().modify(|w| {
576                w.set_dmaen(false);
577                w.set_iterren(false);
578                w.set_itevten(false);
579            })
580        });
581
582        if frame.send_start() {
583            // Send a START condition and set ACK bit
584            self.info.regs.cr1().modify(|reg| {
585                reg.set_start(true);
586                reg.set_ack(true);
587            });
588
589            // Wait until START condition was generated
590            poll_fn(|cx| {
591                self.state.waker.register(cx.waker());
592
593                match Self::check_and_clear_error_flags(self.info) {
594                    Err(e) => Poll::Ready(Err(e)),
595                    Ok(sr1) => {
596                        if sr1.start() {
597                            Poll::Ready(Ok(()))
598                        } else {
599                            // When pending, (re-)enable interrupts to wake us up.
600                            Self::enable_interrupts(self.info);
601                            Poll::Pending
602                        }
603                    }
604                }
605            })
606            .await?;
607
608            // Check if we were the ones to generate START
609            if self.info.regs.cr1().read().start() || !self.info.regs.sr2().read().msl() {
610                return Err(Error::Arbitration);
611            }
612
613            // Set up current address we're trying to talk to
614            self.info
615                .regs
616                .dr()
617                .write(|reg| reg.set_dr((address << 1) + 1));
618
619            // Wait for the address to be acknowledged
620            poll_fn(|cx| {
621                self.state.waker.register(cx.waker());
622
623                match Self::check_and_clear_error_flags(self.info) {
624                    Err(e) => Poll::Ready(Err(e)),
625                    Ok(sr1) => {
626                        if sr1.addr() {
627                            Poll::Ready(Ok(()))
628                        } else {
629                            // When pending, (re-)enable interrupts to wake us up.
630                            Self::enable_interrupts(self.info);
631                            Poll::Pending
632                        }
633                    }
634                }
635            })
636            .await?;
637
638            // 18.3.8: When a single byte must be received: the NACK must be programmed during EV6
639            // event, i.e. program ACK=0 when ADDR=1, before clearing ADDR flag.
640            if frame.send_nack() && single_byte {
641                self.info.regs.cr1().modify(|w| {
642                    w.set_ack(false);
643                });
644            }
645
646            // Clear condition by reading SR2
647            self.info.regs.sr2().read();
648        } else {
649            // Before starting reception of single byte (but without START condition, i.e. in case
650            // of continued frame), program NACK to emit at end of this byte.
651            if frame.send_nack() && single_byte {
652                self.info.regs.cr1().modify(|w| {
653                    w.set_ack(false);
654                });
655            }
656        }
657
658        // 18.3.8: When a single byte must be received: [snip] Then the user can program the STOP
659        // condition either after clearing ADDR flag, or in the DMA Transfer Complete interrupt
660        // routine.
661        if frame.send_stop() && single_byte {
662            self.info.regs.cr1().modify(|w| {
663                w.set_stop(true);
664            });
665        }
666
667        let dma_transfer = unsafe {
668            // Set the I2C_DR register address in the DMA_SxPAR register. The data will be moved
669            // from this address from the memory after each RxE event.
670            let src = self.info.regs.dr().as_ptr() as *mut u8;
671
672            self.rx_dma
673                .as_mut()
674                .unwrap()
675                .read(src, buffer, Default::default())
676        };
677
678        // Wait for bytes to be received, or an error to occur.
679        let poll_error = poll_fn(|cx| {
680            self.state.waker.register(cx.waker());
681
682            match Self::check_and_clear_error_flags(self.info) {
683                Err(e) => Poll::Ready(Err::<(), Error>(e)),
684                _ => {
685                    // When pending, (re-)enable interrupts to wake us up.
686                    Self::enable_interrupts(self.info);
687                    Poll::Pending
688                }
689            }
690        });
691
692        match select(dma_transfer, poll_error).await {
693            Either::Second(Err(e)) => Err(e),
694            _ => Ok(()),
695        }?;
696
697        self.info.regs.cr2().modify(|w| {
698            w.set_dmaen(false);
699        });
700
701        if frame.send_stop() && !single_byte {
702            self.info.regs.cr1().modify(|w| {
703                w.set_stop(true);
704            });
705        }
706
707        drop(on_drop);
708
709        // Fallthrough is success
710        Ok(())
711    }
712
713    /// Write, restart, read.
714    pub async fn write_read(
715        &mut self,
716        address: u8,
717        write: &[u8],
718        read: &mut [u8],
719    ) -> Result<(), Error> {
720        // Check empty read buffer before starting transaction. Otherwise, we would not generate the
721        // stop condition below.
722        if read.is_empty() {
723            return Err(Error::Overrun);
724        }
725
726        self.write_frame(address, write, FrameOptions::FirstFrame)
727            .await?;
728        self.read_frame(address, read, FrameOptions::FirstAndLastFrame)
729            .await
730    }
731
732    /// Transaction with operations.
733    ///
734    /// Consecutive operations of same type are merged. See [transaction contract] for details.
735    ///
736    /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction
737    pub async fn transaction(
738        &mut self,
739        addr: u8,
740        operations: &mut [Operation<'_>],
741    ) -> Result<(), Error> {
742        for (op, frame) in operation_frames(operations)? {
743            match op {
744                Operation::Read(read) => self.read_frame(addr, read, frame).await?,
745                Operation::Write(write) => self.write_frame(addr, write, frame).await?,
746            }
747        }
748
749        Ok(())
750    }
751}
752
753enum Mode {
754    Fast,
755    Standard,
756}
757
758impl Mode {
759    fn f_s(&self) -> i2c::vals::FS {
760        match self {
761            Mode::Fast => i2c::vals::FS::FAST,
762            Mode::Standard => i2c::vals::FS::STANDARD,
763        }
764    }
765}
766
767enum Duty {
768    Duty2_1,
769    Duty16_9,
770}
771
772impl Duty {
773    fn duty(&self) -> i2c::vals::Duty {
774        match self {
775            Duty::Duty2_1 => i2c::vals::Duty::DUTY2_1,
776            Duty::Duty16_9 => i2c::vals::Duty::DUTY16_9,
777        }
778    }
779}
780
781struct Timings {
782    freq: u8,
783    mode: Mode,
784    trise: u8,
785    ccr: u16,
786    duty: Duty,
787}
788
789impl Timings {
790    fn new(i2cclk: Hertz, speed: Hertz) -> Self {
791        // Calculate settings for I2C speed modes
792        let speed = speed.0;
793        let clock = i2cclk.0;
794        let freq = clock / 1_000_000;
795        assert!((2..=50).contains(&freq));
796
797        // Configure bus frequency into I2C peripheral
798        let trise = if speed <= 100_000 {
799            freq + 1
800        } else {
801            (freq * 300) / 1000 + 1
802        };
803
804        let mut ccr;
805        let duty;
806        let mode;
807
808        // I2C clock control calculation
809        if speed <= 100_000 {
810            duty = Duty::Duty2_1;
811            mode = Mode::Standard;
812            ccr = {
813                let ccr = clock / (speed * 2);
814                if ccr < 4 {
815                    4
816                } else {
817                    ccr
818                }
819            };
820        } else {
821            const DUTYCYCLE: u8 = 0;
822            mode = Mode::Fast;
823            if DUTYCYCLE == 0 {
824                duty = Duty::Duty2_1;
825                ccr = clock / (speed * 3);
826                ccr = if ccr < 1 { 1 } else { ccr };
827
828                // Set clock to fast mode with appropriate parameters for selected speed (2:1 duty cycle)
829            } else {
830                duty = Duty::Duty16_9;
831                ccr = clock / (speed * 25);
832                ccr = if ccr < 1 { 1 } else { ccr };
833
834                // Set clock to fast mode with appropriate parameters for selected speed (16:9 duty cycle)
835            }
836        }
837
838        Self {
839            freq: freq as u8,
840            trise: trise as u8,
841            ccr: ccr as u16,
842            duty,
843            mode,
844            //prescale: presc_reg,
845            //scll,
846            //sclh,
847            //sdadel,
848            //scldel,
849        }
850    }
851}
852
853impl<'d, M: PeriMode> SetConfig for I2c<'d, M> {
854    type Config = Hertz;
855    type ConfigError = ();
856    fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
857        let timings = Timings::new(self.kernel_clock, *config);
858        self.info.regs.cr2().modify(|reg| {
859            reg.set_freq(timings.freq);
860        });
861        self.info.regs.ccr().modify(|reg| {
862            reg.set_f_s(timings.mode.f_s());
863            reg.set_duty(timings.duty.duty());
864            reg.set_ccr(timings.ccr);
865        });
866        self.info.regs.trise().modify(|reg| {
867            reg.set_trise(timings.trise);
868        });
869
870        Ok(())
871    }
872}