1
//! # Inter-Integrated Circuit (I2C) - Slave mode
2
//!
3
//! ## Overview
4
//!
5
//! This driver implements the I2C Slave mode. In this mode, the MCU responds to
6
//! and communicates with one or more master devices. The MCU acts as a slave
7
//! device on the I2C bus, identified by its unique I2C address.
8
//!
9
//! ## Implementation
10
//!
11
//! This driver supports both Blocking and Async modes, using hardware SCL clock stretching
12
//! to handle flow control. The async implementation runs a callback-free waker model, waking
13
//! the task waker when stretching or transaction completeness interrupts occur.
14

            
15
use core::{
16
    future::Future,
17
    marker::PhantomData,
18
    pin::Pin,
19
    task::{Context, Poll},
20
};
21

            
22
use enumset::{EnumSet, EnumSetType};
23

            
24
use crate::{
25
    Async,
26
    Blocking,
27
    DriverMode,
28
    asynch::AtomicWaker,
29
    gpio::{
30
        DriveMode,
31
        InputSignal,
32
        OutputConfig,
33
        OutputSignal,
34
        PinGuard,
35
        Pull,
36
        interconnect::{self, PeripheralInput, PeripheralOutput},
37
    },
38
    handler,
39
    i2c::master::I2cAddress,
40
    interrupt::InterruptHandler,
41
    pac::i2c0::RegisterBlock,
42
    private,
43
    ram,
44
    rtc_cntl::WakeLock,
45
    system::PeripheralGuard,
46
};
47

            
48
/// FIFO size of the I2C peripheral.
49
pub const FIFO_SIZE: usize = property!("i2c_master.fifo_size");
50

            
51
/// I2C Slave error
52
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
53
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
54
#[non_exhaustive]
55
pub enum Error {
56
    /// A timeout occurred during transmission.
57
    Timeout,
58
    /// The arbitration for the bus was lost.
59
    ArbitrationLost,
60
}
61

            
62
impl embedded_hal::i2c::Error for Error {
63
    fn kind(&self) -> embedded_hal::i2c::ErrorKind {
64
        match self {
65
            Self::ArbitrationLost => embedded_hal::i2c::ErrorKind::ArbitrationLoss,
66
            _ => embedded_hal::i2c::ErrorKind::Other,
67
        }
68
    }
69
}
70

            
71
/// I2C Slave configuration
72
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, procmacros::BuilderLite)]
73
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
74
#[non_exhaustive]
75
pub struct Config {
76
    /// The I2C slave address.
77
    address: I2cAddress,
78
}
79

            
80
impl Config {
81
    /// Creates a new I2C slave configuration with the specified address.
82
    pub fn new(address: impl Into<I2cAddress>) -> Self {
83
        Config {
84
            address: address.into(),
85
        }
86
    }
87
}
88

            
89
/// I2C slave configuration errors
90
#[derive(Debug, Clone, Copy, PartialEq)]
91
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
92
#[non_exhaustive]
93
pub enum ConfigError {
94
    /// Provided address is not valid.
95
    AddressInvalid,
96
}
97

            
98
impl core::error::Error for ConfigError {}
99

            
100
impl core::fmt::Display for ConfigError {
101
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
102
        match self {
103
            ConfigError::AddressInvalid => write!(f, "Provided address is invalid"),
104
        }
105
    }
106
}
107

            
108
/// Received command from the master
109
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
110
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
111
pub enum Command {
112
    /// The master is requesting data from the slave.
113
    Read,
114
    /// The master wrote the specified number of bytes to the slave.
115
    Write(usize),
116
}
117

            
118
/// Possible responses to responding to a read request
119
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
120
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
121
pub enum ReadStatus {
122
    /// Transaction Complete; master completed reading all provided bytes.
123
    Done,
124
    /// Transaction Incomplete; master is trying to read more bytes than were provided.
125
    NeedMoreBytes,
126
    /// Transaction Complete, but master stopped reading before all bytes were consumed.
127
    LeftoverBytes(u16),
128
}
129

            
130
/// I2C Slave driver
131
#[derive(Debug)]
132
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
133
pub struct I2cSlave<'d, Dm: DriverMode> {
134
    i2c: AnyI2c<'d>,
