aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHybridChild <[email protected]>2025-08-10 10:05:26 +0200
committerHybridChild <[email protected]>2025-08-23 08:53:43 +0200
commit6570036f141befc76fd5f5237db0045c0b0f9a71 (patch)
treedfcd32a242895442d77c988ec994e6929209afcf
parentb88c5195e030b6fac129ea9cb74eb169227f7335 (diff)
stm32/i2c_v1: Add defmt trace messages
-rw-r--r--embassy-stm32/src/i2c/v1.rs75
1 files changed, 65 insertions, 10 deletions
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs
index 7b6ecf869..3aa003fa5 100644
--- a/embassy-stm32/src/i2c/v1.rs
+++ b/embassy-stm32/src/i2c/v1.rs
@@ -60,6 +60,7 @@ enum SlaveReceiveResult {
60// hit a case like this! 60// hit a case like this!
61pub unsafe fn on_interrupt<T: Instance>() { 61pub unsafe fn on_interrupt<T: Instance>() {
62 let regs = T::info().regs; 62 let regs = T::info().regs;
63 trace!("i2c v1 interrupt triggered");
63 // i2c v2 only woke the task on transfer complete interrupts. v1 uses interrupts for a bunch of 64 // i2c v2 only woke the task on transfer complete interrupts. v1 uses interrupts for a bunch of
64 // other stuff, so we wake the task on every interrupt. 65 // other stuff, so we wake the task on every interrupt.
65 T::state().waker.wake(); 66 T::state().waker.wake();
@@ -122,6 +123,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
122 self.info.regs.cr1().modify(|reg| { 123 self.info.regs.cr1().modify(|reg| {
123 reg.set_pe(true); 124 reg.set_pe(true);
124 }); 125 });
126 trace!("i2c v1 init complete");
125 } 127 }
126 128
127 fn check_and_clear_error_flags(info: &'static Info) -> Result<i2c::regs::Sr1, Error> { 129 fn check_and_clear_error_flags(info: &'static Info) -> Result<i2c::regs::Sr1, Error> {
@@ -407,6 +409,7 @@ impl<'d, M: Mode> I2c<'d, M, Master> {
407 409
408impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> { 410impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
409 pub(crate) fn init_slave(&mut self, config: SlaveAddrConfig) { 411 pub(crate) fn init_slave(&mut self, config: SlaveAddrConfig) {
412 trace!("i2c v1 slave init: config={:?}", config);
410 // Disable peripheral for configuration 413 // Disable peripheral for configuration
411 self.info.regs.cr1().modify(|reg| { 414 self.info.regs.cr1().modify(|reg| {
412 reg.set_pe(false); 415 reg.set_pe(false);
@@ -425,6 +428,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
425 self.info.regs.cr1().modify(|reg| { 428 self.info.regs.cr1().modify(|reg| {
426 reg.set_pe(true); 429 reg.set_pe(true);
427 }); 430 });
431 trace!("i2c v1 slave init complete");
428 } 432 }
429 433
430 fn configure_oa1(&mut self, addr: Address) { 434 fn configure_oa1(&mut self, addr: Address) {
@@ -471,7 +475,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
471 if !matches!(oa2.mask, AddrMask::NOMASK) { 475 if !matches!(oa2.mask, AddrMask::NOMASK) {
472 // Could log a warning here that masking is ignored in v1 476 // Could log a warning here that masking is ignored in v1
473 #[cfg(feature = "defmt")] 477 #[cfg(feature = "defmt")]
474 defmt::warn!("I2C v1 does not support OA2 address masking, ignoring mask setting"); 478 warn!("I2C v1 does not support OA2 address masking, ignoring mask setting");
475 } 479 }
476 480
477 // Must have a default OA1 when using OA2-only mode 481 // Must have a default OA1 when using OA2-only mode
@@ -506,24 +510,34 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
506impl<'d, M: Mode> I2c<'d, M, MultiMaster> { 510impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
507 /// Listen for incoming I2C address match and return the command type 511 /// Listen for incoming I2C address match and return the command type
508 pub fn blocking_listen(&mut self) -> Result<SlaveCommand, Error> { 512 pub fn blocking_listen(&mut self) -> Result<SlaveCommand, Error> {
513 trace!("i2c v1 slave: blocking_listen start");
509 let timeout = self.timeout(); // Get timeout internally 514 let timeout = self.timeout(); // Get timeout internally
510 self.blocking_listen_timeout(timeout) 515 let result = self.blocking_listen_timeout(timeout);
516 trace!("i2c v1 slave: blocking_listen result={:?}", result);
517 result
511 } 518 }
512 519
513 /// Respond to master read request (master wants to read from us) 520 /// Respond to master read request (master wants to read from us)
514 pub fn blocking_respond_to_read(&mut self, data: &[u8]) -> Result<usize, Error> { 521 pub fn blocking_respond_to_read(&mut self, data: &[u8]) -> Result<usize, Error> {
522 trace!("i2c v1 slave: blocking_respond_to_read start, data_len={}", data.len());
515 let timeout = self.timeout(); // Get timeout internally 523 let timeout = self.timeout(); // Get timeout internally
516 self.blocking_respond_to_read_timeout(data, timeout) 524 let result = self.blocking_respond_to_read_timeout(data, timeout);
525 trace!("i2c v1 slave: blocking_respond_to_read result={:?}", result);
526 result
517 } 527 }
518 528
519 /// Respond to master write request (master wants to write to us) 529 /// Respond to master write request (master wants to write to us)
520 pub fn blocking_respond_to_write(&mut self, buffer: &mut [u8]) -> Result<usize, Error> { 530 pub fn blocking_respond_to_write(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
531 trace!("i2c v1 slave: blocking_respond_to_write start, buffer_len={}", buffer.len());
521 let timeout = self.timeout(); // Get timeout internally 532 let timeout = self.timeout(); // Get timeout internally
522 self.blocking_respond_to_write_timeout(buffer, timeout) 533 let result = self.blocking_respond_to_write_timeout(buffer, timeout);
534 trace!("i2c v1 slave: blocking_respond_to_write result={:?}", result);
535 result
523 } 536 }
524 537
525 // Private implementation methods with Timeout parameter 538 // Private implementation methods with Timeout parameter
526 fn blocking_listen_timeout(&mut self, timeout: Timeout) -> Result<SlaveCommand, Error> { 539 fn blocking_listen_timeout(&mut self, timeout: Timeout) -> Result<SlaveCommand, Error> {
540 trace!("i2c v1 slave: listen_timeout start");
527 // Enable address match interrupt for slave mode 541 // Enable address match interrupt for slave mode
528 self.info.regs.cr2().modify(|w| { 542 self.info.regs.cr2().modify(|w| {
529 w.set_itevten(true); // Enable event interrupts 543 w.set_itevten(true); // Enable event interrupts
@@ -537,13 +551,16 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
537 // Address matched! Read SR2 to get direction and clear ADDR 551 // Address matched! Read SR2 to get direction and clear ADDR
538 let sr2 = self.info.regs.sr2().read(); 552 let sr2 = self.info.regs.sr2().read();
539 let direction = if sr2.tra() { 553 let direction = if sr2.tra() {
554 trace!("i2c v1 slave: address match - READ direction (master wants to read from us)");
540 SlaveCommandKind::Read // Master wants to read from us (we transmit) 555 SlaveCommandKind::Read // Master wants to read from us (we transmit)
541 } else { 556 } else {
557 trace!("i2c v1 slave: address match - WRITE direction (master wants to write to us)");
542 SlaveCommandKind::Write // Master wants to write to us (we receive) 558 SlaveCommandKind::Write // Master wants to write to us (we receive)
543 }; 559 };
544 560
545 // Determine which address was matched 561 // Determine which address was matched
546 let matched_address = self.determine_matched_address(sr2)?; 562 let matched_address = self.determine_matched_address(sr2)?;
563 trace!("i2c v1 slave: matched address={:?}", matched_address);
547 564
548 // ADDR is automatically cleared by reading SR1 then SR2 565 // ADDR is automatically cleared by reading SR1 then SR2
549 return Ok(SlaveCommand { 566 return Ok(SlaveCommand {
@@ -557,62 +574,86 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
557 } 574 }
558 575
559 fn blocking_respond_to_read_timeout(&mut self, data: &[u8], timeout: Timeout) -> Result<usize, Error> { 576 fn blocking_respond_to_read_timeout(&mut self, data: &[u8], timeout: Timeout) -> Result<usize, Error> {
577 trace!("i2c v1 slave: respond_to_read_timeout start, data_len={}", data.len());
560 let mut bytes_sent = 0; 578 let mut bytes_sent = 0;
561 579
562 for &byte in data { 580 for &byte in data {
581 trace!("i2c v1 slave: sending byte={:#x} ({})", byte, bytes_sent);
563 match self.send_byte_or_nack(byte, timeout)? { 582 match self.send_byte_or_nack(byte, timeout)? {
564 SlaveSendResult::Acked => { 583 SlaveSendResult::Acked => {
565 bytes_sent += 1; 584 bytes_sent += 1;
585 trace!("i2c v1 slave: byte acked, total_sent={}", bytes_sent);
566 // Continue sending 586 // Continue sending
567 }, 587 },
568 SlaveSendResult::Nacked | SlaveSendResult::Stopped => { 588 SlaveSendResult::Nacked => {
569 // Master finished reading or sent STOP 589 trace!("i2c v1 slave: byte nacked, stopping transmission");
590 break;
591 },
592 SlaveSendResult::Stopped => {
593 trace!("i2c v1 slave: stop condition detected, stopping transmission");
570 break; 594 break;
571 } 595 }
572 SlaveSendResult::Restart => { 596 SlaveSendResult::Restart => {
573 // Master wants to change direction (rare but possible) 597 trace!("i2c v1 slave: restart detected, stopping transmission");
574 break; 598 break;
575 } 599 }
576 } 600 }
577 } 601 }
578 602
603 trace!("i2c v1 slave: respond_to_read_timeout complete, bytes_sent={}", bytes_sent);
579 Ok(bytes_sent) 604 Ok(bytes_sent)
580 } 605 }
581 606
582 fn blocking_respond_to_write_timeout(&mut self, buffer: &mut [u8], timeout: Timeout) -> Result<usize, Error> { 607 fn blocking_respond_to_write_timeout(&mut self, buffer: &mut [u8], timeout: Timeout) -> Result<usize, Error> {
608 trace!("i2c v1 slave: respond_to_write_timeout start, buffer_len={}", buffer.len());
583 let mut bytes_received = 0; 609 let mut bytes_received = 0;
584 while bytes_received < buffer.len() { 610 while bytes_received < buffer.len() {
585 match self.recv_byte_or_stop(timeout)? { 611 match self.recv_byte_or_stop(timeout)? {
586 SlaveReceiveResult::Byte(b) => { 612 SlaveReceiveResult::Byte(b) => {
613 trace!("i2c v1 slave: received byte={:#x} ({})", b, bytes_received);
587 buffer[bytes_received] = b; 614 buffer[bytes_received] = b;
588 bytes_received += 1; 615 bytes_received += 1;
589 }, 616 },
590 SlaveReceiveResult::Stop => break, 617 SlaveReceiveResult::Stop => {
591 SlaveReceiveResult::Restart => break, 618 trace!("i2c v1 slave: stop condition detected, stopping reception");
619 break;
620 },
621 SlaveReceiveResult::Restart => {
622 trace!("i2c v1 slave: restart detected, stopping reception");
623 break;
624 },
592 } 625 }
593 } 626 }
627 trace!("i2c v1 slave: respond_to_write_timeout complete, bytes_received={}", bytes_received);
594 Ok(bytes_received) 628 Ok(bytes_received)
595 } 629 }
596 630
597 fn determine_matched_address(&self, sr2: stm32_metapac::i2c::regs::Sr2) -> Result<Address, Error> { 631 fn determine_matched_address(&self, sr2: stm32_metapac::i2c::regs::Sr2) -> Result<Address, Error> {
632 trace!("i2c v1 slave: determine_matched_address, sr2={:#x}", sr2.0);
598 // Check for general call first 633 // Check for general call first
599 if sr2.gencall() { 634 if sr2.gencall() {
635 trace!("i2c v1 slave: general call address matched");
600 Ok(Address::SevenBit(0x00)) 636 Ok(Address::SevenBit(0x00))
601 } else if sr2.dualf() { 637 } else if sr2.dualf() {
602 // OA2 was matched - verify it's actually enabled 638 // OA2 was matched - verify it's actually enabled
603 let oar2 = self.info.regs.oar2().read(); 639 let oar2 = self.info.regs.oar2().read();
604 if oar2.endual() != i2c::vals::Endual::DUAL { 640 if oar2.endual() != i2c::vals::Endual::DUAL {
641 error!("i2c v1 slave: OA2 matched but not enabled - hardware inconsistency");
605 return Err(Error::Bus); // Hardware inconsistency 642 return Err(Error::Bus); // Hardware inconsistency
606 } 643 }
644 trace!("i2c v1 slave: OA2 address matched: {:#x}", oar2.add2());
607 Ok(Address::SevenBit(oar2.add2())) 645 Ok(Address::SevenBit(oar2.add2()))
608 } else { 646 } else {
609 // OA1 was matched 647 // OA1 was matched
610 let oar1 = self.info.regs.oar1().read(); 648 let oar1 = self.info.regs.oar1().read();
611 match oar1.addmode() { 649 match oar1.addmode() {
612 i2c::vals::Addmode::BIT7 => { 650 i2c::vals::Addmode::BIT7 => {
613 Ok(Address::SevenBit((oar1.add() >> 1) as u8)) 651 let addr = (oar1.add() >> 1) as u8;
652 trace!("i2c v1 slave: OA1 7-bit address matched: {:#x}", addr);
653 Ok(Address::SevenBit(addr))
614 }, 654 },
615 i2c::vals::Addmode::BIT10 => { 655 i2c::vals::Addmode::BIT10 => {
656 trace!("i2c v1 slave: OA1 10-bit address matched: {:#x}", oar1.add());
616 Ok(Address::TenBit(oar1.add())) 657 Ok(Address::TenBit(oar1.add()))
617 }, 658 },
618 } 659 }
@@ -621,30 +662,35 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
621 662
622 /// Send a byte in slave transmitter mode and check for ACK/NACK/STOP 663 /// Send a byte in slave transmitter mode and check for ACK/NACK/STOP
623 fn send_byte_or_nack(&mut self, byte: u8, timeout: Timeout) -> Result<SlaveSendResult, Error> { 664 fn send_byte_or_nack(&mut self, byte: u8, timeout: Timeout) -> Result<SlaveSendResult, Error> {
665 trace!("i2c v1 slave: send_byte_or_nack start, byte={:#x}", byte);
624 // Wait until we're ready for sending (TXE flag set) 666 // Wait until we're ready for sending (TXE flag set)
625 loop { 667 loop {
626 let sr1 = Self::check_and_clear_error_flags(self.info)?; 668 let sr1 = Self::check_and_clear_error_flags(self.info)?;
627 669
628 // Check for STOP condition first 670 // Check for STOP condition first
629 if sr1.stopf() { 671 if sr1.stopf() {
672 trace!("i2c v1 slave: STOP detected before send");
630 self.info.regs.cr1().modify(|_w| {}); 673 self.info.regs.cr1().modify(|_w| {});
631 return Ok(SlaveSendResult::Stopped); 674 return Ok(SlaveSendResult::Stopped);
632 } 675 }
633 676
634 // Check for RESTART (new ADDR) 677 // Check for RESTART (new ADDR)
635 if sr1.addr() { 678 if sr1.addr() {
679 trace!("i2c v1 slave: RESTART detected before send");
636 // Don't clear ADDR here - let next blocking_listen() handle it 680 // Don't clear ADDR here - let next blocking_listen() handle it
637 return Ok(SlaveSendResult::Restart); 681 return Ok(SlaveSendResult::Restart);
638 } 682 }
639 683
640 // Check for NACK (AF flag) 684 // Check for NACK (AF flag)
641 if sr1.af() { 685 if sr1.af() {
686 trace!("i2c v1 slave: NACK detected before send");
642 self.info.regs.sr1().modify(|w| w.set_af(false)); 687 self.info.regs.sr1().modify(|w| w.set_af(false));
643 return Ok(SlaveSendResult::Nacked); 688 return Ok(SlaveSendResult::Nacked);
644 } 689 }
645 690
646 // Check if we can send data 691 // Check if we can send data
647 if sr1.txe() { 692 if sr1.txe() {
693 trace!("i2c v1 slave: TXE ready, sending byte");
648 break; // Ready to send 694 break; // Ready to send
649 } 695 }
650 696
@@ -653,6 +699,7 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
653 699
654 // Send the byte 700 // Send the byte
655 self.info.regs.dr().write(|w| w.set_dr(byte)); 701 self.info.regs.dr().write(|w| w.set_dr(byte));
702 trace!("i2c v1 slave: byte written to DR, waiting for BTF");
656 703
657 // Wait for byte transfer to complete (BTF flag or error) 704 // Wait for byte transfer to complete (BTF flag or error)
658 loop { 705 loop {
@@ -660,23 +707,27 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
660 707
661 // Check for STOP condition 708 // Check for STOP condition
662 if sr1.stopf() { 709 if sr1.stopf() {
710 trace!("i2c v1 slave: STOP detected after send");
663 self.info.regs.cr1().modify(|_w| {}); 711 self.info.regs.cr1().modify(|_w| {});
664 return Ok(SlaveSendResult::Stopped); 712 return Ok(SlaveSendResult::Stopped);
665 } 713 }
666 714
667 // Check for RESTART (new ADDR) 715 // Check for RESTART (new ADDR)
668 if sr1.addr() { 716 if sr1.addr() {
717 trace!("i2c v1 slave: RESTART detected after send");
669 return Ok(SlaveSendResult::Restart); 718 return Ok(SlaveSendResult::Restart);
670 } 719 }
671 720
672 // Check for NACK (AF flag) 721 // Check for NACK (AF flag)
673 if sr1.af() { 722 if sr1.af() {
723 trace!("i2c v1 slave: NACK detected after send");
674 self.info.regs.sr1().modify(|w| w.set_af(false)); 724 self.info.regs.sr1().modify(|w| w.set_af(false));
675 return Ok(SlaveSendResult::Nacked); 725 return Ok(SlaveSendResult::Nacked);
676 } 726 }
677 727
678 // Check for byte transfer finished 728 // Check for byte transfer finished
679 if sr1.btf() { 729 if sr1.btf() {
730 trace!("i2c v1 slave: BTF set, byte transfer complete");
680 return Ok(SlaveSendResult::Acked); 731 return Ok(SlaveSendResult::Acked);
681 } 732 }
682 733
@@ -686,23 +737,27 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
686 737
687 /// Receive a byte in slave receiver mode or detect STOP condition 738 /// Receive a byte in slave receiver mode or detect STOP condition
688 fn recv_byte_or_stop(&mut self, timeout: Timeout) -> Result<SlaveReceiveResult, Error> { 739 fn recv_byte_or_stop(&mut self, timeout: Timeout) -> Result<SlaveReceiveResult, Error> {
740 trace!("i2c v1 slave: recv_byte_or_stop start");
689 loop { 741 loop {
690 let sr1 = Self::check_and_clear_error_flags(self.info)?; 742 let sr1 = Self::check_and_clear_error_flags(self.info)?;
691 743
692 // Check for STOP condition first 744 // Check for STOP condition first
693 if sr1.stopf() { 745 if sr1.stopf() {
746 trace!("i2c v1 slave: STOP detected during receive");
694 self.info.regs.cr1().modify(|_w| {}); 747 self.info.regs.cr1().modify(|_w| {});
695 return Ok(SlaveReceiveResult::Stop); 748 return Ok(SlaveReceiveResult::Stop);
696 } 749 }
697 750
698 // Check for RESTART (new ADDR) 751 // Check for RESTART (new ADDR)
699 if sr1.addr() { 752 if sr1.addr() {
753 trace!("i2c v1 slave: RESTART detected during receive");
700 // Don't clear ADDR here - let next blocking_listen() handle it 754 // Don't clear ADDR here - let next blocking_listen() handle it
701 return Ok(SlaveReceiveResult::Restart); 755 return Ok(SlaveReceiveResult::Restart);
702 } 756 }
703 757
704 if sr1.rxne() { 758 if sr1.rxne() {
705 let byte = self.info.regs.dr().read().dr(); 759 let byte = self.info.regs.dr().read().dr();
760 trace!("i2c v1 slave: received byte={:#x}", byte);
706 return Ok(SlaveReceiveResult::Byte(byte)); 761 return Ok(SlaveReceiveResult::Byte(byte));
707 } 762 }
708 763