aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/i2c/v1.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32/src/i2c/v1.rs')
-rw-r--r--embassy-stm32/src/i2c/v1.rs1095
1 files changed, 1031 insertions, 64 deletions
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs
index 081eb1191..81a6d74c1 100644
--- a/embassy-stm32/src/i2c/v1.rs
+++ b/embassy-stm32/src/i2c/v1.rs
@@ -8,7 +8,7 @@ use core::future::poll_fn;
8use core::task::Poll; 8use core::task::Poll;
9 9
10use embassy_embedded_hal::SetConfig; 10use embassy_embedded_hal::SetConfig;
11use embassy_futures::select::{select, Either}; 11use embassy_futures::select::{Either, select};
12use embassy_hal_internal::drop::OnDrop; 12use embassy_hal_internal::drop::OnDrop;
13use embedded_hal_1::i2c::Operation; 13use embedded_hal_1::i2c::Operation;
14use mode::Master; 14use mode::Master;
@@ -30,6 +30,7 @@ use crate::pac::i2c;
30// hit a case like this! 30// hit a case like this!
31pub unsafe fn on_interrupt<T: Instance>() { 31pub unsafe fn on_interrupt<T: Instance>() {
32 let regs = T::info().regs; 32 let regs = T::info().regs;
33 trace!("I2C interrupt triggered");
33 // i2c v2 only woke the task on transfer complete interrupts. v1 uses interrupts for a bunch of 34 // i2c v2 only woke the task on transfer complete interrupts. v1 uses interrupts for a bunch of
34 // other stuff, so we wake the task on every interrupt. 35 // other stuff, so we wake the task on every interrupt.
35 T::state().waker.wake(); 36 T::state().waker.wake();
@@ -92,6 +93,7 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> {
92 self.info.regs.cr1().modify(|reg| { 93 self.info.regs.cr1().modify(|reg| {
93 reg.set_pe(true); 94 reg.set_pe(true);
94 }); 95 });
96 trace!("i2c v1 init complete");
95 } 97 }
96 98
97 fn check_and_clear_error_flags(info: &'static Info) -> Result<i2c::regs::Sr1, Error> { 99 fn check_and_clear_error_flags(info: &'static Info) -> Result<i2c::regs::Sr1, Error> {
@@ -151,7 +153,13 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> {
151 Ok(sr1) 153 Ok(sr1)
152 } 154 }
153 155
154 fn write_bytes(&mut self, addr: u8, bytes: &[u8], timeout: Timeout, frame: FrameOptions) -> Result<(), Error> { 156 fn write_bytes(
157 &mut self,
158 address: u8,
159 write_buffer: &[u8],
160 timeout: Timeout,
161 frame: FrameOptions,
162 ) -> Result<(), Error> {
155 if frame.send_start() { 163 if frame.send_start() {
156 // Send a START condition 164 // Send a START condition
157 165
@@ -170,7 +178,7 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> {
170 } 178 }
171 179
172 // Set up current address we're trying to talk to 180 // Set up current address we're trying to talk to
173 self.info.regs.dr().write(|reg| reg.set_dr(addr << 1)); 181 self.info.regs.dr().write(|reg| reg.set_dr(address << 1));
174 182
175 // Wait until address was sent 183 // Wait until address was sent
176 // Wait for the address to be acknowledged 184 // Wait for the address to be acknowledged
@@ -184,7 +192,7 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> {
184 } 192 }
185 193
186 // Send bytes 194 // Send bytes
187 for c in bytes { 195 for c in write_buffer {
188 self.send_byte(*c, timeout)?; 196 self.send_byte(*c, timeout)?;
189 } 197 }
190 198
@@ -236,12 +244,12 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> {
236 244
237 fn blocking_read_timeout( 245 fn blocking_read_timeout(
238 &mut self, 246 &mut self,
239 addr: u8, 247 address: u8,
240 buffer: &mut [u8], 248 read_buffer: &mut [u8],
241 timeout: Timeout, 249 timeout: Timeout,
242 frame: FrameOptions, 250 frame: FrameOptions,
243 ) -> Result<(), Error> { 251 ) -> Result<(), Error> {
244 let Some((last, buffer)) = buffer.split_last_mut() else { 252 let Some((last_byte, read_buffer)) = read_buffer.split_last_mut() else {
245 return Err(Error::Overrun); 253 return Err(Error::Overrun);
246 }; 254 };
247 255
@@ -263,7 +271,7 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> {
263 } 271 }
264 272
265 // Set up current address we're trying to talk to 273 // Set up current address we're trying to talk to
266 self.info.regs.dr().write(|reg| reg.set_dr((addr << 1) + 1)); 274 self.info.regs.dr().write(|reg| reg.set_dr((address << 1) + 1));
267 275
268 // Wait until address was sent 276 // Wait until address was sent
269 // Wait for the address to be acknowledged 277 // Wait for the address to be acknowledged
@@ -276,7 +284,7 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> {
276 } 284 }
277 285
278 // Receive bytes into buffer 286 // Receive bytes into buffer
279 for c in buffer { 287 for c in read_buffer {
280 *c = self.recv_byte(timeout)?; 288 *c = self.recv_byte(timeout)?;
281 } 289 }
282 290
@@ -291,37 +299,42 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> {
291 }); 299 });
292 300
293 // Receive last byte 301 // Receive last byte
294 *last = self.recv_byte(timeout)?; 302 *last_byte = self.recv_byte(timeout)?;
295 303
296 // Fallthrough is success 304 // Fallthrough is success
297 Ok(()) 305 Ok(())
298 } 306 }
299 307
300 /// Blocking read. 308 /// Blocking read.
301 pub fn blocking_read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Error> { 309 pub fn blocking_read(&mut self, address: u8, read_buffer: &mut [u8]) -> Result<(), Error> {
302 self.blocking_read_timeout(addr, read, self.timeout(), FrameOptions::FirstAndLastFrame) 310 self.blocking_read_timeout(address, read_buffer, self.timeout(), FrameOptions::FirstAndLastFrame)
303 } 311 }
304 312
305 /// Blocking write. 313 /// Blocking write.
306 pub fn blocking_write(&mut self, addr: u8, write: &[u8]) -> Result<(), Error> { 314 pub fn blocking_write(&mut self, address: u8, write_buffer: &[u8]) -> Result<(), Error> {
307 self.write_bytes(addr, write, self.timeout(), FrameOptions::FirstAndLastFrame)?; 315 self.write_bytes(address, write_buffer, self.timeout(), FrameOptions::FirstAndLastFrame)?;
308 316
309 // Fallthrough is success 317 // Fallthrough is success
310 Ok(()) 318 Ok(())
311 } 319 }
312 320
313 /// Blocking write, restart, read. 321 /// Blocking write, restart, read.
314 pub fn blocking_write_read(&mut self, addr: u8, write: &[u8], read: &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> {
315 // 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
316 // stop condition below. 329 // stop condition below.
317 if read.is_empty() { 330 if read_buffer.is_empty() {
318 return Err(Error::Overrun); 331 return Err(Error::Overrun);
319 } 332 }
320 333
321 let timeout = self.timeout(); 334 let timeout = self.timeout();
322 335
323 self.write_bytes(addr, write, timeout, FrameOptions::FirstFrame)?; 336 self.write_bytes(address, write_buffer, timeout, FrameOptions::FirstFrame)?;
324 self.blocking_read_timeout(addr, read, timeout, FrameOptions::FirstAndLastFrame)?; 337 self.blocking_read_timeout(address, read_buffer, timeout, FrameOptions::FirstAndLastFrame)?;
325 338
326 Ok(()) 339 Ok(())
327 } 340 }
@@ -331,32 +344,43 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> {
331 /// Consecutive operations of same type are merged. See [transaction contract] for details. 344 /// Consecutive operations of same type are merged. See [transaction contract] for details.
332 /// 345 ///
333 /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction 346 /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction
334 pub fn blocking_transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> { 347 pub fn blocking_transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> {
335 let timeout = self.timeout(); 348 let timeout = self.timeout();
336 349
337 for (op, frame) in operation_frames(operations)? { 350 for (op, frame) in operation_frames(operations)? {
338 match op { 351 match op {
339 Operation::Read(read) => self.blocking_read_timeout(addr, read, timeout, frame)?, 352 Operation::Read(read_buffer) => self.blocking_read_timeout(address, read_buffer, timeout, frame)?,
340 Operation::Write(write) => self.write_bytes(addr, write, timeout, frame)?, 353 Operation::Write(write_buffer) => self.write_bytes(address, write_buffer, timeout, frame)?,
341 } 354 }
342 } 355 }
343 356
344 Ok(()) 357 Ok(())
345 } 358 }
346 359
347 // Async 360 /// Can be used by both blocking and async implementations
348
349 #[inline] // pretty sure this should always be inlined 361 #[inline] // pretty sure this should always be inlined
350 fn enable_interrupts(info: &'static Info) -> () { 362 fn enable_interrupts(info: &'static Info) {
351 info.regs.cr2().modify(|w| { 363 // The interrupt handler disables interrupts globally, so we need to re-enable them
352 w.set_iterren(true); 364 // This must be done in a critical section to avoid races
353 w.set_itevten(true); 365 critical_section::with(|_| {
366 info.regs.cr2().modify(|w| {
367 w.set_iterren(true);
368 w.set_itevten(true);
369 });
354 }); 370 });
355 } 371 }
372
373 /// Can be used by both blocking and async implementations
374 fn clear_stop_flag(info: &'static Info) {
375 trace!("I2C slave: clearing STOPF flag (v1 sequence)");
376 // v1 requires: READ SR1 then WRITE CR1 to clear STOPF
377 let _ = info.regs.sr1().read();
378 info.regs.cr1().modify(|_| {}); // Dummy write to clear STOPF
379 }
356} 380}
357 381
358impl<'d, IM: MasterMode> I2c<'d, Async, IM> { 382impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
359 async fn write_frame(&mut self, address: u8, write: &[u8], frame: FrameOptions) -> Result<(), Error> { 383 async fn write_frame(&mut self, address: u8, write_buffer: &[u8], frame: FrameOptions) -> Result<(), Error> {
360 self.info.regs.cr2().modify(|w| { 384 self.info.regs.cr2().modify(|w| {
361 // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for 385 // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for
362 // reception. 386 // reception.
@@ -439,7 +463,10 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
439 // this address from the memory after each TxE event. 463 // this address from the memory after each TxE event.
440 let dst = self.info.regs.dr().as_ptr() as *mut u8; 464 let dst = self.info.regs.dr().as_ptr() as *mut u8;
441 465
442 self.tx_dma.as_mut().unwrap().write(write, dst, Default::default()) 466 self.tx_dma
467 .as_mut()
468 .unwrap()
469 .write(write_buffer, dst, Default::default())
443 }; 470 };
444 471
445 // Wait for bytes to be sent, or an error to occur. 472 // Wait for bytes to be sent, or an error to occur.
@@ -501,28 +528,30 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
501 } 528 }
502 529
503 /// Write. 530 /// Write.
504 pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> { 531 pub async fn write(&mut self, address: u8, write_buffer: &[u8]) -> Result<(), Error> {
505 self.write_frame(address, write, FrameOptions::FirstAndLastFrame) 532 let _scoped_block_stop = self.info.rcc.block_stop();
533 self.write_frame(address, write_buffer, FrameOptions::FirstAndLastFrame)
506 .await?; 534 .await?;
507 535
508 Ok(()) 536 Ok(())
509 } 537 }
510 538
511 /// Read. 539 /// Read.
512 pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> { 540 pub async fn read(&mut self, address: u8, read_buffer: &mut [u8]) -> Result<(), Error> {
513 self.read_frame(address, buffer, FrameOptions::FirstAndLastFrame) 541 let _scoped_block_stop = self.info.rcc.block_stop();
542 self.read_frame(address, read_buffer, FrameOptions::FirstAndLastFrame)
514 .await?; 543 .await?;
515 544
516 Ok(()) 545 Ok(())
517 } 546 }
518 547
519 async fn read_frame(&mut self, address: u8, buffer: &mut [u8], frame: FrameOptions) -> Result<(), Error> { 548 async fn read_frame(&mut self, address: u8, read_buffer: &mut [u8], frame: FrameOptions) -> Result<(), Error> {
520 if buffer.is_empty() { 549 if read_buffer.is_empty() {
521 return Err(Error::Overrun); 550 return Err(Error::Overrun);
522 } 551 }
523 552
524 // Some branches below depend on whether the buffer contains only a single byte. 553 // Some branches below depend on whether the buffer contains only a single byte.
525 let single_byte = buffer.len() == 1; 554 let single_byte = read_buffer.len() == 1;
526 555
527 self.info.regs.cr2().modify(|w| { 556 self.info.regs.cr2().modify(|w| {
528 // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for 557 // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for
@@ -612,7 +641,7 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
612 self.info.regs.sr2().read(); 641 self.info.regs.sr2().read();
613 } else { 642 } else {
614 // Before starting reception of single byte (but without START condition, i.e. in case 643 // Before starting reception of single byte (but without START condition, i.e. in case
615 // of continued frame), program NACK to emit at end of this byte. 644 // of merged operations), program NACK to emit at end of this byte.
616 if frame.send_nack() && single_byte { 645 if frame.send_nack() && single_byte {
617 self.info.regs.cr1().modify(|w| { 646 self.info.regs.cr1().modify(|w| {
618 w.set_ack(false); 647 w.set_ack(false);
@@ -634,7 +663,7 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
634 // from this address from the memory after each RxE event. 663 // from this address from the memory after each RxE event.
635 let src = self.info.regs.dr().as_ptr() as *mut u8; 664 let src = self.info.regs.dr().as_ptr() as *mut u8;
636 665
637 self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default()) 666 self.rx_dma.as_mut().unwrap().read(src, read_buffer, Default::default())
638 }; 667 };
639 668
640 // Wait for bytes to be received, or an error to occur. 669 // Wait for bytes to be received, or an error to occur.
@@ -673,15 +702,18 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
673 } 702 }
674 703
675 /// Write, restart, read. 704 /// Write, restart, read.
676 pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { 705 pub async fn write_read(&mut self, address: u8, write_buffer: &[u8], read_buffer: &mut [u8]) -> Result<(), Error> {
706 let _scoped_block_stop = self.info.rcc.block_stop();
677 // Check empty read buffer before starting transaction. Otherwise, we would not generate the 707 // Check empty read buffer before starting transaction. Otherwise, we would not generate the
678 // stop condition below. 708 // stop condition below.
679 if read.is_empty() { 709 if read_buffer.is_empty() {
680 return Err(Error::Overrun); 710 return Err(Error::Overrun);
681 } 711 }
682 712
683 self.write_frame(address, write, FrameOptions::FirstFrame).await?; 713 self.write_frame(address, write_buffer, FrameOptions::FirstFrame)
684 self.read_frame(address, read, FrameOptions::FirstAndLastFrame).await 714 .await?;
715 self.read_frame(address, read_buffer, FrameOptions::FirstAndLastFrame)
716 .await
685 } 717 }
686 718
687 /// Transaction with operations. 719 /// Transaction with operations.
@@ -689,11 +721,12 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
689 /// Consecutive operations of same type are merged. See [transaction contract] for details. 721 /// Consecutive operations of same type are merged. See [transaction contract] for details.
690 /// 722 ///
691 /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction 723 /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction
692 pub async fn transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> { 724 pub async fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> {
725 let _scoped_block_stop = self.info.rcc.block_stop();
693 for (op, frame) in operation_frames(operations)? { 726 for (op, frame) in operation_frames(operations)? {
694 match op { 727 match op {
695 Operation::Read(read) => self.read_frame(addr, read, frame).await?, 728 Operation::Read(read_buffer) => self.read_frame(address, read_buffer, frame).await?,
696 Operation::Write(write) => self.write_frame(addr, write, frame).await?, 729 Operation::Write(write_buffer) => self.write_frame(address, write_buffer, frame).await?,
697 } 730 }
698 } 731 }
699 732
@@ -729,12 +762,959 @@ impl Duty {
729 } 762 }
730} 763}
731 764
765/// Result of attempting to send a byte in slave transmitter mode
766#[derive(Debug, PartialEq)]
767enum TransmitResult {
768 /// Byte sent and ACKed by master - continue transmission
769 Acknowledged,
770 /// Byte sent but NACKed by master - normal end of read transaction
771 NotAcknowledged,
772 /// STOP condition detected - master terminated transaction
773 Stopped,
774 /// RESTART condition detected - master starting new transaction
775 Restarted,
776}
777
778/// Result of attempting to receive a byte in slave receiver mode
779#[derive(Debug, PartialEq)]
780enum ReceiveResult {
781 /// Data byte successfully received
782 Data(u8),
783 /// STOP condition detected - end of write transaction
784 Stopped,
785 /// RESTART condition detected - master starting new transaction
786 Restarted,
787}
788
789/// Enumeration of slave transaction termination conditions
790#[derive(Debug, Clone, Copy, PartialEq)]
791#[cfg_attr(feature = "defmt", derive(defmt::Format))]
792enum SlaveTermination {
793 /// STOP condition received - normal end of transaction
794 Stop,
795 /// RESTART condition received - master starting new transaction
796 Restart,
797 /// NACK received - normal end of read transaction
798 Nack,
799}
800
801impl<'d, M: PeriMode> I2c<'d, M, Master> {
802 /// Configure the I2C driver for slave operations, allowing for the driver to be used as a slave and a master (multimaster)
803 pub fn into_slave_multimaster(mut self, slave_addr_config: SlaveAddrConfig) -> I2c<'d, M, MultiMaster> {
804 let mut slave = I2c {
805 info: self.info,
806 state: self.state,
807 kernel_clock: self.kernel_clock,
808 tx_dma: self.tx_dma.take(), // Use take() to move ownership
809 rx_dma: self.rx_dma.take(), // Use take() to move ownership
810 #[cfg(feature = "time")]
811 timeout: self.timeout,
812 _phantom: PhantomData,
813 _phantom2: PhantomData,
814 _drop_guard: self._drop_guard, // Move the drop guard
815 };
816 slave.init_slave(slave_addr_config);
817 slave
818 }
819}
820
821// Address configuration methods
822impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> {
823 /// Initialize slave mode with address configuration
824 pub(crate) fn init_slave(&mut self, config: SlaveAddrConfig) {
825 trace!("I2C slave: initializing with config={:?}", config);
826
827 // Disable peripheral for configuration
828 self.info.regs.cr1().modify(|reg| reg.set_pe(false));
829
830 // Configure slave addresses
831 self.apply_address_configuration(config);
832
833 // Enable peripheral with slave settings
834 self.info.regs.cr1().modify(|reg| {
835 reg.set_pe(true);
836 reg.set_ack(true); // Enable acknowledgment for slave mode
837 reg.set_nostretch(false); // Allow clock stretching for processing time
838 });
839
840 trace!("I2C slave: initialization complete");
841 }
842
843 /// Apply the complete address configuration for slave mode
844 fn apply_address_configuration(&mut self, config: SlaveAddrConfig) {
845 match config.addr {
846 OwnAddresses::OA1(addr) => {
847 self.configure_primary_address(addr);
848 self.disable_secondary_address();
849 }
850 OwnAddresses::OA2(oa2) => {
851 self.configure_default_primary_address();
852 self.configure_secondary_address(oa2.addr); // v1 ignores mask
853 }
854 OwnAddresses::Both { oa1, oa2 } => {
855 self.configure_primary_address(oa1);
856 self.configure_secondary_address(oa2.addr); // v1 ignores mask
857 }
858 }
859
860 // Configure general call detection
861 if config.general_call {
862 self.info.regs.cr1().modify(|w| w.set_engc(true));
863 }
864 }
865
866 /// Configure the primary address (OA1) register
867 fn configure_primary_address(&mut self, addr: Address) {
868 match addr {
869 Address::SevenBit(addr) => {
870 self.info.regs.oar1().write(|reg| {
871 let hw_addr = (addr as u16) << 1; // Address in bits [7:1]
872 reg.set_add(hw_addr);
873 reg.set_addmode(i2c::vals::Addmode::BIT7);
874 });
875 }
876 Address::TenBit(addr) => {
877 self.info.regs.oar1().write(|reg| {
878 reg.set_add(addr);
879 reg.set_addmode(i2c::vals::Addmode::BIT10);
880 });
881 }
882 }
883
884 // Set required bit 14 as per reference manual
885 self.info.regs.oar1().modify(|reg| reg.0 |= 1 << 14);
886 }
887
888 /// Configure the secondary address (OA2) register
889 fn configure_secondary_address(&mut self, addr: u8) {
890 self.info.regs.oar2().write(|reg| {
891 reg.set_add2(addr);
892 reg.set_endual(i2c::vals::Endual::DUAL);
893 });
894 }
895
896 /// Set a default primary address when using OA2-only mode
897 fn configure_default_primary_address(&mut self) {
898 self.info.regs.oar1().write(|reg| {
899 reg.set_add(0); // Reserved address, safe to use
900 reg.set_addmode(i2c::vals::Addmode::BIT7);
901 });
902 self.info.regs.oar1().modify(|reg| reg.0 |= 1 << 14);
903 }
904
905 /// Disable secondary address when not needed
906 fn disable_secondary_address(&mut self) {
907 self.info.regs.oar2().write(|reg| {
908 reg.set_endual(i2c::vals::Endual::SINGLE);
909 });
910 }
911}
912
913impl<'d, M: PeriMode> I2c<'d, M, MultiMaster> {
914 /// Listen for incoming I2C address match and return the command type
915 ///
916 /// This method blocks until the slave address is matched by a master.
917 /// Returns the command type (Read/Write) and the matched address.
918 pub fn blocking_listen(&mut self) -> Result<SlaveCommand, Error> {
919 trace!("I2C slave: starting blocking listen for address match");
920 let result = self.blocking_listen_with_timeout(self.timeout());
921 trace!("I2C slave: blocking listen complete, result={:?}", result);
922 result
923 }
924
925 /// Respond to a master read request by transmitting data
926 ///
927 /// Sends the provided data to the master. If the master requests more bytes
928 /// than available, padding bytes (0x00) are sent until the master terminates
929 /// the transaction with NACK.
930 ///
931 /// Returns the total number of bytes transmitted (including padding).
932 pub fn blocking_respond_to_read(&mut self, data: &[u8]) -> Result<usize, Error> {
933 trace!("I2C slave: starting blocking respond_to_read, data_len={}", data.len());
934
935 if let Some(zero_length_result) = self.detect_zero_length_read(self.timeout())? {
936 trace!("I2C slave: zero-length read detected");
937 return Ok(zero_length_result);
938 }
939
940 let result = self.transmit_to_master(data, self.timeout());
941 trace!("I2C slave: blocking respond_to_read complete, result={:?}", result);
942 result
943 }
944
945 /// Respond to a master write request by receiving data
946 ///
947 /// Receives data from the master into the provided buffer. If the master
948 /// sends more bytes than the buffer can hold, excess bytes are acknowledged
949 /// but discarded.
950 ///
951 /// Returns the number of bytes stored in the buffer (not total received).
952 pub fn blocking_respond_to_write(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
953 trace!(
954 "I2C slave: starting blocking respond_to_write, buffer_len={}",
955 buffer.len()
956 );
957 let result = self.receive_from_master(buffer, self.timeout());
958 trace!("I2C slave: blocking respond_to_write complete, result={:?}", result);
959 result
960 }
961
962 // Private implementation methods
963
964 /// Wait for address match and determine transaction type
965 fn blocking_listen_with_timeout(&mut self, timeout: Timeout) -> Result<SlaveCommand, Error> {
966 // Ensure interrupts are disabled for blocking operation
967 self.disable_i2c_interrupts();
968
969 // Wait for address match (ADDR flag)
970 loop {
971 let sr1 = Self::read_status_and_handle_errors(self.info)?;
972
973 if sr1.addr() {
974 // Address matched - read SR2 to get direction and clear ADDR flag
975 let sr2 = self.info.regs.sr2().read();
976 let direction = if sr2.tra() {
977 SlaveCommandKind::Read
978 } else {
979 SlaveCommandKind::Write
980 };
981
982 // Use the static method instead of the instance method
983 let matched_address = Self::decode_matched_address(sr2, self.info)?;
984 trace!(
985 "I2C slave: address matched, direction={:?}, addr={:?}",
986 direction, matched_address
987 );
988
989 return Ok(SlaveCommand {
990 kind: direction,
991 address: matched_address,
992 });
993 }
994
995 timeout.check()?;
996 }
997 }
998
999 /// Transmit data to master in response to read request
1000 fn transmit_to_master(&mut self, data: &[u8], timeout: Timeout) -> Result<usize, Error> {
1001 let mut bytes_transmitted = 0;
1002 let mut padding_count = 0;
1003
1004 loop {
1005 let byte_to_send = if bytes_transmitted < data.len() {
1006 data[bytes_transmitted]
1007 } else {
1008 padding_count += 1;
1009 0x00 // Send padding bytes when data is exhausted
1010 };
1011
1012 match self.transmit_byte(byte_to_send, timeout)? {
1013 TransmitResult::Acknowledged => {
1014 bytes_transmitted += 1;
1015 }
1016 TransmitResult::NotAcknowledged => {
1017 bytes_transmitted += 1; // Count the NACKed byte
1018 break;
1019 }
1020 TransmitResult::Stopped | TransmitResult::Restarted => {
1021 break;
1022 }
1023 }
1024 }
1025
1026 if padding_count > 0 {
1027 trace!(
1028 "I2C slave: sent {} data bytes + {} padding bytes = {} total",
1029 data.len(),
1030 padding_count,
1031 bytes_transmitted
1032 );
1033 }
1034
1035 Ok(bytes_transmitted)
1036 }
1037
1038 /// Receive data from master during write request
1039 fn receive_from_master(&mut self, buffer: &mut [u8], timeout: Timeout) -> Result<usize, Error> {
1040 let mut bytes_stored = 0;
1041
1042 // Receive bytes that fit in buffer
1043 while bytes_stored < buffer.len() {
1044 match self.receive_byte(timeout)? {
1045 ReceiveResult::Data(byte) => {
1046 buffer[bytes_stored] = byte;
1047 bytes_stored += 1;
1048 }
1049 ReceiveResult::Stopped | ReceiveResult::Restarted => {
1050 return Ok(bytes_stored);
1051 }
1052 }
1053 }
1054
1055 // Handle buffer overflow by discarding excess bytes
1056 if bytes_stored == buffer.len() {
1057 trace!("I2C slave: buffer full, discarding excess bytes");
1058 self.discard_excess_bytes(timeout)?;
1059 }
1060
1061 Ok(bytes_stored)
1062 }
1063
1064 /// Detect zero-length read pattern early
1065 ///
1066 /// Zero-length reads occur when a master sends START+ADDR+R followed immediately
1067 /// by NACK+STOP without wanting any data. This must be detected before attempting
1068 /// to transmit any bytes to avoid SDA line issues.
1069 fn detect_zero_length_read(&mut self, _timeout: Timeout) -> Result<Option<usize>, Error> {
1070 // Quick check for immediate termination signals
1071 let sr1 = self.info.regs.sr1().read();
1072
1073 // Check for immediate NACK (fastest zero-length pattern)
1074 if sr1.af() {
1075 self.clear_acknowledge_failure();
1076 return Ok(Some(0));
1077 }
1078
1079 // Check for immediate STOP (alternative zero-length pattern)
1080 if sr1.stopf() {
1081 Self::clear_stop_flag(self.info);
1082 return Ok(Some(0));
1083 }
1084
1085 // Give a brief window for master to send termination signals
1086 // This handles masters that have slight delays between address ACK and NACK
1087 const ZERO_LENGTH_DETECTION_CYCLES: u32 = 20; // ~5-10µs window
1088
1089 for _ in 0..ZERO_LENGTH_DETECTION_CYCLES {
1090 let sr1 = self.info.regs.sr1().read();
1091
1092 // Immediate NACK indicates zero-length read
1093 if sr1.af() {
1094 self.clear_acknowledge_failure();
1095 return Ok(Some(0));
1096 }
1097
1098 // Immediate STOP indicates zero-length read
1099 if sr1.stopf() {
1100 Self::clear_stop_flag(self.info);
1101 return Ok(Some(0));
1102 }
1103
1104 // If TXE becomes ready, master is waiting for data - not zero-length
1105 if sr1.txe() {
1106 return Ok(None); // Proceed with normal transmission
1107 }
1108
1109 // If RESTART detected, handle as zero-length
1110 if sr1.addr() {
1111 return Ok(Some(0));
1112 }
1113 }
1114
1115 // No zero-length pattern detected within the window
1116 Ok(None)
1117 }
1118
1119 /// Discard excess bytes when buffer is full
1120 fn discard_excess_bytes(&mut self, timeout: Timeout) -> Result<(), Error> {
1121 let mut discarded_count = 0;
1122
1123 loop {
1124 match self.receive_byte(timeout)? {
1125 ReceiveResult::Data(_) => {
1126 discarded_count += 1;
1127 continue;
1128 }
1129 ReceiveResult::Stopped | ReceiveResult::Restarted => {
1130 if discarded_count > 0 {
1131 trace!("I2C slave: discarded {} excess bytes", discarded_count);
1132 }
1133 break;
1134 }
1135 }
1136 }
1137 Ok(())
1138 }
1139
1140 /// Send a single byte and wait for master's response
1141 fn transmit_byte(&mut self, byte: u8, timeout: Timeout) -> Result<TransmitResult, Error> {
1142 // Wait for transmit buffer ready
1143 self.wait_for_transmit_ready(timeout)?;
1144
1145 // Send the byte
1146 self.info.regs.dr().write(|w| w.set_dr(byte));
1147
1148 // Wait for transmission completion or master response
1149 self.wait_for_transmit_completion(timeout)
1150 }
1151
1152 /// Wait until transmit buffer is ready (TXE flag set)
1153 fn wait_for_transmit_ready(&mut self, timeout: Timeout) -> Result<(), Error> {
1154 loop {
1155 let sr1 = Self::read_status_and_handle_errors(self.info)?;
1156
1157 // Check for early termination conditions
1158 if let Some(result) = Self::check_early_termination(sr1) {
1159 return Err(self.handle_early_termination(result));
1160 }
1161
1162 if sr1.txe() {
1163 return Ok(()); // Ready to transmit
1164 }
1165
1166 timeout.check()?;
1167 }
1168 }
1169
1170 /// Wait for byte transmission completion or master response
1171 fn wait_for_transmit_completion(&mut self, timeout: Timeout) -> Result<TransmitResult, Error> {
1172 loop {
1173 let sr1 = self.info.regs.sr1().read();
1174
1175 // Check flags in priority order
1176 if sr1.af() {
1177 self.clear_acknowledge_failure();
1178 return Ok(TransmitResult::NotAcknowledged);
1179 }
1180
1181 if sr1.btf() {
1182 return Ok(TransmitResult::Acknowledged);
1183 }
1184
1185 if sr1.stopf() {
1186 Self::clear_stop_flag(self.info);
1187 return Ok(TransmitResult::Stopped);
1188 }
1189
1190 if sr1.addr() {
1191 return Ok(TransmitResult::Restarted);
1192 }
1193
1194 // Check for other error conditions
1195 self.check_for_hardware_errors(sr1)?;
1196
1197 timeout.check()?;
1198 }
1199 }
1200
1201 /// Receive a single byte or detect transaction termination
1202 fn receive_byte(&mut self, timeout: Timeout) -> Result<ReceiveResult, Error> {
1203 loop {
1204 let sr1 = Self::read_status_and_handle_errors(self.info)?;
1205
1206 // Check for received data first (prioritize data over control signals)
1207 if sr1.rxne() {
1208 let byte = self.info.regs.dr().read().dr();
1209 return Ok(ReceiveResult::Data(byte));
1210 }
1211
1212 // Check for transaction termination
1213 if sr1.addr() {
1214 return Ok(ReceiveResult::Restarted);
1215 }
1216
1217 if sr1.stopf() {
1218 Self::clear_stop_flag(self.info);
1219 return Ok(ReceiveResult::Stopped);
1220 }
1221
1222 timeout.check()?;
1223 }
1224 }
1225
1226 /// Determine which slave address was matched based on SR2 flags
1227 fn decode_matched_address(sr2: i2c::regs::Sr2, info: &'static Info) -> Result<Address, Error> {
1228 if sr2.gencall() {
1229 Ok(Address::SevenBit(0x00)) // General call address
1230 } else if sr2.dualf() {
1231 // OA2 (secondary address) was matched
1232 let oar2 = info.regs.oar2().read();
1233 if oar2.endual() != i2c::vals::Endual::DUAL {
1234 return Err(Error::Bus); // Hardware inconsistency
1235 }
1236 Ok(Address::SevenBit(oar2.add2()))
1237 } else {
1238 // OA1 (primary address) was matched
1239 let oar1 = info.regs.oar1().read();
1240 match oar1.addmode() {
1241 i2c::vals::Addmode::BIT7 => {
1242 let addr = (oar1.add() >> 1) as u8;
1243 Ok(Address::SevenBit(addr))
1244 }
1245 i2c::vals::Addmode::BIT10 => Ok(Address::TenBit(oar1.add())),
1246 }
1247 }
1248 }
1249
1250 // Helper methods for hardware interaction
1251
1252 /// Read status register and handle I2C errors (except NACK in slave mode)
1253 fn read_status_and_handle_errors(info: &'static Info) -> Result<i2c::regs::Sr1, Error> {
1254 match Self::check_and_clear_error_flags(info) {
1255 Ok(sr1) => Ok(sr1),
1256 Err(Error::Nack) => {
1257 // In slave mode, NACK is normal protocol behavior, not an error
1258 Ok(info.regs.sr1().read())
1259 }
1260 Err(other_error) => Err(other_error),
1261 }
1262 }
1263
1264 /// Check for conditions that cause early termination of operations
1265 fn check_early_termination(sr1: i2c::regs::Sr1) -> Option<TransmitResult> {
1266 if sr1.stopf() {
1267 Some(TransmitResult::Stopped)
1268 } else if sr1.addr() {
1269 Some(TransmitResult::Restarted)
1270 } else if sr1.af() {
1271 Some(TransmitResult::NotAcknowledged)
1272 } else {
1273 None
1274 }
1275 }
1276
1277 /// Convert early termination to appropriate error
1278 fn handle_early_termination(&mut self, result: TransmitResult) -> Error {
1279 match result {
1280 TransmitResult::Stopped => {
1281 Self::clear_stop_flag(self.info);
1282 Error::Bus // Unexpected STOP during setup
1283 }
1284 TransmitResult::Restarted => {
1285 Error::Bus // Unexpected RESTART during setup
1286 }
1287 TransmitResult::NotAcknowledged => {
1288 self.clear_acknowledge_failure();
1289 Error::Bus // Unexpected NACK during setup
1290 }
1291 TransmitResult::Acknowledged => {
1292 unreachable!() // This should never be passed to this function
1293 }
1294 }
1295 }
1296
1297 /// Check for hardware-level I2C errors during transmission
1298 fn check_for_hardware_errors(&self, sr1: i2c::regs::Sr1) -> Result<(), Error> {
1299 if sr1.timeout() || sr1.ovr() || sr1.arlo() || sr1.berr() {
1300 // Delegate to existing error handling
1301 Self::check_and_clear_error_flags(self.info)?;
1302 }
1303 Ok(())
1304 }
1305
1306 /// Disable I2C event and error interrupts for blocking operations
1307 fn disable_i2c_interrupts(&mut self) {
1308 self.info.regs.cr2().modify(|w| {
1309 w.set_itevten(false);
1310 w.set_iterren(false);
1311 });
1312 }
1313
1314 /// Clear the acknowledge failure flag
1315 fn clear_acknowledge_failure(&mut self) {
1316 self.info.regs.sr1().write(|reg| {
1317 reg.0 = !0;
1318 reg.set_af(false);
1319 });
1320 }
1321
1322 /// Configure DMA settings for slave operations (shared between read/write)
1323 fn setup_slave_dma_base(&mut self) {
1324 self.info.regs.cr2().modify(|w| {
1325 w.set_itbufen(false); // Always disable buffer interrupts when using DMA
1326 w.set_dmaen(true); // Enable DMA requests
1327 w.set_last(false); // LAST bit not used in slave mode for v1 hardware
1328 });
1329 }
1330
1331 /// Disable DMA and interrupts in a critical section
1332 fn disable_dma_and_interrupts(info: &'static Info) {
1333 critical_section::with(|_| {
1334 info.regs.cr2().modify(|w| {
1335 w.set_dmaen(false);
1336 w.set_iterren(false);
1337 w.set_itevten(false);
1338 });
1339 });
1340 }
1341
1342 /// Check for early termination conditions during slave operations
1343 /// Returns Some(result) if termination detected, None to continue
1344 fn check_slave_termination_conditions(sr1: i2c::regs::Sr1) -> Option<SlaveTermination> {
1345 if sr1.stopf() {
1346 Some(SlaveTermination::Stop)
1347 } else if sr1.addr() {
1348 Some(SlaveTermination::Restart)
1349 } else if sr1.af() {
1350 Some(SlaveTermination::Nack)
1351 } else {
1352 None
1353 }
1354 }
1355}
1356
1357impl<'d> I2c<'d, Async, MultiMaster> {
1358 /// Async listen for incoming I2C messages using interrupts
1359 ///
1360 /// Waits for a master to address this slave and returns the command type
1361 /// (Read/Write) and the matched address. This method will suspend until
1362 /// an address match occurs.
1363 pub async fn listen(&mut self) -> Result<SlaveCommand, Error> {
1364 let _scoped_block_stop = self.info.rcc.block_stop();
1365 trace!("I2C slave: starting async listen for address match");
1366 let state = self.state;
1367 let info = self.info;
1368
1369 Self::enable_interrupts(info);
1370
1371 let on_drop = OnDrop::new(|| {
1372 Self::disable_dma_and_interrupts(info);
1373 });
1374
1375 let result = poll_fn(|cx| {
1376 state.waker.register(cx.waker());
1377
1378 match Self::check_and_clear_error_flags(info) {
1379 Err(e) => {
1380 error!("I2C slave: error during listen: {:?}", e);
1381 Poll::Ready(Err(e))
1382 }
1383 Ok(sr1) => {
1384 if sr1.addr() {
1385 let sr2 = info.regs.sr2().read();
1386 let direction = if sr2.tra() {
1387 SlaveCommandKind::Read
1388 } else {
1389 SlaveCommandKind::Write
1390 };
1391
1392 let matched_address = match Self::decode_matched_address(sr2, info) {
1393 Ok(addr) => {
1394 trace!("I2C slave: address matched, direction={:?}, addr={:?}", direction, addr);
1395 addr
1396 }
1397 Err(e) => {
1398 error!("I2C slave: failed to decode matched address: {:?}", e);
1399 return Poll::Ready(Err(e));
1400 }
1401 };
1402
1403 Poll::Ready(Ok(SlaveCommand {
1404 kind: direction,
1405 address: matched_address,
1406 }))
1407 } else {
1408 Self::enable_interrupts(info);
1409 Poll::Pending
1410 }
1411 }
1412 }
1413 })
1414 .await;
1415
1416 drop(on_drop);
1417 trace!("I2C slave: listen complete, result={:?}", result);
1418 result
1419 }
1420
1421 /// Async respond to write command using RX DMA
1422 ///
1423 /// Receives data from the master into the provided buffer using DMA.
1424 /// If the master sends more bytes than the buffer can hold, excess bytes
1425 /// are acknowledged but discarded to prevent interrupt flooding.
1426 ///
1427 /// Returns the number of bytes stored in the buffer (not total received).
1428 pub async fn respond_to_write(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
1429 let _scoped_block_stop = self.info.rcc.block_stop();
1430 trace!("I2C slave: starting respond_to_write, buffer_len={}", buffer.len());
1431
1432 if buffer.is_empty() {
1433 warn!("I2C slave: respond_to_write called with empty buffer");
1434 return Err(Error::Overrun);
1435 }
1436
1437 let state = self.state;
1438 let info = self.info;
1439
1440 self.setup_slave_dma_base();
1441
1442 let on_drop = OnDrop::new(|| {
1443 Self::disable_dma_and_interrupts(info);
1444 });
1445
1446 info.regs.sr2().read();
1447
1448 let result = self.execute_slave_receive_transfer(buffer, state, info).await;
1449
1450 drop(on_drop);
1451 trace!("I2C slave: respond_to_write complete, result={:?}", result);
1452 result
1453 }
1454
1455 /// Async respond to read command using TX DMA
1456 ///
1457 /// Transmits data to the master using DMA. If the master requests more bytes
1458 /// than available in the data buffer, padding bytes (0x00) are sent until
1459 /// the master terminates the transaction with NACK, STOP, or RESTART.
1460 ///
1461 /// Returns the total number of bytes transmitted (data + padding).
1462 pub async fn respond_to_read(&mut self, data: &[u8]) -> Result<usize, Error> {
1463 let _scoped_block_stop = self.info.rcc.block_stop();
1464 trace!("I2C slave: starting respond_to_read, data_len={}", data.len());
1465
1466 if data.is_empty() {
1467 warn!("I2C slave: respond_to_read called with empty data");
1468 return Err(Error::Overrun);
1469 }
1470
1471 let state = self.state;
1472 let info = self.info;
1473
1474 self.setup_slave_dma_base();
1475
1476 let on_drop = OnDrop::new(|| {
1477 Self::disable_dma_and_interrupts(info);
1478 });
1479
1480 info.regs.sr2().read();
1481
1482 let result = self.execute_slave_transmit_transfer(data, state, info).await;
1483
1484 drop(on_drop);
1485 trace!("I2C slave: respond_to_read complete, result={:?}", result);
1486 result
1487 }
1488
1489 // === Private Transfer Execution Methods ===
1490
1491 /// Execute complete slave receive transfer with excess byte handling
1492 async fn execute_slave_receive_transfer(
1493 &mut self,
1494 buffer: &mut [u8],
1495 state: &'static State,
1496 info: &'static Info,
1497 ) -> Result<usize, Error> {
1498 let dma_transfer = unsafe {
1499 let src = info.regs.dr().as_ptr() as *mut u8;
1500 self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default())
1501 };
1502
1503 let i2c_monitor =
1504 Self::create_termination_monitor(state, info, &[SlaveTermination::Stop, SlaveTermination::Restart]);
1505
1506 match select(dma_transfer, i2c_monitor).await {
1507 Either::Second(Err(e)) => {
1508 error!("I2C slave: error during receive transfer: {:?}", e);
1509 Self::disable_dma_and_interrupts(info);
1510 Err(e)
1511 }
1512 Either::First(_) => {
1513 trace!("I2C slave: DMA receive completed, handling excess bytes");
1514 Self::disable_dma_and_interrupts(info);
1515 self.handle_excess_bytes(state, info).await?;
1516 Ok(buffer.len())
1517 }
1518 Either::Second(Ok(termination)) => {
1519 trace!("I2C slave: receive terminated by I2C event: {:?}", termination);
1520 Self::disable_dma_and_interrupts(info);
1521 Ok(buffer.len())
1522 }
1523 }
1524 }
1525
1526 /// Execute complete slave transmit transfer with padding byte handling
1527 async fn execute_slave_transmit_transfer(
1528 &mut self,
1529 data: &[u8],
1530 state: &'static State,
1531 info: &'static Info,
1532 ) -> Result<usize, Error> {
1533 let dma_transfer = unsafe {
1534 let dst = info.regs.dr().as_ptr() as *mut u8;
1535 self.tx_dma.as_mut().unwrap().write(data, dst, Default::default())
1536 };
1537
1538 let i2c_monitor = Self::create_termination_monitor(
1539 state,
1540 info,
1541 &[
1542 SlaveTermination::Stop,
1543 SlaveTermination::Restart,
1544 SlaveTermination::Nack,
1545 ],
1546 );
1547
1548 match select(dma_transfer, i2c_monitor).await {
1549 Either::Second(Err(e)) => {
1550 error!("I2C slave: error during transmit transfer: {:?}", e);
1551 Self::disable_dma_and_interrupts(info);
1552 Err(e)
1553 }
1554 Either::First(_) => {
1555 trace!("I2C slave: DMA transmit completed, handling padding bytes");
1556 Self::disable_dma_and_interrupts(info);
1557 let padding_count = self.handle_padding_bytes(state, info).await?;
1558 let total_bytes = data.len() + padding_count;
1559 trace!(
1560 "I2C slave: sent {} data bytes + {} padding bytes = {} total",
1561 data.len(),
1562 padding_count,
1563 total_bytes
1564 );
1565 Ok(total_bytes)
1566 }
1567 Either::Second(Ok(termination)) => {
1568 trace!("I2C slave: transmit terminated by I2C event: {:?}", termination);
1569 Self::disable_dma_and_interrupts(info);
1570 Ok(data.len())
1571 }
1572 }
1573 }
1574
1575 /// Create a future that monitors for specific slave termination conditions
1576 fn create_termination_monitor(
1577 state: &'static State,
1578 info: &'static Info,
1579 allowed_terminations: &'static [SlaveTermination],
1580 ) -> impl Future<Output = Result<SlaveTermination, Error>> {
1581 poll_fn(move |cx| {
1582 state.waker.register(cx.waker());
1583
1584 match Self::check_and_clear_error_flags(info) {
1585 Err(Error::Nack) if allowed_terminations.contains(&SlaveTermination::Nack) => {
1586 Poll::Ready(Ok(SlaveTermination::Nack))
1587 }
1588 Err(e) => Poll::Ready(Err(e)),
1589 Ok(sr1) => {
1590 if let Some(termination) = Self::check_slave_termination_conditions(sr1) {
1591 if allowed_terminations.contains(&termination) {
1592 // Handle the specific termination condition
1593 match termination {
1594 SlaveTermination::Stop => Self::clear_stop_flag(info),
1595 SlaveTermination::Nack => {
1596 info.regs.sr1().write(|reg| {
1597 reg.0 = !0;
1598 reg.set_af(false);
1599 });
1600 }
1601 SlaveTermination::Restart => {
1602 // ADDR flag will be handled by next listen() call
1603 }
1604 }
1605 Poll::Ready(Ok(termination))
1606 } else {
1607 // Unexpected termination condition
1608 Poll::Ready(Err(Error::Bus))
1609 }
1610 } else {
1611 Self::enable_interrupts(info);
1612 Poll::Pending
1613 }
1614 }
1615 }
1616 })
1617 }
1618
1619 /// Handle excess bytes after DMA buffer is full
1620 ///
1621 /// Reads and discards bytes until transaction termination to prevent interrupt flooding
1622 async fn handle_excess_bytes(&mut self, state: &'static State, info: &'static Info) -> Result<(), Error> {
1623 let mut discarded_count = 0;
1624
1625 poll_fn(|cx| {
1626 state.waker.register(cx.waker());
1627
1628 match Self::check_and_clear_error_flags(info) {
1629 Err(e) => {
1630 error!("I2C slave: error while discarding excess bytes: {:?}", e);
1631 Poll::Ready(Err(e))
1632 }
1633 Ok(sr1) => {
1634 if let Some(termination) = Self::check_slave_termination_conditions(sr1) {
1635 match termination {
1636 SlaveTermination::Stop => Self::clear_stop_flag(info),
1637 SlaveTermination::Restart => {}
1638 SlaveTermination::Nack => unreachable!("NACK not expected during receive"),
1639 }
1640 if discarded_count > 0 {
1641 trace!("I2C slave: discarded {} excess bytes", discarded_count);
1642 }
1643 return Poll::Ready(Ok(()));
1644 }
1645
1646 if sr1.rxne() {
1647 let _discarded_byte = info.regs.dr().read().dr();
1648 discarded_count += 1;
1649 Self::enable_interrupts(info);
1650 return Poll::Pending;
1651 }
1652
1653 Self::enable_interrupts(info);
1654 Poll::Pending
1655 }
1656 }
1657 })
1658 .await
1659 }
1660
1661 /// Handle padding bytes after DMA data is exhausted
1662 ///
1663 /// Sends 0x00 bytes until transaction termination to prevent interrupt flooding
1664 async fn handle_padding_bytes(&mut self, state: &'static State, info: &'static Info) -> Result<usize, Error> {
1665 let mut padding_count = 0;
1666
1667 poll_fn(|cx| {
1668 state.waker.register(cx.waker());
1669
1670 match Self::check_and_clear_error_flags(info) {
1671 Err(Error::Nack) => Poll::Ready(Ok(padding_count)),
1672 Err(e) => {
1673 error!("I2C slave: error while sending padding bytes: {:?}", e);
1674 Poll::Ready(Err(e))
1675 }
1676 Ok(sr1) => {
1677 if let Some(termination) = Self::check_slave_termination_conditions(sr1) {
1678 match termination {
1679 SlaveTermination::Stop => Self::clear_stop_flag(info),
1680 SlaveTermination::Restart => {}
1681 SlaveTermination::Nack => {
1682 info.regs.sr1().write(|reg| {
1683 reg.0 = !0;
1684 reg.set_af(false);
1685 });
1686 }
1687 }
1688 return Poll::Ready(Ok(padding_count));
1689 }
1690
1691 if sr1.txe() {
1692 info.regs.dr().write(|w| w.set_dr(0x00));
1693 padding_count += 1;
1694 Self::enable_interrupts(info);
1695 return Poll::Pending;
1696 }
1697
1698 Self::enable_interrupts(info);
1699 Poll::Pending
1700 }
1701 }
1702 })
1703 .await
1704 }
1705}
1706
1707/// Timing configuration for I2C v1 hardware
1708///
1709/// This struct encapsulates the complex timing calculations required for STM32 I2C v1
1710/// peripherals, which use three separate registers (CR2.FREQ, CCR, TRISE) instead of
1711/// the unified TIMINGR register found in v2 hardware.
732struct Timings { 1712struct Timings {
733 freq: u8, 1713 freq: u8, // APB frequency in MHz for CR2.FREQ register
734 mode: Mode, 1714 mode: Mode, // Standard or Fast mode selection
735 trise: u8, 1715 trise: u8, // Rise time compensation value
736 ccr: u16, 1716 ccr: u16, // Clock control register value
737 duty: Duty, 1717 duty: Duty, // Fast mode duty cycle selection
738} 1718}
739 1719
740impl Timings { 1720impl Timings {
@@ -762,11 +1742,7 @@ impl Timings {
762 mode = Mode::Standard; 1742 mode = Mode::Standard;
763 ccr = { 1743 ccr = {
764 let ccr = clock / (frequency * 2); 1744 let ccr = clock / (frequency * 2);
765 if ccr < 4 { 1745 if ccr < 4 { 4 } else { ccr }
766 4
767 } else {
768 ccr
769 }
770 }; 1746 };
771 } else { 1747 } else {
772 const DUTYCYCLE: u8 = 0; 1748 const DUTYCYCLE: u8 = 0;
@@ -775,14 +1751,10 @@ impl Timings {
775 duty = Duty::Duty2_1; 1751 duty = Duty::Duty2_1;
776 ccr = clock / (frequency * 3); 1752 ccr = clock / (frequency * 3);
777 ccr = if ccr < 1 { 1 } else { ccr }; 1753 ccr = if ccr < 1 { 1 } else { ccr };
778
779 // Set clock to fast mode with appropriate parameters for selected speed (2:1 duty cycle)
780 } else { 1754 } else {
781 duty = Duty::Duty16_9; 1755 duty = Duty::Duty16_9;
782 ccr = clock / (frequency * 25); 1756 ccr = clock / (frequency * 25);
783 ccr = if ccr < 1 { 1 } else { ccr }; 1757 ccr = if ccr < 1 { 1 } else { ccr };
784
785 // Set clock to fast mode with appropriate parameters for selected speed (16:9 duty cycle)
786 } 1758 }
787 } 1759 }
788 1760
@@ -792,11 +1764,6 @@ impl Timings {
792 ccr: ccr as u16, 1764 ccr: ccr as u16,
793 duty, 1765 duty,
794 mode, 1766 mode,
795 //prescale: presc_reg,
796 //scll,
797 //sclh,
798 //sdadel,
799 //scldel,
800 } 1767 }
801 } 1768 }
802} 1769}