135
    phantom: PhantomData<Dm>,
136
    guard: PeripheralGuard,
137
    config: DriverConfig,
138
}
139

            
140
#[derive(Debug)]
141
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
142
struct DriverConfig {
143
    config: Config,
144
    sda_pin: PinGuard,
145
    scl_pin: PinGuard,
146
}
147

            
148
impl<Dm: DriverMode> embedded_hal::i2c::ErrorType for I2cSlave<'_, Dm> {
149
    type Error = Error;
150
}
151

            
152
impl<'d> I2cSlave<'d, Blocking> {
153
    /// Creates a new I2C slave instance.
154
    pub fn new(i2c: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
155
        let guard = PeripheralGuard::new(i2c.info().peripheral);
156

            
157
        let sda_pin = PinGuard::new_unconnected();
158
        let scl_pin = PinGuard::new_unconnected();
159

            
160
        let mut slave = I2cSlave {
161
            i2c: i2c.degrade(),
162
            phantom: PhantomData,
163
            guard,
164
            config: DriverConfig {
165
                config,
166
                sda_pin,
167
                scl_pin,
168
            },
169
        };
170

            
171
        slave.apply_config(&config)?;
172
        Ok(slave)
173
    }
174

            
175
    /// Reconfigures the driver to operate in [`Async`] mode.
176
    pub fn into_async(self) -> I2cSlave<'d, Async> {
177
        self.i2c
178
            .set_interrupt_handler(self.driver().info.async_handler);
179

            
180
        I2cSlave {
181
            i2c: self.i2c,
182
            phantom: PhantomData,
183
            guard: self.guard,
184
            config: self.config,
185
        }
186
    }
187
}
188

            
189
impl<'d> I2cSlave<'d, Async> {
190
    /// Reconfigures the driver to operate in [`Blocking`] mode.
191
    pub fn into_blocking(self) -> I2cSlave<'d, Blocking> {
192
        self.i2c.disable_peri_interrupt();
193

            
194
        I2cSlave {
195
            i2c: self.i2c,
196
            phantom: PhantomData,
197
            guard: self.guard,
198
            config: self.config,
199
        }
200
    }
201
}
202

            
203
impl<'d, Dm: DriverMode> I2cSlave<'d, Dm> {
204
    fn driver(&self) -> Driver<'_> {
205
        Driver {
206
            info: self.i2c.info(),
207
            state: self.i2c.state(),
208
            config: &self.config,
209
        }
210
    }
211

            
212
    /// Connects a pin to the I2C SDA signal.
213
    pub fn with_sda(mut self, sda: impl PeripheralInput<'d> + PeripheralOutput<'d>) -> Self {
214
        let info = self.driver().info;
215
        let input = info.sda_input;
216
        let output = info.sda_output;
217
        Driver::connect_pin(sda.into(), input, output, &mut self.config.sda_pin);
218
        self
219
    }
220

            
221
    /// Connects a pin to the I2C SCL signal.
222
    pub fn with_scl(mut self, scl: impl PeripheralInput<'d> + PeripheralOutput<'d>) -> Self {
223
        let info = self.driver().info;
224
        let input = info.scl_input;
225
        let output = info.scl_output;
226
        Driver::connect_pin(scl.into(), input, output, &mut self.config.scl_pin);
227
        self
228
    }
229

            
230
    /// Applies a new configuration.
231
    pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
232
        self.config.config = *config;
233
        self.driver().setup(config)?;
234
        Ok(())
235
    }
