aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/i2c
diff options
context:
space:
mode:
authorHybridChild <[email protected]>2025-08-11 19:56:52 +0200
committerHybridChild <[email protected]>2025-08-23 08:53:48 +0200
commitfd7158063d38ece65f6f3f13422b2d744e8a144f (patch)
treeb85ab3f804c51bf9564bf73d9a030fbbf0cbc40d /embassy-stm32/src/i2c
parent4f7febc34eab0dd5822f313854338997f6dbf617 (diff)
stm32/i2c_v1: Clean up slave implementation
Diffstat (limited to 'embassy-stm32/src/i2c')
-rw-r--r--embassy-stm32/src/i2c/v1.rs992
1 files changed, 470 insertions, 522 deletions
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs
index 9022c2f5d..8f4128b45 100644
--- a/embassy-stm32/src/i2c/v1.rs
+++ b/embassy-stm32/src/i2c/v1.rs
@@ -32,21 +32,6 @@ impl State {
32 } 32 }
33} 33}
34 34
35#[derive(Debug, PartialEq)]
36enum SlaveSendResult {
37 Acked, // Byte sent and ACK received from master
38 Nacked, // Byte sent but NACK received (normal end of transmission)
39 Stopped, // STOP condition detected
40 Restart, // RESTART condition detected
41}
42
43#[derive(Debug, PartialEq)]
44enum SlaveReceiveResult {
45 Byte(u8), // Data byte received
46 Stop, // STOP condition detected
47 Restart, // RESTART condition (new ADDR) detected
48}
49
50// /!\ /!\ 35// /!\ /!\
51// /!\ Implementation note! /!\ 36// /!\ Implementation note! /!\
52// /!\ /!\ 37// /!\ /!\
@@ -387,513 +372,6 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
387 } 372 }
388} 373}
389 374
390impl<'d, M: Mode> I2c<'d, M, Master> {
391 /// Configure the I2C driver for slave operations, allowing for the driver to be used as a slave and a master (multimaster)
392 pub fn into_slave_multimaster(mut self, slave_addr_config: SlaveAddrConfig) -> I2c<'d, M, MultiMaster> {
393 let mut slave = I2c {
394 info: self.info,
395 state: self.state,
396 kernel_clock: self.kernel_clock,
397 tx_dma: self.tx_dma.take(), // Use take() to move ownership
398 rx_dma: self.rx_dma.take(), // Use take() to move ownership
399 #[cfg(feature = "time")]
400 timeout: self.timeout,
401 _phantom: PhantomData,
402 _phantom2: PhantomData,
403 _drop_guard: self._drop_guard, // Move the drop guard
404 };
405 slave.init_slave(slave_addr_config);
406 slave
407 }
408}
409
410impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
411 /// Slave configuration with v1 address setup
412 pub(crate) fn init_slave(&mut self, config: SlaveAddrConfig) {
413 trace!("i2c v1 slave init: config={:?}", config);
414
415 // Disable peripheral for configuration
416 self.info.regs.cr1().modify(|reg| {
417 reg.set_pe(false);
418 });
419
420 // Configure addresses with proper v1 format
421 self.configure_addresses(config);
422
423 // Configure general call if requested
424 if config.general_call {
425 self.info.regs.cr1().modify(|w| w.set_engc(true));
426 trace!("i2c v1 slave: General call enabled");
427 }
428
429 // Log final configuration before enabling
430 let cr1 = self.info.regs.cr1().read();
431 let oar1 = self.info.regs.oar1().read();
432 let oar2 = self.info.regs.oar2().read();
433 trace!("i2c v1 slave: Pre-enable state - CR1={:#x}, OAR1={:#x}, OAR2={:#x}",
434 cr1.0, oar1.0, oar2.0);
435 trace!("i2c v1 slave: Address details - OAR1.ADD={:#x}, OAR1.ADDMODE={}, bit14={}",
436 oar1.add(), oar1.addmode() as u8, (oar1.0 >> 14) & 1);
437
438 self.info.regs.cr1().modify(|reg| {
439 reg.set_pe(true); // Re-enable peripheral
440 reg.set_ack(true); // Critical for slave to ACK its address
441 });
442
443 // Verify peripheral is enabled and ready
444 let cr1_final = self.info.regs.cr1().read();
445 trace!("i2c v1 slave: Final state - CR1={:#x}, PE={}", cr1_final.0, cr1_final.pe());
446
447 trace!("i2c v1 slave init complete");
448 }
449
450 fn configure_oa1(&mut self, addr: Address) {
451 match addr {
452 Address::SevenBit(addr) => {
453 trace!("i2c v1 slave: Setting OA1 7-bit address: input={:#x}", addr);
454 self.info.regs.oar1().write(|reg| {
455 // For I2C v1, the 7-bit address goes in bits [7:1] of the ADD field
456 // The ADD field spans bits [9:0], so we put the address in the correct position
457 let hw_addr = (addr as u16) << 1; // This puts address in bits [7:1], bit [0] = 0
458 reg.set_add(hw_addr);
459 reg.set_addmode(i2c::vals::Addmode::BIT7);
460 });
461
462 // CRITICAL: Set bit 14 as required by the reference manual
463 // "Bit 14: Should always be kept at 1 by software"
464 self.info.regs.oar1().modify(|reg| {
465 reg.0 |= 1 << 14; // Set bit 14
466 });
467
468 let oar1_verify = self.info.regs.oar1().read();
469 trace!("i2c v1 slave: OA1 configured - OAR1={:#x}, stored_addr={:#x}, bit14={}",
470 oar1_verify.0, oar1_verify.add(), (oar1_verify.0 >> 14) & 1);
471 },
472 Address::TenBit(addr) => {
473 trace!("i2c v1 slave: Setting OA1 10-bit address: {:#x}", addr);
474 self.info.regs.oar1().write(|reg| {
475 reg.set_add(addr); // For 10-bit, full address goes in ADD field
476 reg.set_addmode(i2c::vals::Addmode::BIT10);
477 });
478
479 // Set required bit 14 for 10-bit mode too
480 self.info.regs.oar1().modify(|reg| {
481 reg.0 |= 1 << 14; // Set bit 14
482 });
483
484 let oar1_verify = self.info.regs.oar1().read();
485 trace!("i2c v1 slave: OA1 10-bit configured - OAR1={:#x}, bit14={}",
486 oar1_verify.0, (oar1_verify.0 >> 14) & 1);
487 }
488 }
489 }
490
491 fn configure_oa2_simple(&mut self, addr: u8) {
492 trace!("i2c v1 slave: Setting OA2 address: {:#x}", addr);
493 self.info.regs.oar2().write(|reg| {
494 // For OA2, the address goes in bits [7:1] of the ADD2 field
495 reg.set_add2(addr); // ADD2 field automatically handles bits [7:1] placement
496 reg.set_endual(i2c::vals::Endual::DUAL); // Enable dual addressing
497 });
498
499 let oar2_verify = self.info.regs.oar2().read();
500 trace!("i2c v1 slave: OA2 configured - OAR2={:#x}, ADD2={:#x}, ENDUAL={}",
501 oar2_verify.0, oar2_verify.add2(), oar2_verify.endual() as u8);
502 }
503
504 fn configure_addresses(&mut self, config: SlaveAddrConfig) {
505 match config.addr {
506 OwnAddresses::OA1(addr) => {
507 self.configure_oa1(addr);
508 // Disable OA2 if not needed
509 self.info.regs.oar2().write(|reg| {
510 reg.set_endual(i2c::vals::Endual::SINGLE);
511 });
512 },
513 OwnAddresses::OA2(oa2) => {
514 // v1 limitation: ignore mask, only support simple OA2
515 if !matches!(oa2.mask, AddrMask::NOMASK) {
516 // Could log a warning here that masking is ignored in v1
517 #[cfg(feature = "defmt")]
518 warn!("I2C v1 does not support OA2 address masking, ignoring mask setting");
519 }
520
521 // Must have a default OA1 when using OA2-only mode
522 // Set OA1 to a reserved address that won't conflict
523 self.info.regs.oar1().write(|reg| {
524 reg.set_add(0); // Address 0x00 is reserved, safe to use
525 reg.set_addmode(i2c::vals::Addmode::BIT7);
526 });
527
528 self.configure_oa2_simple(oa2.addr);
529 },
530 OwnAddresses::Both { oa1, oa2 } => {
531 self.configure_oa1(oa1);
532
533 // Same masking limitation applies
534 if !matches!(oa2.mask, AddrMask::NOMASK) {
535 #[cfg(feature = "defmt")]
536 defmt::warn!("I2C v1 does not support OA2 address masking, ignoring mask setting");
537 }
538
539 self.configure_oa2_simple(oa2.addr);
540 }
541 }
542
543 // Configure general call if requested
544 if config.general_call {
545 self.info.regs.cr1().modify(|w| w.set_engc(true));
546 }
547 }
548}
549
550impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
551 /// Listen for incoming I2C address match and return the command type
552 pub fn blocking_listen(&mut self) -> Result<SlaveCommand, Error> {
553 trace!("i2c v1 slave: blocking_listen start");
554 let timeout = self.timeout(); // Get timeout internally
555 let result = self.blocking_listen_timeout(timeout);
556 trace!("i2c v1 slave: blocking_listen result={:?}", result);
557 result
558 }
559
560 /// Respond to master read request (master wants to read from us)
561 pub fn blocking_respond_to_read(&mut self, data: &[u8]) -> Result<usize, Error> {
562 trace!("i2c v1 slave: blocking_respond_to_read start, data_len={}", data.len());
563 let timeout = self.timeout(); // Get timeout internally
564 let result = self.blocking_respond_to_read_timeout(data, timeout);
565 trace!("i2c v1 slave: blocking_respond_to_read result={:?}", result);
566 result
567 }
568
569 /// Respond to master write request (master wants to write to us)
570 pub fn blocking_respond_to_write(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
571 trace!("i2c v1 slave: blocking_respond_to_write start, buffer_len={}", buffer.len());
572 let timeout = self.timeout(); // Get timeout internally
573 let result = self.blocking_respond_to_write_timeout(buffer, timeout);
574 trace!("i2c v1 slave: blocking_respond_to_write result={:?}", result);
575 result
576 }
577
578 // Private implementation methods with Timeout parameter
579 fn blocking_listen_timeout(&mut self, timeout: Timeout) -> Result<SlaveCommand, Error> {
580 trace!("i2c v1 slave: listen_timeout start");
581
582 // Disable interrupts for blocking operation
583 self.info.regs.cr2().modify(|w| {
584 w.set_itevten(false);
585 w.set_iterren(false);
586 });
587
588 // Wait for address match (ADDR flag)
589 loop {
590 let sr1 = Self::check_slave_error_flags_and_get_sr1(self.info)?;
591
592 if sr1.addr() {
593 // Address matched! Read SR2 to get direction and clear ADDR
594 let sr2 = self.info.regs.sr2().read();
595 let direction = if sr2.tra() {
596 trace!("i2c v1 slave: address match - READ direction");
597 SlaveCommandKind::Read
598 } else {
599 trace!("i2c v1 slave: address match - WRITE direction");
600 SlaveCommandKind::Write
601 };
602
603 // Determine which address was matched
604 let matched_address = self.determine_matched_address(sr2)?;
605 trace!("i2c v1 slave: matched address={:?}", matched_address);
606
607 // ADDR is automatically cleared by reading SR1 then SR2
608 return Ok(SlaveCommand {
609 kind: direction,
610 address: matched_address,
611 });
612 }
613
614 timeout.check()?;
615 }
616 }
617
618 fn blocking_respond_to_read_timeout(&mut self, data: &[u8], timeout: Timeout) -> Result<usize, Error> {
619 trace!("i2c v1 slave: respond_to_read_timeout start, data_len={}", data.len());
620 let mut bytes_sent = 0;
621 let mut data_exhausted = false;
622
623 loop {
624 // Determine what byte to send
625 let byte_to_send = if bytes_sent < data.len() {
626 // Send real data
627 data[bytes_sent]
628 } else {
629 // Data exhausted - send padding bytes
630 if !data_exhausted {
631 trace!("i2c v1 slave: real data exhausted, sending padding bytes");
632 data_exhausted = true;
633 }
634 0x00 // Send zeros as padding (or 0xFF, or last byte repeated)
635 };
636
637 trace!("i2c v1 slave: sending byte={:#x} ({})", byte_to_send, bytes_sent);
638 match self.send_byte_or_nack(byte_to_send, timeout)? {
639 SlaveSendResult::Acked => {
640 bytes_sent += 1;
641 trace!("i2c v1 slave: byte acked, total_sent={}", bytes_sent);
642 // Continue sending more bytes
643 },
644 SlaveSendResult::Nacked => {
645 bytes_sent += 1; // Count the NACKed byte as sent
646 trace!("i2c v1 slave: byte nacked by master (normal completion), total_sent={}", bytes_sent);
647 break; // Normal end of transmission
648 },
649 SlaveSendResult::Stopped => {
650 trace!("i2c v1 slave: stop condition detected, stopping transmission");
651 break; // Master sent STOP
652 }
653 SlaveSendResult::Restart => {
654 trace!("i2c v1 slave: restart detected, stopping transmission");
655 break; // Master sent RESTART
656 }
657 }
658 }
659
660 trace!("i2c v1 slave: respond_to_read_timeout complete, bytes_sent={}", bytes_sent);
661 Ok(bytes_sent) // Return total bytes sent (including padding)
662 }
663
664 fn blocking_respond_to_write_timeout(&mut self, buffer: &mut [u8], timeout: Timeout) -> Result<usize, Error> {
665 trace!("i2c v1 slave: respond_to_write_timeout start, buffer_len={}", buffer.len());
666 let mut bytes_received = 0;
667 let buffer_capacity = buffer.len();
668 let mut overflow_detected = false;
669
670 while bytes_received < buffer_capacity {
671 match self.recv_byte_or_stop(timeout)? {
672 SlaveReceiveResult::Byte(b) => {
673 trace!("i2c v1 slave: received byte={:#x} ({})", b, bytes_received);
674 buffer[bytes_received] = b;
675 bytes_received += 1;
676 },
677 SlaveReceiveResult::Stop => {
678 trace!("i2c v1 slave: stop condition detected, stopping reception");
679 break;
680 },
681 SlaveReceiveResult::Restart => {
682 trace!("i2c v1 slave: restart detected, stopping reception");
683 break;
684 },
685 }
686 }
687
688 // Handle buffer overflow - continue receiving but discard bytes
689 if bytes_received >= buffer_capacity {
690 loop {
691 match self.recv_byte_or_stop(timeout)? {
692 SlaveReceiveResult::Byte(b) => {
693 if !overflow_detected {
694 trace!("i2c v1 slave: buffer full, discarding excess bytes");
695 overflow_detected = true;
696 }
697 trace!("i2c v1 slave: discarding overflow byte={:#x}", b);
698 // Byte is discarded but we still ACK it
699 },
700 SlaveReceiveResult::Stop => {
701 trace!("i2c v1 slave: stop condition detected after overflow");
702 break;
703 },
704 SlaveReceiveResult::Restart => {
705 trace!("i2c v1 slave: restart detected after overflow");
706 break;
707 },
708 }
709 }
710 }
711
712 if overflow_detected {
713 trace!("i2c v1 slave: transaction complete with overflow - received {} bytes, buffer held {}",
714 bytes_received, buffer_capacity);
715 } else {
716 trace!("i2c v1 slave: respond_to_write_timeout complete, bytes_received={}", bytes_received);
717 }
718
719 Ok(bytes_received.min(buffer_capacity)) // Return stored bytes, not total received
720 }
721
722 fn determine_matched_address(&self, sr2: stm32_metapac::i2c::regs::Sr2) -> Result<Address, Error> {
723 trace!("i2c v1 slave: determine_matched_address, sr2={:#x}", sr2.0);
724 // Check for general call first
725 if sr2.gencall() {
726 trace!("i2c v1 slave: general call address matched");
727 Ok(Address::SevenBit(0x00))
728 } else if sr2.dualf() {
729 // OA2 was matched - verify it's actually enabled
730 let oar2 = self.info.regs.oar2().read();
731 if oar2.endual() != i2c::vals::Endual::DUAL {
732 error!("i2c v1 slave: OA2 matched but not enabled - hardware inconsistency");
733 return Err(Error::Bus); // Hardware inconsistency
734 }
735 trace!("i2c v1 slave: OA2 address matched: {:#x}", oar2.add2());
736 Ok(Address::SevenBit(oar2.add2()))
737 } else {
738 // OA1 was matched
739 let oar1 = self.info.regs.oar1().read();
740 match oar1.addmode() {
741 i2c::vals::Addmode::BIT7 => {
742 let addr = (oar1.add() >> 1) as u8;
743 trace!("i2c v1 slave: OA1 7-bit address matched: {:#x}", addr);
744 Ok(Address::SevenBit(addr))
745 },
746 i2c::vals::Addmode::BIT10 => {
747 trace!("i2c v1 slave: OA1 10-bit address matched: {:#x}", oar1.add());
748 Ok(Address::TenBit(oar1.add()))
749 },
750 }
751 }
752 }
753
754 /// Send a byte in slave transmitter mode and check for ACK/NACK/STOP
755 fn send_byte_or_nack(&mut self, byte: u8, timeout: Timeout) -> Result<SlaveSendResult, Error> {
756 trace!("i2c v1 slave: send_byte_or_nack start, byte={:#x}", byte);
757
758 // Wait until we're ready for sending (TXE flag set)
759 loop {
760 let sr1 = Self::check_slave_error_flags_and_get_sr1(self.info)?;
761
762 // Check for STOP condition first
763 if sr1.stopf() {
764 trace!("i2c v1 slave: STOP detected before send");
765 self.info.regs.cr1().modify(|_w| {});
766 return Ok(SlaveSendResult::Stopped);
767 }
768
769 // Check for RESTART (new ADDR)
770 if sr1.addr() {
771 trace!("i2c v1 slave: RESTART detected before send");
772 return Ok(SlaveSendResult::Restart);
773 }
774
775 // Check for NACK (AF flag) before writing
776 let sr1_current = self.info.regs.sr1().read();
777 if sr1_current.af() {
778 trace!("i2c v1 slave: NACK detected before send");
779 self.info.regs.sr1().write(|reg| {
780 reg.0 = !0;
781 reg.set_af(false);
782 });
783 return Ok(SlaveSendResult::Nacked);
784 }
785
786 // Check if we can send data
787 if sr1.txe() {
788 trace!("i2c v1 slave: TXE ready, sending byte");
789 break; // Ready to send
790 }
791
792 timeout.check()?;
793 }
794
795 // Send the byte
796 self.info.regs.dr().write(|w| w.set_dr(byte));
797 trace!("i2c v1 slave: byte written to DR, waiting for completion");
798
799 // Wait for completion - but be more flexible about what constitutes "completion"
800 // In slave transmitter mode, we need to detect:
801 // 1. BTF - byte transfer finished (normal case)
802 // 2. AF (NACK) - master signals end of transaction
803 // 3. STOP - master terminates transaction
804 // 4. ADDR - master starts new transaction (restart)
805 loop {
806 // Get current flags without error handling that clears AF
807 let sr1 = self.info.regs.sr1().read();
808
809 // Check for NACK FIRST - this is the most likely end condition
810 if sr1.af() {
811 trace!("i2c v1 slave: NACK detected after send");
812 // Clear the AF flag
813 self.info.regs.sr1().write(|reg| {
814 reg.0 = !0;
815 reg.set_af(false);
816 });
817 return Ok(SlaveSendResult::Nacked);
818 }
819
820 // Check for STOP condition
821 if sr1.stopf() {
822 trace!("i2c v1 slave: STOP detected after send");
823 self.info.regs.cr1().modify(|_w| {});
824 return Ok(SlaveSendResult::Stopped);
825 }
826
827 // Check for RESTART (new ADDR)
828 if sr1.addr() {
829 trace!("i2c v1 slave: RESTART detected after send");
830 return Ok(SlaveSendResult::Restart);
831 }
832
833 // Check for byte transfer finished (normal ACK case)
834 if sr1.btf() {
835 trace!("i2c v1 slave: BTF set, byte transfer complete (ACK)");
836 return Ok(SlaveSendResult::Acked);
837 }
838
839 // Check for other error conditions that should be propagated
840 if sr1.timeout() || sr1.ovr() || sr1.arlo() || sr1.berr() {
841 // Use the error handling function for these
842 match Self::check_and_clear_error_flags(self.info) {
843 Ok(_) => {}, // Shouldn't happen given the flags we checked
844 Err(e) => return Err(e),
845 }
846 }
847
848 timeout.check()?;
849 }
850 }
851
852 /// Receive a byte in slave receiver mode or detect STOP condition
853 fn recv_byte_or_stop(&mut self, timeout: Timeout) -> Result<SlaveReceiveResult, Error> {
854 trace!("i2c v1 slave: recv_byte_or_stop start");
855 loop {
856 let sr1 = Self::check_slave_error_flags_and_get_sr1(self.info)?;
857
858 // Check for received data FIRST (handles race condition)
859 if sr1.rxne() {
860 let byte = self.info.regs.dr().read().dr();
861 trace!("i2c v1 slave: received byte={:#x}", byte);
862 return Ok(SlaveReceiveResult::Byte(byte));
863 }
864
865 // Check for RESTART (new ADDR) before STOP
866 if sr1.addr() {
867 trace!("i2c v1 slave: RESTART detected during receive");
868 return Ok(SlaveReceiveResult::Restart);
869 }
870
871 // Check for STOP condition LAST
872 if sr1.stopf() {
873 trace!("i2c v1 slave: STOP detected during receive");
874 self.info.regs.cr1().modify(|_w| {});
875 return Ok(SlaveReceiveResult::Stop);
876 }
877
878 timeout.check()?;
879 }
880 }
881
882 /// Wrapper that treats AF (NACK) as normal protocol behavior in slave mode
883 fn check_slave_error_flags_and_get_sr1(info: &'static Info) -> Result<i2c::regs::Sr1, Error> {
884 match Self::check_and_clear_error_flags(info) {
885 Ok(sr1) => Ok(sr1),
886 Err(Error::Nack) => {
887 // AF flag was set and cleared by check_and_clear_error_flags
888 // In slave mode, this is normal protocol behavior, not an error
889 // Read SR1 again to get current state (AF should now be cleared)
890 Ok(info.regs.sr1().read())
891 },
892 Err(other_error) => Err(other_error), // Propagate real errors
893 }
894 }
895}
896
897impl<'d, IM: MasterMode> I2c<'d, Async, IM> { 375impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
898 async fn write_with_framing(&mut self, address: u8, write_buffer: &[u8], framing: OperationFraming) -> Result<(), Error> { 376 async fn write_with_framing(&mut self, address: u8, write_buffer: &[u8], framing: OperationFraming) -> Result<(), Error> {
899 self.info.regs.cr2().modify(|w| { 377 self.info.regs.cr2().modify(|w| {
@@ -1240,6 +718,476 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
1240 } 718 }
1241} 719}
1242 720
721/// Result of attempting to send a byte in slave transmitter mode
722#[derive(Debug, PartialEq)]
723enum TransmitResult {
724 /// Byte sent and ACKed by master - continue transmission
725 Acknowledged,
726 /// Byte sent but NACKed by master - normal end of read transaction
727 NotAcknowledged,
728 /// STOP condition detected - master terminated transaction
729 Stopped,
730 /// RESTART condition detected - master starting new transaction
731 Restarted,
732}
733
734/// Result of attempting to receive a byte in slave receiver mode
735#[derive(Debug, PartialEq)]
736enum ReceiveResult {
737 /// Data byte successfully received
738 Data(u8),
739 /// STOP condition detected - end of write transaction
740 Stopped,
741 /// RESTART condition detected - master starting new transaction
742 Restarted,
743}
744
745impl<'d, M: Mode> I2c<'d, M, Master> {
746 /// Configure the I2C driver for slave operations, allowing for the driver to be used as a slave and a master (multimaster)
747 pub fn into_slave_multimaster(mut self, slave_addr_config: SlaveAddrConfig) -> I2c<'d, M, MultiMaster> {
748 let mut slave = I2c {
749 info: self.info,
750 state: self.state,
751 kernel_clock: self.kernel_clock,
752 tx_dma: self.tx_dma.take(), // Use take() to move ownership
753 rx_dma: self.rx_dma.take(), // Use take() to move ownership
754 #[cfg(feature = "time")]
755 timeout: self.timeout,
756 _phantom: PhantomData,
757 _phantom2: PhantomData,
758 _drop_guard: self._drop_guard, // Move the drop guard
759 };
760 slave.init_slave(slave_addr_config);
761 slave
762 }
763}
764
765impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
766 /// Listen for incoming I2C address match and return the command type
767 ///
768 /// This method blocks until the slave address is matched by a master.
769 /// Returns the command type (Read/Write) and the matched address.
770 pub fn blocking_listen(&mut self) -> Result<SlaveCommand, Error> {
771 trace!("I2C slave: listening for address match");
772 let result = self.blocking_listen_with_timeout(self.timeout());
773 trace!("I2C slave: listen result={:?}", result);
774 result
775 }
776
777 /// Respond to a master read request by transmitting data
778 ///
779 /// Sends the provided data to the master. If the master requests more bytes
780 /// than available, padding bytes (0x00) are sent until the master terminates
781 /// the transaction with NACK.
782 ///
783 /// Returns the total number of bytes transmitted (including padding).
784 pub fn blocking_respond_to_read(&mut self, data: &[u8]) -> Result<usize, Error> {
785 trace!("I2C slave: responding to read, data_len={}", data.len());
786 let result = self.transmit_to_master(data, self.timeout());
787 trace!("I2C slave: read response complete, result={:?}", result);
788 result
789 }
790
791 /// Respond to a master write request by receiving data
792 ///
793 /// Receives data from the master into the provided buffer. If the master
794 /// sends more bytes than the buffer can hold, excess bytes are acknowledged
795 /// but discarded.
796 ///
797 /// Returns the number of bytes stored in the buffer (not total received).
798 pub fn blocking_respond_to_write(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
799 trace!("I2C slave: responding to write, buffer_len={}", buffer.len());
800 let result = self.receive_from_master(buffer, self.timeout());
801 trace!("I2C slave: write response complete, result={:?}", result);
802 result
803 }
804
805 // Private implementation methods
806
807 /// Wait for address match and determine transaction type
808 fn blocking_listen_with_timeout(&mut self, timeout: Timeout) -> Result<SlaveCommand, Error> {
809 // Ensure interrupts are disabled for blocking operation
810 self.disable_i2c_interrupts();
811
812 // Wait for address match (ADDR flag)
813 loop {
814 let sr1 = Self::read_status_and_handle_errors(self.info)?;
815
816 if sr1.addr() {
817 // Address matched - read SR2 to get direction and clear ADDR flag
818 let sr2 = self.info.regs.sr2().read();
819 let direction = if sr2.tra() {
820 SlaveCommandKind::Read
821 } else {
822 SlaveCommandKind::Write
823 };
824
825 let matched_address = self.decode_matched_address(sr2)?;
826 trace!("I2C slave: address matched, direction={:?}, addr={:?}", direction, matched_address);
827
828 return Ok(SlaveCommand {
829 kind: direction,
830 address: matched_address,
831 });
832 }
833
834 timeout.check()?;
835 }
836 }
837
838 /// Transmit data to master in response to read request
839 fn transmit_to_master(&mut self, data: &[u8], timeout: Timeout) -> Result<usize, Error> {
840 let mut bytes_transmitted = 0;
841
842 loop {
843 // Determine next byte to send
844 let byte_to_send = if bytes_transmitted < data.len() {
845 data[bytes_transmitted]
846 } else {
847 0x00 // Send padding bytes when data is exhausted
848 };
849
850 // Attempt to send the byte
851 match self.transmit_byte(byte_to_send, timeout)? {
852 TransmitResult::Acknowledged => {
853 bytes_transmitted += 1;
854 // Continue transmission
855 },
856 TransmitResult::NotAcknowledged => {
857 bytes_transmitted += 1; // Count the NACKed byte
858 break; // Normal end of read transaction
859 },
860 TransmitResult::Stopped | TransmitResult::Restarted => {
861 break; // Transaction terminated by master
862 }
863 }
864 }
865
866 Ok(bytes_transmitted)
867 }
868
869 /// Receive data from master during write request
870 fn receive_from_master(&mut self, buffer: &mut [u8], timeout: Timeout) -> Result<usize, Error> {
871 let mut bytes_stored = 0;
872
873 // Receive bytes that fit in buffer
874 while bytes_stored < buffer.len() {
875 match self.receive_byte(timeout)? {
876 ReceiveResult::Data(byte) => {
877 buffer[bytes_stored] = byte;
878 bytes_stored += 1;
879 },
880 ReceiveResult::Stopped | ReceiveResult::Restarted => {
881 return Ok(bytes_stored);
882 },
883 }
884 }
885
886 // Handle buffer overflow by discarding excess bytes
887 if bytes_stored == buffer.len() {
888 trace!("I2C slave: buffer full, discarding excess bytes");
889 self.discard_excess_bytes(timeout)?;
890 }
891
892 Ok(bytes_stored)
893 }
894
895 /// Discard excess bytes when buffer is full
896 fn discard_excess_bytes(&mut self, timeout: Timeout) -> Result<(), Error> {
897 loop {
898 match self.receive_byte(timeout)? {
899 ReceiveResult::Data(_) => {
900 // Byte received and ACKed, but discarded
901 continue;
902 },
903 ReceiveResult::Stopped | ReceiveResult::Restarted => {
904 break; // Transaction completed
905 },
906 }
907 }
908 Ok(())
909 }
910
911 /// Send a single byte and wait for master's response
912 fn transmit_byte(&mut self, byte: u8, timeout: Timeout) -> Result<TransmitResult, Error> {
913 // Wait for transmit buffer ready
914 self.wait_for_transmit_ready(timeout)?;
915
916 // Send the byte
917 self.info.regs.dr().write(|w| w.set_dr(byte));
918
919 // Wait for transmission completion or master response
920 self.wait_for_transmit_completion(timeout)
921 }
922
923 /// Wait until transmit buffer is ready (TXE flag set)
924 fn wait_for_transmit_ready(&mut self, timeout: Timeout) -> Result<(), Error> {
925 loop {
926 let sr1 = Self::read_status_and_handle_errors(self.info)?;
927
928 // Check for early termination conditions
929 if let Some(result) = Self::check_early_termination(sr1) {
930 return Err(self.handle_early_termination(result));
931 }
932
933 if sr1.txe() {
934 return Ok(()); // Ready to transmit
935 }
936
937 timeout.check()?;
938 }
939 }
940
941 /// Wait for byte transmission completion or master response
942 fn wait_for_transmit_completion(&mut self, timeout: Timeout) -> Result<TransmitResult, Error> {
943 loop {
944 let sr1 = self.info.regs.sr1().read();
945
946 // Check flags in priority order
947 if sr1.af() {
948 self.clear_acknowledge_failure();
949 return Ok(TransmitResult::NotAcknowledged);
950 }
951
952 if sr1.btf() {
953 return Ok(TransmitResult::Acknowledged);
954 }
955
956 if sr1.stopf() {
957 self.clear_stop_flag();
958 return Ok(TransmitResult::Stopped);
959 }
960
961 if sr1.addr() {
962 return Ok(TransmitResult::Restarted);
963 }
964
965 // Check for other error conditions
966 self.check_for_hardware_errors(sr1)?;
967
968 timeout.check()?;
969 }
970 }
971
972 /// Receive a single byte or detect transaction termination
973 fn receive_byte(&mut self, timeout: Timeout) -> Result<ReceiveResult, Error> {
974 loop {
975 let sr1 = Self::read_status_and_handle_errors(self.info)?;
976
977 // Check for received data first (prioritize data over control signals)
978 if sr1.rxne() {
979 let byte = self.info.regs.dr().read().dr();
980 return Ok(ReceiveResult::Data(byte));
981 }
982
983 // Check for transaction termination
984 if sr1.addr() {
985 return Ok(ReceiveResult::Restarted);
986 }
987
988 if sr1.stopf() {
989 self.clear_stop_flag();
990 return Ok(ReceiveResult::Stopped);
991 }
992
993 timeout.check()?;
994 }
995 }
996
997 /// Determine which slave address was matched based on SR2 flags
998 fn decode_matched_address(&self, sr2: i2c::regs::Sr2) -> Result<Address, Error> {
999 if sr2.gencall() {
1000 Ok(Address::SevenBit(0x00)) // General call address
1001 } else if sr2.dualf() {
1002 // OA2 (secondary address) was matched
1003 let oar2 = self.info.regs.oar2().read();
1004 if oar2.endual() != i2c::vals::Endual::DUAL {
1005 return Err(Error::Bus); // Hardware inconsistency
1006 }
1007 Ok(Address::SevenBit(oar2.add2()))
1008 } else {
1009 // OA1 (primary address) was matched
1010 let oar1 = self.info.regs.oar1().read();
1011 match oar1.addmode() {
1012 i2c::vals::Addmode::BIT7 => {
1013 let addr = (oar1.add() >> 1) as u8;
1014 Ok(Address::SevenBit(addr))
1015 },
1016 i2c::vals::Addmode::BIT10 => {
1017 Ok(Address::TenBit(oar1.add()))
1018 },
1019 }
1020 }
1021 }
1022
1023 // Helper methods for hardware interaction
1024
1025 /// Read status register and handle I2C errors (except NACK in slave mode)
1026 fn read_status_and_handle_errors(info: &'static Info) -> Result<i2c::regs::Sr1, Error> {
1027 match Self::check_and_clear_error_flags(info) {
1028 Ok(sr1) => Ok(sr1),
1029 Err(Error::Nack) => {
1030 // In slave mode, NACK is normal protocol behavior, not an error
1031 Ok(info.regs.sr1().read())
1032 },
1033 Err(other_error) => Err(other_error),
1034 }
1035 }
1036
1037 /// Check for conditions that cause early termination of operations
1038 fn check_early_termination(sr1: i2c::regs::Sr1) -> Option<TransmitResult> {
1039 if sr1.stopf() {
1040 Some(TransmitResult::Stopped)
1041 } else if sr1.addr() {
1042 Some(TransmitResult::Restarted)
1043 } else if sr1.af() {
1044 Some(TransmitResult::NotAcknowledged)
1045 } else {
1046 None
1047 }
1048 }
1049
1050 /// Convert early termination to appropriate error
1051 fn handle_early_termination(&mut self, result: TransmitResult) -> Error {
1052 match result {
1053 TransmitResult::Stopped => {
1054 self.clear_stop_flag();
1055 Error::Bus // Unexpected STOP during setup
1056 },
1057 TransmitResult::Restarted => {
1058 Error::Bus // Unexpected RESTART during setup
1059 },
1060 TransmitResult::NotAcknowledged => {
1061 self.clear_acknowledge_failure();
1062 Error::Bus // Unexpected NACK during setup
1063 },
1064 TransmitResult::Acknowledged => {
1065 unreachable!() // This should never be passed to this function
1066 }
1067 }
1068 }
1069
1070 /// Check for hardware-level I2C errors during transmission
1071 fn check_for_hardware_errors(&self, sr1: i2c::regs::Sr1) -> Result<(), Error> {
1072 if sr1.timeout() || sr1.ovr() || sr1.arlo() || sr1.berr() {
1073 // Delegate to existing error handling
1074 Self::check_and_clear_error_flags(self.info)?;
1075 }
1076 Ok(())
1077 }
1078
1079 /// Disable I2C event and error interrupts for blocking operations
1080 fn disable_i2c_interrupts(&mut self) {
1081 self.info.regs.cr2().modify(|w| {
1082 w.set_itevten(false);
1083 w.set_iterren(false);
1084 });
1085 }
1086
1087 /// Clear the acknowledge failure flag
1088 fn clear_acknowledge_failure(&mut self) {
1089 self.info.regs.sr1().write(|reg| {
1090 reg.0 = !0;
1091 reg.set_af(false);
1092 });
1093 }
1094
1095 /// Clear the stop condition flag
1096 fn clear_stop_flag(&mut self) {
1097 self.info.regs.cr1().modify(|_w| {});
1098 }
1099}
1100
1101// Address configuration methods
1102impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
1103 /// Initialize slave mode with address configuration
1104 pub(crate) fn init_slave(&mut self, config: SlaveAddrConfig) {
1105 trace!("I2C slave: initializing with config={:?}", config);
1106
1107 // Disable peripheral for configuration
1108 self.info.regs.cr1().modify(|reg| reg.set_pe(false));
1109
1110 // Configure slave addresses
1111 self.apply_address_configuration(config);
1112
1113 // Enable peripheral with slave settings
1114 self.info.regs.cr1().modify(|reg| {
1115 reg.set_pe(true);
1116 reg.set_ack(true); // Enable acknowledgment for slave mode
1117 });
1118
1119 trace!("I2C slave: initialization complete");
1120 }
1121
1122 /// Apply the complete address configuration for slave mode
1123 fn apply_address_configuration(&mut self, config: SlaveAddrConfig) {
1124 match config.addr {
1125 OwnAddresses::OA1(addr) => {
1126 self.configure_primary_address(addr);
1127 self.disable_secondary_address();
1128 },
1129 OwnAddresses::OA2(oa2) => {
1130 self.configure_default_primary_address();
1131 self.configure_secondary_address(oa2.addr); // v1 ignores mask
1132 },
1133 OwnAddresses::Both { oa1, oa2 } => {
1134 self.configure_primary_address(oa1);
1135 self.configure_secondary_address(oa2.addr); // v1 ignores mask
1136 }
1137 }
1138
1139 // Configure general call detection
1140 if config.general_call {
1141 self.info.regs.cr1().modify(|w| w.set_engc(true));
1142 }
1143 }
1144
1145 /// Configure the primary address (OA1) register
1146 fn configure_primary_address(&mut self, addr: Address) {
1147 match addr {
1148 Address::SevenBit(addr) => {
1149 self.info.regs.oar1().write(|reg| {
1150 let hw_addr = (addr as u16) << 1; // Address in bits [7:1]
1151 reg.set_add(hw_addr);
1152 reg.set_addmode(i2c::vals::Addmode::BIT7);
1153 });
1154 },
1155 Address::TenBit(addr) => {
1156 self.info.regs.oar1().write(|reg| {
1157 reg.set_add(addr);
1158 reg.set_addmode(i2c::vals::Addmode::BIT10);
1159 });
1160 }
1161 }
1162
1163 // Set required bit 14 as per reference manual
1164 self.info.regs.oar1().modify(|reg| reg.0 |= 1 << 14);
1165 }
1166
1167 /// Configure the secondary address (OA2) register
1168 fn configure_secondary_address(&mut self, addr: u8) {
1169 self.info.regs.oar2().write(|reg| {
1170 reg.set_add2(addr);
1171 reg.set_endual(i2c::vals::Endual::DUAL);
1172 });
1173 }
1174
1175 /// Set a default primary address when using OA2-only mode
1176 fn configure_default_primary_address(&mut self) {
1177 self.info.regs.oar1().write(|reg| {
1178 reg.set_add(0); // Reserved address, safe to use
1179 reg.set_addmode(i2c::vals::Addmode::BIT7);
1180 });
1181 self.info.regs.oar1().modify(|reg| reg.0 |= 1 << 14);
1182 }
1183
1184 /// Disable secondary address when not needed
1185 fn disable_secondary_address(&mut self) {
1186 self.info.regs.oar2().write(|reg| {
1187 reg.set_endual(i2c::vals::Endual::SINGLE);
1188 });
1189 }
1190}
1243 1191
1244/// Timing configuration for I2C v1 hardware 1192/// Timing configuration for I2C v1 hardware
1245/// 1193///