Skip to main content

hal_mik32/
i2c.rs

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/// Raw values for the I2C `TIMINGR` register.
32///
33/// The default values configure approximately 100 kHz SCL when I2CCLK is
34/// 32 MHz. Applications using another peripheral clock should provide values
35/// calculated for that clock.
36#[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    /// Byte sent when the master reads beyond the supplied slave TX buffer.
102    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    /// The master writes and the slave receives.
263    Receive,
264    /// The master reads and the slave transmits.
265    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    /// Selects whether the slave acknowledges the next received byte.
391    ///
392    /// This is primarily useful after [`wait_address`](Self::wait_address)
393    /// and before [`slave_receive`](Self::slave_receive). The peripheral
394    /// clears the NACK request automatically on STOP or a new address match.
395    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    /// Waits until this slave address is matched.
417    ///
418    /// With clock stretching enabled, SCL remains stretched until
419    /// [`slave_receive`](Self::slave_receive) or
420    /// [`slave_transmit`](Self::slave_transmit) clears the `ADDR` flag.
421    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            // ADDR can only be raised for an enabled own address or general
462            // call. With OA1 and general call ruled out above, this is OA2,
463            // including matches accepted through OA2MSK.
464            AddressMatchSource::Secondary
465        }
466    }
467
468    /// Receives bytes written by the master until STOP or repeated START.
469    /// If more bytes arrive than fit in `buffer`, the extra byte is discarded,
470    /// NACK is requested, and [`SlaveBufferStatus::Overflow`] is reported.
471    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    /// Transmits bytes requested by the master until NACK, STOP, or repeated
484    /// START. If the master requests more bytes than supplied,
485    /// [`Config::underflow_fill`] is sent and
486    /// [`SlaveBufferStatus::Underflow`] is reported.
487    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    /// Waits until `TXDR` is ready for the next byte in master transmit mode.
1099    ///
1100    /// Polls the `ISR` register until the `TXIS` flag is set.
1101    ///
1102    /// # Errors
1103    ///
1104    /// Returns:
1105    /// - [`Error::Nack`] if the `NACKF` flag is set.
1106    /// - [`Error::BusError`] if the `BERR` flag is set.
1107    /// - [`Error::ArbitrationLoss`] if the `ARLO` flag is set.
1108    /// - [`Error::Timeout`] if `TXIS` is not set before `Config::timeout`
1109    ///   polling attempts are exhausted.
1110    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    /// Waits until the I2C bus is no longer busy.
1119    ///
1120    /// Polls the `ISR` register until the `BUSY` flag is cleared.
1121    /// # Errors
1122    ///
1123    /// Returns [`Error::Timeout`] if the `BUSY` flag is still set after
1124    /// `Config::timeout` polling attempts are exhausted.
1125    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    /// Waits until the current master transfer is complete.
1136    ///
1137    /// Polls the `ISR` register until the `TC` flag is set.
1138    ///
1139    /// # Errors
1140    ///
1141    /// Returns [`Error::Timeout`] if the `TC` flag is not set before
1142    /// `Config::timeout` polling attempts are exhausted.
1143    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        // TXE is software-settable to discard pending TXDR data, but the PAC
1160        // does not currently expose a typed writer for this bit.
1161        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        // After losing arbitration another master owns the bus. Generating
1168        // STOP or toggling PE here would interfere with its transaction.
1169        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}