236
}
237

            
238
impl<'d, Dm: DriverMode> I2cSlave<'d, Dm> {
239
    /// Listens for a request from the master.
240
    ///
241
    /// If the master writes to the slave, this method reads data into the provided
242
    /// `buffer` and returns `Command::Write(len)`.
243
    /// If the master is requesting a read, it returns `Command::Read` with the SCL line
244
    /// stretched (held low).
245
    pub fn listen(&mut self, buffer: &mut [u8]) -> Result<Command, Error> {
246
        let regs = self.driver().info.regs();
247

            
248
        self.driver().reset_fifo();
249

            
250
        regs.scl_stretch_conf().modify(|_, w| unsafe {
251
            w.stretch_protect_num().bits(0x3ff);
252
            w.slave_scl_stretch_en().set_bit()
253
        });
254

            
255
        regs.int_clr().write(|w| unsafe { w.bits(0x3fff) });
256
        regs.scl_stretch_conf()
257
            .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
258
        self.driver().update_registers();
259

            
260
        let mut bytes_read = 0;
261
        loop {
262
            self.driver().check_errors()?;
263
            if let Some(res) = self.driver().listen_step(buffer, &mut bytes_read) {
264
                return res;
265
            }
266
        }
267
    }
268

            
269
    /// Responds to a master read request.
270
    ///
271
    /// Writes the contents of `buffer` to the TX FIFO, clears the clock stretch,
272
    /// and waits for the transaction to complete.
273
    pub fn respond_to_read(&mut self, buffer: &[u8]) -> Result<ReadStatus, Error> {
274
        let regs = self.driver().info.regs();
275
        let mut bytes_written = 0;
276
        let initial_write = core::cmp::min(buffer.len(), FIFO_SIZE);
277
        for &byte in buffer.iter().take(initial_write) {
278
            regs.data().write(|w| unsafe { w.fifo_rdata().bits(byte) });
279
        }
280
        bytes_written += initial_write;
281

            
282
        regs.scl_stretch_conf()
283
            .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
284
        regs.int_clr().write(|w| unsafe { w.bits(0x3fff) });
285
        self.driver().update_registers();
286

            
287
        loop {
288
            self.driver().check_errors()?;
289
            if let Some(res) = self
290
                .driver()
291
                .respond_to_read_step(buffer, &mut bytes_written)
292
            {
293
                return res;
294
            }
295
        }
296
    }
297
}
298

            
299
impl<'d> I2cSlave<'d, Async> {
300
    /// Listens for a request from the master asynchronously.
301
    pub async fn listen_async(&mut self, buffer: &mut [u8]) -> Result<Command, Error> {
302
        let regs = self.driver().info.regs();
303
        let state = self.i2c.state();
304

            
305
        self.driver().reset_fifo();
306

            
307
        regs.scl_stretch_conf().modify(|_, w| unsafe {
308
            w.stretch_protect_num().bits(0x3ff);
309
            w.slave_scl_stretch_en().set_bit()
310
        });
311

            
312
        regs.int_clr().write(|w| unsafe { w.bits(0x3fff) });
313
        regs.scl_stretch_conf()
314
            .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
315
        self.driver().update_registers();
316

            
317
        let mut bytes_read = 0;
318
        loop {
319
            I2cSlaveFuture::new(regs, state, Event::SlaveStretch | Event::TransComplete).await?;
320
            if let Some(res) = self.driver().listen_step(buffer, &mut bytes_read) {
321
                return res;
322
            }
323
        }
324
    }
325

            
326
    /// Responds to a master read request asynchronously.
327
    pub async fn respond_to_read_async(&mut self, buffer: &[u8]) -> Result<ReadStatus, Error> {
328
        let regs = self.driver().info.regs();
329
        let state = self.i2c.state();
330

            
331
        let mut bytes_written = 0;
332
        let initial_write = core::cmp::min(buffer.len(), FIFO_SIZE);
333
        for &byte in buffer.iter().take(initial_write) {
334
            regs.data().write(|w| unsafe { w.fifo_rdata().bits(byte) });
335
        }
336
        bytes_written += initial_write;
337

            
338
        regs.scl_stretch_conf()
339
            .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
340
        regs.int_clr().write(|w| unsafe { w.bits(0x3fff) });
341
        self.driver().update_registers();
342

            
343
        loop {
344
            I2cSlaveFuture::new(
345
                regs,
346
                state,
347
                Event::SlaveStretch | Event::TransComplete | Event::Nack,
348
            )
349
            .await?;
350

            
351
            if let Some(res) = self
352
                .driver()
353
                .respond_to_read_step(buffer, &mut bytes_written)
354
            {
355
                return res;
356
            }
357
        }
358
    }
359
}
360

            
361
impl<Dm: DriverMode> private::Sealed for I2cSlave<'_, Dm> {}
362

            
363
#[derive(Debug, EnumSetType)]
364
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
365
#[non_exhaustive]
366
pub(crate) enum Event {
367
    SlaveStretch,
368
    TransComplete,
369
    Nack,
370
}
371

            
372
#[must_use = "futures do nothing unless you `.await` or poll them"]
373
struct I2cSlaveFuture<'a> {
374
    regs: &'a RegisterBlock,
