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}