imxrt10xx/
lpi2c.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5use core::cell::Cell;
6
7use kernel::debug;
8use kernel::utilities::cells::{OptionalCell, TakeCell};
9use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
10use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite, WriteOnly};
11use kernel::utilities::StaticRef;
12
13use kernel::hil;
14use kernel::hil::i2c::{self, Error, I2CHwMasterClient, I2CMaster};
15use kernel::platform::chip::ClockInterface;
16
17use crate::ccm;
18
19pub enum Lpi2cSpeed {
20    Speed100k,
21    Speed400k,
22    Speed1M,
23}
24
25/// Inter-integrated Circuit
26#[repr(C)]
27struct Lpi2cRegisters {
28    // Version ID Register
29    verid: ReadOnly<u32, VERID::Register>,
30    // Parameter Register
31    param: ReadOnly<u32, PARAM::Register>,
32    _reserved1: [u8; 8],
33    // Master Control Register
34    mcr: ReadWrite<u32, MCR::Register>,
35    // Master Status Register
36    msr: ReadWrite<u32, MSR::Register>,
37    // Master Interrupt Enable Register
38    mier: ReadWrite<u32, MIER::Register>,
39    // Master DMA Enable Register
40    mder: ReadWrite<u32, MDER::Register>,
41    // Master Configuration Register 0
42    mcfgr0: ReadWrite<u32, MCFGR0::Register>,
43    // Master Configuration Register 1
44    mcfgr1: ReadWrite<u32, MCFGR1::Register>,
45    // Master Configuration Register 2
46    mcfgr2: ReadWrite<u32, MCFGR2::Register>,
47    // Master Configuration Register 3
48    mcfgr3: ReadWrite<u32, MCFGR3::Register>,
49    _reserved2: [u8; 16],
50    // Master Data Match Register
51    mdmr: ReadWrite<u32, MDMR::Register>,
52    _reserved3: [u8; 4],
53    // Master Configuration Register 0
54    mccr0: ReadWrite<u32, MCCR0::Register>,
55    _reserved4: [u8; 4],
56    // Master Configuration Register 1
57    mccr1: ReadWrite<u32, MCCR1::Register>,
58    _reserved5: [u8; 4],
59    // Master FIFO Control Register
60    mfcr: ReadWrite<u32, MFCR::Register>,
61    // Master FIFO Status Register
62    mfsr: ReadOnly<u32, MFSR::Register>,
63    // Master Transmit Data Register
64    mtdr: WriteOnly<u32, MTDR::Register>,
65    _reserved6: [u8; 12],
66    // Master Receive Data Register
67    mrdr: ReadOnly<u32, MRDR::Register>,
68    _reserved7: [u8; 156],
69    // Slave Control Register
70    scr: ReadWrite<u32, SCR::Register>,
71    // Slave Status Register
72    ssr: ReadWrite<u32, SSR::Register>,
73    // Slave Interrupt Enable Register
74    sier: ReadWrite<u32, SIER::Register>,
75    // Slave DMA Enable Register
76    sder: ReadWrite<u32, SDER::Register>,
77    _reserved8: [u8; 4],
78    // Slave Configuration Register 1
79    scfgr1: ReadWrite<u32, SCFGR1::Register>,
80    // Slave Configuration Register 2
81    scfgr2: ReadWrite<u32, SCFGR2::Register>,
82    _reserved9: [u8; 20],
83    // Slave Address Match Register
84    samr: ReadWrite<u32, SAMR::Register>,
85    _reserved10: [u8; 12],
86    // Slave Status Match Register
87    sasr: ReadOnly<u32, SAMR::Register>,
88    // Slave Transmit ACK Register
89    star: ReadWrite<u32, STAR::Register>,
90    _reserved11: [u8; 8],
91    // Slave Transmit Data Register
92    stdr: WriteOnly<u32, STDR::Register>,
93    _reserved12: [u8; 12],
94    // Slave Receive Data Register
95    srdr: ReadOnly<u32, SRDR::Register>,
96}
97
98register_bitfields![u32,
99    VERID [
100        /// Major Version Number
101        MAJOR OFFSET(24) NUMBITS(8) [],
102        /// Minor Version Number
103        MINOR OFFSET(16) NUMBITS(8) [],
104        /// Feature Identification Number
105        FEATURE OFFSET(0) NUMBITS(16) []
106    ],
107
108    PARAM [
109        /// Receive FIFO Size
110        MRXFIFO OFFSET(8) NUMBITS(4) [],
111        /// Transmit FIFO Size
112        MTXFIFO OFFSET(0) NUMBITS(4) []
113    ],
114
115    MCR [
116        /// Reset Receive FIFO
117        RRF OFFSET(9) NUMBITS(1) [],
118        /// Reset Transmit FIFO
119        RTF OFFSET(8) NUMBITS(1) [],
120        /// Debug Enable
121        DBGEN OFFSET(3) NUMBITS(1) [],
122        /// Doze Mode Enable
123        DOZEN OFFSET(2) NUMBITS(1) [],
124        /// Software Reset
125        RST OFFSET(1) NUMBITS(1) [],
126        /// Master Enable
127        MEN OFFSET(0) NUMBITS(1) []
128    ],
129
130    MSR [
131        /// Bus Busy Flag
132        BBF OFFSET(25) NUMBITS(1) [],
133        /// Master Busy Flag
134        MBF OFFSET(24) NUMBITS(1) [],
135        /// Data Match Flag
136        DMF OFFSET(14) NUMBITS(1) [],
137        /// Pin Low Timeout Flag
138        PLTF OFFSET(13) NUMBITS(1) [],
139        /// FIFO Error Flag
140        FEF OFFSET(12) NUMBITS(1) [],
141        /// Arbitration Lost Flag
142        ALF OFFSET(11) NUMBITS(1) [],
143        /// NACK Detect Flag
144        NDF OFFSET(10) NUMBITS(1) [],
145        /// STOP Detect Flag
146        SDF OFFSET(9) NUMBITS(1) [],
147        /// End Packet Flag
148        EPF OFFSET(8) NUMBITS(1) [],
149        /// Receive Data Flag
150        RDF OFFSET(1) NUMBITS(1) [],
151        /// Transmit Data Flag
152        TDF OFFSET(0) NUMBITS(1) []
153    ],
154
155    MIER [
156        /// Data Match Interrupt Enable
157        DMIE OFFSET(14) NUMBITS(1) [],
158        /// Pin Low Timeout Interrupt Enable
159        PLTIE OFFSET(13) NUMBITS(1) [],
160        /// FIFO Error Interrupt Enable
161        FEIE OFFSET(12) NUMBITS(1) [],
162        /// Arbitration Lost Interrupt Enable
163        ALIE OFFSET(11) NUMBITS(1) [],
164        /// NACK Detect Interrupt Enable
165        NDIE OFFSET(10) NUMBITS(1) [],
166        /// STOP Detect Interrupt Enable
167        SDIE OFFSET(9) NUMBITS(1) [],
168        /// End Packet Interrupt Enable
169        EPIE OFFSET(8) NUMBITS(1) [],
170        /// Receive Data Interrupt Enable
171        RDIE OFFSET(1) NUMBITS(1) [],
172        /// Transmit Data Interrupt Enable
173        TDIE OFFSET(0) NUMBITS(1) []
174    ],
175
176    MDER [
177        /// Receive Data DMA Enable
178        RDDE OFFSET(1) NUMBITS(1) [],
179        /// Transmit Data DMA Enable
180        TDDE OFFSET(0) NUMBITS(1) []
181    ],
182
183    MCFGR0 [
184        /// Receive Data Match Only
185        RDMO OFFSET(9) NUMBITS(1) [],
186        /// Circular FIFO Enable
187        CIRFIFO OFFSET(8) NUMBITS(1) [],
188        /// Host Request Select
189        HRSEL OFFSET(2) NUMBITS(1) [],
190        /// Host Request Polarity
191        HRPOL OFFSET(1) NUMBITS(1) [],
192        /// Host Request Enable
193        HREN OFFSET(0) NUMBITS(1) []
194    ],
195
196    MCFGR1 [
197        /// Pin Configuration
198        PINCFG OFFSET(24) NUMBITS(3) [],
199        /// Match Configuration
200        MATCFG OFFSET(16) NUMBITS(3) [],
201        /// Timeout Configuration
202        TIMECFG OFFSET(10) NUMBITS(1) [],
203        /// IGNACK
204        IGNACK OFFSET(9) NUMBITS(1) [],
205        /// Automatic STOP Generation
206        AUTOSTOP OFFSET(8) NUMBITS(1) [],
207        /// Prescaler
208        PRESCALE OFFSET(0) NUMBITS(3) []
209    ],
210
211    MCFGR2 [
212        /// Glitch Filter SDA
213        FILTSDA OFFSET(24) NUMBITS(4) [],
214        /// Glitch Filter SCL
215        FILTSCL OFFSET(16) NUMBITS(4) [],
216        /// Bus Idle Timeout
217        BUSIDLE OFFSET(0) NUMBITS(12) []
218    ],
219
220    MCFGR3 [
221        /// Pin Low Timeout
222        PINLOW OFFSET(8) NUMBITS(12) []
223    ],
224
225    MDMR [
226        /// Match 1 Value
227        MATCH1 OFFSET(16) NUMBITS(8) [],
228        /// Match 0 Value
229        MATCH0 OFFSET(0) NUMBITS(8) []
230    ],
231
232    MCCR0 [
233        /// Data Valid Delay
234        DATAVD OFFSET(24) NUMBITS(6) [],
235        /// Setup Hold Delay
236        SETHOLD OFFSET(16) NUMBITS(6) [],
237        /// Clock High Period
238        CLKHI OFFSET(8) NUMBITS(6) [],
239        /// Clock Low Period
240        CLKLO OFFSET(0) NUMBITS(6) []
241    ],
242
243    MCCR1 [
244        /// Data Valid Delay
245        DATAVD OFFSET(24) NUMBITS(6) [],
246        /// Setup Hold Delay
247        SETHOLD OFFSET(16) NUMBITS(6) [],
248        /// Clock High Period
249        CLKHI OFFSET(8) NUMBITS(6) [],
250        /// Clock Low Period
251        CLKLO OFFSET(0) NUMBITS(6) []
252    ],
253
254    MFCR [
255        /// Receive FIFO Watermark
256        RXWATER OFFSET(16) NUMBITS(2) [],
257        /// Transmit FIFO Watermark
258        TXWATER OFFSET(0) NUMBITS(2) []
259    ],
260
261    MFSR [
262        /// Receive FIFO Count
263        RXCOUNT OFFSET(16) NUMBITS(3) [],
264        /// Transmit FIFO Count
265        TXCOUNT OFFSET(0) NUMBITS(3) []
266    ],
267
268    MTDR [
269        /// Command Data
270        CMD OFFSET(8) NUMBITS(3) [],
271        /// Transmit Data
272        DATA OFFSET(0) NUMBITS(8) []
273    ],
274
275    MRDR [
276        /// RX Empty
277        RXEMPTY OFFSET(14) NUMBITS(1) [],
278        /// Receive Data
279        DATA OFFSET(0) NUMBITS(8) []
280    ],
281
282    SCR [
283        /// Reset Receive FIFO
284        RRF OFFSET(9) NUMBITS(1) [],
285        /// Reset Transmit FIFO
286        RTF OFFSET(8) NUMBITS(1) [],
287        /// Filter Doze Enable
288        FILTDZ OFFSET(5) NUMBITS(1) [],
289        /// Filter Enable
290        FILTEN OFFSET(4) NUMBITS(1) [],
291        /// Software Reset
292        RST OFFSET(1) NUMBITS(1) [],
293        /// Slave Enable
294        SEN OFFSET(0) NUMBITS(1) []
295    ],
296
297    SSR [
298        /// Bus Busy Flag
299        BBF OFFSET(25) NUMBITS(1) [],
300        /// Slave Busy Flag
301        SBF OFFSET(24) NUMBITS(1) [],
302        /// SMBus Alert Response Flag
303        SARF OFFSET(15) NUMBITS(1) [],
304        /// General Call Flag
305        GCF OFFSET(14) NUMBITS(1) [],
306        /// Address Match 1 Flag
307        AM1F OFFSET(13) NUMBITS(1) [],
308        /// Address Match 0 Flag
309        AM0F OFFSET(12) NUMBITS(1) [],
310        /// FIFO Error Flag
311        FEF OFFSET(11) NUMBITS(1) [],
312        /// Bit Error Flag
313        BEF OFFSET(10) NUMBITS(1) [],
314        /// STOP Detect Flag
315        SDF OFFSET(9) NUMBITS(1) [],
316        /// Repeated Start Flag
317        RSF OFFSET(8) NUMBITS(1) [],
318        /// Transmit ACK Flag
319        TAF OFFSET(3) NUMBITS(1) [],
320        /// Address Valid Flag
321        AVF OFFSET(2) NUMBITS(1) [],
322        /// Receive Data Flag
323        RDF OFFSET(1) NUMBITS(1) [],
324        /// Transmit Data Flag
325        TDF OFFSET(0) NUMBITS(1) []
326    ],
327
328    SIER [
329        /// SMBus Alert Response Interrupt Enable
330        SARIE OFFSET(15) NUMBITS(1) [],
331        /// General Call Interrupt Enable
332        GCIE OFFSET(14) NUMBITS(1) [],
333        /// Address Match 1 Interrupt Enable
334        AM1F OFFSET(13) NUMBITS(1) [],
335        /// Address Match 0 Interrupt Enable
336        AM0IE OFFSET(12) NUMBITS(1) [],
337        /// FIFO Error Interrupt Enable
338        FEIE OFFSET(11) NUMBITS(1) [],
339        /// Bit Error Interrupt Enable
340        BEIE OFFSET(10) NUMBITS(1) [],
341        /// STOP Detect Interrupt Enable
342        SDIE OFFSET(9) NUMBITS(1) [],
343        /// Repeated Start Interrupt Enable
344        RSIE OFFSET(8) NUMBITS(1) [],
345        /// Transmit ACK Interrupt Enable
346        TAIE OFFSET(3) NUMBITS(1) [],
347        /// Address Valid Interrupt Enable
348        AVIE OFFSET(2) NUMBITS(1) [],
349        /// Receive Data Interrupt Enable
350        RDIE OFFSET(1) NUMBITS(1) [],
351        /// Transmit Data Interrupt Enable
352        TDIE OFFSET(0) NUMBITS(1) []
353    ],
354
355    SDER [
356        /// Address Valid DMA Enable
357        AVDE OFFSET(2) NUMBITS(1) [],
358        /// Receive Data DMA Enable
359        RDDE OFFSET(1) NUMBITS(1) [],
360        /// Transmit Data DMA Enable
361        TDDE OFFSET(0) NUMBITS(1) []
362    ],
363
364    SCFGR1 [
365        /// Address Configuration
366        ADDRCFG OFFSET(16) NUMBITS(3) [],
367        /// High Speed Mode Enable
368        HSMEN OFFSET(13) NUMBITS(1) [],
369        /// Ignore NACK
370        IGNACK OFFSET(12) NUMBITS(1) [],
371        /// Receive Data Configuration
372        RXCFG OFFSET(11) NUMBITS(1) [],
373        /// Transmit Flag Configuration
374        TXCFG OFFSET(10) NUMBITS(1) [],
375        /// SMBus Alert Enable
376        SAEN OFFSET(9) NUMBITS(1) [],
377        /// General Call Enable
378        GCEN OFFSET(8) NUMBITS(1) [],
379        /// ACK SCL Stall
380        ACKSTALL OFFSET(3) NUMBITS(1) [],
381        /// TX Data SCL Stall
382        TXDSTALL OFFSET(2) NUMBITS(1) [],
383        /// RX SCL Stall
384        RXSTALL OFFSET(1) NUMBITS(1) [],
385        /// Address SCL Stall
386        ADRSTALL OFFSET(0) NUMBITS(1) []
387    ],
388
389    SCFGR2 [
390        /// Glitch Filter SDA
391        FILTSDA OFFSET(24) NUMBITS(4) [],
392        /// Glitch Filter SCL
393        FILTSCL OFFSET(16) NUMBITS(4) [],
394        /// Data Valid Delay
395        DATAVD OFFSET(8) NUMBITS(6) [],
396        /// Clock Hold Time
397        CLKHOLD OFFSET(0) NUMBITS(4) []
398    ],
399
400    SAMR [
401        /// Address 1 Value
402        ADDR1 OFFSET(17) NUMBITS(10) [],
403        /// Address 0 Value
404        ADDR0 OFFSET(1) NUMBITS(10) []
405    ],
406
407    SASR [
408        /// Address Not Valid
409        ANV OFFSET(14) NUMBITS(1) [],
410        /// Received Address
411        RADDR OFFSET(0) NUMBITS(11) []
412    ],
413
414    STAR [
415        /// Transmit NACK
416        TXNACK OFFSET(0) NUMBITS(1) []
417    ],
418
419    STDR [
420        /// Transmit Data
421        TXNACK OFFSET(0) NUMBITS(8) []
422    ],
423
424    SRDR [
425        /// Start Of Frame
426        SOF OFFSET(15) NUMBITS(1) [],
427        /// RX Empty
428        RXEMPTY OFFSET(14) NUMBITS(1) [],
429        /// Receive Data
430        DATA OFFSET(0) NUMBITS(8) []
431    ]
432];
433
434const LPI2C1_BASE: StaticRef<Lpi2cRegisters> =
435    unsafe { StaticRef::new(0x403F_0000 as *const Lpi2cRegisters) };
436
437pub struct Lpi2c<'a> {
438    registers: StaticRef<Lpi2cRegisters>,
439    clock: Lpi2cClock<'a>,
440
441    // I2C slave support not yet implemented
442    master_client: OptionalCell<&'a dyn hil::i2c::I2CHwMasterClient>,
443
444    buffer: TakeCell<'static, [u8]>,
445    tx_position: Cell<usize>,
446    rx_position: Cell<usize>,
447    tx_len: Cell<usize>,
448    rx_len: Cell<usize>,
449
450    slave_address: Cell<u8>,
451
452    status: Cell<Lpi2cStatus>,
453    // transfers: Cell<u8>
454    int: Cell<usize>,
455}
456
457// Since we do not have a register for setting the number of bytes to be sent
458// or a register in which we set slave address. We will need 3 additional states
459// WritingAddress, WritingReadingAddress, ReadingAddress in order to check the
460// status of the i2c transmission.
461#[derive(Debug, Copy, Clone, PartialEq)]
462enum Lpi2cStatus {
463    Idle,
464    Writing,
465    WritingReading,
466    Reading,
467}
468
469impl<'a> Lpi2c<'a> {
470    pub fn new_lpi2c1(ccm: &'a ccm::Ccm) -> Self {
471        Lpi2c::new(
472            LPI2C1_BASE,
473            Lpi2cClock(ccm::PeripheralClock::ccgr2(ccm, ccm::HCLK2::LPI2C1)),
474        )
475    }
476    fn new(base_addr: StaticRef<Lpi2cRegisters>, clock: Lpi2cClock<'a>) -> Self {
477        Self {
478            registers: base_addr,
479            clock,
480
481            master_client: OptionalCell::empty(),
482
483            slave_address: Cell::new(0),
484
485            buffer: TakeCell::empty(),
486            tx_position: Cell::new(0),
487            rx_position: Cell::new(0),
488
489            tx_len: Cell::new(0),
490            rx_len: Cell::new(0),
491            status: Cell::new(Lpi2cStatus::Idle),
492
493            int: Cell::new(0),
494        }
495    }
496
497    pub fn set_speed(&self, speed: Lpi2cSpeed, _system_clock_in_mhz: usize) {
498        self.disable();
499        match speed {
500            Lpi2cSpeed::Speed100k => {
501                let prescaler = 4;
502                self.registers.mccr0.modify(MCCR0::CLKHI.val(12));
503                self.registers.mccr0.modify(MCCR0::CLKLO.val(24));
504                self.registers.mccr0.modify(MCCR0::SETHOLD.val(12));
505                self.registers.mccr0.modify(MCCR0::DATAVD.val(6));
506                self.registers
507                    .mcfgr1
508                    .modify(MCFGR1::PRESCALE.val(prescaler as u32));
509            }
510            Lpi2cSpeed::Speed400k => {
511                let prescaler = 1;
512                self.registers.mccr0.modify(MCCR0::CLKHI.val(12));
513                self.registers.mccr0.modify(MCCR0::CLKLO.val(24));
514                self.registers.mccr0.modify(MCCR0::SETHOLD.val(12));
515                self.registers.mccr0.modify(MCCR0::DATAVD.val(6));
516                self.registers
517                    .mcfgr1
518                    .modify(MCFGR1::PRESCALE.val(prescaler as u32));
519            }
520            Lpi2cSpeed::Speed1M => {
521                panic!("i2c speed 1MHz not implemented");
522            }
523        }
524        self.enable();
525    }
526
527    pub fn is_enabled_clock(&self) -> bool {
528        self.clock.is_enabled()
529    }
530
531    pub fn enable_clock(&self) {
532        self.clock.enable();
533    }
534
535    pub fn disable_clock(&self) {
536        self.clock.disable();
537    }
538
539    pub fn send_byte(&self) -> bool {
540        if self.buffer.is_some() && self.tx_position.get() < self.tx_len.get() {
541            self.buffer.map(|buf| {
542                let byte = buf[self.tx_position.get()];
543                self.registers.mtdr.write(MTDR::DATA.val(byte as u32));
544                self.tx_position.set(self.tx_position.get() + 1);
545            });
546            true
547        } else {
548            false
549            // panic!("i2c error, attempting to transmit more bytes than available in the buffer");
550        }
551    }
552
553    pub fn read_byte(&self) -> bool {
554        let byte = self.registers.mrdr.read(MRDR::DATA) as u8;
555        if self.buffer.is_some() && self.rx_position.get() < self.rx_len.get() {
556            self.buffer.map(|buf| {
557                buf[self.rx_position.get()] = byte;
558                self.rx_position.set(self.rx_position.get() + 1);
559            });
560            true
561        } else {
562            false
563        }
564    }
565
566    pub fn handle_event(&self) {
567        self.int.set(self.int.get() + 1);
568        if self.int.get() > 20 {
569            panic!("exceded 100");
570        }
571
572        if self.registers.msr.is_set(MSR::FEF) {
573            debug!("FIFO Error");
574            self.registers.msr.modify(MSR::FEF::SET);
575        }
576
577        // Transmit data is requested
578        if self.registers.msr.is_set(MSR::TDF) {
579            // send the next byte
580            if self.tx_position.get() < self.tx_len.get() {
581                self.send_byte();
582            } else {
583                self.registers.mtdr.write(MTDR::CMD.val(0b010));
584            }
585        }
586
587        // Receive data is ready
588        while self.registers.msr.is_set(MSR::RDF) {
589            // read the next byte
590            if self.rx_position.get() < self.rx_len.get() {
591                self.read_byte();
592            } else {
593                self.registers.mtdr.write(MTDR::CMD.val(0b010));
594            }
595        }
596
597        // End packet flag set
598        if self.registers.msr.is_set(MSR::EPF) {
599            match self.status.get() {
600                // if it is in the Address state, we set the status
601                // accordingly and send the next byte
602                Lpi2cStatus::Writing | Lpi2cStatus::WritingReading => {
603                    // if there are more bytes to be sent, send next byte
604                    if self.tx_position.get() < self.tx_len.get() {
605                        self.stop();
606                        self.master_client.map(|client| {
607                            self.buffer
608                                .take()
609                                .map(|buf| client.command_complete(buf, Err(Error::DataNak)))
610                        });
611                    } else {
612                        if self.status.get() == Lpi2cStatus::Writing {
613                            self.registers.mtdr.write(MTDR::CMD.val(0b010));
614                            self.stop();
615                            self.master_client.map(|client| {
616                                self.buffer
617                                    .take()
618                                    .map(|buf| client.command_complete(buf, Ok(())))
619                            });
620                        } else {
621                            self.status.set(Lpi2cStatus::Reading);
622                            self.start_read();
623                        }
624                    }
625                }
626                Lpi2cStatus::Reading => {
627                    // if there are more bytes to be read, read next byte
628                    if self.rx_position.get() == self.rx_len.get() {
629                        self.stop();
630                        self.master_client.map(|client| {
631                            self.buffer
632                                .take()
633                                .map(|buf| client.command_complete(buf, Ok(())))
634                        });
635                    } else {
636                        self.stop();
637                        self.master_client.map(|client| {
638                            self.buffer
639                                .take()
640                                .map(|buf| client.command_complete(buf, Err(Error::DataNak)))
641                        });
642                    }
643                }
644                _ => panic!("i2c should not arrive here"),
645            }
646        }
647
648        // abort transfer due to NACK
649        if self.registers.msr.is_set(MSR::NDF) {
650            self.registers.msr.modify(MSR::NDF::SET);
651            self.registers.mtdr.write(MTDR::CMD.val(0b010));
652            self.stop();
653            let err = Err(Error::DataNak);
654            self.master_client.map(|client| {
655                self.buffer
656                    .take()
657                    .map(|buf| client.command_complete(buf, err))
658            });
659        }
660    }
661
662    pub fn handle_error(&self) {}
663
664    fn reset(&self) {
665        self.disable();
666        self.enable();
667    }
668
669    fn start_write(&self) {
670        self.tx_position.set(0);
671        self.registers.mier.modify(MIER::EPIE::CLEAR);
672        self.registers
673            .mtdr
674            .write(MTDR::CMD.val(0b100) + MTDR::DATA.val((self.slave_address.get() << 1) as u32));
675
676        self.registers.mcfgr1.modify(MCFGR1::PINCFG::CLEAR);
677
678        self.registers.mier.modify(
679            MIER::TDIE::SET + MIER::NDIE::SET + MIER::RDIE::SET + MIER::EPIE::SET + MIER::FEIE::SET,
680        );
681    }
682
683    fn stop(&self) {
684        self.tx_position.set(0);
685        self.tx_len.set(0);
686        self.rx_position.set(0);
687        self.rx_len.set(0);
688        self.status.set(Lpi2cStatus::Idle);
689        if self.registers.msr.is_set(MSR::FEF) {
690            self.registers.msr.modify(MSR::FEF::SET);
691        }
692        self.registers.mier.modify(
693            MIER::TDIE::CLEAR
694                + MIER::NDIE::CLEAR
695                + MIER::EPIE::CLEAR
696                + MIER::SDIE::CLEAR
697                + MIER::RDIE::CLEAR,
698        );
699    }
700
701    fn start_read(&self) {
702        self.rx_position.set(0);
703
704        // setting slave address
705        self.registers.mier.modify(MIER::EPIE::CLEAR);
706        self.registers.mtdr.write(
707            MTDR::CMD.val(100) + MTDR::DATA.val((self.slave_address.get() << (1 + 1)) as u32),
708        );
709
710        self.registers.mcfgr1.modify(MCFGR1::PINCFG::CLEAR);
711        self.registers
712            .mier
713            .modify(MIER::NDIE::SET + MIER::EPIE::SET + MIER::RDIE::SET);
714    }
715}
716
717impl<'a> i2c::I2CMaster<'a> for Lpi2c<'a> {
718    fn set_master_client(&self, master_client: &'a dyn I2CHwMasterClient) {
719        self.master_client.replace(master_client);
720    }
721    fn enable(&self) {
722        self.registers.mcr.modify(MCR::RRF::SET);
723        self.registers.mcr.modify(MCR::RTF::SET);
724        self.registers.mcr.modify(MCR::MEN::SET);
725    }
726    fn disable(&self) {
727        self.registers.mcr.modify(MCR::MEN::CLEAR);
728    }
729    fn write_read(
730        &self,
731        addr: u8,
732        data: &'static mut [u8],
733        write_len: usize,
734        read_len: usize,
735    ) -> Result<(), (i2c::Error, &'static mut [u8])> {
736        if self.status.get() == Lpi2cStatus::Idle {
737            self.reset();
738            self.status.set(Lpi2cStatus::WritingReading);
739            self.slave_address.set(addr);
740            self.buffer.replace(data);
741            self.tx_len.set(write_len);
742            self.rx_len.set(read_len);
743            self.registers.mcfgr1.modify(MCFGR1::AUTOSTOP::CLEAR);
744            self.start_write();
745            Ok(())
746        } else {
747            Err((i2c::Error::Busy, data))
748        }
749    }
750
751    fn write(
752        &self,
753        addr: u8,
754        data: &'static mut [u8],
755        len: usize,
756    ) -> Result<(), (i2c::Error, &'static mut [u8])> {
757        if self.status.get() == Lpi2cStatus::Idle {
758            self.reset();
759            self.status.set(Lpi2cStatus::Writing);
760            self.slave_address.set(addr);
761            self.buffer.replace(data);
762            self.tx_len.set(len);
763            self.registers.mcfgr1.modify(MCFGR1::AUTOSTOP::CLEAR);
764            self.start_write();
765            Ok(())
766        } else {
767            Err((i2c::Error::Busy, data))
768        }
769    }
770
771    fn read(
772        &self,
773        addr: u8,
774        buffer: &'static mut [u8],
775        len: usize,
776    ) -> Result<(), (i2c::Error, &'static mut [u8])> {
777        if self.status.get() == Lpi2cStatus::Idle {
778            self.reset();
779            self.status.set(Lpi2cStatus::Reading);
780            self.slave_address.set(addr);
781            self.buffer.replace(buffer);
782            self.rx_len.set(len);
783            self.registers.mcfgr1.modify(MCFGR1::AUTOSTOP::CLEAR);
784            self.start_read();
785            Ok(())
786        } else {
787            Err((i2c::Error::Busy, buffer))
788        }
789    }
790}
791
792struct Lpi2cClock<'a>(ccm::PeripheralClock<'a>);
793
794impl ClockInterface for Lpi2cClock<'_> {
795    fn is_enabled(&self) -> bool {
796        self.0.is_enabled()
797    }
798
799    fn enable(&self) {
800        self.0.enable();
801    }
802
803    fn disable(&self) {
804        self.0.disable();
805    }
806}