375
    state: &'a State,
376
    events: EnumSet<Event>,
377
    _wake_lock: WakeLock,
378
}
379

            
380
impl<'a> I2cSlaveFuture<'a> {
381
    pub fn new(regs: &'a RegisterBlock, state: &'a State, events: EnumSet<Event>) -> Self {
382
        regs.int_ena().modify(|_, w| {
383
            if events.contains(Event::SlaveStretch) {
384
                w.slave_stretch().set_bit();
385
            }
386
            if events.contains(Event::TransComplete) {
387
                w.trans_complete().set_bit();
388
            }
389
            if events.contains(Event::Nack) {
390
                w.nack().set_bit();
391
            }
392
            w.arbitration_lost().set_bit();
393
            w.time_out().set_bit();
394
            w
395
        });
396

            
397
        Self {
398
            regs,
399
            state,
400
            events,
401
            _wake_lock: WakeLock::new(),
402
        }
403
    }
404
}
405

            
406
impl Future for I2cSlaveFuture<'_> {
407
    type Output = Result<(), Error>;
408

            
409
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
410
        self.state.waker.register(cx.waker());
411

            
412
        let raw = self.regs.int_raw().read();
413

            
414
        if raw.arbitration_lost().bit_is_set() {
415
            return Poll::Ready(Err(Error::ArbitrationLost));
416
        }
417
        if raw.time_out().bit_is_set() {
418
            return Poll::Ready(Err(Error::Timeout));
419
        }
420

            
421
        let mut triggered = false;
422
        if self.events.contains(Event::SlaveStretch) && raw.slave_stretch().bit_is_set() {
423
            triggered = true;
424
        }
425
        if self.events.contains(Event::TransComplete) && raw.trans_complete().bit_is_set() {
426
            triggered = true;
427
        }
428
        if self.events.contains(Event::Nack) && raw.nack().bit_is_set() {
429
            triggered = true;
430
        }
431

            
432
        if triggered {
433
            Poll::Ready(Ok(()))
434
        } else {
435
            self.regs.int_ena().modify(|_, w| {
436
                if self.events.contains(Event::SlaveStretch) {
437
                    w.slave_stretch().set_bit();
438
                }
439
                if self.events.contains(Event::TransComplete) {
440
                    w.trans_complete().set_bit();
441
                }
442
                if self.events.contains(Event::Nack) {
443
                    w.nack().set_bit();
444
                }
445
                w.arbitration_lost().set_bit();
446
                w.time_out().set_bit();
447
                w
448
            });
449
            Poll::Pending
450
        }
451
    }
452
}
453

            
454
impl Drop for I2cSlaveFuture<'_> {
455
    fn drop(&mut self) {
456
        self.regs.int_ena().write(|w| unsafe { w.bits(0) });
457
    }
458
}
459

            
460
#[ram]
461
fn async_handler(info: &Info, state: &State) {
462
    info.regs().int_ena().write(|w| unsafe { w.bits(0) });
463
    state.waker.wake();
464
}
465

            
466
/// I2C Slave state.
467
#[non_exhaustive]
468
pub struct State {
469
    pub(crate) waker: AtomicWaker,
470
}
471

            
472
impl core::fmt::Debug for State {
473
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
474
        f.debug_struct("State")
475
            .field("waker", &"<AtomicWaker>")
476
            .finish()
477
    }
