diff options
| author | HybridChild <[email protected]> | 2025-08-23 10:46:39 +0200 |
|---|---|---|
| committer | HybridChild <[email protected]> | 2025-08-23 10:46:39 +0200 |
| commit | 97d5de640a90ce31b81411a742b33d9b86d2b441 (patch) | |
| tree | 3775d177128f7d88b11f917978ba5744238b40f0 | |
| parent | a51c0320e907d895bb1f55e8960a69df5f5a276b (diff) | |
stm32: Run cargo fmt
| -rw-r--r-- | embassy-stm32/src/i2c/mod.rs | 12 | ||||
| -rw-r--r-- | embassy-stm32/src/i2c/v1.rs | 362 |
2 files changed, 212 insertions, 162 deletions
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index 00330c97e..7f5cde1c5 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs | |||
| @@ -442,7 +442,7 @@ impl<'d, IM: MasterMode> embedded_hal_async::i2c::I2c for I2c<'d, Async, IM> { | |||
| 442 | /// controlling the generation of start conditions (ST or SR), stop conditions (SP), | 442 | /// controlling the generation of start conditions (ST or SR), stop conditions (SP), |
| 443 | /// and ACK/NACK behavior for read operations. | 443 | /// and ACK/NACK behavior for read operations. |
| 444 | /// | 444 | /// |
| 445 | /// For write operations, some framing configurations are functionally identical | 445 | /// For write operations, some framing configurations are functionally identical |
| 446 | /// because they differ only in ACK/NACK treatment which is relevant only for reads: | 446 | /// because they differ only in ACK/NACK treatment which is relevant only for reads: |
| 447 | /// | 447 | /// |
| 448 | /// - `First` and `FirstAndNext` behave identically for writes | 448 | /// - `First` and `FirstAndNext` behave identically for writes |
| @@ -489,7 +489,7 @@ impl OperationFraming { | |||
| 489 | } | 489 | } |
| 490 | 490 | ||
| 491 | /// Returns true if NACK should be sent after the last byte received in a read operation. | 491 | /// Returns true if NACK should be sent after the last byte received in a read operation. |
| 492 | /// | 492 | /// |
| 493 | /// This signals the end of a read sequence and releases the bus for the master's | 493 | /// This signals the end of a read sequence and releases the bus for the master's |
| 494 | /// next transmission (or stop condition). | 494 | /// next transmission (or stop condition). |
| 495 | fn send_nack(self) -> bool { | 495 | fn send_nack(self) -> bool { |
| @@ -525,7 +525,7 @@ impl OperationFraming { | |||
| 525 | /// | 525 | /// |
| 526 | /// # Returns | 526 | /// # Returns |
| 527 | /// An iterator over (operation, framing) pairs, or an error if the transaction is invalid | 527 | /// An iterator over (operation, framing) pairs, or an error if the transaction is invalid |
| 528 | /// | 528 | /// |
| 529 | #[allow(dead_code)] | 529 | #[allow(dead_code)] |
| 530 | fn assign_operation_framing<'a, 'b: 'a>( | 530 | fn assign_operation_framing<'a, 'b: 'a>( |
| 531 | operations: &'a mut [embedded_hal_1::i2c::Operation<'b>], | 531 | operations: &'a mut [embedded_hal_1::i2c::Operation<'b>], |
| @@ -535,7 +535,7 @@ fn assign_operation_framing<'a, 'b: 'a>( | |||
| 535 | // Validate that no read operations have empty buffers before starting the transaction. | 535 | // Validate that no read operations have empty buffers before starting the transaction. |
| 536 | // Empty read operations would risk halting with an error mid-transaction. | 536 | // Empty read operations would risk halting with an error mid-transaction. |
| 537 | // | 537 | // |
| 538 | // Note: We could theoretically allow empty read operations within consecutive read | 538 | // Note: We could theoretically allow empty read operations within consecutive read |
| 539 | // sequences as long as the final merged read has at least one byte, but this would | 539 | // sequences as long as the final merged read has at least one byte, but this would |
| 540 | // complicate the logic significantly and create error-prone edge cases. | 540 | // complicate the logic significantly and create error-prone edge cases. |
| 541 | if operations.iter().any(|op| match op { | 541 | if operations.iter().any(|op| match op { |
| @@ -558,7 +558,7 @@ fn assign_operation_framing<'a, 'b: 'a>( | |||
| 558 | // Compute the appropriate framing based on three key properties: | 558 | // Compute the appropriate framing based on three key properties: |
| 559 | // | 559 | // |
| 560 | // 1. **Start Condition**: Generate (repeated) start for first operation of each type | 560 | // 1. **Start Condition**: Generate (repeated) start for first operation of each type |
| 561 | // 2. **Stop Condition**: Generate stop for the final operation in the entire transaction | 561 | // 2. **Stop Condition**: Generate stop for the final operation in the entire transaction |
| 562 | // 3. **ACK/NACK for Reads**: For read operations, send ACK if more reads follow in the | 562 | // 3. **ACK/NACK for Reads**: For read operations, send ACK if more reads follow in the |
| 563 | // sequence, or NACK for the final read in a sequence (before write or transaction end) | 563 | // sequence, or NACK for the final read in a sequence (before write or transaction end) |
| 564 | // | 564 | // |
| @@ -571,7 +571,7 @@ fn assign_operation_framing<'a, 'b: 'a>( | |||
| 571 | (true, Some(Read(_))) => OperationFraming::FirstAndNext, | 571 | (true, Some(Read(_))) => OperationFraming::FirstAndNext, |
| 572 | // First operation of type, next operation is write (end current sequence) | 572 | // First operation of type, next operation is write (end current sequence) |
| 573 | (true, Some(Write(_))) => OperationFraming::First, | 573 | (true, Some(Write(_))) => OperationFraming::First, |
| 574 | 574 | ||
| 575 | // Continuation operation, and it's the final operation overall | 575 | // Continuation operation, and it's the final operation overall |
| 576 | (false, None) => OperationFraming::Last, | 576 | (false, None) => OperationFraming::Last, |
| 577 | // Continuation operation, next operation is also a read (continue read sequence) | 577 | // Continuation operation, next operation is also a read (continue read sequence) |
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index 879d1686b..d1e15d6f2 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs | |||
| @@ -153,7 +153,13 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 153 | Ok(sr1) | 153 | Ok(sr1) |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | fn write_bytes(&mut self, address: u8, write_buffer: &[u8], timeout: Timeout, framing: OperationFraming) -> Result<(), Error> { | 156 | fn write_bytes( |
| 157 | &mut self, | ||
| 158 | address: u8, | ||
| 159 | write_buffer: &[u8], | ||
| 160 | timeout: Timeout, | ||
| 161 | framing: OperationFraming, | ||
| 162 | ) -> Result<(), Error> { | ||
| 157 | if framing.send_start() { | 163 | if framing.send_start() { |
| 158 | // Send a START condition | 164 | // Send a START condition |
| 159 | 165 | ||
| @@ -313,7 +319,12 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 313 | } | 319 | } |
| 314 | 320 | ||
| 315 | /// Blocking write, restart, read. | 321 | /// Blocking write, restart, read. |
| 316 | pub fn blocking_write_read(&mut self, address: u8, write_buffer: &[u8], read_buffer: &mut [u8]) -> Result<(), Error> { | 322 | pub fn blocking_write_read( |
| 323 | &mut self, | ||
| 324 | address: u8, | ||
| 325 | write_buffer: &[u8], | ||
| 326 | read_buffer: &mut [u8], | ||
| 327 | ) -> Result<(), Error> { | ||
| 317 | // Check empty read buffer before starting transaction. Otherwise, we would not generate the | 328 | // Check empty read buffer before starting transaction. Otherwise, we would not generate the |
| 318 | // stop condition below. | 329 | // stop condition below. |
| 319 | if read_buffer.is_empty() { | 330 | if read_buffer.is_empty() { |
| @@ -345,7 +356,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 345 | 356 | ||
| 346 | Ok(()) | 357 | Ok(()) |
| 347 | } | 358 | } |
| 348 | 359 | ||
| 349 | /// Can be used by both blocking and async implementations | 360 | /// Can be used by both blocking and async implementations |
| 350 | #[inline] // pretty sure this should always be inlined | 361 | #[inline] // pretty sure this should always be inlined |
| 351 | fn enable_interrupts(info: &'static Info) { | 362 | fn enable_interrupts(info: &'static Info) { |
| @@ -366,11 +377,15 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 366 | let _ = info.regs.sr1().read(); | 377 | let _ = info.regs.sr1().read(); |
| 367 | info.regs.cr1().modify(|_| {}); // Dummy write to clear STOPF | 378 | info.regs.cr1().modify(|_| {}); // Dummy write to clear STOPF |
| 368 | } | 379 | } |
| 369 | |||
| 370 | } | 380 | } |
| 371 | 381 | ||
| 372 | impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | 382 | impl<'d, IM: MasterMode> I2c<'d, Async, IM> { |
| 373 | async fn write_with_framing(&mut self, address: u8, write_buffer: &[u8], framing: OperationFraming) -> Result<(), Error> { | 383 | async fn write_with_framing( |
| 384 | &mut self, | ||
| 385 | address: u8, | ||
| 386 | write_buffer: &[u8], | ||
| 387 | framing: OperationFraming, | ||
| 388 | ) -> Result<(), Error> { | ||
| 374 | self.info.regs.cr2().modify(|w| { | 389 | self.info.regs.cr2().modify(|w| { |
| 375 | // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for | 390 | // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for |
| 376 | // reception. | 391 | // reception. |
| @@ -453,7 +468,10 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | |||
| 453 | // this address from the memory after each TxE event. | 468 | // this address from the memory after each TxE event. |
| 454 | let dst = self.info.regs.dr().as_ptr() as *mut u8; | 469 | let dst = self.info.regs.dr().as_ptr() as *mut u8; |
| 455 | 470 | ||
| 456 | self.tx_dma.as_mut().unwrap().write(write_buffer, dst, Default::default()) | 471 | self.tx_dma |
| 472 | .as_mut() | ||
| 473 | .unwrap() | ||
| 474 | .write(write_buffer, dst, Default::default()) | ||
| 457 | }; | 475 | }; |
| 458 | 476 | ||
| 459 | // Wait for bytes to be sent, or an error to occur. | 477 | // Wait for bytes to be sent, or an error to occur. |
| @@ -530,7 +548,12 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | |||
| 530 | Ok(()) | 548 | Ok(()) |
| 531 | } | 549 | } |
| 532 | 550 | ||
| 533 | async fn read_with_framing(&mut self, address: u8, read_buffer: &mut [u8], framing: OperationFraming) -> Result<(), Error> { | 551 | async fn read_with_framing( |
| 552 | &mut self, | ||
| 553 | address: u8, | ||
| 554 | read_buffer: &mut [u8], | ||
| 555 | framing: OperationFraming, | ||
| 556 | ) -> Result<(), Error> { | ||
| 534 | if read_buffer.is_empty() { | 557 | if read_buffer.is_empty() { |
| 535 | return Err(Error::Overrun); | 558 | return Err(Error::Overrun); |
| 536 | } | 559 | } |
| @@ -694,8 +717,10 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | |||
| 694 | return Err(Error::Overrun); | 717 | return Err(Error::Overrun); |
| 695 | } | 718 | } |
| 696 | 719 | ||
| 697 | self.write_with_framing(address, write_buffer, OperationFraming::First).await?; | 720 | self.write_with_framing(address, write_buffer, OperationFraming::First) |
| 698 | self.read_with_framing(address, read_buffer, OperationFraming::FirstAndLast).await | 721 | .await?; |
| 722 | self.read_with_framing(address, read_buffer, OperationFraming::FirstAndLast) | ||
| 723 | .await | ||
| 699 | } | 724 | } |
| 700 | 725 | ||
| 701 | /// Transaction with operations. | 726 | /// Transaction with operations. |
| @@ -758,13 +783,13 @@ impl<'d, M: Mode> I2c<'d, M, Master> { | |||
| 758 | info: self.info, | 783 | info: self.info, |
| 759 | state: self.state, | 784 | state: self.state, |
| 760 | kernel_clock: self.kernel_clock, | 785 | kernel_clock: self.kernel_clock, |
| 761 | tx_dma: self.tx_dma.take(), // Use take() to move ownership | 786 | tx_dma: self.tx_dma.take(), // Use take() to move ownership |
| 762 | rx_dma: self.rx_dma.take(), // Use take() to move ownership | 787 | rx_dma: self.rx_dma.take(), // Use take() to move ownership |
| 763 | #[cfg(feature = "time")] | 788 | #[cfg(feature = "time")] |
| 764 | timeout: self.timeout, | 789 | timeout: self.timeout, |
| 765 | _phantom: PhantomData, | 790 | _phantom: PhantomData, |
| 766 | _phantom2: PhantomData, | 791 | _phantom2: PhantomData, |
| 767 | _drop_guard: self._drop_guard, // Move the drop guard | 792 | _drop_guard: self._drop_guard, // Move the drop guard |
| 768 | }; | 793 | }; |
| 769 | slave.init_slave(slave_addr_config); | 794 | slave.init_slave(slave_addr_config); |
| 770 | slave | 795 | slave |
| @@ -776,46 +801,46 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 776 | /// Initialize slave mode with address configuration | 801 | /// Initialize slave mode with address configuration |
| 777 | pub(crate) fn init_slave(&mut self, config: SlaveAddrConfig) { | 802 | pub(crate) fn init_slave(&mut self, config: SlaveAddrConfig) { |
| 778 | trace!("I2C slave: initializing with config={:?}", config); | 803 | trace!("I2C slave: initializing with config={:?}", config); |
| 779 | 804 | ||
| 780 | // Disable peripheral for configuration | 805 | // Disable peripheral for configuration |
| 781 | self.info.regs.cr1().modify(|reg| reg.set_pe(false)); | 806 | self.info.regs.cr1().modify(|reg| reg.set_pe(false)); |
| 782 | 807 | ||
| 783 | // Configure slave addresses | 808 | // Configure slave addresses |
| 784 | self.apply_address_configuration(config); | 809 | self.apply_address_configuration(config); |
| 785 | 810 | ||
| 786 | // Enable peripheral with slave settings | 811 | // Enable peripheral with slave settings |
| 787 | self.info.regs.cr1().modify(|reg| { | 812 | self.info.regs.cr1().modify(|reg| { |
| 788 | reg.set_pe(true); | 813 | reg.set_pe(true); |
| 789 | reg.set_ack(true); // Enable acknowledgment for slave mode | 814 | reg.set_ack(true); // Enable acknowledgment for slave mode |
| 790 | reg.set_nostretch(false); // Allow clock stretching for processing time | 815 | reg.set_nostretch(false); // Allow clock stretching for processing time |
| 791 | }); | 816 | }); |
| 792 | 817 | ||
| 793 | trace!("I2C slave: initialization complete"); | 818 | trace!("I2C slave: initialization complete"); |
| 794 | } | 819 | } |
| 795 | 820 | ||
| 796 | /// Apply the complete address configuration for slave mode | 821 | /// Apply the complete address configuration for slave mode |
| 797 | fn apply_address_configuration(&mut self, config: SlaveAddrConfig) { | 822 | fn apply_address_configuration(&mut self, config: SlaveAddrConfig) { |
| 798 | match config.addr { | 823 | match config.addr { |
| 799 | OwnAddresses::OA1(addr) => { | 824 | OwnAddresses::OA1(addr) => { |
| 800 | self.configure_primary_address(addr); | 825 | self.configure_primary_address(addr); |
| 801 | self.disable_secondary_address(); | 826 | self.disable_secondary_address(); |
| 802 | }, | 827 | } |
| 803 | OwnAddresses::OA2(oa2) => { | 828 | OwnAddresses::OA2(oa2) => { |
| 804 | self.configure_default_primary_address(); | 829 | self.configure_default_primary_address(); |
| 805 | self.configure_secondary_address(oa2.addr); // v1 ignores mask | 830 | self.configure_secondary_address(oa2.addr); // v1 ignores mask |
| 806 | }, | 831 | } |
| 807 | OwnAddresses::Both { oa1, oa2 } => { | 832 | OwnAddresses::Both { oa1, oa2 } => { |
| 808 | self.configure_primary_address(oa1); | 833 | self.configure_primary_address(oa1); |
| 809 | self.configure_secondary_address(oa2.addr); // v1 ignores mask | 834 | self.configure_secondary_address(oa2.addr); // v1 ignores mask |
| 810 | } | 835 | } |
| 811 | } | 836 | } |
| 812 | 837 | ||
| 813 | // Configure general call detection | 838 | // Configure general call detection |
| 814 | if config.general_call { | 839 | if config.general_call { |
| 815 | self.info.regs.cr1().modify(|w| w.set_engc(true)); | 840 | self.info.regs.cr1().modify(|w| w.set_engc(true)); |
| 816 | } | 841 | } |
| 817 | } | 842 | } |
| 818 | 843 | ||
| 819 | /// Configure the primary address (OA1) register | 844 | /// Configure the primary address (OA1) register |
| 820 | fn configure_primary_address(&mut self, addr: Address) { | 845 | fn configure_primary_address(&mut self, addr: Address) { |
| 821 | match addr { | 846 | match addr { |
| @@ -825,7 +850,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 825 | reg.set_add(hw_addr); | 850 | reg.set_add(hw_addr); |
| 826 | reg.set_addmode(i2c::vals::Addmode::BIT7); | 851 | reg.set_addmode(i2c::vals::Addmode::BIT7); |
| 827 | }); | 852 | }); |
| 828 | }, | 853 | } |
| 829 | Address::TenBit(addr) => { | 854 | Address::TenBit(addr) => { |
| 830 | self.info.regs.oar1().write(|reg| { | 855 | self.info.regs.oar1().write(|reg| { |
| 831 | reg.set_add(addr); | 856 | reg.set_add(addr); |
| @@ -833,11 +858,11 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 833 | }); | 858 | }); |
| 834 | } | 859 | } |
| 835 | } | 860 | } |
| 836 | 861 | ||
| 837 | // Set required bit 14 as per reference manual | 862 | // Set required bit 14 as per reference manual |
| 838 | self.info.regs.oar1().modify(|reg| reg.0 |= 1 << 14); | 863 | self.info.regs.oar1().modify(|reg| reg.0 |= 1 << 14); |
| 839 | } | 864 | } |
| 840 | 865 | ||
| 841 | /// Configure the secondary address (OA2) register | 866 | /// Configure the secondary address (OA2) register |
| 842 | fn configure_secondary_address(&mut self, addr: u8) { | 867 | fn configure_secondary_address(&mut self, addr: u8) { |
| 843 | self.info.regs.oar2().write(|reg| { | 868 | self.info.regs.oar2().write(|reg| { |
| @@ -845,7 +870,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 845 | reg.set_endual(i2c::vals::Endual::DUAL); | 870 | reg.set_endual(i2c::vals::Endual::DUAL); |
| 846 | }); | 871 | }); |
| 847 | } | 872 | } |
| 848 | 873 | ||
| 849 | /// Set a default primary address when using OA2-only mode | 874 | /// Set a default primary address when using OA2-only mode |
| 850 | fn configure_default_primary_address(&mut self) { | 875 | fn configure_default_primary_address(&mut self) { |
| 851 | self.info.regs.oar1().write(|reg| { | 876 | self.info.regs.oar1().write(|reg| { |
| @@ -854,7 +879,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 854 | }); | 879 | }); |
| 855 | self.info.regs.oar1().modify(|reg| reg.0 |= 1 << 14); | 880 | self.info.regs.oar1().modify(|reg| reg.0 |= 1 << 14); |
| 856 | } | 881 | } |
| 857 | 882 | ||
| 858 | /// Disable secondary address when not needed | 883 | /// Disable secondary address when not needed |
| 859 | fn disable_secondary_address(&mut self) { | 884 | fn disable_secondary_address(&mut self) { |
| 860 | self.info.regs.oar2().write(|reg| { | 885 | self.info.regs.oar2().write(|reg| { |
| @@ -865,7 +890,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 865 | 890 | ||
| 866 | impl<'d, M: Mode> I2c<'d, M, MultiMaster> { | 891 | impl<'d, M: Mode> I2c<'d, M, MultiMaster> { |
| 867 | /// Listen for incoming I2C address match and return the command type | 892 | /// Listen for incoming I2C address match and return the command type |
| 868 | /// | 893 | /// |
| 869 | /// This method blocks until the slave address is matched by a master. | 894 | /// This method blocks until the slave address is matched by a master. |
| 870 | /// Returns the command type (Read/Write) and the matched address. | 895 | /// Returns the command type (Read/Write) and the matched address. |
| 871 | pub fn blocking_listen(&mut self) -> Result<SlaveCommand, Error> { | 896 | pub fn blocking_listen(&mut self) -> Result<SlaveCommand, Error> { |
| @@ -874,7 +899,7 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> { | |||
| 874 | trace!("I2C slave: blocking listen complete, result={:?}", result); | 899 | trace!("I2C slave: blocking listen complete, result={:?}", result); |
| 875 | result | 900 | result |
| 876 | } | 901 | } |
| 877 | 902 | ||
| 878 | /// Respond to a master read request by transmitting data | 903 | /// Respond to a master read request by transmitting data |
| 879 | /// | 904 | /// |
| 880 | /// Sends the provided data to the master. If the master requests more bytes | 905 | /// Sends the provided data to the master. If the master requests more bytes |
| @@ -884,17 +909,17 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> { | |||
| 884 | /// Returns the total number of bytes transmitted (including padding). | 909 | /// Returns the total number of bytes transmitted (including padding). |
| 885 | pub fn blocking_respond_to_read(&mut self, data: &[u8]) -> Result<usize, Error> { | 910 | pub fn blocking_respond_to_read(&mut self, data: &[u8]) -> Result<usize, Error> { |
| 886 | trace!("I2C slave: starting blocking respond_to_read, data_len={}", data.len()); | 911 | trace!("I2C slave: starting blocking respond_to_read, data_len={}", data.len()); |
| 887 | 912 | ||
| 888 | if let Some(zero_length_result) = self.detect_zero_length_read(self.timeout())? { | 913 | if let Some(zero_length_result) = self.detect_zero_length_read(self.timeout())? { |
| 889 | trace!("I2C slave: zero-length read detected"); | 914 | trace!("I2C slave: zero-length read detected"); |
| 890 | return Ok(zero_length_result); | 915 | return Ok(zero_length_result); |
| 891 | } | 916 | } |
| 892 | 917 | ||
| 893 | let result = self.transmit_to_master(data, self.timeout()); | 918 | let result = self.transmit_to_master(data, self.timeout()); |
| 894 | trace!("I2C slave: blocking respond_to_read complete, result={:?}", result); | 919 | trace!("I2C slave: blocking respond_to_read complete, result={:?}", result); |
| 895 | result | 920 | result |
| 896 | } | 921 | } |
| 897 | 922 | ||
| 898 | /// Respond to a master write request by receiving data | 923 | /// Respond to a master write request by receiving data |
| 899 | /// | 924 | /// |
| 900 | /// Receives data from the master into the provided buffer. If the master | 925 | /// Receives data from the master into the provided buffer. If the master |
| @@ -903,23 +928,26 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> { | |||
| 903 | /// | 928 | /// |
| 904 | /// Returns the number of bytes stored in the buffer (not total received). | 929 | /// Returns the number of bytes stored in the buffer (not total received). |
| 905 | pub fn blocking_respond_to_write(&mut self, buffer: &mut [u8]) -> Result<usize, Error> { | 930 | pub fn blocking_respond_to_write(&mut self, buffer: &mut [u8]) -> Result<usize, Error> { |
| 906 | trace!("I2C slave: starting blocking respond_to_write, buffer_len={}", buffer.len()); | 931 | trace!( |
| 932 | "I2C slave: starting blocking respond_to_write, buffer_len={}", | ||
| 933 | buffer.len() | ||
| 934 | ); | ||
| 907 | let result = self.receive_from_master(buffer, self.timeout()); | 935 | let result = self.receive_from_master(buffer, self.timeout()); |
| 908 | trace!("I2C slave: blocking respond_to_write complete, result={:?}", result); | 936 | trace!("I2C slave: blocking respond_to_write complete, result={:?}", result); |
| 909 | result | 937 | result |
| 910 | } | 938 | } |
| 911 | 939 | ||
| 912 | // Private implementation methods | 940 | // Private implementation methods |
| 913 | 941 | ||
| 914 | /// Wait for address match and determine transaction type | 942 | /// Wait for address match and determine transaction type |
| 915 | fn blocking_listen_with_timeout(&mut self, timeout: Timeout) -> Result<SlaveCommand, Error> { | 943 | fn blocking_listen_with_timeout(&mut self, timeout: Timeout) -> Result<SlaveCommand, Error> { |
| 916 | // Ensure interrupts are disabled for blocking operation | 944 | // Ensure interrupts are disabled for blocking operation |
| 917 | self.disable_i2c_interrupts(); | 945 | self.disable_i2c_interrupts(); |
| 918 | 946 | ||
| 919 | // Wait for address match (ADDR flag) | 947 | // Wait for address match (ADDR flag) |
| 920 | loop { | 948 | loop { |
| 921 | let sr1 = Self::read_status_and_handle_errors(self.info)?; | 949 | let sr1 = Self::read_status_and_handle_errors(self.info)?; |
| 922 | 950 | ||
| 923 | if sr1.addr() { | 951 | if sr1.addr() { |
| 924 | // Address matched - read SR2 to get direction and clear ADDR flag | 952 | // Address matched - read SR2 to get direction and clear ADDR flag |
| 925 | let sr2 = self.info.regs.sr2().read(); | 953 | let sr2 = self.info.regs.sr2().read(); |
| @@ -928,26 +956,30 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> { | |||
| 928 | } else { | 956 | } else { |
| 929 | SlaveCommandKind::Write | 957 | SlaveCommandKind::Write |
| 930 | }; | 958 | }; |
| 931 | 959 | ||
| 932 | // Use the static method instead of the instance method | 960 | // Use the static method instead of the instance method |
| 933 | let matched_address = Self::decode_matched_address(sr2, self.info)?; | 961 | let matched_address = Self::decode_matched_address(sr2, self.info)?; |
| 934 | trace!("I2C slave: address matched, direction={:?}, addr={:?}", direction, matched_address); | 962 | trace!( |
| 935 | 963 | "I2C slave: address matched, direction={:?}, addr={:?}", | |
| 964 | direction, | ||
| 965 | matched_address | ||
| 966 | ); | ||
| 967 | |||
| 936 | return Ok(SlaveCommand { | 968 | return Ok(SlaveCommand { |
| 937 | kind: direction, | 969 | kind: direction, |
| 938 | address: matched_address, | 970 | address: matched_address, |
| 939 | }); | 971 | }); |
| 940 | } | 972 | } |
| 941 | 973 | ||
| 942 | timeout.check()?; | 974 | timeout.check()?; |
| 943 | } | 975 | } |
| 944 | } | 976 | } |
| 945 | 977 | ||
| 946 | /// Transmit data to master in response to read request | 978 | /// Transmit data to master in response to read request |
| 947 | fn transmit_to_master(&mut self, data: &[u8], timeout: Timeout) -> Result<usize, Error> { | 979 | fn transmit_to_master(&mut self, data: &[u8], timeout: Timeout) -> Result<usize, Error> { |
| 948 | let mut bytes_transmitted = 0; | 980 | let mut bytes_transmitted = 0; |
| 949 | let mut padding_count = 0; | 981 | let mut padding_count = 0; |
| 950 | 982 | ||
| 951 | loop { | 983 | loop { |
| 952 | let byte_to_send = if bytes_transmitted < data.len() { | 984 | let byte_to_send = if bytes_transmitted < data.len() { |
| 953 | data[bytes_transmitted] | 985 | data[bytes_transmitted] |
| @@ -955,217 +987,221 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> { | |||
| 955 | padding_count += 1; | 987 | padding_count += 1; |
| 956 | 0x00 // Send padding bytes when data is exhausted | 988 | 0x00 // Send padding bytes when data is exhausted |
| 957 | }; | 989 | }; |
| 958 | 990 | ||
| 959 | match self.transmit_byte(byte_to_send, timeout)? { | 991 | match self.transmit_byte(byte_to_send, timeout)? { |
| 960 | TransmitResult::Acknowledged => { | 992 | TransmitResult::Acknowledged => { |
| 961 | bytes_transmitted += 1; | 993 | bytes_transmitted += 1; |
| 962 | }, | 994 | } |
| 963 | TransmitResult::NotAcknowledged => { | 995 | TransmitResult::NotAcknowledged => { |
| 964 | bytes_transmitted += 1; // Count the NACKed byte | 996 | bytes_transmitted += 1; // Count the NACKed byte |
| 965 | break; | 997 | break; |
| 966 | }, | 998 | } |
| 967 | TransmitResult::Stopped | TransmitResult::Restarted => { | 999 | TransmitResult::Stopped | TransmitResult::Restarted => { |
| 968 | break; | 1000 | break; |
| 969 | } | 1001 | } |
| 970 | } | 1002 | } |
| 971 | } | 1003 | } |
| 972 | 1004 | ||
| 973 | if padding_count > 0 { | 1005 | if padding_count > 0 { |
| 974 | trace!("I2C slave: sent {} data bytes + {} padding bytes = {} total", | 1006 | trace!( |
| 975 | data.len(), padding_count, bytes_transmitted); | 1007 | "I2C slave: sent {} data bytes + {} padding bytes = {} total", |
| 1008 | data.len(), | ||
| 1009 | padding_count, | ||
| 1010 | bytes_transmitted | ||
| 1011 | ); | ||
| 976 | } | 1012 | } |
| 977 | 1013 | ||
| 978 | Ok(bytes_transmitted) | 1014 | Ok(bytes_transmitted) |
| 979 | } | 1015 | } |
| 980 | 1016 | ||
| 981 | /// Receive data from master during write request | 1017 | /// Receive data from master during write request |
| 982 | fn receive_from_master(&mut self, buffer: &mut [u8], timeout: Timeout) -> Result<usize, Error> { | 1018 | fn receive_from_master(&mut self, buffer: &mut [u8], timeout: Timeout) -> Result<usize, Error> { |
| 983 | let mut bytes_stored = 0; | 1019 | let mut bytes_stored = 0; |
| 984 | 1020 | ||
| 985 | // Receive bytes that fit in buffer | 1021 | // Receive bytes that fit in buffer |
| 986 | while bytes_stored < buffer.len() { | 1022 | while bytes_stored < buffer.len() { |
| 987 | match self.receive_byte(timeout)? { | 1023 | match self.receive_byte(timeout)? { |
| 988 | ReceiveResult::Data(byte) => { | 1024 | ReceiveResult::Data(byte) => { |
| 989 | buffer[bytes_stored] = byte; | 1025 | buffer[bytes_stored] = byte; |
| 990 | bytes_stored += 1; | 1026 | bytes_stored += 1; |
| 991 | }, | 1027 | } |
| 992 | ReceiveResult::Stopped | ReceiveResult::Restarted => { | 1028 | ReceiveResult::Stopped | ReceiveResult::Restarted => { |
| 993 | return Ok(bytes_stored); | 1029 | return Ok(bytes_stored); |
| 994 | }, | 1030 | } |
| 995 | } | 1031 | } |
| 996 | } | 1032 | } |
| 997 | 1033 | ||
| 998 | // Handle buffer overflow by discarding excess bytes | 1034 | // Handle buffer overflow by discarding excess bytes |
| 999 | if bytes_stored == buffer.len() { | 1035 | if bytes_stored == buffer.len() { |
| 1000 | trace!("I2C slave: buffer full, discarding excess bytes"); | 1036 | trace!("I2C slave: buffer full, discarding excess bytes"); |
| 1001 | self.discard_excess_bytes(timeout)?; | 1037 | self.discard_excess_bytes(timeout)?; |
| 1002 | } | 1038 | } |
| 1003 | 1039 | ||
| 1004 | Ok(bytes_stored) | 1040 | Ok(bytes_stored) |
| 1005 | } | 1041 | } |
| 1006 | 1042 | ||
| 1007 | /// Detect zero-length read pattern early | 1043 | /// Detect zero-length read pattern early |
| 1008 | /// | 1044 | /// |
| 1009 | /// Zero-length reads occur when a master sends START+ADDR+R followed immediately | 1045 | /// Zero-length reads occur when a master sends START+ADDR+R followed immediately |
| 1010 | /// by NACK+STOP without wanting any data. This must be detected before attempting | 1046 | /// by NACK+STOP without wanting any data. This must be detected before attempting |
| 1011 | /// to transmit any bytes to avoid SDA line issues. | 1047 | /// to transmit any bytes to avoid SDA line issues. |
| 1012 | fn detect_zero_length_read(&mut self, _timeout: Timeout) -> Result<Option<usize>, Error> { | 1048 | fn detect_zero_length_read(&mut self, _timeout: Timeout) -> Result<Option<usize>, Error> { |
| 1013 | // Quick check for immediate termination signals | 1049 | // Quick check for immediate termination signals |
| 1014 | let sr1 = self.info.regs.sr1().read(); | 1050 | let sr1 = self.info.regs.sr1().read(); |
| 1015 | 1051 | ||
| 1016 | // Check for immediate NACK (fastest zero-length pattern) | 1052 | // Check for immediate NACK (fastest zero-length pattern) |
| 1017 | if sr1.af() { | 1053 | if sr1.af() { |
| 1018 | self.clear_acknowledge_failure(); | 1054 | self.clear_acknowledge_failure(); |
| 1019 | return Ok(Some(0)); | 1055 | return Ok(Some(0)); |
| 1020 | } | 1056 | } |
| 1021 | 1057 | ||
| 1022 | // Check for immediate STOP (alternative zero-length pattern) | 1058 | // Check for immediate STOP (alternative zero-length pattern) |
| 1023 | if sr1.stopf() { | 1059 | if sr1.stopf() { |
| 1024 | Self::clear_stop_flag(self.info); | 1060 | Self::clear_stop_flag(self.info); |
| 1025 | return Ok(Some(0)); | 1061 | return Ok(Some(0)); |
| 1026 | } | 1062 | } |
| 1027 | 1063 | ||
| 1028 | // Give a brief window for master to send termination signals | 1064 | // Give a brief window for master to send termination signals |
| 1029 | // This handles masters that have slight delays between address ACK and NACK | 1065 | // This handles masters that have slight delays between address ACK and NACK |
| 1030 | const ZERO_LENGTH_DETECTION_CYCLES: u32 = 20; // ~5-10µs window | 1066 | const ZERO_LENGTH_DETECTION_CYCLES: u32 = 20; // ~5-10µs window |
| 1031 | 1067 | ||
| 1032 | for _ in 0..ZERO_LENGTH_DETECTION_CYCLES { | 1068 | for _ in 0..ZERO_LENGTH_DETECTION_CYCLES { |
| 1033 | let sr1 = self.info.regs.sr1().read(); | 1069 | let sr1 = self.info.regs.sr1().read(); |
| 1034 | 1070 | ||
| 1035 | // Immediate NACK indicates zero-length read | 1071 | // Immediate NACK indicates zero-length read |
| 1036 | if sr1.af() { | 1072 | if sr1.af() { |
| 1037 | self.clear_acknowledge_failure(); | 1073 | self.clear_acknowledge_failure(); |
| 1038 | return Ok(Some(0)); | 1074 | return Ok(Some(0)); |
| 1039 | } | 1075 | } |
| 1040 | 1076 | ||
| 1041 | // Immediate STOP indicates zero-length read | 1077 | // Immediate STOP indicates zero-length read |
| 1042 | if sr1.stopf() { | 1078 | if sr1.stopf() { |
| 1043 | Self::clear_stop_flag(self.info); | 1079 | Self::clear_stop_flag(self.info); |
| 1044 | return Ok(Some(0)); | 1080 | return Ok(Some(0)); |
| 1045 | } | 1081 | } |
| 1046 | 1082 | ||
| 1047 | // If TXE becomes ready, master is waiting for data - not zero-length | 1083 | // If TXE becomes ready, master is waiting for data - not zero-length |
| 1048 | if sr1.txe() { | 1084 | if sr1.txe() { |
| 1049 | return Ok(None); // Proceed with normal transmission | 1085 | return Ok(None); // Proceed with normal transmission |
| 1050 | } | 1086 | } |
| 1051 | 1087 | ||
| 1052 | // If RESTART detected, handle as zero-length | 1088 | // If RESTART detected, handle as zero-length |
| 1053 | if sr1.addr() { | 1089 | if sr1.addr() { |
| 1054 | return Ok(Some(0)); | 1090 | return Ok(Some(0)); |
| 1055 | } | 1091 | } |
| 1056 | } | 1092 | } |
| 1057 | 1093 | ||
| 1058 | // No zero-length pattern detected within the window | 1094 | // No zero-length pattern detected within the window |
| 1059 | Ok(None) | 1095 | Ok(None) |
| 1060 | } | 1096 | } |
| 1061 | 1097 | ||
| 1062 | /// Discard excess bytes when buffer is full | 1098 | /// Discard excess bytes when buffer is full |
| 1063 | fn discard_excess_bytes(&mut self, timeout: Timeout) -> Result<(), Error> { | 1099 | fn discard_excess_bytes(&mut self, timeout: Timeout) -> Result<(), Error> { |
| 1064 | let mut discarded_count = 0; | 1100 | let mut discarded_count = 0; |
| 1065 | 1101 | ||
| 1066 | loop { | 1102 | loop { |
| 1067 | match self.receive_byte(timeout)? { | 1103 | match self.receive_byte(timeout)? { |
| 1068 | ReceiveResult::Data(_) => { | 1104 | ReceiveResult::Data(_) => { |
| 1069 | discarded_count += 1; | 1105 | discarded_count += 1; |
| 1070 | continue; | 1106 | continue; |
| 1071 | }, | 1107 | } |
| 1072 | ReceiveResult::Stopped | ReceiveResult::Restarted => { | 1108 | ReceiveResult::Stopped | ReceiveResult::Restarted => { |
| 1073 | if discarded_count > 0 { | 1109 | if discarded_count > 0 { |
| 1074 | trace!("I2C slave: discarded {} excess bytes", discarded_count); | 1110 | trace!("I2C slave: discarded {} excess bytes", discarded_count); |
| 1075 | } | 1111 | } |
| 1076 | break; | 1112 | break; |
| 1077 | }, | 1113 | } |
| 1078 | } | 1114 | } |
| 1079 | } | 1115 | } |
| 1080 | Ok(()) | 1116 | Ok(()) |
| 1081 | } | 1117 | } |
| 1082 | 1118 | ||
| 1083 | /// Send a single byte and wait for master's response | 1119 | /// Send a single byte and wait for master's response |
| 1084 | fn transmit_byte(&mut self, byte: u8, timeout: Timeout) -> Result<TransmitResult, Error> { | 1120 | fn transmit_byte(&mut self, byte: u8, timeout: Timeout) -> Result<TransmitResult, Error> { |
| 1085 | // Wait for transmit buffer ready | 1121 | // Wait for transmit buffer ready |
| 1086 | self.wait_for_transmit_ready(timeout)?; | 1122 | self.wait_for_transmit_ready(timeout)?; |
| 1087 | 1123 | ||
| 1088 | // Send the byte | 1124 | // Send the byte |
| 1089 | self.info.regs.dr().write(|w| w.set_dr(byte)); | 1125 | self.info.regs.dr().write(|w| w.set_dr(byte)); |
| 1090 | 1126 | ||
| 1091 | // Wait for transmission completion or master response | 1127 | // Wait for transmission completion or master response |
| 1092 | self.wait_for_transmit_completion(timeout) | 1128 | self.wait_for_transmit_completion(timeout) |
| 1093 | } | 1129 | } |
| 1094 | 1130 | ||
| 1095 | /// Wait until transmit buffer is ready (TXE flag set) | 1131 | /// Wait until transmit buffer is ready (TXE flag set) |
| 1096 | fn wait_for_transmit_ready(&mut self, timeout: Timeout) -> Result<(), Error> { | 1132 | fn wait_for_transmit_ready(&mut self, timeout: Timeout) -> Result<(), Error> { |
| 1097 | loop { | 1133 | loop { |
| 1098 | let sr1 = Self::read_status_and_handle_errors(self.info)?; | 1134 | let sr1 = Self::read_status_and_handle_errors(self.info)?; |
| 1099 | 1135 | ||
| 1100 | // Check for early termination conditions | 1136 | // Check for early termination conditions |
| 1101 | if let Some(result) = Self::check_early_termination(sr1) { | 1137 | if let Some(result) = Self::check_early_termination(sr1) { |
| 1102 | return Err(self.handle_early_termination(result)); | 1138 | return Err(self.handle_early_termination(result)); |
| 1103 | } | 1139 | } |
| 1104 | 1140 | ||
| 1105 | if sr1.txe() { | 1141 | if sr1.txe() { |
| 1106 | return Ok(()); // Ready to transmit | 1142 | return Ok(()); // Ready to transmit |
| 1107 | } | 1143 | } |
| 1108 | 1144 | ||
| 1109 | timeout.check()?; | 1145 | timeout.check()?; |
| 1110 | } | 1146 | } |
| 1111 | } | 1147 | } |
| 1112 | 1148 | ||
| 1113 | /// Wait for byte transmission completion or master response | 1149 | /// Wait for byte transmission completion or master response |
| 1114 | fn wait_for_transmit_completion(&mut self, timeout: Timeout) -> Result<TransmitResult, Error> { | 1150 | fn wait_for_transmit_completion(&mut self, timeout: Timeout) -> Result<TransmitResult, Error> { |
| 1115 | loop { | 1151 | loop { |
| 1116 | let sr1 = self.info.regs.sr1().read(); | 1152 | let sr1 = self.info.regs.sr1().read(); |
| 1117 | 1153 | ||
| 1118 | // Check flags in priority order | 1154 | // Check flags in priority order |
| 1119 | if sr1.af() { | 1155 | if sr1.af() { |
| 1120 | self.clear_acknowledge_failure(); | 1156 | self.clear_acknowledge_failure(); |
| 1121 | return Ok(TransmitResult::NotAcknowledged); | 1157 | return Ok(TransmitResult::NotAcknowledged); |
| 1122 | } | 1158 | } |
| 1123 | 1159 | ||
| 1124 | if sr1.btf() { | 1160 | if sr1.btf() { |
| 1125 | return Ok(TransmitResult::Acknowledged); | 1161 | return Ok(TransmitResult::Acknowledged); |
| 1126 | } | 1162 | } |
| 1127 | 1163 | ||
| 1128 | if sr1.stopf() { | 1164 | if sr1.stopf() { |
| 1129 | Self::clear_stop_flag(self.info); | 1165 | Self::clear_stop_flag(self.info); |
| 1130 | return Ok(TransmitResult::Stopped); | 1166 | return Ok(TransmitResult::Stopped); |
| 1131 | } | 1167 | } |
| 1132 | 1168 | ||
| 1133 | if sr1.addr() { | 1169 | if sr1.addr() { |
| 1134 | return Ok(TransmitResult::Restarted); | 1170 | return Ok(TransmitResult::Restarted); |
| 1135 | } | 1171 | } |
| 1136 | 1172 | ||
| 1137 | // Check for other error conditions | 1173 | // Check for other error conditions |
| 1138 | self.check_for_hardware_errors(sr1)?; | 1174 | self.check_for_hardware_errors(sr1)?; |
| 1139 | 1175 | ||
| 1140 | timeout.check()?; | 1176 | timeout.check()?; |
| 1141 | } | 1177 | } |
| 1142 | } | 1178 | } |
| 1143 | 1179 | ||
| 1144 | /// Receive a single byte or detect transaction termination | 1180 | /// Receive a single byte or detect transaction termination |
| 1145 | fn receive_byte(&mut self, timeout: Timeout) -> Result<ReceiveResult, Error> { | 1181 | fn receive_byte(&mut self, timeout: Timeout) -> Result<ReceiveResult, Error> { |
| 1146 | loop { | 1182 | loop { |
| 1147 | let sr1 = Self::read_status_and_handle_errors(self.info)?; | 1183 | let sr1 = Self::read_status_and_handle_errors(self.info)?; |
| 1148 | 1184 | ||
| 1149 | // Check for received data first (prioritize data over control signals) | 1185 | // Check for received data first (prioritize data over control signals) |
| 1150 | if sr1.rxne() { | 1186 | if sr1.rxne() { |
| 1151 | let byte = self.info.regs.dr().read().dr(); | 1187 | let byte = self.info.regs.dr().read().dr(); |
| 1152 | return Ok(ReceiveResult::Data(byte)); | 1188 | return Ok(ReceiveResult::Data(byte)); |
| 1153 | } | 1189 | } |
| 1154 | 1190 | ||
| 1155 | // Check for transaction termination | 1191 | // Check for transaction termination |
| 1156 | if sr1.addr() { | 1192 | if sr1.addr() { |
| 1157 | return Ok(ReceiveResult::Restarted); | 1193 | return Ok(ReceiveResult::Restarted); |
| 1158 | } | 1194 | } |
| 1159 | 1195 | ||
| 1160 | if sr1.stopf() { | 1196 | if sr1.stopf() { |
| 1161 | Self::clear_stop_flag(self.info); | 1197 | Self::clear_stop_flag(self.info); |
| 1162 | return Ok(ReceiveResult::Stopped); | 1198 | return Ok(ReceiveResult::Stopped); |
| 1163 | } | 1199 | } |
| 1164 | 1200 | ||
| 1165 | timeout.check()?; | 1201 | timeout.check()?; |
| 1166 | } | 1202 | } |
| 1167 | } | 1203 | } |
| 1168 | 1204 | ||
| 1169 | /// Determine which slave address was matched based on SR2 flags | 1205 | /// Determine which slave address was matched based on SR2 flags |
| 1170 | fn decode_matched_address(sr2: i2c::regs::Sr2, info: &'static Info) -> Result<Address, Error> { | 1206 | fn decode_matched_address(sr2: i2c::regs::Sr2, info: &'static Info) -> Result<Address, Error> { |
| 1171 | if sr2.gencall() { | 1207 | if sr2.gencall() { |
| @@ -1184,16 +1220,14 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> { | |||
| 1184 | i2c::vals::Addmode::BIT7 => { | 1220 | i2c::vals::Addmode::BIT7 => { |
| 1185 | let addr = (oar1.add() >> 1) as u8; | 1221 | let addr = (oar1.add() >> 1) as u8; |
| 1186 | Ok(Address::SevenBit(addr)) | 1222 | Ok(Address::SevenBit(addr)) |
| 1187 | }, | 1223 | } |
| 1188 | i2c::vals::Addmode::BIT10 => { | 1224 | i2c::vals::Addmode::BIT10 => Ok(Address::TenBit(oar1.add())), |
| 1189 | Ok(Address::TenBit(oar1.add())) | ||
| 1190 | }, | ||
| 1191 | } | 1225 | } |
| 1192 | } | 1226 | } |
| 1193 | } | 1227 | } |
| 1194 | 1228 | ||
| 1195 | // Helper methods for hardware interaction | 1229 | // Helper methods for hardware interaction |
| 1196 | 1230 | ||
| 1197 | /// Read status register and handle I2C errors (except NACK in slave mode) | 1231 | /// Read status register and handle I2C errors (except NACK in slave mode) |
| 1198 | fn read_status_and_handle_errors(info: &'static Info) -> Result<i2c::regs::Sr1, Error> { | 1232 | fn read_status_and_handle_errors(info: &'static Info) -> Result<i2c::regs::Sr1, Error> { |
| 1199 | match Self::check_and_clear_error_flags(info) { | 1233 | match Self::check_and_clear_error_flags(info) { |
| @@ -1201,11 +1235,11 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> { | |||
| 1201 | Err(Error::Nack) => { | 1235 | Err(Error::Nack) => { |
| 1202 | // In slave mode, NACK is normal protocol behavior, not an error | 1236 | // In slave mode, NACK is normal protocol behavior, not an error |
| 1203 | Ok(info.regs.sr1().read()) | 1237 | Ok(info.regs.sr1().read()) |
| 1204 | }, | 1238 | } |
| 1205 | Err(other_error) => Err(other_error), | 1239 | Err(other_error) => Err(other_error), |
| 1206 | } | 1240 | } |
| 1207 | } | 1241 | } |
| 1208 | 1242 | ||
| 1209 | /// Check for conditions that cause early termination of operations | 1243 | /// Check for conditions that cause early termination of operations |
| 1210 | fn check_early_termination(sr1: i2c::regs::Sr1) -> Option<TransmitResult> { | 1244 | fn check_early_termination(sr1: i2c::regs::Sr1) -> Option<TransmitResult> { |
| 1211 | if sr1.stopf() { | 1245 | if sr1.stopf() { |
| @@ -1218,27 +1252,27 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> { | |||
| 1218 | None | 1252 | None |
| 1219 | } | 1253 | } |
| 1220 | } | 1254 | } |
| 1221 | 1255 | ||
| 1222 | /// Convert early termination to appropriate error | 1256 | /// Convert early termination to appropriate error |
| 1223 | fn handle_early_termination(&mut self, result: TransmitResult) -> Error { | 1257 | fn handle_early_termination(&mut self, result: TransmitResult) -> Error { |
| 1224 | match result { | 1258 | match result { |
| 1225 | TransmitResult::Stopped => { | 1259 | TransmitResult::Stopped => { |
| 1226 | Self::clear_stop_flag(self.info); | 1260 | Self::clear_stop_flag(self.info); |
| 1227 | Error::Bus // Unexpected STOP during setup | 1261 | Error::Bus // Unexpected STOP during setup |
| 1228 | }, | 1262 | } |
| 1229 | TransmitResult::Restarted => { | 1263 | TransmitResult::Restarted => { |
| 1230 | Error::Bus // Unexpected RESTART during setup | 1264 | Error::Bus // Unexpected RESTART during setup |
| 1231 | }, | 1265 | } |
| 1232 | TransmitResult::NotAcknowledged => { | 1266 | TransmitResult::NotAcknowledged => { |
| 1233 | self.clear_acknowledge_failure(); | 1267 | self.clear_acknowledge_failure(); |
| 1234 | Error::Bus // Unexpected NACK during setup | 1268 | Error::Bus // Unexpected NACK during setup |
| 1235 | }, | 1269 | } |
| 1236 | TransmitResult::Acknowledged => { | 1270 | TransmitResult::Acknowledged => { |
| 1237 | unreachable!() // This should never be passed to this function | 1271 | unreachable!() // This should never be passed to this function |
| 1238 | } | 1272 | } |
| 1239 | } | 1273 | } |
| 1240 | } | 1274 | } |
| 1241 | 1275 | ||
| 1242 | /// Check for hardware-level I2C errors during transmission | 1276 | /// Check for hardware-level I2C errors during transmission |
| 1243 | fn check_for_hardware_errors(&self, sr1: i2c::regs::Sr1) -> Result<(), Error> { | 1277 | fn check_for_hardware_errors(&self, sr1: i2c::regs::Sr1) -> Result<(), Error> { |
| 1244 | if sr1.timeout() || sr1.ovr() || sr1.arlo() || sr1.berr() { | 1278 | if sr1.timeout() || sr1.ovr() || sr1.arlo() || sr1.berr() { |
| @@ -1247,7 +1281,7 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> { | |||
| 1247 | } | 1281 | } |
| 1248 | Ok(()) | 1282 | Ok(()) |
| 1249 | } | 1283 | } |
| 1250 | 1284 | ||
| 1251 | /// Disable I2C event and error interrupts for blocking operations | 1285 | /// Disable I2C event and error interrupts for blocking operations |
| 1252 | fn disable_i2c_interrupts(&mut self) { | 1286 | fn disable_i2c_interrupts(&mut self) { |
| 1253 | self.info.regs.cr2().modify(|w| { | 1287 | self.info.regs.cr2().modify(|w| { |
| @@ -1255,7 +1289,7 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> { | |||
| 1255 | w.set_iterren(false); | 1289 | w.set_iterren(false); |
| 1256 | }); | 1290 | }); |
| 1257 | } | 1291 | } |
| 1258 | 1292 | ||
| 1259 | /// Clear the acknowledge failure flag | 1293 | /// Clear the acknowledge failure flag |
| 1260 | fn clear_acknowledge_failure(&mut self) { | 1294 | fn clear_acknowledge_failure(&mut self) { |
| 1261 | self.info.regs.sr1().write(|reg| { | 1295 | self.info.regs.sr1().write(|reg| { |
| @@ -1268,11 +1302,11 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> { | |||
| 1268 | fn setup_slave_dma_base(&mut self) { | 1302 | fn setup_slave_dma_base(&mut self) { |
| 1269 | self.info.regs.cr2().modify(|w| { | 1303 | self.info.regs.cr2().modify(|w| { |
| 1270 | w.set_itbufen(false); // Always disable buffer interrupts when using DMA | 1304 | w.set_itbufen(false); // Always disable buffer interrupts when using DMA |
| 1271 | w.set_dmaen(true); // Enable DMA requests | 1305 | w.set_dmaen(true); // Enable DMA requests |
| 1272 | w.set_last(false); // LAST bit not used in slave mode for v1 hardware | 1306 | w.set_last(false); // LAST bit not used in slave mode for v1 hardware |
| 1273 | }); | 1307 | }); |
| 1274 | } | 1308 | } |
| 1275 | 1309 | ||
| 1276 | /// Disable DMA and interrupts in a critical section | 1310 | /// Disable DMA and interrupts in a critical section |
| 1277 | fn disable_dma_and_interrupts(info: &'static Info) { | 1311 | fn disable_dma_and_interrupts(info: &'static Info) { |
| 1278 | critical_section::with(|_| { | 1312 | critical_section::with(|_| { |
| @@ -1301,7 +1335,7 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> { | |||
| 1301 | 1335 | ||
| 1302 | impl<'d> I2c<'d, Async, MultiMaster> { | 1336 | impl<'d> I2c<'d, Async, MultiMaster> { |
| 1303 | /// Async listen for incoming I2C messages using interrupts | 1337 | /// Async listen for incoming I2C messages using interrupts |
| 1304 | /// | 1338 | /// |
| 1305 | /// Waits for a master to address this slave and returns the command type | 1339 | /// Waits for a master to address this slave and returns the command type |
| 1306 | /// (Read/Write) and the matched address. This method will suspend until | 1340 | /// (Read/Write) and the matched address. This method will suspend until |
| 1307 | /// an address match occurs. | 1341 | /// an address match occurs. |
| @@ -1309,7 +1343,7 @@ impl<'d> I2c<'d, Async, MultiMaster> { | |||
| 1309 | trace!("I2C slave: starting async listen for address match"); | 1343 | trace!("I2C slave: starting async listen for address match"); |
| 1310 | let state = self.state; | 1344 | let state = self.state; |
| 1311 | let info = self.info; | 1345 | let info = self.info; |
| 1312 | 1346 | ||
| 1313 | Self::enable_interrupts(info); | 1347 | Self::enable_interrupts(info); |
| 1314 | 1348 | ||
| 1315 | let on_drop = OnDrop::new(|| { | 1349 | let on_drop = OnDrop::new(|| { |
| @@ -1323,7 +1357,7 @@ impl<'d> I2c<'d, Async, MultiMaster> { | |||
| 1323 | Err(e) => { | 1357 | Err(e) => { |
| 1324 | error!("I2C slave: error during listen: {:?}", e); | 1358 | error!("I2C slave: error during listen: {:?}", e); |
| 1325 | Poll::Ready(Err(e)) | 1359 | Poll::Ready(Err(e)) |
| 1326 | }, | 1360 | } |
| 1327 | Ok(sr1) => { | 1361 | Ok(sr1) => { |
| 1328 | if sr1.addr() { | 1362 | if sr1.addr() { |
| 1329 | let sr2 = info.regs.sr2().read(); | 1363 | let sr2 = info.regs.sr2().read(); |
| @@ -1332,18 +1366,18 @@ impl<'d> I2c<'d, Async, MultiMaster> { | |||
| 1332 | } else { | 1366 | } else { |
| 1333 | SlaveCommandKind::Write | 1367 | SlaveCommandKind::Write |
| 1334 | }; | 1368 | }; |
| 1335 | 1369 | ||
| 1336 | let matched_address = match Self::decode_matched_address(sr2, info) { | 1370 | let matched_address = match Self::decode_matched_address(sr2, info) { |
| 1337 | Ok(addr) => { | 1371 | Ok(addr) => { |
| 1338 | trace!("I2C slave: address matched, direction={:?}, addr={:?}", direction, addr); | 1372 | trace!("I2C slave: address matched, direction={:?}, addr={:?}", direction, addr); |
| 1339 | addr | 1373 | addr |
| 1340 | }, | 1374 | } |
| 1341 | Err(e) => { | 1375 | Err(e) => { |
| 1342 | error!("I2C slave: failed to decode matched address: {:?}", e); | 1376 | error!("I2C slave: failed to decode matched address: {:?}", e); |
| 1343 | return Poll::Ready(Err(e)); | 1377 | return Poll::Ready(Err(e)); |
| 1344 | } | 1378 | } |
| 1345 | }; | 1379 | }; |
| 1346 | 1380 | ||
| 1347 | Poll::Ready(Ok(SlaveCommand { | 1381 | Poll::Ready(Ok(SlaveCommand { |
| 1348 | kind: direction, | 1382 | kind: direction, |
| 1349 | address: matched_address, | 1383 | address: matched_address, |
| @@ -1354,7 +1388,8 @@ impl<'d> I2c<'d, Async, MultiMaster> { | |||
| 1354 | } | 1388 | } |
| 1355 | } | 1389 | } |
| 1356 | } | 1390 | } |
| 1357 | }).await; | 1391 | }) |
| 1392 | .await; | ||
| 1358 | 1393 | ||
| 1359 | drop(on_drop); | 1394 | drop(on_drop); |
| 1360 | trace!("I2C slave: listen complete, result={:?}", result); | 1395 | trace!("I2C slave: listen complete, result={:?}", result); |
| @@ -1362,15 +1397,15 @@ impl<'d> I2c<'d, Async, MultiMaster> { | |||
| 1362 | } | 1397 | } |
| 1363 | 1398 | ||
| 1364 | /// Async respond to write command using RX DMA | 1399 | /// Async respond to write command using RX DMA |
| 1365 | /// | 1400 | /// |
| 1366 | /// Receives data from the master into the provided buffer using DMA. | 1401 | /// Receives data from the master into the provided buffer using DMA. |
| 1367 | /// If the master sends more bytes than the buffer can hold, excess bytes | 1402 | /// If the master sends more bytes than the buffer can hold, excess bytes |
| 1368 | /// are acknowledged but discarded to prevent interrupt flooding. | 1403 | /// are acknowledged but discarded to prevent interrupt flooding. |
| 1369 | /// | 1404 | /// |
| 1370 | /// Returns the number of bytes stored in the buffer (not total received). | 1405 | /// Returns the number of bytes stored in the buffer (not total received). |
| 1371 | pub async fn respond_to_write(&mut self, buffer: &mut [u8]) -> Result<usize, Error> { | 1406 | pub async fn respond_to_write(&mut self, buffer: &mut [u8]) -> Result<usize, Error> { |
| 1372 | trace!("I2C slave: starting respond_to_write, buffer_len={}", buffer.len()); | 1407 | trace!("I2C slave: starting respond_to_write, buffer_len={}", buffer.len()); |
| 1373 | 1408 | ||
| 1374 | if buffer.is_empty() { | 1409 | if buffer.is_empty() { |
| 1375 | warn!("I2C slave: respond_to_write called with empty buffer"); | 1410 | warn!("I2C slave: respond_to_write called with empty buffer"); |
| 1376 | return Err(Error::Overrun); | 1411 | return Err(Error::Overrun); |
| @@ -1395,15 +1430,15 @@ impl<'d> I2c<'d, Async, MultiMaster> { | |||
| 1395 | } | 1430 | } |
| 1396 | 1431 | ||
| 1397 | /// Async respond to read command using TX DMA | 1432 | /// Async respond to read command using TX DMA |
| 1398 | /// | 1433 | /// |
| 1399 | /// Transmits data to the master using DMA. If the master requests more bytes | 1434 | /// Transmits data to the master using DMA. If the master requests more bytes |
| 1400 | /// than available in the data buffer, padding bytes (0x00) are sent until | 1435 | /// than available in the data buffer, padding bytes (0x00) are sent until |
| 1401 | /// the master terminates the transaction with NACK, STOP, or RESTART. | 1436 | /// the master terminates the transaction with NACK, STOP, or RESTART. |
| 1402 | /// | 1437 | /// |
| 1403 | /// Returns the total number of bytes transmitted (data + padding). | 1438 | /// Returns the total number of bytes transmitted (data + padding). |
| 1404 | pub async fn respond_to_read(&mut self, data: &[u8]) -> Result<usize, Error> { | 1439 | pub async fn respond_to_read(&mut self, data: &[u8]) -> Result<usize, Error> { |
| 1405 | trace!("I2C slave: starting respond_to_read, data_len={}", data.len()); | 1440 | trace!("I2C slave: starting respond_to_read, data_len={}", data.len()); |
| 1406 | 1441 | ||
| 1407 | if data.is_empty() { | 1442 | if data.is_empty() { |
| 1408 | warn!("I2C slave: respond_to_read called with empty data"); | 1443 | warn!("I2C slave: respond_to_read called with empty data"); |
| 1409 | return Err(Error::Overrun); | 1444 | return Err(Error::Overrun); |
| @@ -1431,17 +1466,18 @@ impl<'d> I2c<'d, Async, MultiMaster> { | |||
| 1431 | 1466 | ||
| 1432 | /// Execute complete slave receive transfer with excess byte handling | 1467 | /// Execute complete slave receive transfer with excess byte handling |
| 1433 | async fn execute_slave_receive_transfer( | 1468 | async fn execute_slave_receive_transfer( |
| 1434 | &mut self, | 1469 | &mut self, |
| 1435 | buffer: &mut [u8], | 1470 | buffer: &mut [u8], |
| 1436 | state: &'static State, | 1471 | state: &'static State, |
| 1437 | info: &'static Info | 1472 | info: &'static Info, |
| 1438 | ) -> Result<usize, Error> { | 1473 | ) -> Result<usize, Error> { |
| 1439 | let dma_transfer = unsafe { | 1474 | let dma_transfer = unsafe { |
| 1440 | let src = info.regs.dr().as_ptr() as *mut u8; | 1475 | let src = info.regs.dr().as_ptr() as *mut u8; |
| 1441 | self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default()) | 1476 | self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default()) |
| 1442 | }; | 1477 | }; |
| 1443 | 1478 | ||
| 1444 | let i2c_monitor = Self::create_termination_monitor(state, info, &[SlaveTermination::Stop, SlaveTermination::Restart]); | 1479 | let i2c_monitor = |
| 1480 | Self::create_termination_monitor(state, info, &[SlaveTermination::Stop, SlaveTermination::Restart]); | ||
| 1445 | 1481 | ||
| 1446 | match select(dma_transfer, i2c_monitor).await { | 1482 | match select(dma_transfer, i2c_monitor).await { |
| 1447 | Either::Second(Err(e)) => { | 1483 | Either::Second(Err(e)) => { |
| @@ -1465,17 +1501,25 @@ impl<'d> I2c<'d, Async, MultiMaster> { | |||
| 1465 | 1501 | ||
| 1466 | /// Execute complete slave transmit transfer with padding byte handling | 1502 | /// Execute complete slave transmit transfer with padding byte handling |
| 1467 | async fn execute_slave_transmit_transfer( | 1503 | async fn execute_slave_transmit_transfer( |
| 1468 | &mut self, | 1504 | &mut self, |
| 1469 | data: &[u8], | 1505 | data: &[u8], |
| 1470 | state: &'static State, | 1506 | state: &'static State, |
| 1471 | info: &'static Info | 1507 | info: &'static Info, |
| 1472 | ) -> Result<usize, Error> { | 1508 | ) -> Result<usize, Error> { |
| 1473 | let dma_transfer = unsafe { | 1509 | let dma_transfer = unsafe { |
| 1474 | let dst = info.regs.dr().as_ptr() as *mut u8; | 1510 | let dst = info.regs.dr().as_ptr() as *mut u8; |
| 1475 | self.tx_dma.as_mut().unwrap().write(data, dst, Default::default()) | 1511 | self.tx_dma.as_mut().unwrap().write(data, dst, Default::default()) |
| 1476 | }; | 1512 | }; |
| 1477 | 1513 | ||
| 1478 | let i2c_monitor = Self::create_termination_monitor(state, info, &[SlaveTermination::Stop, SlaveTermination::Restart, SlaveTermination::Nack]); | 1514 | let i2c_monitor = Self::create_termination_monitor( |
| 1515 | state, | ||
| 1516 | info, | ||
| 1517 | &[ | ||
| 1518 | SlaveTermination::Stop, | ||
| 1519 | SlaveTermination::Restart, | ||
| 1520 | SlaveTermination::Nack, | ||
| 1521 | ], | ||
| 1522 | ); | ||
| 1479 | 1523 | ||
| 1480 | match select(dma_transfer, i2c_monitor).await { | 1524 | match select(dma_transfer, i2c_monitor).await { |
| 1481 | Either::Second(Err(e)) => { | 1525 | Either::Second(Err(e)) => { |
| @@ -1488,8 +1532,12 @@ impl<'d> I2c<'d, Async, MultiMaster> { | |||
| 1488 | Self::disable_dma_and_interrupts(info); | 1532 | Self::disable_dma_and_interrupts(info); |
| 1489 | let padding_count = self.handle_padding_bytes(state, info).await?; | 1533 | let padding_count = self.handle_padding_bytes(state, info).await?; |
| 1490 | let total_bytes = data.len() + padding_count; | 1534 | let total_bytes = data.len() + padding_count; |
| 1491 | trace!("I2C slave: sent {} data bytes + {} padding bytes = {} total", | 1535 | trace!( |
| 1492 | data.len(), padding_count, total_bytes); | 1536 | "I2C slave: sent {} data bytes + {} padding bytes = {} total", |
| 1537 | data.len(), | ||
| 1538 | padding_count, | ||
| 1539 | total_bytes | ||
| 1540 | ); | ||
| 1493 | Ok(total_bytes) | 1541 | Ok(total_bytes) |
| 1494 | } | 1542 | } |
| 1495 | Either::Second(Ok(termination)) => { | 1543 | Either::Second(Ok(termination)) => { |
| @@ -1508,7 +1556,7 @@ impl<'d> I2c<'d, Async, MultiMaster> { | |||
| 1508 | ) -> impl Future<Output = Result<SlaveTermination, Error>> { | 1556 | ) -> impl Future<Output = Result<SlaveTermination, Error>> { |
| 1509 | poll_fn(move |cx| { | 1557 | poll_fn(move |cx| { |
| 1510 | state.waker.register(cx.waker()); | 1558 | state.waker.register(cx.waker()); |
| 1511 | 1559 | ||
| 1512 | match Self::check_and_clear_error_flags(info) { | 1560 | match Self::check_and_clear_error_flags(info) { |
| 1513 | Err(Error::Nack) if allowed_terminations.contains(&SlaveTermination::Nack) => { | 1561 | Err(Error::Nack) if allowed_terminations.contains(&SlaveTermination::Nack) => { |
| 1514 | Poll::Ready(Ok(SlaveTermination::Nack)) | 1562 | Poll::Ready(Ok(SlaveTermination::Nack)) |
| @@ -1545,24 +1593,24 @@ impl<'d> I2c<'d, Async, MultiMaster> { | |||
| 1545 | } | 1593 | } |
| 1546 | 1594 | ||
| 1547 | /// Handle excess bytes after DMA buffer is full | 1595 | /// Handle excess bytes after DMA buffer is full |
| 1548 | /// | 1596 | /// |
| 1549 | /// Reads and discards bytes until transaction termination to prevent interrupt flooding | 1597 | /// Reads and discards bytes until transaction termination to prevent interrupt flooding |
| 1550 | async fn handle_excess_bytes(&mut self, state: &'static State, info: &'static Info) -> Result<(), Error> { | 1598 | async fn handle_excess_bytes(&mut self, state: &'static State, info: &'static Info) -> Result<(), Error> { |
| 1551 | let mut discarded_count = 0; | 1599 | let mut discarded_count = 0; |
| 1552 | 1600 | ||
| 1553 | poll_fn(|cx| { | 1601 | poll_fn(|cx| { |
| 1554 | state.waker.register(cx.waker()); | 1602 | state.waker.register(cx.waker()); |
| 1555 | 1603 | ||
| 1556 | match Self::check_and_clear_error_flags(info) { | 1604 | match Self::check_and_clear_error_flags(info) { |
| 1557 | Err(e) => { | 1605 | Err(e) => { |
| 1558 | error!("I2C slave: error while discarding excess bytes: {:?}", e); | 1606 | error!("I2C slave: error while discarding excess bytes: {:?}", e); |
| 1559 | Poll::Ready(Err(e)) | 1607 | Poll::Ready(Err(e)) |
| 1560 | }, | 1608 | } |
| 1561 | Ok(sr1) => { | 1609 | Ok(sr1) => { |
| 1562 | if let Some(termination) = Self::check_slave_termination_conditions(sr1) { | 1610 | if let Some(termination) = Self::check_slave_termination_conditions(sr1) { |
| 1563 | match termination { | 1611 | match termination { |
| 1564 | SlaveTermination::Stop => Self::clear_stop_flag(info), | 1612 | SlaveTermination::Stop => Self::clear_stop_flag(info), |
| 1565 | SlaveTermination::Restart => {}, | 1613 | SlaveTermination::Restart => {} |
| 1566 | SlaveTermination::Nack => unreachable!("NACK not expected during receive"), | 1614 | SlaveTermination::Nack => unreachable!("NACK not expected during receive"), |
| 1567 | } | 1615 | } |
| 1568 | if discarded_count > 0 { | 1616 | if discarded_count > 0 { |
| @@ -1570,41 +1618,42 @@ impl<'d> I2c<'d, Async, MultiMaster> { | |||
| 1570 | } | 1618 | } |
| 1571 | return Poll::Ready(Ok(())); | 1619 | return Poll::Ready(Ok(())); |
| 1572 | } | 1620 | } |
| 1573 | 1621 | ||
| 1574 | if sr1.rxne() { | 1622 | if sr1.rxne() { |
| 1575 | let _discarded_byte = info.regs.dr().read().dr(); | 1623 | let _discarded_byte = info.regs.dr().read().dr(); |
| 1576 | discarded_count += 1; | 1624 | discarded_count += 1; |
| 1577 | Self::enable_interrupts(info); | 1625 | Self::enable_interrupts(info); |
| 1578 | return Poll::Pending; | 1626 | return Poll::Pending; |
| 1579 | } | 1627 | } |
| 1580 | 1628 | ||
| 1581 | Self::enable_interrupts(info); | 1629 | Self::enable_interrupts(info); |
| 1582 | Poll::Pending | 1630 | Poll::Pending |
| 1583 | } | 1631 | } |
| 1584 | } | 1632 | } |
| 1585 | }).await | 1633 | }) |
| 1634 | .await | ||
| 1586 | } | 1635 | } |
| 1587 | 1636 | ||
| 1588 | /// Handle padding bytes after DMA data is exhausted | 1637 | /// Handle padding bytes after DMA data is exhausted |
| 1589 | /// | 1638 | /// |
| 1590 | /// Sends 0x00 bytes until transaction termination to prevent interrupt flooding | 1639 | /// Sends 0x00 bytes until transaction termination to prevent interrupt flooding |
| 1591 | async fn handle_padding_bytes(&mut self, state: &'static State, info: &'static Info) -> Result<usize, Error> { | 1640 | async fn handle_padding_bytes(&mut self, state: &'static State, info: &'static Info) -> Result<usize, Error> { |
| 1592 | let mut padding_count = 0; | 1641 | let mut padding_count = 0; |
| 1593 | 1642 | ||
| 1594 | poll_fn(|cx| { | 1643 | poll_fn(|cx| { |
| 1595 | state.waker.register(cx.waker()); | 1644 | state.waker.register(cx.waker()); |
| 1596 | 1645 | ||
| 1597 | match Self::check_and_clear_error_flags(info) { | 1646 | match Self::check_and_clear_error_flags(info) { |
| 1598 | Err(Error::Nack) => Poll::Ready(Ok(padding_count)), | 1647 | Err(Error::Nack) => Poll::Ready(Ok(padding_count)), |
| 1599 | Err(e) => { | 1648 | Err(e) => { |
| 1600 | error!("I2C slave: error while sending padding bytes: {:?}", e); | 1649 | error!("I2C slave: error while sending padding bytes: {:?}", e); |
| 1601 | Poll::Ready(Err(e)) | 1650 | Poll::Ready(Err(e)) |
| 1602 | }, | 1651 | } |
| 1603 | Ok(sr1) => { | 1652 | Ok(sr1) => { |
| 1604 | if let Some(termination) = Self::check_slave_termination_conditions(sr1) { | 1653 | if let Some(termination) = Self::check_slave_termination_conditions(sr1) { |
| 1605 | match termination { | 1654 | match termination { |
| 1606 | SlaveTermination::Stop => Self::clear_stop_flag(info), | 1655 | SlaveTermination::Stop => Self::clear_stop_flag(info), |
| 1607 | SlaveTermination::Restart => {}, | 1656 | SlaveTermination::Restart => {} |
| 1608 | SlaveTermination::Nack => { | 1657 | SlaveTermination::Nack => { |
| 1609 | info.regs.sr1().write(|reg| { | 1658 | info.regs.sr1().write(|reg| { |
| 1610 | reg.0 = !0; | 1659 | reg.0 = !0; |
| @@ -1614,33 +1663,34 @@ impl<'d> I2c<'d, Async, MultiMaster> { | |||
| 1614 | } | 1663 | } |
| 1615 | return Poll::Ready(Ok(padding_count)); | 1664 | return Poll::Ready(Ok(padding_count)); |
| 1616 | } | 1665 | } |
| 1617 | 1666 | ||
| 1618 | if sr1.txe() { | 1667 | if sr1.txe() { |
| 1619 | info.regs.dr().write(|w| w.set_dr(0x00)); | 1668 | info.regs.dr().write(|w| w.set_dr(0x00)); |
| 1620 | padding_count += 1; | 1669 | padding_count += 1; |
| 1621 | Self::enable_interrupts(info); | 1670 | Self::enable_interrupts(info); |
| 1622 | return Poll::Pending; | 1671 | return Poll::Pending; |
| 1623 | } | 1672 | } |
| 1624 | 1673 | ||
| 1625 | Self::enable_interrupts(info); | 1674 | Self::enable_interrupts(info); |
| 1626 | Poll::Pending | 1675 | Poll::Pending |
| 1627 | } | 1676 | } |
| 1628 | } | 1677 | } |
| 1629 | }).await | 1678 | }) |
| 1679 | .await | ||
| 1630 | } | 1680 | } |
| 1631 | } | 1681 | } |
| 1632 | 1682 | ||
| 1633 | /// Timing configuration for I2C v1 hardware | 1683 | /// Timing configuration for I2C v1 hardware |
| 1634 | /// | 1684 | /// |
| 1635 | /// This struct encapsulates the complex timing calculations required for STM32 I2C v1 | 1685 | /// This struct encapsulates the complex timing calculations required for STM32 I2C v1 |
| 1636 | /// peripherals, which use three separate registers (CR2.FREQ, CCR, TRISE) instead of | 1686 | /// peripherals, which use three separate registers (CR2.FREQ, CCR, TRISE) instead of |
| 1637 | /// the unified TIMINGR register found in v2 hardware. | 1687 | /// the unified TIMINGR register found in v2 hardware. |
| 1638 | struct Timings { | 1688 | struct Timings { |
| 1639 | freq: u8, // APB frequency in MHz for CR2.FREQ register | 1689 | freq: u8, // APB frequency in MHz for CR2.FREQ register |
| 1640 | f_s: i2c::vals::FS, // Standard or Fast mode selection | 1690 | f_s: i2c::vals::FS, // Standard or Fast mode selection |
| 1641 | trise: u8, // Rise time compensation value | 1691 | trise: u8, // Rise time compensation value |
| 1642 | ccr: u16, // Clock control register value | 1692 | ccr: u16, // Clock control register value |
| 1643 | duty: i2c::vals::Duty, // Fast mode duty cycle selection | 1693 | duty: i2c::vals::Duty, // Fast mode duty cycle selection |
| 1644 | } | 1694 | } |
| 1645 | 1695 | ||
| 1646 | impl Timings { | 1696 | impl Timings { |
