1use 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#[repr(C)]
27struct Lpi2cRegisters {
28 verid: ReadOnly<u32, VERID::Register>,
30 param: ReadOnly<u32, PARAM::Register>,
32 _reserved1: [u8; 8],
33 mcr: ReadWrite<u32, MCR::Register>,
35 msr: ReadWrite<u32, MSR::Register>,
37 mier: ReadWrite<u32, MIER::Register>,
39 mder: ReadWrite<u32, MDER::Register>,
41 mcfgr0: ReadWrite<u32, MCFGR0::Register>,
43 mcfgr1: ReadWrite<u32, MCFGR1::Register>,
45 mcfgr2: ReadWrite<u32, MCFGR2::Register>,
47 mcfgr3: ReadWrite<u32, MCFGR3::Register>,
49 _reserved2: [u8; 16],
50 mdmr: ReadWrite<u32, MDMR::Register>,
52 _reserved3: [u8; 4],
53 mccr0: ReadWrite<u32, MCCR0::Register>,
55 _reserved4: [u8; 4],
56 mccr1: ReadWrite<u32, MCCR1::Register>,
58 _reserved5: [u8; 4],
59 mfcr: ReadWrite<u32, MFCR::Register>,
61 mfsr: ReadOnly<u32, MFSR::Register>,
63 mtdr: WriteOnly<u32, MTDR::Register>,
65 _reserved6: [u8; 12],
66 mrdr: ReadOnly<u32, MRDR::Register>,
68 _reserved7: [u8; 156],
69 scr: ReadWrite<u32, SCR::Register>,
71 ssr: ReadWrite<u32, SSR::Register>,
73 sier: ReadWrite<u32, SIER::Register>,
75 sder: ReadWrite<u32, SDER::Register>,
77 _reserved8: [u8; 4],
78 scfgr1: ReadWrite<u32, SCFGR1::Register>,
80 scfgr2: ReadWrite<u32, SCFGR2::Register>,
82 _reserved9: [u8; 20],
83 samr: ReadWrite<u32, SAMR::Register>,
85 _reserved10: [u8; 12],
86 sasr: ReadOnly<u32, SAMR::Register>,
88 star: ReadWrite<u32, STAR::Register>,
90 _reserved11: [u8; 8],
91 stdr: WriteOnly<u32, STDR::Register>,
93 _reserved12: [u8; 12],
94 srdr: ReadOnly<u32, SRDR::Register>,
96}
97
98register_bitfields![u32,
99 VERID [
100 MAJOR OFFSET(24) NUMBITS(8) [],
102 MINOR OFFSET(16) NUMBITS(8) [],
104 FEATURE OFFSET(0) NUMBITS(16) []
106 ],
107
108 PARAM [
109 MRXFIFO OFFSET(8) NUMBITS(4) [],
111 MTXFIFO OFFSET(0) NUMBITS(4) []
113 ],
114
115 MCR [
116 RRF OFFSET(9) NUMBITS(1) [],
118 RTF OFFSET(8) NUMBITS(1) [],
120 DBGEN OFFSET(3) NUMBITS(1) [],
122 DOZEN OFFSET(2) NUMBITS(1) [],
124 RST OFFSET(1) NUMBITS(1) [],
126 MEN OFFSET(0) NUMBITS(1) []
128 ],
129
130 MSR [
131 BBF OFFSET(25) NUMBITS(1) [],
133 MBF OFFSET(24) NUMBITS(1) [],
135 DMF OFFSET(14) NUMBITS(1) [],
137 PLTF OFFSET(13) NUMBITS(1) [],
139 FEF OFFSET(12) NUMBITS(1) [],
141 ALF OFFSET(11) NUMBITS(1) [],
143 NDF OFFSET(10) NUMBITS(1) [],
145 SDF OFFSET(9) NUMBITS(1) [],
147 EPF OFFSET(8) NUMBITS(1) [],
149 RDF OFFSET(1) NUMBITS(1) [],
151 TDF OFFSET(0) NUMBITS(1) []
153 ],
154
155 MIER [
156 DMIE OFFSET(14) NUMBITS(1) [],
158 PLTIE OFFSET(13) NUMBITS(1) [],
160 FEIE OFFSET(12) NUMBITS(1) [],
162 ALIE OFFSET(11) NUMBITS(1) [],
164 NDIE OFFSET(10) NUMBITS(1) [],
166 SDIE OFFSET(9) NUMBITS(1) [],
168 EPIE OFFSET(8) NUMBITS(1) [],
170 RDIE OFFSET(1) NUMBITS(1) [],
172 TDIE OFFSET(0) NUMBITS(1) []
174 ],
175
176 MDER [
177 RDDE OFFSET(1) NUMBITS(1) [],
179 TDDE OFFSET(0) NUMBITS(1) []
181 ],
182
183 MCFGR0 [
184 RDMO OFFSET(9) NUMBITS(1) [],
186 CIRFIFO OFFSET(8) NUMBITS(1) [],
188 HRSEL OFFSET(2) NUMBITS(1) [],
190 HRPOL OFFSET(1) NUMBITS(1) [],
192 HREN OFFSET(0) NUMBITS(1) []
194 ],
195
196 MCFGR1 [
197 PINCFG OFFSET(24) NUMBITS(3) [],
199 MATCFG OFFSET(16) NUMBITS(3) [],
201 TIMECFG OFFSET(10) NUMBITS(1) [],
203 IGNACK OFFSET(9) NUMBITS(1) [],
205 AUTOSTOP OFFSET(8) NUMBITS(1) [],
207 PRESCALE OFFSET(0) NUMBITS(3) []
209 ],
210
211 MCFGR2 [
212 FILTSDA OFFSET(24) NUMBITS(4) [],
214 FILTSCL OFFSET(16) NUMBITS(4) [],
216 BUSIDLE OFFSET(0) NUMBITS(12) []
218 ],
219
220 MCFGR3 [
221 PINLOW OFFSET(8) NUMBITS(12) []
223 ],
224
225 MDMR [
226 MATCH1 OFFSET(16) NUMBITS(8) [],
228 MATCH0 OFFSET(0) NUMBITS(8) []
230 ],
231
232 MCCR0 [
233 DATAVD OFFSET(24) NUMBITS(6) [],
235 SETHOLD OFFSET(16) NUMBITS(6) [],
237 CLKHI OFFSET(8) NUMBITS(6) [],
239 CLKLO OFFSET(0) NUMBITS(6) []
241 ],
242
243 MCCR1 [
244 DATAVD OFFSET(24) NUMBITS(6) [],
246 SETHOLD OFFSET(16) NUMBITS(6) [],
248 CLKHI OFFSET(8) NUMBITS(6) [],
250 CLKLO OFFSET(0) NUMBITS(6) []
252 ],
253
254 MFCR [
255 RXWATER OFFSET(16) NUMBITS(2) [],
257 TXWATER OFFSET(0) NUMBITS(2) []
259 ],
260
261 MFSR [
262 RXCOUNT OFFSET(16) NUMBITS(3) [],
264 TXCOUNT OFFSET(0) NUMBITS(3) []
266 ],
267
268 MTDR [
269 CMD OFFSET(8) NUMBITS(3) [],
271 DATA OFFSET(0) NUMBITS(8) []
273 ],
274
275 MRDR [
276 RXEMPTY OFFSET(14) NUMBITS(1) [],
278 DATA OFFSET(0) NUMBITS(8) []
280 ],
281
282 SCR [
283 RRF OFFSET(9) NUMBITS(1) [],
285 RTF OFFSET(8) NUMBITS(1) [],
287 FILTDZ OFFSET(5) NUMBITS(1) [],
289 FILTEN OFFSET(4) NUMBITS(1) [],
291 RST OFFSET(1) NUMBITS(1) [],
293 SEN OFFSET(0) NUMBITS(1) []
295 ],
296
297 SSR [
298 BBF OFFSET(25) NUMBITS(1) [],
300 SBF OFFSET(24) NUMBITS(1) [],
302 SARF OFFSET(15) NUMBITS(1) [],
304 GCF OFFSET(14) NUMBITS(1) [],
306 AM1F OFFSET(13) NUMBITS(1) [],
308 AM0F OFFSET(12) NUMBITS(1) [],
310 FEF OFFSET(11) NUMBITS(1) [],
312 BEF OFFSET(10) NUMBITS(1) [],
314 SDF OFFSET(9) NUMBITS(1) [],
316 RSF OFFSET(8) NUMBITS(1) [],
318 TAF OFFSET(3) NUMBITS(1) [],
320 AVF OFFSET(2) NUMBITS(1) [],
322 RDF OFFSET(1) NUMBITS(1) [],
324 TDF OFFSET(0) NUMBITS(1) []
326 ],
327
328 SIER [
329 SARIE OFFSET(15) NUMBITS(1) [],
331 GCIE OFFSET(14) NUMBITS(1) [],
333 AM1F OFFSET(13) NUMBITS(1) [],
335 AM0IE OFFSET(12) NUMBITS(1) [],
337 FEIE OFFSET(11) NUMBITS(1) [],
339 BEIE OFFSET(10) NUMBITS(1) [],
341 SDIE OFFSET(9) NUMBITS(1) [],
343 RSIE OFFSET(8) NUMBITS(1) [],
345 TAIE OFFSET(3) NUMBITS(1) [],
347 AVIE OFFSET(2) NUMBITS(1) [],
349 RDIE OFFSET(1) NUMBITS(1) [],
351 TDIE OFFSET(0) NUMBITS(1) []
353 ],
354
355 SDER [
356 AVDE OFFSET(2) NUMBITS(1) [],
358 RDDE OFFSET(1) NUMBITS(1) [],
360 TDDE OFFSET(0) NUMBITS(1) []
362 ],
363
364 SCFGR1 [
365 ADDRCFG OFFSET(16) NUMBITS(3) [],
367 HSMEN OFFSET(13) NUMBITS(1) [],
369 IGNACK OFFSET(12) NUMBITS(1) [],
371 RXCFG OFFSET(11) NUMBITS(1) [],
373 TXCFG OFFSET(10) NUMBITS(1) [],
375 SAEN OFFSET(9) NUMBITS(1) [],
377 GCEN OFFSET(8) NUMBITS(1) [],
379 ACKSTALL OFFSET(3) NUMBITS(1) [],
381 TXDSTALL OFFSET(2) NUMBITS(1) [],
383 RXSTALL OFFSET(1) NUMBITS(1) [],
385 ADRSTALL OFFSET(0) NUMBITS(1) []
387 ],
388
389 SCFGR2 [
390 FILTSDA OFFSET(24) NUMBITS(4) [],
392 FILTSCL OFFSET(16) NUMBITS(4) [],
394 DATAVD OFFSET(8) NUMBITS(6) [],
396 CLKHOLD OFFSET(0) NUMBITS(4) []
398 ],
399
400 SAMR [
401 ADDR1 OFFSET(17) NUMBITS(10) [],
403 ADDR0 OFFSET(1) NUMBITS(10) []
405 ],
406
407 SASR [
408 ANV OFFSET(14) NUMBITS(1) [],
410 RADDR OFFSET(0) NUMBITS(11) []
412 ],
413
414 STAR [
415 TXNACK OFFSET(0) NUMBITS(1) []
417 ],
418
419 STDR [
420 TXNACK OFFSET(0) NUMBITS(8) []
422 ],
423
424 SRDR [
425 SOF OFFSET(15) NUMBITS(1) [],
427 RXEMPTY OFFSET(14) NUMBITS(1) [],
429 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 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 int: Cell<usize>,
455}
456
457#[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 }
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 if self.registers.msr.is_set(MSR::TDF) {
579 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 while self.registers.msr.is_set(MSR::RDF) {
589 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 if self.registers.msr.is_set(MSR::EPF) {
599 match self.status.get() {
600 Lpi2cStatus::Writing | Lpi2cStatus::WritingReading => {
603 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 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 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 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}