478
}
479

            
480
/// I2C Slave peripheral information.
481
#[derive(Debug)]
482
#[non_exhaustive]
483
pub struct Info {
484
    pub(crate) register_block: *const RegisterBlock,
485
    pub(crate) peripheral: crate::system::Peripheral,
486
    pub(crate) async_handler: InterruptHandler,
487
    pub(crate) scl_output: OutputSignal,
488
    pub(crate) scl_input: InputSignal,
489
    pub(crate) sda_output: OutputSignal,
490
    pub(crate) sda_input: InputSignal,
491
}
492

            
493
impl Info {
494
    pub(crate) fn regs(&self) -> &RegisterBlock {
495
        unsafe { &*self.register_block }
496
    }
497
}
498

            
499
unsafe impl Sync for Info {}
500

            
501
/// I2C Slave peripheral instance.
502
pub trait Instance: crate::private::Sealed + any::Degrade {
503
    #[doc(hidden)]
504
    fn parts(&self) -> (&Info, &State);
505

            
506
    #[doc(hidden)]
507
    #[inline(always)]
508
    fn info(&self) -> &Info {
509
        self.parts().0
510
    }
511

            
512
    #[doc(hidden)]
513
    #[inline(always)]
514
    fn state(&self) -> &State {
515
        self.parts().1
516
    }
517
}
518

            
519
#[allow(dead_code)]
520
struct Driver<'a> {
521
    info: &'a Info,
522
    state: &'a State,
523
    config: &'a DriverConfig,
524
}
525

            
526
impl Driver<'_> {
527
    fn regs(&self) -> &RegisterBlock {
528
        self.info.regs()
529
    }
530

            
531
    fn connect_pin(
532
        pin: crate::gpio::interconnect::OutputSignal<'_>,
533
        input: InputSignal,
534
        output: OutputSignal,
535
        guard: &mut PinGuard,
536
    ) {
537
        pin.set_output_high(true);
538
        pin.apply_output_config(
539
            &OutputConfig::default()
540
                .with_drive_mode(DriveMode::OpenDrain)
541
                .with_pull(Pull::Up),
542
        );
543
        pin.set_output_enable(true);
544
        pin.set_input_enable(true);
545
        input.connect_to(&pin);
546
        *guard = interconnect::OutputSignal::connect_with_guard(pin, output);
547
    }
548

            
549
    fn init_slave(&self) {
550
        self.regs().ctr().write(|w| {
551
            w.ms_mode().clear_bit(); // Slave mode
552
            w.sda_force_out().set_bit();
553
            w.scl_force_out().set_bit();
554
            #[cfg(i2c_master_has_arbitration_en)]
555
            w.arbitration_en().clear_bit();
556
            w.tx_lsb_first().clear_bit();
557
            w.rx_lsb_first().clear_bit();
558
            w
559
        });
560

            
561
        self.reset_fifo();
562

            
563
        self.regs().fifo_conf().modify(|_, w| {
564
            w.nonfifo_en().clear_bit();
565
            w
566
        });
567
    }
568

            
569
    fn set_slave_addr(&self, address: I2cAddress) -> Result<(), ConfigError> {
570
        match address {
571
            I2cAddress::SevenBit(addr) if addr <= 0x7F => {
572
                self.regs().slave_addr().write(|w| unsafe {
573
                    w.slave_addr().bits(addr as u16);
574
                    w.addr_10bit_en().bit(false)
575
                });
576
                Ok(())
577
            }
578
            _ => Err(ConfigError::AddressInvalid),
579
        }
580
    }
581

            
582
    fn update_registers(&self) {
583
        #[cfg(i2c_master_has_conf_update)]
584
        self.regs().ctr().modify(|_, w| w.conf_upgate().set_bit());
585
    }
