1use crate::dma::{DMAChannel, DMAClient, DMAPeripheral};
17use crate::pm;
18use core::cell::Cell;
19use kernel::hil;
20use kernel::platform::chip::ClockInterface;
21use kernel::utilities::cells::{OptionalCell, TakeCell};
22use kernel::utilities::peripheral_management::{PeripheralManagement, PeripheralManager};
23use kernel::utilities::registers::interfaces::{Readable, Writeable};
24use kernel::utilities::registers::{
25 register_bitfields, FieldValue, ReadOnly, ReadWrite, WriteOnly,
26};
27use kernel::utilities::StaticRef;
28
29#[repr(C)]
32#[allow(dead_code)]
33struct TWIMRegisters {
34 cr: WriteOnly<u32, Control::Register>,
35 cwgr: ReadWrite<u32, ClockWaveformGenerator::Register>,
36 smbtr: ReadWrite<u32, SmbusTiming::Register>,
37 cmdr: ReadWrite<u32, Command::Register>,
38 ncmdr: ReadWrite<u32, Command::Register>,
39 rhr: ReadOnly<u32, ReceiveHolding::Register>,
40 thr: WriteOnly<u32, TransmitHolding::Register>,
41 sr: ReadOnly<u32, Status::Register>,
42 ier: WriteOnly<u32, Interrupt::Register>,
43 idr: WriteOnly<u32, Interrupt::Register>,
44 imr: ReadOnly<u32, Interrupt::Register>,
45 scr: WriteOnly<u32, StatusClear::Register>,
46 pr: ReadOnly<u32>,
47 vr: ReadOnly<u32>,
48 hscwgr: ReadWrite<u32>,
49 srr: ReadWrite<u32, SlewRate::Register>,
50 hssrr: ReadWrite<u32>,
51}
52
53#[repr(C)]
56#[allow(dead_code)]
57struct TWISRegisters {
58 cr: ReadWrite<u32, ControlSlave::Register>,
59 nbytes: ReadWrite<u32, Nbytes::Register>,
60 tr: ReadWrite<u32, Timing::Register>,
61 rhr: ReadOnly<u32, ReceiveHolding::Register>,
62 thr: WriteOnly<u32, TransmitHolding::Register>,
63 pecr: ReadOnly<u32, PacketErrorCheck::Register>,
64 sr: ReadOnly<u32, StatusSlave::Register>,
65 ier: WriteOnly<u32, InterruptSlave::Register>,
66 idr: WriteOnly<u32, InterruptSlave::Register>,
67 imr: ReadOnly<u32, InterruptSlave::Register>,
68 scr: WriteOnly<u32, StatusClearSlave::Register>,
69 pr: ReadOnly<u32>,
70 vr: ReadOnly<u32>,
71 hstr: ReadWrite<u32>,
72 srr: ReadWrite<u32, SlewRateSlave::Register>,
73 hssrr: ReadWrite<u32>,
74}
75
76register_bitfields![u32,
77 Control [
78 STOP 8,
80 SWRST 7,
82 SMDIS 5,
84 SMEN 4,
86 MDIS 1,
88 MEN 0
90 ],
91
92 ClockWaveformGenerator [
93 EXP OFFSET(28) NUMBITS(3) [],
95 DATA OFFSET(24) NUMBITS(4) [],
97 STASTO OFFSET(16) NUMBITS(8) [],
99 HIGH OFFSET(8) NUMBITS(8) [],
101 LOW OFFSET(0) NUMBITS(8) []
103 ],
104
105 SmbusTiming [
106 EXP OFFSET(28) NUMBITS(4) [],
108 THMAX OFFSET(16) NUMBITS(8) [],
110 TLWOM OFFSET(8) NUMBITS(8) [],
112 TLOWS OFFSET(0) NUMBITS(8) []
114 ],
115
116 Command [
117 HSMCODE OFFSET(28) NUMBITS(3) [],
119 HS OFFSET(26) NUMBITS(1) [
121 NoHSMode = 0,
122 HSMode = 1
123 ],
124 ACKLAST OFFSET(25) NUMBITS(1) [
126 NackLast = 0,
127 AckLast = 1
128 ],
129 PECEN OFFSET(24) NUMBITS(1) [
131 NoPecByteVerification = 0,
132 PecByteVerification = 1
133 ],
134 NBYTES OFFSET(16) NUMBITS(8) [],
136 VALID OFFSET(15) NUMBITS(1) [],
138 STOP OFFSET(14) NUMBITS(1) [
140 NoSendStop = 0,
141 SendStop = 1
142 ],
143 START OFFSET(13) NUMBITS(1) [
145 NoStartCondition = 0,
146 StartCondition = 1
147 ],
148 REPSAME OFFSET(12) NUMBITS(1) [],
150 TENBIT OFFSET(11) NUMBITS(1) [
152 SevenBitAddressing = 0,
153 TenBitAddressing = 1
154 ],
155 SADR OFFSET(1) NUMBITS(10) [],
157 READ OFFSET(0) NUMBITS(1) [
159 Transmit = 0,
160 Receive = 1
161 ]
162 ],
163
164 ReceiveHolding [
165 RXDATA OFFSET(0) NUMBITS(8) []
167 ],
168
169 TransmitHolding [
170 TXDATA OFFSET(0) NUMBITS(8) []
172 ],
173
174 Status [
175 HSMCACK 17,
177 MENB 16,
179 STOP 14,
181 PECERR 13,
183 TOUT 12,
185 ARBLST 10,
187 DNAK 9,
189 ANAK 8,
191 BUSFREE 5,
193 IDLE 4,
195 CCOMP 3,
197 CRDY 2,
199 TXRDY 1,
201 RXRDY 0
203 ],
204
205 Interrupt [
206 HSMCACK 17,
208 STOP 14,
210 PECERR 13,
212 TOUT 12,
214 ARBLST 10,
216 DNAK 9,
218 ANAK 8,
220 BUSFREE 5,
222 IDLE 4,
224 CCOMP 3,
226 CRDY 2,
228 TXRDY 1,
230 RXRDY 0
232 ],
233
234 StatusClear [
235 HSMCACK 17,
237 STOP 14,
239 PECERR 13,
241 TOUT 12,
243 ARBLST 10,
245 DNAK 9,
247 ANAK 8,
249 CCOMP 3
251 ],
252
253 SlewRate [
254 FILTER OFFSET(28) NUMBITS(2) [
256 StandardOrFast = 2,
257 FastModePlus = 3
258 ],
259 CLSLEW OFFSET(24) NUMBITS(2) [],
261 CLDRIVEL OFFSET(16) NUMBITS(3) [],
263 DASLEW OFFSET(8) NUMBITS(2) [],
265 DADRIVEL OFFSET(0) NUMBITS(3) []
267 ]
268];
269
270register_bitfields![u32,
271 ControlSlave [
272 TENBIT OFFSET(26) NUMBITS(1) [
274 Disable = 0,
275 Enable = 1
276 ],
277 ADR OFFSET(16) NUMBITS(10) [],
279 SODR OFFSET(15) NUMBITS(1) [],
281 SOAM OFFSET(14) NUMBITS(1) [
283 NoStretch = 0,
284 Stretch = 1
285 ],
286 CUP OFFSET(13) NUMBITS(1) [
288 CountDown = 0,
289 CountUp = 1
290 ],
291 ACK OFFSET(12) NUMBITS(1) [
293 AckLow = 0,
294 AckHigh = 1
295 ],
296 PECEN OFFSET(11) NUMBITS(1) [
298 Disable = 0,
299 Enable = 1
300 ],
301 SMHH OFFSET(10) NUMBITS(1) [
303 NoAckHostHeader = 0,
304 AckHostHeader = 1
305 ],
306 SMDA OFFSET(9) NUMBITS(1) [
308 NoAckDefaultAddress = 0,
309 AckDefaultAddress = 1
310 ],
311 SWRST OFFSET(7) NUMBITS(1) [],
313 STREN OFFSET(4) NUMBITS(1) [
315 Disable = 0,
316 Enable = 1
317 ],
318 GCMATCH OFFSET(3) NUMBITS(1) [
320 NoAckGeneralCallAddress = 0,
321 AckGeneralCallAddress = 1
322 ],
323 SMATCH OFFSET(2) NUMBITS(1) [
325 NoAckSlaveAddress = 0,
326 AckSlaveAddress = 1
327 ],
328 SMEN OFFSET(1) NUMBITS(1) [
330 Disable = 0,
331 Enable = 1
332 ],
333 SEN OFFSET(0) NUMBITS(1) [
335 Disable = 0,
336 Enable = 1
337 ]
338 ],
339
340 Nbytes [
341 NBYTES OFFSET(0) NUMBITS(8) []
342 ],
343
344 Timing [
345 EXP OFFSET(28) NUMBITS(4) [],
347 SUDAT OFFSET(16) NUMBITS(8) [],
349 TTOUT OFFSET(8) NUMBITS(8) [],
351 TLOWS OFFSET(0) NUMBITS(8) []
353 ],
354
355 PacketErrorCheck [
356 PEC OFFSET(0) NUMBITS(8) []
358 ],
359
360 StatusSlave [
361 BTF 23,
363 REP 22,
365 STO 21,
367 SMBDAM 20,
369 SMBHHM 19,
371 GCM 17,
373 SAM 16,
375 BUSERR 14,
377 SMBPECERR 13,
379 SMBTOUT 12,
381 NAK 8,
383 ORUN 7,
385 URUN 6,
387 TRA 5,
389 TCOMP 3,
391 SEN 2,
393 TXRDY 1,
395 RXRDY 0
397 ],
398
399 InterruptSlave [
400 BTF 23,
402 REP 22,
404 STO 21,
406 SMBDAM 20,
408 SMBHHM 19,
410 GCM 17,
412 SAM 16,
414 BUSERR 14,
416 SMBPECERR 13,
418 SMBTOUT 12,
420 NAK 8,
422 ORUN 7,
424 URUN 6,
426 TCOMP 3,
428 TXRDY 1,
430 RXRDY 0
432 ],
433
434 StatusClearSlave [
435 BTF 23,
437 REP 22,
439 STO 21,
441 SMBDAM 20,
443 SMBHHM 19,
445 GCM 17,
447 SAM 16,
449 BUSERR 14,
451 SMBPECERR 13,
453 SMBTOUT 12,
455 NAK 8,
457 ORUN 7,
459 URUN 6,
461 TCOMP 3
463 ],
464
465 SlewRateSlave [
466 FILTER OFFSET(28) NUMBITS(2) [],
468 DASLEW OFFSET(8) NUMBITS(2) [],
470 DADRIVEL OFFSET(0) NUMBITS(3) []
472 ]
473];
474
475const I2C_BASE_ADDRS: [StaticRef<TWIMRegisters>; 4] = unsafe {
477 [
478 StaticRef::new(0x40018000 as *const TWIMRegisters),
479 StaticRef::new(0x4001C000 as *const TWIMRegisters),
480 StaticRef::new(0x40078000 as *const TWIMRegisters),
481 StaticRef::new(0x4007C000 as *const TWIMRegisters),
482 ]
483};
484
485const I2C_SLAVE_BASE_ADDRS: [StaticRef<TWISRegisters>; 2] = unsafe {
487 [
488 StaticRef::new(0x40018400 as *const TWISRegisters),
489 StaticRef::new(0x4001C400 as *const TWISRegisters),
490 ]
491};
492
493#[derive(Clone, Copy)]
495pub enum Speed {
496 Standard100k,
497 Fast400k,
498 FastPlus1M,
499}
500
501struct TWIMClock {
503 master: pm::Clock,
504 slave: Option<pm::Clock>,
505}
506impl ClockInterface for TWIMClock {
507 fn is_enabled(&self) -> bool {
508 self.master.is_enabled()
509 }
510
511 fn enable(&self) {
512 self.slave.map(|slave_clock| {
513 if slave_clock.is_enabled() {
514 panic!("I2C: Request for master clock, but slave active");
515 }
516 });
517 self.master.enable();
518 }
519
520 fn disable(&self) {
521 self.master.disable();
522 }
523}
524
525struct TWISClock {
527 master: pm::Clock,
528 slave: Option<pm::Clock>,
529}
530impl ClockInterface for TWISClock {
531 fn is_enabled(&self) -> bool {
532 let slave_clock = self.slave.unwrap(); slave_clock.is_enabled()
534 }
535
536 fn enable(&self) {
537 let slave_clock = self.slave.unwrap(); if self.master.is_enabled() {
539 panic!("I2C: Request for slave clock, but master active");
540 }
541 slave_clock.enable();
542 }
543
544 fn disable(&self) {
545 let slave_clock = self.slave.unwrap(); slave_clock.disable();
547 }
548}
549
550pub struct I2CHw<'a> {
552 master_mmio_address: StaticRef<TWIMRegisters>,
553 slave_mmio_address: Option<StaticRef<TWISRegisters>>,
554 master_clock: TWIMClock,
555 slave_clock: TWISClock,
556 dma: OptionalCell<&'static DMAChannel>,
557 dma_pids: (DMAPeripheral, DMAPeripheral),
558 master_client: Cell<Option<&'a dyn hil::i2c::I2CHwMasterClient>>,
559 slave_client: Cell<Option<&'a dyn hil::i2c::I2CHwSlaveClient>>,
560 on_deck: Cell<Option<(DMAPeripheral, usize)>>,
561
562 slave_enabled: Cell<bool>,
563 my_slave_address: Cell<u8>,
564 slave_read_buffer: TakeCell<'static, [u8]>,
565 slave_read_buffer_len: Cell<usize>,
566 slave_read_buffer_index: Cell<usize>,
567 slave_write_buffer: TakeCell<'static, [u8]>,
568 slave_write_buffer_len: Cell<usize>,
569 slave_write_buffer_index: Cell<usize>,
570 pm: &'static pm::PowerManager,
571}
572
573impl PeripheralManagement<TWIMClock> for I2CHw<'_> {
574 type RegisterType = TWIMRegisters;
575
576 fn get_registers(&self) -> &TWIMRegisters {
577 &self.master_mmio_address
578 }
579
580 fn get_clock(&self) -> &TWIMClock {
581 &self.master_clock
582 }
583
584 fn before_peripheral_access(&self, clock: &TWIMClock, _: &TWIMRegisters) {
585 if !clock.is_enabled() {
586 clock.enable();
587 }
588 }
589
590 fn after_peripheral_access(&self, clock: &TWIMClock, registers: &TWIMRegisters) {
591 if registers.imr.get() == 0 {
594 clock.disable();
595 }
596 }
597}
598type TWIMRegisterManager<'a, 'm> = PeripheralManager<'m, I2CHw<'a>, TWIMClock>;
599
600impl PeripheralManagement<TWISClock> for I2CHw<'_> {
601 type RegisterType = TWISRegisters;
602
603 fn get_registers(&self) -> &TWISRegisters {
604 self.slave_mmio_address.as_ref().unwrap() }
606
607 fn get_clock(&self) -> &TWISClock {
608 &self.slave_clock
609 }
610
611 fn before_peripheral_access(&self, clock: &TWISClock, _: &TWISRegisters) {
612 if !clock.is_enabled() {
613 clock.enable();
614 }
615 }
616
617 fn after_peripheral_access(&self, clock: &TWISClock, registers: &TWISRegisters) {
618 if registers.imr.get() == 0 {
621 clock.disable();
622 }
623 }
624}
625type TWISRegisterManager<'a, 'm> = PeripheralManager<'m, I2CHw<'a>, TWISClock>;
626
627const fn create_twims_clocks(
628 master: pm::Clock,
629 slave: Option<pm::Clock>,
630) -> (TWIMClock, TWISClock) {
631 (TWIMClock { master, slave }, TWISClock { master, slave })
632}
633
634impl<'a> I2CHw<'a> {
637 fn new(
638 base_addr: StaticRef<TWIMRegisters>,
639 slave_base_addr: Option<StaticRef<TWISRegisters>>,
640 clocks: (TWIMClock, TWISClock),
641 dma_rx: DMAPeripheral,
642 dma_tx: DMAPeripheral,
643 pm: &'static pm::PowerManager,
644 ) -> I2CHw<'a> {
645 I2CHw {
646 master_mmio_address: base_addr,
647 slave_mmio_address: slave_base_addr,
648 master_clock: clocks.0,
649 slave_clock: clocks.1,
650 dma: OptionalCell::empty(),
651 dma_pids: (dma_rx, dma_tx),
652 master_client: Cell::new(None),
653 slave_client: Cell::new(None),
654 on_deck: Cell::new(None),
655
656 slave_enabled: Cell::new(false),
657 my_slave_address: Cell::new(0),
658 slave_read_buffer: TakeCell::empty(),
659 slave_read_buffer_len: Cell::new(0),
660 slave_read_buffer_index: Cell::new(0),
661 slave_write_buffer: TakeCell::empty(),
662 slave_write_buffer_len: Cell::new(0),
663 slave_write_buffer_index: Cell::new(0),
664 pm,
665 }
666 }
667
668 pub fn new_i2c0(pm: &'static pm::PowerManager) -> Self {
669 I2CHw::new(
670 I2C_BASE_ADDRS[0],
671 Some(I2C_SLAVE_BASE_ADDRS[0]),
672 create_twims_clocks(
673 pm::Clock::PBA(pm::PBAClock::TWIM0),
674 Some(pm::Clock::PBA(pm::PBAClock::TWIS0)),
675 ),
676 DMAPeripheral::TWIM0_RX,
677 DMAPeripheral::TWIM0_TX,
678 pm,
679 )
680 }
681
682 pub fn new_i2c1(pm: &'static pm::PowerManager) -> Self {
683 I2CHw::new(
684 I2C_BASE_ADDRS[1],
685 Some(I2C_SLAVE_BASE_ADDRS[1]),
686 create_twims_clocks(
687 pm::Clock::PBA(pm::PBAClock::TWIM1),
688 Some(pm::Clock::PBA(pm::PBAClock::TWIS1)),
689 ),
690 DMAPeripheral::TWIM1_RX,
691 DMAPeripheral::TWIM1_TX,
692 pm,
693 )
694 }
695
696 pub fn new_i2c2(pm: &'static pm::PowerManager) -> Self {
697 I2CHw::new(
698 I2C_BASE_ADDRS[2],
699 None,
700 create_twims_clocks(pm::Clock::PBA(pm::PBAClock::TWIM2), None),
701 DMAPeripheral::TWIM2_RX,
702 DMAPeripheral::TWIM2_TX,
703 pm,
704 )
705 }
706
707 pub fn new_i2c3(pm: &'static pm::PowerManager) -> Self {
708 I2CHw::new(
709 I2C_BASE_ADDRS[3],
710 None,
711 create_twims_clocks(pm::Clock::PBA(pm::PBAClock::TWIM3), None),
712 DMAPeripheral::TWIM3_RX,
713 DMAPeripheral::TWIM3_TX,
714 pm,
715 )
716 }
717
718 fn set_bus_speed(&self, twim: &TWIMRegisterManager) {
721 let system_frequency = self.pm.get_system_frequency();
723 let mut exp = 0;
724 let mut f_prescaled = system_frequency / 400000 / 2;
725 while (f_prescaled > 0xff) && (exp <= 0x7) {
726 exp += 1;
728 f_prescaled /= 2;
729 }
730
731 if exp > 0x7 {
733 panic!("Cannot setup I2C waveform timing with given system clock.");
734 }
735
736 let low = f_prescaled / 2;
737 let high = f_prescaled - low;
738 let data = 0;
739 let stasto = f_prescaled;
740
741 twim.registers.cwgr.write(
742 ClockWaveformGenerator::EXP.val(exp)
743 + ClockWaveformGenerator::DATA.val(data)
744 + ClockWaveformGenerator::STASTO.val(stasto)
745 + ClockWaveformGenerator::HIGH.val(high)
746 + ClockWaveformGenerator::LOW.val(low),
747 )
748 }
749
750 pub fn set_dma(&self, dma: &'static DMAChannel) {
751 self.dma.set(dma);
752 }
753
754 pub fn handle_interrupt(&self) {
755 let old_status = {
756 let twim = &TWIMRegisterManager::new(self);
757
758 let old_status = twim.registers.sr.extract();
759
760 twim.registers.scr.write(
762 StatusClear::HSMCACK::SET
763 + StatusClear::STOP::SET
764 + StatusClear::PECERR::SET
765 + StatusClear::TOUT::SET
766 + StatusClear::ARBLST::SET
767 + StatusClear::DNAK::SET
768 + StatusClear::ANAK::SET
769 + StatusClear::CCOMP::SET,
770 );
771
772 old_status
773 };
774
775 let err = if old_status.is_set(Status::ANAK) {
776 Some(Err(hil::i2c::Error::AddressNak))
777 } else if old_status.is_set(Status::DNAK) {
778 Some(Err(hil::i2c::Error::DataNak))
779 } else if old_status.is_set(Status::ARBLST) {
780 Some(Err(hil::i2c::Error::ArbitrationLost))
781 } else if old_status.is_set(Status::CCOMP) {
782 Some(Ok(()))
783 } else {
784 None
785 };
786
787 let on_deck = self.on_deck.get();
788 self.on_deck.set(None);
789 match on_deck {
790 None => {
791 {
792 let twim = &TWIMRegisterManager::new(self);
793
794 twim.registers.cmdr.set(0);
795 twim.registers.ncmdr.set(0);
796 self.disable_interrupts(twim);
797
798 if err.is_some() {
799 twim.registers.cr.write(Control::MEN::SET);
801 twim.registers.cr.write(Control::SWRST::SET);
802 twim.registers.cr.write(Control::MDIS::SET);
803 }
804 }
805
806 err.map(|err| {
807 self.master_client.get().map(|client| {
808 let buf = self.dma.and_then(|dma| {
809 let b = dma.abort_transfer();
810 self.dma.set(dma);
811 b
812 });
813 buf.map(|buf| {
814 client.command_complete(buf, err);
815 });
816 });
817 });
818 }
819 Some((dma_periph, len)) => {
820 if (len == 1) && old_status.is_set(Status::TXRDY) {
828 let the_byte = {
829 let twim = &TWIMRegisterManager::new(self);
830
831 twim.registers.cmdr.set(0);
832 twim.registers.ncmdr.set(0);
833 self.disable_interrupts(twim);
834
835 if err.is_some() {
836 twim.registers.cr.write(Control::MEN::SET);
838 twim.registers.cr.write(Control::SWRST::SET);
839 twim.registers.cr.write(Control::MDIS::SET);
840 }
841
842 twim.registers.rhr.read(ReceiveHolding::RXDATA) as u8
843 };
844
845 err.map(|err| {
846 self.master_client.get().map(|client| {
847 let buf = self.dma.and_then(|dma| {
848 let b = dma.abort_transfer();
849 self.dma.set(dma);
850 b
851 });
852 buf.map(|buf| {
853 buf[0] = the_byte;
855 client.command_complete(buf, err);
856 });
857 });
858 });
859 } else {
860 {
861 let twim = &TWIMRegisterManager::new(self);
862 twim.registers.ier.write(
864 Interrupt::CCOMP::SET
865 + Interrupt::ANAK::SET
866 + Interrupt::DNAK::SET
867 + Interrupt::ARBLST::SET,
868 );
869 }
870 self.dma.map(|dma| {
871 let buf = dma.abort_transfer().unwrap();
872 dma.prepare_transfer(dma_periph, buf, len);
873 dma.start_transfer();
874 });
875 }
876 }
877 }
878 }
879
880 fn setup_transfer(
881 &self,
882 twim: &TWIMRegisterManager,
883 chip: u8,
884 flags: FieldValue<u32, Command::Register>,
885 direction: FieldValue<u32, Command::Register>,
886 len: usize,
887 ) {
888 twim.registers.cr.write(Control::MDIS::SET);
890
891 twim.registers.cmdr.write(
893 Command::SADR.val(chip as u32)
894 + flags
895 + Command::VALID::SET
896 + Command::NBYTES.val(len as u32)
897 + direction,
898 );
899 twim.registers.ncmdr.set(0);
900
901 twim.registers.ier.write(
903 Interrupt::CCOMP::SET
904 + Interrupt::ANAK::SET
905 + Interrupt::DNAK::SET
906 + Interrupt::ARBLST::SET,
907 );
908 }
909
910 fn setup_nextfer(
911 &self,
912 twim: &TWIMRegisterManager,
913 chip: u8,
914 flags: FieldValue<u32, Command::Register>,
915 direction: FieldValue<u32, Command::Register>,
916 len: usize,
917 ) {
918 twim.registers.cr.write(Control::MDIS::SET);
920
921 twim.registers.ncmdr.write(
922 Command::SADR.val(chip as u32)
923 + flags
924 + Command::VALID::SET
925 + Command::NBYTES.val(len as u32)
926 + direction,
927 );
928
929 twim.registers.cr.write(Control::MEN::SET);
931 }
932
933 fn master_enable(&self, twim: &TWIMRegisterManager) {
934 twim.registers.cr.write(Control::MEN::SET);
936 }
937
938 fn write(
939 &self,
940 chip: u8,
941 flags: FieldValue<u32, Command::Register>,
942 data: &'static mut [u8],
943 len: usize,
944 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
945 let twim = &TWIMRegisterManager::new(self);
946 if self.dma.is_some() {
947 self.dma.map(move |dma| {
948 dma.enable();
949 dma.prepare_transfer(self.dma_pids.1, data, len);
950 self.setup_transfer(twim, chip, flags, Command::READ::Transmit, len);
951 self.master_enable(twim);
952 dma.start_transfer();
953 });
954 Ok(())
955 } else {
956 Err((hil::i2c::Error::NotSupported, data))
957 }
958 }
959
960 fn read(
961 &self,
962 chip: u8,
963 flags: FieldValue<u32, Command::Register>,
964 data: &'static mut [u8],
965 len: usize,
966 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
967 let twim = &TWIMRegisterManager::new(self);
968 if self.dma.is_some() {
969 self.dma.map(move |dma| {
970 dma.enable();
971 dma.prepare_transfer(self.dma_pids.0, data, len);
972 self.setup_transfer(twim, chip, flags, Command::READ::Receive, len);
973 self.master_enable(twim);
974 dma.start_transfer();
975 });
976 Ok(())
977 } else {
978 Err((hil::i2c::Error::NotSupported, data))
979 }
980 }
981
982 fn write_read(
983 &self,
984 chip: u8,
985 data: &'static mut [u8],
986 split: usize,
987 read_len: usize,
988 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
989 let twim = &TWIMRegisterManager::new(self);
990 if self.dma.is_some() {
991 self.dma.map(move |dma| {
992 dma.enable();
993 dma.prepare_transfer(self.dma_pids.1, data, split);
994 self.setup_transfer(
995 twim,
996 chip,
997 Command::START::StartCondition,
998 Command::READ::Transmit,
999 split,
1000 );
1001 self.setup_nextfer(
1002 twim,
1003 chip,
1004 Command::START::StartCondition + Command::STOP::SendStop,
1005 Command::READ::Receive,
1006 read_len,
1007 );
1008 self.on_deck.set(Some((self.dma_pids.0, read_len)));
1009 dma.start_transfer();
1010 });
1011 Ok(())
1012 } else {
1013 Err((hil::i2c::Error::NotSupported, data))
1014 }
1015 }
1016
1017 fn disable_interrupts(&self, twim: &TWIMRegisterManager) {
1018 twim.registers.idr.set(!0);
1019 }
1020
1021 pub fn handle_slave_interrupt(&self) {
1023 if self.slave_mmio_address.is_some() {
1024 let twis = &TWISRegisterManager::new(self);
1025
1026 let status = twis.registers.sr.extract();
1028 let imr = twis.registers.imr.extract();
1029 let interrupts = status.bitand(imr.get());
1032
1033 if interrupts.any_matching_bits_set(
1035 StatusSlave::BUSERR::SET
1036 + StatusSlave::SMBPECERR::SET
1037 + StatusSlave::SMBTOUT::SET
1038 + StatusSlave::ORUN::SET
1039 + StatusSlave::URUN::SET,
1040 ) {
1041 if interrupts.is_set(StatusSlave::BUSERR) {
1045 twis.registers.scr.set(status.get());
1047 return;
1048 }
1049
1050 panic!("ERR 0x{:x}", interrupts.get());
1051 }
1052
1053 if interrupts.is_set(StatusSlave::SAM) {
1055 twis.registers.nbytes.write(Nbytes::NBYTES.val(0));
1056
1057 if status.is_set(StatusSlave::TRA) {
1059 twis.registers.scr.write(StatusClearSlave::BTF::SET);
1064
1065 twis.registers
1067 .ier
1068 .write(InterruptSlave::TCOMP::SET + InterruptSlave::BTF::SET);
1069 twis.registers.ier.write(
1070 InterruptSlave::BUSERR::SET
1071 + InterruptSlave::SMBPECERR::SET
1072 + InterruptSlave::SMBTOUT::SET
1073 + InterruptSlave::ORUN::SET
1074 + InterruptSlave::URUN::SET,
1075 );
1076
1077 if self.slave_read_buffer.is_some() {
1078 self.slave_read_buffer_index.set(0);
1080 let len = self.slave_read_buffer_len.get();
1081
1082 if len >= 1 {
1083 self.slave_read_buffer.map(|buffer| {
1084 twis.registers
1085 .thr
1086 .write(TransmitHolding::TXDATA.val(buffer[0] as u32));
1087 });
1088 self.slave_read_buffer_index.set(1);
1089 } else {
1090 twis.registers.thr.write(TransmitHolding::TXDATA.val(0x2e));
1092 }
1093
1094 twis.registers.scr.set(status.get());
1096 } else {
1097 self.slave_client.get().map(|client| {
1099 client.read_expected();
1100 });
1101 }
1102 } else {
1103 twis.registers
1107 .ier
1108 .write(InterruptSlave::TCOMP::SET + InterruptSlave::RXRDY::SET);
1109
1110 self.slave_write_buffer_index.set(0);
1112
1113 if self.slave_write_buffer.is_some() {
1114 twis.registers.scr.set(status.get());
1116 } else {
1117 self.slave_client.get().map(|client| {
1120 client.write_expected();
1121 });
1122 }
1123 }
1124 } else {
1125 if interrupts.is_set(StatusSlave::TCOMP) {
1128 let nbytes = twis.registers.nbytes.get();
1131
1132 twis.registers.idr.set(!0);
1133 twis.registers.ier.write(InterruptSlave::SAM::SET);
1134 twis.registers.scr.set(status.get());
1135
1136 if status.is_set(StatusSlave::TRA) {
1137 self.slave_client.get().map(|client| {
1139 self.slave_read_buffer.take().map(|buffer| {
1140 client.command_complete(
1141 buffer,
1142 nbytes as usize,
1143 hil::i2c::SlaveTransmissionType::Read,
1144 );
1145 });
1146 });
1147 } else {
1148 let len = self.slave_write_buffer_len.get();
1151 let idx = self.slave_write_buffer_index.get();
1152
1153 if len > idx {
1154 self.slave_write_buffer.map(|buffer| {
1155 buffer[idx] = twis.registers.rhr.read(ReceiveHolding::RXDATA) as u8;
1156 });
1157 self.slave_write_buffer_index.set(idx + 1);
1158 } else {
1159 twis.registers.rhr.get();
1161 }
1162
1163 self.slave_client.get().map(|client| {
1164 self.slave_write_buffer.take().map(|buffer| {
1165 client.command_complete(
1166 buffer,
1167 nbytes as usize,
1168 hil::i2c::SlaveTransmissionType::Write,
1169 );
1170 });
1171 });
1172 }
1173 } else if interrupts.is_set(StatusSlave::BTF) {
1174 if self.slave_read_buffer.is_some() {
1178 let len = self.slave_read_buffer_len.get();
1180 let idx = self.slave_read_buffer_index.get();
1181
1182 if len > idx {
1183 self.slave_read_buffer.map(|buffer| {
1184 twis.registers
1185 .thr
1186 .write(TransmitHolding::TXDATA.val(buffer[idx] as u32));
1187 });
1188 self.slave_read_buffer_index.set(idx + 1);
1189 } else {
1190 twis.registers.thr.write(TransmitHolding::TXDATA.val(0xdf));
1192 }
1193 } else {
1194 twis.registers.thr.write(TransmitHolding::TXDATA.val(0xdc));
1196 }
1197
1198 twis.registers.scr.set(status.get());
1200 } else if interrupts.is_set(StatusSlave::RXRDY) {
1201 if self.slave_write_buffer.is_some() {
1204 if status.is_set(StatusSlave::BTF)
1212 || self.slave_write_buffer_index.get() > 0
1213 {
1214 let len = self.slave_write_buffer_len.get();
1216 let idx = self.slave_write_buffer_index.get();
1217
1218 if len > idx {
1219 self.slave_write_buffer.map(|buffer| {
1220 buffer[idx] =
1221 twis.registers.rhr.read(ReceiveHolding::RXDATA) as u8;
1222 });
1223 self.slave_write_buffer_index.set(idx + 1);
1224 } else {
1225 twis.registers.rhr.get();
1227 }
1228 } else {
1229 twis.registers.rhr.get();
1231 }
1232 } else {
1233 twis.registers.rhr.get();
1235 }
1236
1237 twis.registers.scr.set(status.get());
1238 }
1239 }
1240 }
1241 }
1242
1243 fn slave_write_receive(
1245 &self,
1246 buffer: &'static mut [u8],
1247 len: usize,
1248 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1249 if self.slave_enabled.get() {
1250 if self.slave_mmio_address.is_some() {
1251 self.slave_write_buffer.replace(buffer);
1252 self.slave_write_buffer_len.set(len);
1253 let twis = &TWISRegisterManager::new(self);
1254
1255 let status = twis.registers.sr.extract();
1256 let imr = twis.registers.imr.extract();
1257 let interrupts = status.bitand(imr.get());
1258
1259 if interrupts.is_set(StatusSlave::SAM) && !status.is_set(StatusSlave::TRA) {
1262 twis.registers.scr.set(status.get());
1263 }
1264 Ok(())
1265 } else {
1266 Err((hil::i2c::Error::AddressNak, buffer))
1267 }
1268 } else {
1269 Err((hil::i2c::Error::NotSupported, buffer))
1270 }
1271 }
1272
1273 fn slave_read_send(
1275 &self,
1276 buffer: &'static mut [u8],
1277 len: usize,
1278 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1279 if self.slave_enabled.get() {
1280 if self.slave_mmio_address.is_some() {
1281 self.slave_read_buffer.replace(buffer);
1282 self.slave_read_buffer_len.set(len);
1283 self.slave_read_buffer_index.set(0);
1284 let twis = &TWISRegisterManager::new(self);
1285
1286 let status = twis.registers.sr.extract();
1288 let imr = twis.registers.imr.extract();
1289 let interrupts = status.bitand(imr.get());
1290
1291 if interrupts.is_set(StatusSlave::SAM) && status.is_set(StatusSlave::TRA) {
1295 twis.registers.scr.write(StatusClearSlave::BTF::SET);
1296
1297 let len = self.slave_read_buffer_len.get();
1298
1299 if len >= 1 {
1300 self.slave_read_buffer.map(|buffer| {
1301 twis.registers
1302 .thr
1303 .write(TransmitHolding::TXDATA.val(buffer[0] as u32));
1304 });
1305 self.slave_read_buffer_index.set(1);
1306 } else {
1307 twis.registers.thr.write(TransmitHolding::TXDATA.val(0x75));
1309 }
1310
1311 twis.registers.scr.set(status.get());
1313 }
1314 Ok(())
1315 } else {
1316 Err((hil::i2c::Error::AddressNak, buffer))
1317 }
1318 } else {
1319 Err((hil::i2c::Error::NotSupported, buffer))
1320 }
1321 }
1322
1323 fn slave_disable_interrupts(&self, twis: &TWISRegisterManager) {
1324 twis.registers.idr.set(!0);
1325 }
1326
1327 fn slave_set_address(&self, address: u8) {
1328 self.my_slave_address.set(address);
1329 }
1330
1331 fn slave_listen(&self) {
1332 if self.slave_mmio_address.is_some() {
1333 let twis = &TWISRegisterManager::new(self);
1334
1335 let control = ControlSlave::ADR.val((self.my_slave_address.get() as u32) & 0x7F)
1337 + ControlSlave::SOAM::Stretch
1338 + ControlSlave::CUP::CountUp
1339 + ControlSlave::STREN::Enable
1340 + ControlSlave::SMATCH::AckSlaveAddress;
1341 twis.registers.cr.write(control);
1342
1343 twis.registers.cr.write(control + ControlSlave::SEN::Enable);
1345 }
1346 }
1347}
1348
1349impl DMAClient for I2CHw<'_> {
1350 fn transfer_done(&self, _pid: DMAPeripheral) {}
1351}
1352
1353impl<'a> hil::i2c::I2CMaster<'a> for I2CHw<'a> {
1354 fn set_master_client(&self, client: &'a dyn hil::i2c::I2CHwMasterClient) {
1355 self.master_client.set(Some(client));
1356 }
1357 fn enable(&self) {
1359 hil::i2c::I2CSlave::disable(self);
1361
1362 let twim = &TWIMRegisterManager::new(self);
1363
1364 twim.registers.cr.write(Control::MEN::SET);
1366 twim.registers.cr.write(Control::SWRST::SET);
1367 twim.registers.cr.write(Control::MDIS::SET);
1368
1369 self.set_bus_speed(twim);
1371
1372 twim.registers.srr.write(
1374 SlewRate::FILTER::StandardOrFast
1375 + SlewRate::CLDRIVEL.val(7)
1376 + SlewRate::DADRIVEL.val(7),
1377 );
1378
1379 twim.registers.scr.set(!0);
1381 }
1382
1383 fn disable(&self) {
1385 let twim = &TWIMRegisterManager::new(self);
1386 twim.registers.cr.write(Control::MDIS::SET);
1387 self.disable_interrupts(twim);
1388 }
1389
1390 fn write(
1391 &self,
1392 addr: u8,
1393 data: &'static mut [u8],
1394 len: usize,
1395 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1396 I2CHw::write(
1397 self,
1398 addr,
1399 Command::START::StartCondition + Command::STOP::SendStop,
1400 data,
1401 len,
1402 )
1403 }
1404
1405 fn read(
1406 &self,
1407 addr: u8,
1408 data: &'static mut [u8],
1409 len: usize,
1410 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1411 I2CHw::read(
1412 self,
1413 addr,
1414 Command::START::StartCondition + Command::STOP::SendStop,
1415 data,
1416 len,
1417 )
1418 }
1419
1420 fn write_read(
1421 &self,
1422 addr: u8,
1423 data: &'static mut [u8],
1424 write_len: usize,
1425 read_len: usize,
1426 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1427 I2CHw::write_read(self, addr, data, write_len, read_len)
1428 }
1429}
1430
1431impl<'a> hil::i2c::I2CSlave<'a> for I2CHw<'a> {
1432 fn set_slave_client(&self, client: &'a dyn hil::i2c::I2CHwSlaveClient) {
1433 self.slave_client.set(Some(client));
1434 }
1435 fn enable(&self) {
1436 if self.slave_mmio_address.is_some() {
1437 let twis = &TWISRegisterManager::new(self);
1438
1439 twis.registers.cr.write(ControlSlave::SEN::SET);
1441 twis.registers.cr.write(ControlSlave::SWRST::SET);
1442 twis.registers.cr.set(0);
1443
1444 twis.registers
1446 .srr
1447 .write(SlewRateSlave::FILTER.val(0x2) + SlewRateSlave::DADRIVEL.val(7));
1448
1449 twis.registers.scr.set(!0);
1451
1452 twis.registers.ier.write(InterruptSlave::SAM::SET);
1456
1457 twis.registers.ier.write(
1459 InterruptSlave::BUSERR::SET
1460 + InterruptSlave::SMBPECERR::SET
1461 + InterruptSlave::SMBTOUT::SET
1462 + InterruptSlave::ORUN::SET
1463 + InterruptSlave::URUN::SET,
1464 );
1465 }
1466
1467 self.slave_enabled.set(true);
1468 }
1469
1470 fn disable(&self) {
1472 self.slave_enabled.set(false);
1473
1474 if self.slave_mmio_address.is_some() {
1475 let twis = &TWISRegisterManager::new(self);
1476 twis.registers.cr.set(0);
1477 self.slave_disable_interrupts(twis);
1478 }
1479 }
1480
1481 fn set_address(&self, addr: u8) -> Result<(), hil::i2c::Error> {
1482 self.slave_set_address(addr);
1483 Ok(())
1484 }
1485
1486 fn write_receive(
1487 &self,
1488 data: &'static mut [u8],
1489 max_len: usize,
1490 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1491 self.slave_write_receive(data, max_len)
1492 }
1493
1494 fn read_send(
1495 &self,
1496 data: &'static mut [u8],
1497 max_len: usize,
1498 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1499 self.slave_read_send(data, max_len)
1500 }
1501
1502 fn listen(&self) {
1503 self.slave_listen();
1504 }
1505}