1use core::fmt;
2use embedded_hal::i2c::{
3 self, ErrorType, I2c as HalI2c, NoAcknowledgeSource, Operation, SevenBitAddress,
4};
5use mik32_pac::i2c_0::RegisterBlock;
6use mik32_pac::{I2c0, I2c1, Peripherals};
7
8const I2C_ADDRESS_7BIT_MAX: u16 = 0x7f;
9const I2C_ADDRESS_10BIT_MAX: u16 = 0x03ff;
10const I2C_NBYTE_MAX: usize = 255;
11const TIMING_4BIT_MAX: u8 = 0x0f;
12const DEFAULT_TIMEOUT: u32 = 1_000;
13const DEFAULT_TIMING: Timing = Timing {
14 prescaler: 3,
15 scl_delay: 4,
16 sda_delay: 2,
17 scl_high: 39,
18 scl_low: 39,
19};
20const DEFAULT_CONFIG: Config = Config {
21 mode: Mode::Master,
22 address_primary: 0,
23 address_secondary: None,
24 general_call: false,
25 sbc_mode: false,
26 underflow_fill: 0xff,
27 timing: DEFAULT_TIMING,
28 timeout: DEFAULT_TIMEOUT,
29};
30
31#[derive(Debug, Copy, Clone, Eq, PartialEq)]
37pub struct Timing {
38 pub prescaler: u8,
39 pub scl_delay: u8,
40 pub sda_delay: u8,
41 pub scl_high: u8,
42 pub scl_low: u8,
43}
44
45impl Timing {
46 pub const fn default_100khz_32mhz() -> Self {
47 DEFAULT_TIMING
48 }
49}
50
51impl Default for Timing {
52 fn default() -> Self {
53 DEFAULT_TIMING
54 }
55}
56
57#[derive(Debug, Copy, Clone, Eq, PartialEq)]
58pub enum Mode {
59 Master,
60 Slave,
61}
62
63#[derive(Debug, Copy, Clone, Eq, PartialEq)]
64#[repr(u8)]
65pub enum SecondaryAddressMask {
66 Exact = 0,
67 IgnoreOneBit = 1,
68 IgnoreTwoBits = 2,
69 IgnoreThreeBits = 3,
70 IgnoreFourBits = 4,
71 IgnoreFiveBits = 5,
72 IgnoreSixBits = 6,
73 AllNonReserved = 7,
74}
75
76#[derive(Debug, Copy, Clone, Eq, PartialEq)]
77pub struct SecondaryAddress {
78 pub address: u8,
79 pub mask: SecondaryAddressMask,
80}
81
82impl SecondaryAddress {
83 pub const fn new(address: u8, mask: SecondaryAddressMask) -> Self {
84 Self { address, mask }
85 }
86}
87
88impl Default for Mode {
89 fn default() -> Self {
90 Self::Master
91 }
92}
93
94#[derive(Debug, Copy, Clone, Eq, PartialEq)]
95pub struct Config {
96 pub mode: Mode,
97 pub address_primary: u16,
98 pub address_secondary: Option<SecondaryAddress>,
99 pub general_call: bool,
100 pub sbc_mode: bool,
101 pub underflow_fill: u8,
103 pub timing: Timing,
104 pub timeout: u32,
105}
106
107impl Config {
108 pub const fn default() -> Self {
109 DEFAULT_CONFIG
110 }
111
112 pub const fn as_master(mut self) -> Self {
113 self.mode = Mode::Master;
114 self
115 }
116
117 pub const fn as_slave(mut self) -> Self {
118 self.mode = Mode::Slave;
119 self
120 }
121
122 pub const fn timeout(mut self, timeout: u32) -> Self {
123 self.timeout = timeout;
124 self
125 }
126
127 pub const fn timing(mut self, timing: Timing) -> Self {
128 self.timing = timing;
129 self
130 }
131
132 pub const fn primary_address(mut self, address: u16) -> Self {
133 self.address_primary = address;
134 self
135 }
136
137 pub const fn secondary_address(mut self, address: SecondaryAddress) -> Self {
138 self.address_secondary = Some(address);
139 self
140 }
141
142 pub const fn without_secondary_address(mut self) -> Self {
143 self.address_secondary = None;
144 self
145 }
146
147 pub const fn general_call(mut self, enabled: bool) -> Self {
148 self.general_call = enabled;
149 self
150 }
151
152 pub const fn underflow_fill(mut self, byte: u8) -> Self {
153 self.underflow_fill = byte;
154 self
155 }
156
157 pub const fn validate(&self) -> Result<(), ConfigError> {
158 if self.timeout == 0 {
159 return Err(ConfigError::ZeroTimeout);
160 }
161 if self.timing.prescaler > TIMING_4BIT_MAX {
162 return Err(ConfigError::TimingPrescalerOutOfRange);
163 }
164 if self.timing.scl_delay > TIMING_4BIT_MAX {
165 return Err(ConfigError::TimingSclDelayOutOfRange);
166 }
167 if self.timing.sda_delay > TIMING_4BIT_MAX {
168 return Err(ConfigError::TimingSdaDelayOutOfRange);
169 }
170 match self.mode {
171 Mode::Master => {}
172 Mode::Slave => {
173 if self.address_primary > I2C_ADDRESS_10BIT_MAX {
174 return Err(ConfigError::PrimaryAddressOutOfRange);
175 }
176 if self.address_primary > I2C_ADDRESS_7BIT_MAX {
177 return Err(ConfigError::SlaveTenBitAddressUnsupported);
178 }
179 if let Some(address) = self.address_secondary {
180 if address.address as u16 > I2C_ADDRESS_7BIT_MAX {
181 return Err(ConfigError::SecondaryAddressOutOfRange);
182 }
183 }
184 if self.sbc_mode {
185 return Err(ConfigError::SlaveSbcUnsupported);
186 }
187 }
188 }
189
190 Ok(())
191 }
192}
193
194impl Default for Config {
195 fn default() -> Self {
196 DEFAULT_CONFIG
197 }
198}
199
200#[derive(Debug, Copy, Clone, Eq, PartialEq)]
201pub enum ConfigError {
202 ZeroTimeout,
203 TimingPrescalerOutOfRange,
204 TimingSclDelayOutOfRange,
205 TimingSdaDelayOutOfRange,
206 PrimaryAddressOutOfRange,
207 SlaveTenBitAddressUnsupported,
208 SecondaryAddressOutOfRange,
209 SlaveSbcUnsupported,
210}
211
212pub struct InitError<I2C> {
213 pub i2c: I2C,
214 pub error: ConfigError,
215}
216
217impl<I2C> InitError<I2C> {
218 pub fn into_parts(self) -> (I2C, ConfigError) {
219 (self.i2c, self.error)
220 }
221}
222
223impl<I2C> fmt::Debug for InitError<I2C> {
224 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
225 f.debug_struct("InitError")
226 .field("error", &self.error)
227 .finish_non_exhaustive()
228 }
229}
230
231#[derive(Debug, Copy, Clone, Eq, PartialEq)]
232pub enum Error {
233 BusError,
234 ArbitrationLoss,
235 Nack,
236 Overrun,
237 Timeout,
238 InvalidMode,
239 InvalidAddress,
240 InvalidDirection,
241 SlaveTimeout(SlaveTimeout),
242}
243
244impl i2c::Error for Error {
245 fn kind(&self) -> i2c::ErrorKind {
246 match *self {
247 Error::BusError => i2c::ErrorKind::Bus,
248 Error::ArbitrationLoss => i2c::ErrorKind::ArbitrationLoss,
249 Error::Nack => i2c::ErrorKind::NoAcknowledge(NoAcknowledgeSource::Unknown),
250 Error::Overrun => i2c::ErrorKind::Overrun,
251 Error::Timeout
252 | Error::InvalidMode
253 | Error::InvalidAddress
254 | Error::InvalidDirection
255 | Error::SlaveTimeout(_) => i2c::ErrorKind::Other,
256 }
257 }
258}
259
260#[derive(Debug, Copy, Clone, Eq, PartialEq)]
261pub enum SlaveDirection {
262 Receive,
264 Transmit,
266}
267
268#[derive(Debug, Copy, Clone, Eq, PartialEq)]
269pub struct SlaveTimeout {
270 pub direction: SlaveDirection,
271 pub count: usize,
272 pub buffer_status: SlaveBufferStatus,
273}
274
275#[derive(Debug, Copy, Clone, Eq, PartialEq)]
276pub enum SlaveAcknowledge {
277 Ack,
278 Nack,
279}
280
281#[derive(Debug, Copy, Clone, Eq, PartialEq)]
282pub enum AddressMatchSource {
283 Primary,
284 Secondary,
285 GeneralCall,
286}
287
288#[derive(Debug, Copy, Clone, Eq, PartialEq)]
289pub struct AddressMatch {
290 pub address: u8,
291 pub source: AddressMatchSource,
292 pub direction: SlaveDirection,
293}
294
295#[derive(Debug, Copy, Clone, Eq, PartialEq)]
296pub enum SlaveTransferEnd {
297 Stop,
298 Nack,
299 RepeatedStart,
300}
301
302#[derive(Debug, Copy, Clone, Eq, PartialEq)]
303pub enum SlaveBufferStatus {
304 Complete,
305 Overflow,
306 Underflow,
307}
308
309#[derive(Debug, Copy, Clone, Eq, PartialEq)]
310pub struct SlaveTransfer {
311 pub count: usize,
312 pub end: SlaveTransferEnd,
313 pub buffer_status: SlaveBufferStatus,
314}
315
316#[derive(Debug)]
317pub struct I2c<I2C: Instance> {
318 i2c: I2C,
319 config: Config,
320}
321
322pub type I2c0Bus = I2c<I2c0>;
323pub type I2c1Bus = I2c<I2c1>;
324pub type I2CImpl = I2c0Bus;
325
326mod sealed {
327 pub trait Sealed {}
328
329 impl Sealed for mik32_pac::I2c0 {}
330 impl Sealed for mik32_pac::I2c1 {}
331}
332
333pub trait Instance: sealed::Sealed {
334 fn ptr() -> *const RegisterBlock;
335 fn enable_clock();
336}
337
338impl Instance for I2c0 {
339 #[inline(always)]
340 fn ptr() -> *const RegisterBlock {
341 I2c0::ptr()
342 }
343
344 #[inline(always)]
345 fn enable_clock() {
346 let p = unsafe { Peripherals::steal() };
347 p.pm.clk_apb_p_set().modify(|_, w| w.i2c_0().enable());
348 }
349}
350
351impl Instance for I2c1 {
352 #[inline(always)]
353 fn ptr() -> *const RegisterBlock {
354 I2c1::ptr() as *const RegisterBlock
355 }
356
357 #[inline(always)]
358 fn enable_clock() {
359 let p = unsafe { Peripherals::steal() };
360 p.pm.clk_apb_p_set().modify(|_, w| w.i2c_1().enable());
361 }
362}
363
364impl<I2C: Instance> I2c<I2C> {
365 pub fn new(i2c: I2C, config: Config) -> Result<Self, InitError<I2C>> {
366 if let Err(error) = config.validate() {
367 return Err(InitError { i2c, error });
368 }
369 I2C::enable_clock();
370
371 let regs = regs::<I2C>();
372
373 Self::disable(regs);
374 Self::configure_filters(regs);
375 Self::configure_timing(regs, config.timing);
376 Self::configure_stretching(regs);
377 Self::enable(regs);
378
379 if config.mode == Mode::Slave {
380 Self::configure_slave(regs, config);
381 }
382
383 Ok(Self { i2c, config })
384 }
385
386 pub fn free(self) -> I2C {
387 self.i2c
388 }
389
390 pub fn set_slave_acknowledge(&mut self, acknowledge: SlaveAcknowledge) -> Result<(), Error> {
396 if self.config.mode != Mode::Slave {
397 return Err(Error::InvalidMode);
398 }
399
400 let regs = regs::<I2C>();
401 regs.cr2().modify(|_, w| match acknowledge {
402 SlaveAcknowledge::Ack => w.nack().clear_bit(),
403 SlaveAcknowledge::Nack => w.nack().set_bit(),
404 });
405 Ok(())
406 }
407
408 pub fn slave_ack(&mut self) -> Result<(), Error> {
409 self.set_slave_acknowledge(SlaveAcknowledge::Ack)
410 }
411
412 pub fn slave_nack(&mut self) -> Result<(), Error> {
413 self.set_slave_acknowledge(SlaveAcknowledge::Nack)
414 }
415
416 pub fn wait_address(&mut self) -> Result<AddressMatch, Error> {
422 if self.config.mode != Mode::Slave {
423 return Err(Error::InvalidMode);
424 }
425
426 let regs = regs::<I2C>();
427
428 for _ in 0..self.config.timeout {
429 Self::check_slave_bus_errors(regs)?;
430 let isr = regs.isr().read();
431
432 if isr.addr().bit_is_set() {
433 let address = isr.addcode().bits();
434 let direction = if isr.dir().bit_is_set() {
435 SlaveDirection::Transmit
436 } else {
437 SlaveDirection::Receive
438 };
439
440 return Ok(AddressMatch {
441 address,
442 source: self.address_match_source(address),
443 direction,
444 });
445 }
446
447 if isr.stopf().bit_is_set() || isr.nackf().bit_is_set() {
448 Self::clear_slave_end_flags(regs);
449 }
450 }
451
452 Err(Error::Timeout)
453 }
454
455 fn address_match_source(&self, address: u8) -> AddressMatchSource {
456 if self.config.general_call && address == 0 {
457 AddressMatchSource::GeneralCall
458 } else if self.config.address_primary as u8 == address {
459 AddressMatchSource::Primary
460 } else {
461 AddressMatchSource::Secondary
465 }
466 }
467
468 pub fn slave_receive(&mut self, buffer: &mut [u8]) -> Result<SlaveTransfer, Error> {
472 self.ensure_slave_direction(SlaveDirection::Receive)?;
473 let regs = regs::<I2C>();
474 let result = self.slave_receive_inner(regs, buffer);
475
476 if result.is_err() {
477 self.recover_slave(regs);
478 }
479
480 result
481 }
482
483 pub fn slave_transmit(&mut self, buffer: &[u8]) -> Result<SlaveTransfer, Error> {
488 self.ensure_slave_direction(SlaveDirection::Transmit)?;
489 let regs = regs::<I2C>();
490 let result = self.slave_transmit_inner(regs, buffer);
491
492 if result.is_err() {
493 self.recover_slave(regs);
494 }
495
496 result
497 }
498
499 fn ensure_slave_direction(&self, expected: SlaveDirection) -> Result<(), Error> {
500 if self.config.mode != Mode::Slave {
501 return Err(Error::InvalidMode);
502 }
503
504 let isr = regs::<I2C>().isr().read();
505 if isr.addr().bit_is_clear() {
506 return Err(Error::InvalidDirection);
507 }
508
509 let actual = if isr.dir().bit_is_set() {
510 SlaveDirection::Transmit
511 } else {
512 SlaveDirection::Receive
513 };
514
515 if actual != expected {
516 return Err(Error::InvalidDirection);
517 }
518
519 Ok(())
520 }
521
522 fn slave_receive_inner(
523 &self,
524 i2c: &RegisterBlock,
525 buffer: &mut [u8],
526 ) -> Result<SlaveTransfer, Error> {
527 Self::clear_slave_end_flags(i2c);
528 Self::clear_address(i2c);
529
530 let mut count = 0;
531 let mut overflow = false;
532 let mut remaining = self.config.timeout;
533
534 loop {
535 if remaining == 0 {
536 return Err(Error::SlaveTimeout(SlaveTimeout {
537 direction: SlaveDirection::Receive,
538 count,
539 buffer_status: if overflow {
540 SlaveBufferStatus::Overflow
541 } else {
542 SlaveBufferStatus::Complete
543 },
544 }));
545 }
546 remaining -= 1;
547
548 Self::check_slave_bus_errors(i2c)?;
549 let isr = i2c.isr().read();
550
551 if isr.rxne().bit_is_set() {
552 let byte = Self::read_byte(i2c);
553 if let Some(slot) = buffer.get_mut(count) {
554 *slot = byte;
555 count += 1;
556 } else {
557 overflow = true;
558 i2c.cr2().modify(|_, w| w.nack().set_bit());
559 }
560 remaining = self.config.timeout;
561 continue;
562 }
563
564 if isr.addr().bit_is_set() {
565 return Ok(SlaveTransfer {
566 count,
567 end: SlaveTransferEnd::RepeatedStart,
568 buffer_status: if overflow {
569 SlaveBufferStatus::Overflow
570 } else {
571 SlaveBufferStatus::Complete
572 },
573 });
574 }
575
576 if isr.stopf().bit_is_set() {
577 Self::finish_slave_transfer(i2c);
578 return Ok(SlaveTransfer {
579 count,
580 end: SlaveTransferEnd::Stop,
581 buffer_status: if overflow {
582 SlaveBufferStatus::Overflow
583 } else {
584 SlaveBufferStatus::Complete
585 },
586 });
587 }
588 }
589 }
590
591 fn slave_transmit_inner(
592 &self,
593 i2c: &RegisterBlock,
594 buffer: &[u8],
595 ) -> Result<SlaveTransfer, Error> {
596 Self::clear_slave_end_flags(i2c);
597 Self::flush_txdr(i2c);
598 Self::clear_address(i2c);
599
600 let mut count = 0;
601 let mut underflow = false;
602 let mut saw_nack = false;
603 let mut remaining = self.config.timeout;
604
605 if let Some(byte) = buffer.get(count) {
606 Self::write_byte(i2c, *byte);
607 count += 1;
608 } else {
609 Self::write_byte(i2c, self.config.underflow_fill);
610 underflow = true;
611 }
612
613 loop {
614 if remaining == 0 {
615 return Err(Error::SlaveTimeout(SlaveTimeout {
616 direction: SlaveDirection::Transmit,
617 count,
618 buffer_status: if underflow {
619 SlaveBufferStatus::Underflow
620 } else {
621 SlaveBufferStatus::Complete
622 },
623 }));
624 }
625 remaining -= 1;
626
627 Self::check_slave_bus_errors(i2c)?;
628 let isr = i2c.isr().read();
629
630 if isr.nackf().bit_is_set() {
631 i2c.icr().write(|w| w.nackcf().set_bit());
632 saw_nack = true;
633 remaining = self.config.timeout;
634 }
635
636 if isr.addr().bit_is_set() {
637 Self::flush_txdr(i2c);
638 return Ok(SlaveTransfer {
639 count,
640 end: SlaveTransferEnd::RepeatedStart,
641 buffer_status: if underflow {
642 SlaveBufferStatus::Underflow
643 } else {
644 SlaveBufferStatus::Complete
645 },
646 });
647 }
648
649 if isr.stopf().bit_is_set() {
650 Self::finish_slave_transfer(i2c);
651 return Ok(SlaveTransfer {
652 count,
653 end: if saw_nack {
654 SlaveTransferEnd::Nack
655 } else {
656 SlaveTransferEnd::Stop
657 },
658 buffer_status: if underflow {
659 SlaveBufferStatus::Underflow
660 } else {
661 SlaveBufferStatus::Complete
662 },
663 });
664 }
665
666 if saw_nack && isr.busy().bit_is_clear() {
667 Self::finish_slave_transfer(i2c);
668 return Ok(SlaveTransfer {
669 count,
670 end: SlaveTransferEnd::Nack,
671 buffer_status: if underflow {
672 SlaveBufferStatus::Underflow
673 } else {
674 SlaveBufferStatus::Complete
675 },
676 });
677 }
678
679 if !saw_nack && isr.txis().bit_is_set() {
680 if let Some(byte) = buffer.get(count) {
681 Self::write_byte(i2c, *byte);
682 count += 1;
683 } else {
684 Self::write_byte(i2c, self.config.underflow_fill);
685 underflow = true;
686 }
687 remaining = self.config.timeout;
688 }
689 }
690 }
691
692 fn disable(i2c: &RegisterBlock) {
693 i2c.cr1().modify(|_, w| w.pe().clear_bit());
694 }
695
696 fn enable(i2c: &RegisterBlock) {
697 i2c.cr1().modify(|_, w| w.pe().set_bit());
698 }
699
700 fn configure_filters(i2c: &RegisterBlock) {
701 i2c.cr1()
702 .write(|w| unsafe { w.pe().clear_bit().anfoff().clear_bit().dnf().bits(0) });
703 }
704
705 fn configure_timing(i2c: &RegisterBlock, timing: Timing) {
706 i2c.timingr().write(|w| unsafe {
707 w.presc()
708 .bits(timing.prescaler)
709 .scldel()
710 .bits(timing.scl_delay)
711 .sdadel()
712 .bits(timing.sda_delay)
713 .sclh()
714 .bits(timing.scl_high)
715 .scll()
716 .bits(timing.scl_low)
717 });
718 }
719
720 fn configure_stretching(i2c: &RegisterBlock) {
721 i2c.cr1().modify(|_, w| w.nostretch().clear_bit());
722 }
723
724 fn configure_slave(i2c: &RegisterBlock, config: Config) {
725 Self::configure_primary_address(i2c, config.address_primary);
726 Self::configure_secondary_address(i2c, config.address_secondary);
727
728 if config.general_call {
729 i2c.cr1().modify(|_, w| w.gcen().set_bit());
730 } else {
731 i2c.cr1().modify(|_, w| w.gcen().clear_bit());
732 }
733
734 if config.sbc_mode {
735 i2c.cr1().modify(|_, w| w.sbc().set_bit());
736 } else {
737 i2c.cr1().modify(|_, w| w.sbc().clear_bit());
738 }
739 }
740
741 fn configure_primary_address(i2c: &RegisterBlock, address: u16) {
742 i2c.oar1().write(|w| w.oa1en().clear_bit());
743
744 if address <= I2C_ADDRESS_7BIT_MAX {
745 i2c.oar1()
746 .modify(|_, w| unsafe { w.oa1mode()._7bit().oa1_7bit().bits(address as u8) });
747 } else {
748 i2c.oar1()
749 .modify(|_, w| unsafe { w.oa1mode()._10bit().oa1_10bit().bits(address) });
750 }
751
752 i2c.oar1().modify(|_, w| w.oa1en().set_bit());
753 }
754
755 fn configure_secondary_address(i2c: &RegisterBlock, address: Option<SecondaryAddress>) {
756 i2c.oar2().write(|w| w.oa2en().nack());
757
758 if let Some(address) = address {
759 i2c.oar2().write(|w| {
760 let w = unsafe { w.oa2().bits(address.address) };
761 let w = match address.mask {
762 SecondaryAddressMask::Exact => w.oa2msk().no_mask(),
763 SecondaryAddressMask::IgnoreOneBit => w.oa2msk()._1_1_masked(),
764 SecondaryAddressMask::IgnoreTwoBits => w.oa2msk()._2_1_masked(),
765 SecondaryAddressMask::IgnoreThreeBits => w.oa2msk()._3_1_masked(),
766 SecondaryAddressMask::IgnoreFourBits => w.oa2msk()._4_1_masked(),
767 SecondaryAddressMask::IgnoreFiveBits => w.oa2msk()._5_1_masked(),
768 SecondaryAddressMask::IgnoreSixBits => w.oa2msk()._6_1_masked(),
769 SecondaryAddressMask::AllNonReserved => w.oa2msk()._7_1_masked(),
770 };
771 w.oa2en().ack()
772 });
773 }
774 }
775}
776
777impl<I2C: Instance> ErrorType for I2c<I2C> {
778 type Error = Error;
779}
780
781impl<I2C: Instance> HalI2c<SevenBitAddress> for I2c<I2C> {
782 fn transaction(
783 &mut self,
784 address: SevenBitAddress,
785 operations: &mut [Operation<'_>],
786 ) -> Result<(), Self::Error> {
787 if self.config.mode != Mode::Master {
788 return Err(Error::InvalidMode);
789 }
790 if address as u16 > I2C_ADDRESS_7BIT_MAX {
791 return Err(Error::InvalidAddress);
792 }
793
794 let regs = regs::<I2C>();
795 Self::clear_flags(regs);
796 if let Err(error) = self.wait_bus_idle(regs) {
797 Self::flush_txdr(regs);
798 Self::clear_flags(regs);
799 return Err(error);
800 }
801
802 let result = (|| {
803 let mut previous_direction = None;
804
805 for index in 0..operations.len() {
806 let direction = match &operations[index] {
807 Operation::Read(_) => Direction::Read,
808 Operation::Write(_) => Direction::Write,
809 };
810 let next_direction = operations.get(index + 1).map(|operation| match operation {
811 Operation::Read(_) => Direction::Read,
812 Operation::Write(_) => Direction::Write,
813 });
814 let send_start = previous_direction != Some(direction);
815 let ends_direction = next_direction != Some(direction);
816 let send_stop = next_direction.is_none();
817
818 match &mut operations[index] {
819 Operation::Read(buffer) => self.transaction_read(
820 address,
821 buffer,
822 send_start,
823 ends_direction,
824 send_stop,
825 )?,
826 Operation::Write(bytes) => self.transaction_write(
827 address,
828 bytes,
829 send_start,
830 ends_direction,
831 send_stop,
832 )?,
833 }
834
835 previous_direction = Some(direction);
836 }
837
838 Ok(())
839 })();
840
841 if let Err(error) = result {
842 self.recover(regs, error);
843 }
844
845 result
846 }
847}
848
849#[derive(Debug, Copy, Clone, Eq, PartialEq)]
850enum Direction {
851 Read,
852 Write,
853}
854
855impl<I2C: Instance> I2c<I2C> {
856 fn transaction_read(
857 &mut self,
858 address: SevenBitAddress,
859 buffer: &mut [u8],
860 send_start: bool,
861 ends_direction: bool,
862 send_stop: bool,
863 ) -> Result<(), Error> {
864 let regs = regs::<I2C>();
865
866 if buffer.is_empty() {
867 return self.transaction_empty(
868 regs,
869 address,
870 Direction::Read,
871 send_start,
872 ends_direction,
873 send_stop,
874 );
875 }
876
877 let buffer_start = buffer.as_ptr();
878 let mut chunks = buffer.chunks_mut(I2C_NBYTE_MAX).peekable();
879
880 while let Some(chunk) = chunks.next() {
881 let is_first_chunk = chunk.as_ptr() == buffer_start;
882 let is_last_chunk = chunks.peek().is_none();
883 let reload = !is_last_chunk || !ends_direction;
884 let autoend = is_last_chunk && send_stop;
885
886 Self::configure_transfer_size(regs, chunk.len(), reload, autoend);
887
888 if is_first_chunk && send_start {
889 Self::configure_address(regs, address);
890 Self::start(regs, Direction::Read);
891 }
892
893 for byte in chunk {
894 self.wait_rxne(regs)?;
895 *byte = Self::read_byte(regs);
896 }
897
898 self.wait_chunk_end(regs, reload, autoend)?;
899 }
900
901 Ok(())
902 }
903
904 fn transaction_write(
905 &mut self,
906 address: SevenBitAddress,
907 bytes: &[u8],
908 send_start: bool,
909 ends_direction: bool,
910 send_stop: bool,
911 ) -> Result<(), Error> {
912 let regs = regs::<I2C>();
913
914 if bytes.is_empty() {
915 return self.transaction_empty(
916 regs,
917 address,
918 Direction::Write,
919 send_start,
920 ends_direction,
921 send_stop,
922 );
923 }
924
925 let mut chunks = bytes.chunks(I2C_NBYTE_MAX).peekable();
926
927 while let Some(chunk) = chunks.next() {
928 let is_first_chunk = chunk.as_ptr() == bytes.as_ptr();
929 let is_last_chunk = chunks.peek().is_none();
930 let reload = !is_last_chunk || !ends_direction;
931 let autoend = is_last_chunk && send_stop;
932
933 Self::configure_transfer_size(regs, chunk.len(), reload, autoend);
934
935 if is_first_chunk && send_start {
936 Self::configure_address(regs, address);
937 Self::start(regs, Direction::Write);
938 }
939
940 for byte in chunk {
941 self.wait_txis(regs)?;
942 Self::write_byte(regs, *byte);
943 }
944
945 self.wait_chunk_end(regs, reload, autoend)?;
946 }
947
948 Ok(())
949 }
950
951 fn transaction_empty(
952 &self,
953 i2c: &RegisterBlock,
954 address: SevenBitAddress,
955 direction: Direction,
956 send_start: bool,
957 ends_direction: bool,
958 send_stop: bool,
959 ) -> Result<(), Error> {
960 let reload = !ends_direction;
961 Self::configure_transfer_size(i2c, 0, reload, send_stop);
962
963 if send_start {
964 Self::configure_address(i2c, address);
965 Self::start(i2c, direction);
966 }
967
968 self.wait_chunk_end(i2c, reload, send_stop)
969 }
970
971 fn configure_transfer_size(i2c: &RegisterBlock, len: usize, reload: bool, autoend: bool) {
972 i2c.cr2().modify(|_, w| unsafe {
973 w.nbytes()
974 .bits(len as u8)
975 .reload()
976 .bit(reload)
977 .autoend()
978 .bit(autoend)
979 });
980 }
981
982 fn configure_address(i2c: &RegisterBlock, address: SevenBitAddress) {
983 i2c.cr2().modify(|_, w| unsafe {
984 w.add10()
985 .clear_bit()
986 .sadd_7bit()
987 .bits(address & I2C_ADDRESS_7BIT_MAX as u8)
988 });
989 }
990
991 fn start(i2c: &RegisterBlock, direction: Direction) {
992 i2c.cr2().modify(|_, w| {
993 let w = match direction {
994 Direction::Read => w.rd_wrn().set_bit(),
995 Direction::Write => w.rd_wrn().clear_bit(),
996 };
997 w.start().set_bit()
998 });
999 }
1000
1001 fn write_byte(i2c: &RegisterBlock, byte: u8) {
1002 i2c.txdr().write(|w| unsafe { w.txdata().bits(byte) });
1003 }
1004
1005 fn read_byte(i2c: &RegisterBlock) -> u8 {
1006 i2c.rxdr().read().txdata().bits()
1007 }
1008
1009 fn wait_chunk_end(
1010 &self,
1011 i2c: &RegisterBlock,
1012 reload: bool,
1013 autoend: bool,
1014 ) -> Result<(), Error> {
1015 if reload {
1016 self.wait_tcr(i2c)
1017 } else if autoend {
1018 self.wait_stop(i2c)
1019 } else {
1020 self.wait_tc(i2c)
1021 }
1022 }
1023
1024 fn check_errors(i2c: &RegisterBlock) -> Result<(), Error> {
1025 let isr = i2c.isr().read();
1026
1027 if isr.nackf().bit_is_set() {
1028 i2c.icr().write(|w| w.nackcf().set_bit());
1029 return Err(Error::Nack);
1030 }
1031
1032 Self::check_slave_bus_errors(i2c)
1033 }
1034
1035 fn check_slave_bus_errors(i2c: &RegisterBlock) -> Result<(), Error> {
1036 let isr = i2c.isr().read();
1037
1038 if isr.berr().bit_is_set() {
1039 i2c.icr().write(|w| w.berrcf().set_bit());
1040 return Err(Error::BusError);
1041 }
1042 if isr.arlo().bit_is_set() {
1043 i2c.icr().write(|w| w.arlocf().set_bit());
1044 return Err(Error::ArbitrationLoss);
1045 }
1046 if isr.ovr().bit_is_set() {
1047 i2c.icr().write(|w| w.ovrcf().set_bit());
1048 return Err(Error::Overrun);
1049 }
1050
1051 Ok(())
1052 }
1053
1054 fn clear_address(i2c: &RegisterBlock) {
1055 i2c.icr().write(|w| w.addrcf().set_bit());
1056 }
1057
1058 fn clear_slave_end_flags(i2c: &RegisterBlock) {
1059 i2c.icr().write(|w| w.nackcf().set_bit().stopcf().set_bit());
1060 }
1061
1062 fn finish_slave_transfer(i2c: &RegisterBlock) {
1063 Self::flush_txdr(i2c);
1064 Self::clear_slave_end_flags(i2c);
1065 i2c.cr2().modify(|_, w| w.nack().clear_bit());
1066 }
1067
1068 fn clear_flags(i2c: &RegisterBlock) {
1069 i2c.icr().write(|w| {
1070 w.nackcf()
1071 .set_bit()
1072 .stopcf()
1073 .set_bit()
1074 .berrcf()
1075 .set_bit()
1076 .arlocf()
1077 .set_bit()
1078 .ovrcf()
1079 .set_bit()
1080 });
1081 }
1082
1083 fn wait_until(
1084 &self,
1085 i2c: &RegisterBlock,
1086 ready: impl Fn(&RegisterBlock) -> bool,
1087 ) -> Result<(), Error> {
1088 for _ in 0..self.config.timeout {
1089 Self::check_errors(i2c)?;
1090 if ready(i2c) {
1091 return Ok(());
1092 }
1093 }
1094
1095 Err(Error::Timeout)
1096 }
1097
1098 fn wait_txis(&self, i2c: &RegisterBlock) -> Result<(), Error> {
1111 self.wait_until(i2c, |i2c| i2c.isr().read().txis().bit_is_set())
1112 }
1113
1114 fn wait_rxne(&self, i2c: &RegisterBlock) -> Result<(), Error> {
1115 self.wait_until(i2c, |i2c| i2c.isr().read().rxne().bit_is_set())
1116 }
1117
1118 fn wait_bus_idle(&self, i2c: &RegisterBlock) -> Result<(), Error> {
1126 for _ in 0..self.config.timeout {
1127 if i2c.isr().read().busy().bit_is_clear() {
1128 return Ok(());
1129 }
1130 }
1131
1132 Err(Error::Timeout)
1133 }
1134
1135 fn wait_tc(&self, i2c: &RegisterBlock) -> Result<(), Error> {
1144 self.wait_until(i2c, |i2c| i2c.isr().read().tc().bit_is_set())
1145 }
1146
1147 fn wait_tcr(&self, i2c: &RegisterBlock) -> Result<(), Error> {
1148 self.wait_until(i2c, |i2c| i2c.isr().read().tcr().bit_is_set())
1149 }
1150
1151 fn wait_stop(&self, i2c: &RegisterBlock) -> Result<(), Error> {
1152 self.wait_until(i2c, |i2c| i2c.isr().read().stopf().bit_is_set())?;
1153 Self::flush_txdr(i2c);
1154 i2c.icr().write(|w| w.stopcf().set_bit());
1155 Ok(())
1156 }
1157
1158 fn flush_txdr(i2c: &RegisterBlock) {
1159 i2c.isr().write(|w| unsafe { w.bits(1) });
1162 }
1163
1164 fn recover(&self, i2c: &RegisterBlock, error: Error) {
1165 Self::flush_txdr(i2c);
1166
1167 if error == Error::ArbitrationLoss {
1170 Self::clear_flags(i2c);
1171 return;
1172 }
1173
1174 if i2c.isr().read().busy().bit_is_set() {
1175 i2c.cr2().modify(|_, w| w.stop().set_bit());
1176
1177 for _ in 0..self.config.timeout {
1178 if i2c.isr().read().stopf().bit_is_set() || i2c.isr().read().busy().bit_is_clear() {
1179 break;
1180 }
1181 }
1182 }
1183
1184 Self::flush_txdr(i2c);
1185 Self::clear_flags(i2c);
1186
1187 if i2c.isr().read().busy().bit_is_set() {
1188 Self::disable(i2c);
1189 Self::enable(i2c);
1190 }
1191 }
1192
1193 fn recover_slave(&self, i2c: &RegisterBlock) {
1194 Self::flush_txdr(i2c);
1195 i2c.cr2().modify(|_, w| w.nack().clear_bit());
1196 if i2c.isr().read().addr().bit_is_set() {
1197 Self::clear_address(i2c);
1198 }
1199 Self::clear_flags(i2c);
1200 Self::disable(i2c);
1201 Self::enable(i2c);
1202 }
1203}
1204
1205fn regs<I2C: Instance>() -> &'static RegisterBlock {
1206 unsafe { &*I2C::ptr() }
1207}