586

            
587
    fn setup(&self, config: &Config) -> Result<(), ConfigError> {
588
        self.init_slave();
589
        self.set_slave_addr(config.address)?;
590

            
591
        let regs = self.regs();
592
        regs.to().modify(|_, w| unsafe {
593
            w.time_out_en().set_bit();
594
            w.time_out_value().bits(14);
595
            w
596
        });
597

            
598
        regs.clk_conf().modify(|_, w| w.sclk_sel().clear_bit());
599
        self.set_slave_addr(config.address)?;
600

            
601
        regs.ctr()
602
            .modify(|_, w| w.addr_broadcasting_en().clear_bit());
603

            
604
        regs.fifo_conf().modify(|_, w| {
605
            w.fifo_prt_en().set_bit();
606
            unsafe { w.txfifo_wm_thrhd().bits(0) }
607
        });
608

            
609
        regs.fifo_conf().modify(|_, w| w.fifo_prt_en().set_bit());
610
        regs.ctr().write(|w| w.rx_full_ack_level().clear_bit());
611

            
612
        regs.fifo_conf()
613
            .modify(|_, w| unsafe { w.rxfifo_wm_thrhd().bits(0x1F) });
614

            
615
        regs.sda_hold().write(|w| unsafe { w.time().bits(10u16) });
616
        regs.sda_sample().write(|w| unsafe { w.time().bits(10u16) });
617

            
618
        regs.int_ena().write(|w| unsafe { w.bits(0) });
619
        regs.int_clr().write(|w| unsafe { w.bits(0x3fff) });
620

            
621
        regs.scl_stretch_conf().modify(|_, w| unsafe {
622
            w.stretch_protect_num().bits(0x3ff);
623
            w.slave_scl_stretch_en().set_bit()
624
        });
625

            
626
        regs.scl_stretch_conf()
627
            .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
628
        self.update_registers();
629

            
630
        Ok(())
631
    }
632

            
633
    fn reset_fifo(&self) {
634
        self.regs()
635
            .fifo_conf()
636
            .modify(|_, w| w.tx_fifo_rst().set_bit());
637
        self.regs()
638
            .fifo_conf()
639
            .modify(|_, w| w.tx_fifo_rst().clear_bit());
640
        self.regs()
641
            .fifo_conf()
642
            .modify(|_, w| w.rx_fifo_rst().set_bit());
643
        self.regs()
644
            .fifo_conf()
645
            .modify(|_, w| w.rx_fifo_rst().clear_bit());
646
    }
647

            
648
    fn reset_fsm(&self) {
649
        #[cfg(i2c_master_has_reliable_fsm_reset)]
650
        {
651
            self.regs().ctr().modify(|_, w| w.fsm_rst().set_bit());
652
        }
653
        #[cfg(not(i2c_master_has_reliable_fsm_reset))]
654
        {
655
            crate::system::PeripheralClockControl::reset(self.info.peripheral);
656
            self.setup(&self.config.config).ok();
657
        }
658
    }
659

            
660
    fn check_errors(&self) -> Result<(), Error> {
661
        let r = self.regs().int_raw().read();
662

            
663
        if r.arbitration_lost().bit_is_set() {
664
            return Err(Error::ArbitrationLost);
665
        }
666
        if r.time_out().bit_is_set() {
667
            return Err(Error::Timeout);
668
        }
669
        Ok(())
670
    }
671

            
672
    fn listen_step(
673
        &self,
674
        buffer: &mut [u8],
675
        bytes_read: &mut usize,
676
    ) -> Option<Result<Command, Error>> {
677
        let regs = self.regs();
678
        let ints = regs.int_raw().read();
679

            
680
        if ints.slave_stretch().bit_is_set() {
681
            let cause = regs.sr().read().stretch_cause().bits();
682
            match cause {
683
                0 => {
684
                    let rw = regs.sr().read().slave_rw().bit_is_set();
685
                    if rw {
686
                        regs.int_clr()
687
                            .write(|w| w.slave_stretch().clear_bit_by_one());
688
                        return Some(Ok(Command::Read));
689
                    } else {
690
                        regs.scl_stretch_conf()
691
                            .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
692
                        regs.int_clr()
693
                            .write(|w| w.slave_stretch().clear_bit_by_one());
694
                    }
695
                }
696
                2 => {
697
                    while regs.sr().read().rxfifo_cnt().bits() > 0 && *bytes_read < buffer.len() {
698
                        buffer[*bytes_read] = regs.data().read().fifo_rdata().bits();
699
                        *bytes_read += 1;
700
                    }
701
                    regs.scl_stretch_conf()
702
                        .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
703
                    regs.int_clr()
704
                        .write(|w| w.slave_stretch().clear_bit_by_one());
705
                }
706
                _ => {
707
                    regs.scl_stretch_conf()
708
                        .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
709
                    regs.int_clr()
710
                        .write(|w| w.slave_stretch().clear_bit_by_one());
711
                }
712
            }
713
        }
714

            
715
        while regs.sr().read().rxfifo_cnt().bits() > 0 && *bytes_read < buffer.len() {
716
            buffer[*bytes_read] = regs.data().read().fifo_rdata().bits();
717
            *bytes_read += 1;
718
        }
719

            
720
        if ints.trans_complete().bit_is_set() {
721
            regs.int_clr()
722
                .write(|w| w.trans_complete().clear_bit_by_one());
723
            return Some(Ok(Command::Write(*bytes_read)));
724
        }
725

            
726
        None
727
    }
728

            
729
    fn respond_to_read_step(
730
        &self,
731
        buffer: &[u8],
732
        bytes_written: &mut usize,
733
    ) -> Option<Result<ReadStatus, Error>> {
734
        let regs = self.regs();
735
        let ints = regs.int_raw().read();
736

            
737
        if ints.trans_complete().bit_is_set() || ints.nack().bit_is_set() {
738
            let is_nack = ints.nack().bit_is_set();
739
            regs.int_clr().write(|w| {
740
                w.trans_complete().clear_bit_by_one();
741
                w.nack().clear_bit_by_one()
742
            });
743
            if is_nack {
744
                self.reset_fifo();
745
                self.reset_fsm();
746
            }
747

            
748
            if *bytes_written > buffer.len() {
749
                return Some(Ok(ReadStatus::NeedMoreBytes));
750
            } else if *bytes_written < buffer.len() {
751
                let rem = (buffer.len() - *bytes_written) as u16;
752
                return Some(Ok(ReadStatus::LeftoverBytes(rem)));
753
            } else {
754
                return Some(Ok(ReadStatus::Done));
755
            }
756
        }
757

            
758
        if ints.slave_stretch().bit_is_set() {
759
            let cause = regs.sr().read().stretch_cause().bits();
760
            if cause == 1 {
761
                if *bytes_written < buffer.len() {
762
                    let txfifo_cnt = regs.sr().read().txfifo_cnt().bits() as usize;
763
                    let free = FIFO_SIZE - txfifo_cnt;
764
                    let to_write = core::cmp::min(buffer.len() - *bytes_written, free);
765
                    for i in 0..to_write {
766
                        regs.data()
767
                            .write(|w| unsafe { w.fifo_rdata().bits(buffer[*bytes_written + i]) });
768
                    }
769
                    *bytes_written += to_write;
770

            
771
                    regs.scl_stretch_conf()
772
                        .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
773
                    regs.int_clr()
774
                        .write(|w| w.slave_stretch().clear_bit_by_one());
775
                    self.update_registers();
776
                } else {
777
                    regs.data().write(|w| unsafe { w.fifo_rdata().bits(0xFF) });
778
                    *bytes_written += 1;
779
                    regs.scl_stretch_conf()
780
                        .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
781
                    regs.int_clr()
782
                        .write(|w| w.slave_stretch().clear_bit_by_one());
783
                    self.update_registers();
784
                }
785
            } else {
786
                regs.scl_stretch_conf()
787
                    .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
788
                regs.int_clr()
789
                    .write(|w| w.slave_stretch().clear_bit_by_one());
790
                self.update_registers();
791
            }
792
        }
793

            
794
        None
795
    }
796
}
797

            
798
#[cfg(i2c_slave_i2c0)]
799
impl crate::i2c::slave::Instance for crate::peripherals::I2C0<'_> {
800
    fn parts(&self) -> (&Info, &State) {
801
        #[handler]
802
        #[ram]
803
        pub(super) fn irq_handler() {
804
            async_handler(&PERIPHERAL, &STATE);
805
        }
806

            
807
        static STATE: State = State {
808
            waker: AtomicWaker::new(),
809
        };
810

            
811
        static PERIPHERAL: Info = Info {
812
            register_block: crate::peripherals::I2C0::ptr(),
813
            peripheral: crate::system::Peripheral::I2cExt0,
814
            async_handler: irq_handler,
815
            scl_output: OutputSignal::I2CEXT0_SCL,
816
            scl_input: InputSignal::I2CEXT0_SCL,
817
            sda_output: OutputSignal::I2CEXT0_SDA,
818
            sda_input: InputSignal::I2CEXT0_SDA,
819
        };
820
        (&PERIPHERAL, &STATE)
821
    }
822
}
823

            
824
#[cfg(i2c_slave_i2c1)]
825
impl crate::i2c::slave::Instance for crate::peripherals::I2C1<'_> {
826
    fn parts(&self) -> (&Info, &State) {
827
        #[handler]
828
        #[ram]
829
        pub(super) fn irq_handler() {
830
            async_handler(&PERIPHERAL, &STATE);
831
        }
832

            
833
        static STATE: State = State {
834
            waker: AtomicWaker::new(),
835
        };
836

            
837
        static PERIPHERAL: Info = Info {
838
            register_block: crate::peripherals::I2C1::ptr(),
839
            peripheral: crate::system::Peripheral::I2cExt1,
840
            async_handler: irq_handler,
841
            scl_output: OutputSignal::I2CEXT1_SCL,
842
            scl_input: InputSignal::I2CEXT1_SCL,
843
            sda_output: OutputSignal::I2CEXT1_SDA,
844
            sda_input: InputSignal::I2CEXT1_SDA,
845
        };
846
        (&PERIPHERAL, &STATE)
847
    }
848
}
849

            
850
crate::any_peripheral! {
851
    /// Any I2C peripheral in slave mode.
852
    pub peripheral AnyI2c<'d> {
853
        #[cfg(i2c_slave_i2c0)]
854
        I2c0(crate::peripherals::I2C0<'d>),
855
        #[cfg(i2c_slave_i2c1)]
856
        I2c1(crate::peripherals::I2C1<'d>),
857
    }
858
}
859

            
860
impl crate::i2c::slave::Instance for AnyI2c<'_> {
861
    fn parts(&self) -> (&Info, &State) {
862
        any::delegate!(self, i2c => { crate::i2c::slave::Instance::parts(i2c) })
863
    }
864
}
865

            
866
impl AnyI2c<'_> {
867
    fn bind_peri_interrupt(&self, handler: InterruptHandler) {
868
        any::delegate!(self, i2c => { i2c.bind_peri_interrupt(handler) })
869
    }
870

            
871
    fn disable_peri_interrupt(&self) {
872
        any::delegate!(self, i2c => { i2c.disable_peri_interrupt() })
873
    }
874

            
875
    fn enable_peri_interrupt(&self, priority: crate::interrupt::Priority) {
876
        any::delegate!(self, i2c => { i2c.enable_peri_interrupt(priority) })
877
    }
878

            
879
    fn set_interrupt_handler(&self, handler: InterruptHandler) {
880
        self.disable_peri_interrupt();
881

            
882
        self.info().regs().int_ena().write(|w| unsafe { w.bits(0) });
883
        self.info()
884
            .regs()
885
            .int_clr()
886
            .write(|w| unsafe { w.bits(0x3fff) });
887

            
888
        self.bind_peri_interrupt(handler);
889
        self.enable_peri_interrupt(handler.priority());
890
    }
891
}