aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHybridChild <[email protected]>2025-08-22 13:45:43 +0200
committerHybridChild <[email protected]>2025-08-23 08:54:27 +0200
commite630e1a6d48ca25a92bc0479608ca75b7179c869 (patch)
tree6d018e7e9335c3b02fa2e8f53c34d048ef45be4f
parent8111bbc54594706d26d02a22ad8f1853317d3495 (diff)
stm32/i2c_v1: Update defmt logging for MultiMaster
-rw-r--r--embassy-stm32/src/i2c/v1.rs128
1 files changed, 75 insertions, 53 deletions
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs
index 0f2953ef6..b362ab017 100644
--- a/embassy-stm32/src/i2c/v1.rs
+++ b/embassy-stm32/src/i2c/v1.rs
@@ -45,7 +45,7 @@ impl State {
45// hit a case like this! 45// hit a case like this!
46pub unsafe fn on_interrupt<T: Instance>() { 46pub unsafe fn on_interrupt<T: Instance>() {
47 let regs = T::info().regs; 47 let regs = T::info().regs;
48 trace!("i2c v1 interrupt triggered"); 48 trace!("I2C interrupt triggered");
49 // i2c v2 only woke the task on transfer complete interrupts. v1 uses interrupts for a bunch of 49 // i2c v2 only woke the task on transfer complete interrupts. v1 uses interrupts for a bunch of
50 // other stuff, so we wake the task on every interrupt. 50 // other stuff, so we wake the task on every interrupt.
51 T::state().waker.wake(); 51 T::state().waker.wake();
@@ -360,8 +360,6 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
360 360
361 Ok(()) 361 Ok(())
362 } 362 }
363
364 // Async
365 363
366 /// Can be used by both blocking and async implementations 364 /// Can be used by both blocking and async implementations
367 #[inline] // pretty sure this should always be inlined 365 #[inline] // pretty sure this should always be inlined
@@ -374,7 +372,6 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
374 w.set_itevten(true); 372 w.set_itevten(true);
375 }); 373 });
376 }); 374 });
377 trace!("I2C slave: safely enabled interrupts");
378 } 375 }
379 376
380 /// Can be used by both blocking and async implementations 377 /// Can be used by both blocking and async implementations
@@ -383,7 +380,6 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
383 // v1 requires: READ SR1 then WRITE CR1 to clear STOPF 380 // v1 requires: READ SR1 then WRITE CR1 to clear STOPF
384 let _ = info.regs.sr1().read(); 381 let _ = info.regs.sr1().read();
385 info.regs.cr1().modify(|_| {}); // Dummy write to clear STOPF 382 info.regs.cr1().modify(|_| {}); // Dummy write to clear STOPF
386 trace!("I2C slave: STOPF flag cleared");
387 } 383 }
388 384
389} 385}
@@ -760,6 +756,7 @@ enum ReceiveResult {
760 756
761/// Enumeration of slave transaction termination conditions 757/// Enumeration of slave transaction termination conditions
762#[derive(Debug, Clone, Copy, PartialEq)] 758#[derive(Debug, Clone, Copy, PartialEq)]
759#[cfg_attr(feature = "defmt", derive(defmt::Format))]
763enum SlaveTermination { 760enum SlaveTermination {
764 /// STOP condition received - normal end of transaction 761 /// STOP condition received - normal end of transaction
765 Stop, 762 Stop,
@@ -887,9 +884,9 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
887 /// This method blocks until the slave address is matched by a master. 884 /// This method blocks until the slave address is matched by a master.
888 /// Returns the command type (Read/Write) and the matched address. 885 /// Returns the command type (Read/Write) and the matched address.
889 pub fn blocking_listen(&mut self) -> Result<SlaveCommand, Error> { 886 pub fn blocking_listen(&mut self) -> Result<SlaveCommand, Error> {
890 trace!("I2C slave: listening for address match"); 887 trace!("I2C slave: starting blocking listen for address match");
891 let result = self.blocking_listen_with_timeout(self.timeout()); 888 let result = self.blocking_listen_with_timeout(self.timeout());
892 trace!("I2C slave: listen result={:?}", result); 889 trace!("I2C slave: blocking listen complete, result={:?}", result);
893 result 890 result
894 } 891 }
895 892
@@ -901,16 +898,15 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
901 /// 898 ///
902 /// Returns the total number of bytes transmitted (including padding). 899 /// Returns the total number of bytes transmitted (including padding).
903 pub fn blocking_respond_to_read(&mut self, data: &[u8]) -> Result<usize, Error> { 900 pub fn blocking_respond_to_read(&mut self, data: &[u8]) -> Result<usize, Error> {
904 trace!("I2C slave: responding to read, data_len={}", data.len()); 901 trace!("I2C slave: starting blocking respond_to_read, data_len={}", data.len());
905 902
906 // Check for zero-length read BEFORE any transmission setup
907 if let Some(zero_length_result) = self.detect_zero_length_read(self.timeout())? { 903 if let Some(zero_length_result) = self.detect_zero_length_read(self.timeout())? {
908 trace!("I2C slave: zero-length read detected"); 904 trace!("I2C slave: zero-length read detected");
909 return Ok(zero_length_result); 905 return Ok(zero_length_result);
910 } 906 }
911 907
912 let result = self.transmit_to_master(data, self.timeout()); 908 let result = self.transmit_to_master(data, self.timeout());
913 trace!("I2C slave: read response complete, result={:?}", result); 909 trace!("I2C slave: blocking respond_to_read complete, result={:?}", result);
914 result 910 result
915 } 911 }
916 912
@@ -922,9 +918,9 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
922 /// 918 ///
923 /// Returns the number of bytes stored in the buffer (not total received). 919 /// Returns the number of bytes stored in the buffer (not total received).
924 pub fn blocking_respond_to_write(&mut self, buffer: &mut [u8]) -> Result<usize, Error> { 920 pub fn blocking_respond_to_write(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
925 trace!("I2C slave: responding to write, buffer_len={}", buffer.len()); 921 trace!("I2C slave: starting blocking respond_to_write, buffer_len={}", buffer.len());
926 let result = self.receive_from_master(buffer, self.timeout()); 922 let result = self.receive_from_master(buffer, self.timeout());
927 trace!("I2C slave: write response complete, result={:?}", result); 923 trace!("I2C slave: blocking respond_to_write complete, result={:?}", result);
928 result 924 result
929 } 925 }
930 926
@@ -965,31 +961,35 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
965 /// Transmit data to master in response to read request 961 /// Transmit data to master in response to read request
966 fn transmit_to_master(&mut self, data: &[u8], timeout: Timeout) -> Result<usize, Error> { 962 fn transmit_to_master(&mut self, data: &[u8], timeout: Timeout) -> Result<usize, Error> {
967 let mut bytes_transmitted = 0; 963 let mut bytes_transmitted = 0;
964 let mut padding_count = 0;
968 965
969 loop { 966 loop {
970 // Determine next byte to send
971 let byte_to_send = if bytes_transmitted < data.len() { 967 let byte_to_send = if bytes_transmitted < data.len() {
972 data[bytes_transmitted] 968 data[bytes_transmitted]
973 } else { 969 } else {
970 padding_count += 1;
974 0x00 // Send padding bytes when data is exhausted 971 0x00 // Send padding bytes when data is exhausted
975 }; 972 };
976 973
977 // Attempt to send the byte
978 match self.transmit_byte(byte_to_send, timeout)? { 974 match self.transmit_byte(byte_to_send, timeout)? {
979 TransmitResult::Acknowledged => { 975 TransmitResult::Acknowledged => {
980 bytes_transmitted += 1; 976 bytes_transmitted += 1;
981 // Continue transmission
982 }, 977 },
983 TransmitResult::NotAcknowledged => { 978 TransmitResult::NotAcknowledged => {
984 bytes_transmitted += 1; // Count the NACKed byte 979 bytes_transmitted += 1; // Count the NACKed byte
985 break; // Normal end of read transaction 980 break;
986 }, 981 },
987 TransmitResult::Stopped | TransmitResult::Restarted => { 982 TransmitResult::Stopped | TransmitResult::Restarted => {
988 break; // Transaction terminated by master 983 break;
989 } 984 }
990 } 985 }
991 } 986 }
992 987
988 if padding_count > 0 {
989 trace!("I2C slave: sent {} data bytes + {} padding bytes = {} total",
990 data.len(), padding_count, bytes_transmitted);
991 }
992
993 Ok(bytes_transmitted) 993 Ok(bytes_transmitted)
994 } 994 }
995 995
@@ -1076,14 +1076,19 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
1076 1076
1077 /// Discard excess bytes when buffer is full 1077 /// Discard excess bytes when buffer is full
1078 fn discard_excess_bytes(&mut self, timeout: Timeout) -> Result<(), Error> { 1078 fn discard_excess_bytes(&mut self, timeout: Timeout) -> Result<(), Error> {
1079 let mut discarded_count = 0;
1080
1079 loop { 1081 loop {
1080 match self.receive_byte(timeout)? { 1082 match self.receive_byte(timeout)? {
1081 ReceiveResult::Data(_) => { 1083 ReceiveResult::Data(_) => {
1082 // Byte received and ACKed, but discarded 1084 discarded_count += 1;
1083 continue; 1085 continue;
1084 }, 1086 },
1085 ReceiveResult::Stopped | ReceiveResult::Restarted => { 1087 ReceiveResult::Stopped | ReceiveResult::Restarted => {
1086 break; // Transaction completed 1088 if discarded_count > 0 {
1089 trace!("I2C slave: discarded {} excess bytes", discarded_count);
1090 }
1091 break;
1087 }, 1092 },
1088 } 1093 }
1089 } 1094 }
@@ -1316,12 +1321,12 @@ impl<'d> I2c<'d, Async, MultiMaster> {
1316 /// (Read/Write) and the matched address. This method will suspend until 1321 /// (Read/Write) and the matched address. This method will suspend until
1317 /// an address match occurs. 1322 /// an address match occurs.
1318 pub async fn listen(&mut self) -> Result<SlaveCommand, Error> { 1323 pub async fn listen(&mut self) -> Result<SlaveCommand, Error> {
1324 trace!("I2C slave: starting async listen for address match");
1319 let state = self.state; 1325 let state = self.state;
1320 let info = self.info; 1326 let info = self.info;
1321 1327
1322 Self::enable_interrupts(info); 1328 Self::enable_interrupts(info);
1323 1329
1324 // Ensure interrupts are cleaned up on early exit
1325 let on_drop = OnDrop::new(|| { 1330 let on_drop = OnDrop::new(|| {
1326 Self::disable_dma_and_interrupts(info); 1331 Self::disable_dma_and_interrupts(info);
1327 }); 1332 });
@@ -1330,10 +1335,12 @@ impl<'d> I2c<'d, Async, MultiMaster> {
1330 state.waker.register(cx.waker()); 1335 state.waker.register(cx.waker());
1331 1336
1332 match Self::check_and_clear_error_flags(info) { 1337 match Self::check_and_clear_error_flags(info) {
1333 Err(e) => Poll::Ready(Err(e)), 1338 Err(e) => {
1339 error!("I2C slave: error during listen: {:?}", e);
1340 Poll::Ready(Err(e))
1341 },
1334 Ok(sr1) => { 1342 Ok(sr1) => {
1335 if sr1.addr() { 1343 if sr1.addr() {
1336 // Address matched - determine direction and decode address
1337 let sr2 = info.regs.sr2().read(); 1344 let sr2 = info.regs.sr2().read();
1338 let direction = if sr2.tra() { 1345 let direction = if sr2.tra() {
1339 SlaveCommandKind::Read 1346 SlaveCommandKind::Read
@@ -1342,11 +1349,16 @@ impl<'d> I2c<'d, Async, MultiMaster> {
1342 }; 1349 };
1343 1350
1344 let matched_address = match Self::decode_matched_address(sr2, info) { 1351 let matched_address = match Self::decode_matched_address(sr2, info) {
1345 Ok(addr) => addr, 1352 Ok(addr) => {
1346 Err(e) => return Poll::Ready(Err(e)), 1353 trace!("I2C slave: address matched, direction={:?}, addr={:?}", direction, addr);
1354 addr
1355 },
1356 Err(e) => {
1357 error!("I2C slave: failed to decode matched address: {:?}", e);
1358 return Poll::Ready(Err(e));
1359 }
1347 }; 1360 };
1348 1361
1349 // Don't clear ADDR here - leave it for DMA setup in respond methods
1350 Poll::Ready(Ok(SlaveCommand { 1362 Poll::Ready(Ok(SlaveCommand {
1351 kind: direction, 1363 kind: direction,
1352 address: matched_address, 1364 address: matched_address,
@@ -1360,6 +1372,7 @@ impl<'d> I2c<'d, Async, MultiMaster> {
1360 }).await; 1372 }).await;
1361 1373
1362 drop(on_drop); 1374 drop(on_drop);
1375 trace!("I2C slave: listen complete, result={:?}", result);
1363 result 1376 result
1364 } 1377 }
1365 1378
@@ -1371,28 +1384,28 @@ impl<'d> I2c<'d, Async, MultiMaster> {
1371 /// 1384 ///
1372 /// Returns the number of bytes stored in the buffer (not total received). 1385 /// Returns the number of bytes stored in the buffer (not total received).
1373 pub async fn respond_to_write(&mut self, buffer: &mut [u8]) -> Result<usize, Error> { 1386 pub async fn respond_to_write(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
1387 trace!("I2C slave: starting respond_to_write, buffer_len={}", buffer.len());
1388
1374 if buffer.is_empty() { 1389 if buffer.is_empty() {
1390 warn!("I2C slave: respond_to_write called with empty buffer");
1375 return Err(Error::Overrun); 1391 return Err(Error::Overrun);
1376 } 1392 }
1377 1393
1378 let state = self.state; 1394 let state = self.state;
1379 let info = self.info; 1395 let info = self.info;
1380 1396
1381 // Use shared DMA setup
1382 self.setup_slave_dma_base(); 1397 self.setup_slave_dma_base();
1383 1398
1384 // Ensure proper cleanup on exit
1385 let on_drop = OnDrop::new(|| { 1399 let on_drop = OnDrop::new(|| {
1386 Self::disable_dma_and_interrupts(info); 1400 Self::disable_dma_and_interrupts(info);
1387 }); 1401 });
1388 1402
1389 // Clear ADDR flag to release clock stretching
1390 info.regs.sr2().read(); 1403 info.regs.sr2().read();
1391 1404
1392 // Start DMA transfer and monitor completion
1393 let result = self.execute_slave_receive_transfer(buffer, state, info).await; 1405 let result = self.execute_slave_receive_transfer(buffer, state, info).await;
1394 1406
1395 drop(on_drop); 1407 drop(on_drop);
1408 trace!("I2C slave: respond_to_write complete, result={:?}", result);
1396 result 1409 result
1397 } 1410 }
1398 1411
@@ -1404,28 +1417,28 @@ impl<'d> I2c<'d, Async, MultiMaster> {
1404 /// 1417 ///
1405 /// Returns the total number of bytes transmitted (data + padding). 1418 /// Returns the total number of bytes transmitted (data + padding).
1406 pub async fn respond_to_read(&mut self, data: &[u8]) -> Result<usize, Error> { 1419 pub async fn respond_to_read(&mut self, data: &[u8]) -> Result<usize, Error> {
1420 trace!("I2C slave: starting respond_to_read, data_len={}", data.len());
1421
1407 if data.is_empty() { 1422 if data.is_empty() {
1423 warn!("I2C slave: respond_to_read called with empty data");
1408 return Err(Error::Overrun); 1424 return Err(Error::Overrun);
1409 } 1425 }
1410 1426
1411 let state = self.state; 1427 let state = self.state;
1412 let info = self.info; 1428 let info = self.info;
1413 1429
1414 // Use shared DMA setup
1415 self.setup_slave_dma_base(); 1430 self.setup_slave_dma_base();
1416 1431
1417 // Ensure proper cleanup on exit
1418 let on_drop = OnDrop::new(|| { 1432 let on_drop = OnDrop::new(|| {
1419 Self::disable_dma_and_interrupts(info); 1433 Self::disable_dma_and_interrupts(info);
1420 }); 1434 });
1421 1435
1422 // Clear ADDR flag to release clock stretching
1423 info.regs.sr2().read(); 1436 info.regs.sr2().read();
1424 1437
1425 // Start DMA transfer and monitor completion
1426 let result = self.execute_slave_transmit_transfer(data, state, info).await; 1438 let result = self.execute_slave_transmit_transfer(data, state, info).await;
1427 1439
1428 drop(on_drop); 1440 drop(on_drop);
1441 trace!("I2C slave: respond_to_read complete, result={:?}", result);
1429 result 1442 result
1430 } 1443 }
1431 1444
@@ -1438,28 +1451,27 @@ impl<'d> I2c<'d, Async, MultiMaster> {
1438 state: &'static State, 1451 state: &'static State,
1439 info: &'static Info 1452 info: &'static Info
1440 ) -> Result<usize, Error> { 1453 ) -> Result<usize, Error> {
1441 // Start DMA transfer
1442 let dma_transfer = unsafe { 1454 let dma_transfer = unsafe {
1443 let src = info.regs.dr().as_ptr() as *mut u8; 1455 let src = info.regs.dr().as_ptr() as *mut u8;
1444 self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default()) 1456 self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default())
1445 }; 1457 };
1446 1458
1447 // Monitor for I2C events during transfer
1448 let i2c_monitor = Self::create_termination_monitor(state, info, &[SlaveTermination::Stop, SlaveTermination::Restart]); 1459 let i2c_monitor = Self::create_termination_monitor(state, info, &[SlaveTermination::Stop, SlaveTermination::Restart]);
1449 1460
1450 match select(dma_transfer, i2c_monitor).await { 1461 match select(dma_transfer, i2c_monitor).await {
1451 Either::Second(Err(e)) => { 1462 Either::Second(Err(e)) => {
1463 error!("I2C slave: error during receive transfer: {:?}", e);
1452 Self::disable_dma_and_interrupts(info); 1464 Self::disable_dma_and_interrupts(info);
1453 Err(e) 1465 Err(e)
1454 } 1466 }
1455 Either::First(_) => { 1467 Either::First(_) => {
1456 // DMA completed first - handle potential excess bytes 1468 trace!("I2C slave: DMA receive completed, handling excess bytes");
1457 Self::disable_dma_and_interrupts(info); 1469 Self::disable_dma_and_interrupts(info);
1458 self.handle_excess_bytes(state, info).await?; 1470 self.handle_excess_bytes(state, info).await?;
1459 Ok(buffer.len()) 1471 Ok(buffer.len())
1460 } 1472 }
1461 Either::Second(Ok(_)) => { 1473 Either::Second(Ok(termination)) => {
1462 // I2C event occurred first - normal transaction end 1474 trace!("I2C slave: receive terminated by I2C event: {:?}", termination);
1463 Self::disable_dma_and_interrupts(info); 1475 Self::disable_dma_and_interrupts(info);
1464 Ok(buffer.len()) 1476 Ok(buffer.len())
1465 } 1477 }
@@ -1473,28 +1485,30 @@ impl<'d> I2c<'d, Async, MultiMaster> {
1473 state: &'static State, 1485 state: &'static State,
1474 info: &'static Info 1486 info: &'static Info
1475 ) -> Result<usize, Error> { 1487 ) -> Result<usize, Error> {
1476 // Start DMA transfer
1477 let dma_transfer = unsafe { 1488 let dma_transfer = unsafe {
1478 let dst = info.regs.dr().as_ptr() as *mut u8; 1489 let dst = info.regs.dr().as_ptr() as *mut u8;
1479 self.tx_dma.as_mut().unwrap().write(data, dst, Default::default()) 1490 self.tx_dma.as_mut().unwrap().write(data, dst, Default::default())
1480 }; 1491 };
1481 1492
1482 // Monitor for I2C events during transfer (NACK is normal for slave transmit)
1483 let i2c_monitor = Self::create_termination_monitor(state, info, &[SlaveTermination::Stop, SlaveTermination::Restart, SlaveTermination::Nack]); 1493 let i2c_monitor = Self::create_termination_monitor(state, info, &[SlaveTermination::Stop, SlaveTermination::Restart, SlaveTermination::Nack]);
1484 1494
1485 match select(dma_transfer, i2c_monitor).await { 1495 match select(dma_transfer, i2c_monitor).await {
1486 Either::Second(Err(e)) => { 1496 Either::Second(Err(e)) => {
1497 error!("I2C slave: error during transmit transfer: {:?}", e);
1487 Self::disable_dma_and_interrupts(info); 1498 Self::disable_dma_and_interrupts(info);
1488 Err(e) 1499 Err(e)
1489 } 1500 }
1490 Either::First(_) => { 1501 Either::First(_) => {
1491 // DMA completed first - handle potential padding bytes 1502 trace!("I2C slave: DMA transmit completed, handling padding bytes");
1492 Self::disable_dma_and_interrupts(info); 1503 Self::disable_dma_and_interrupts(info);
1493 let padding_count = self.handle_padding_bytes(state, info).await?; 1504 let padding_count = self.handle_padding_bytes(state, info).await?;
1494 Ok(data.len() + padding_count) 1505 let total_bytes = data.len() + padding_count;
1506 trace!("I2C slave: sent {} data bytes + {} padding bytes = {} total",
1507 data.len(), padding_count, total_bytes);
1508 Ok(total_bytes)
1495 } 1509 }
1496 Either::Second(Ok(_)) => { 1510 Either::Second(Ok(termination)) => {
1497 // I2C event occurred first - normal transaction end 1511 trace!("I2C slave: transmit terminated by I2C event: {:?}", termination);
1498 Self::disable_dma_and_interrupts(info); 1512 Self::disable_dma_and_interrupts(info);
1499 Ok(data.len()) 1513 Ok(data.len())
1500 } 1514 }
@@ -1549,25 +1563,32 @@ impl<'d> I2c<'d, Async, MultiMaster> {
1549 /// 1563 ///
1550 /// Reads and discards bytes until transaction termination to prevent interrupt flooding 1564 /// Reads and discards bytes until transaction termination to prevent interrupt flooding
1551 async fn handle_excess_bytes(&mut self, state: &'static State, info: &'static Info) -> Result<(), Error> { 1565 async fn handle_excess_bytes(&mut self, state: &'static State, info: &'static Info) -> Result<(), Error> {
1566 let mut discarded_count = 0;
1567
1552 poll_fn(|cx| { 1568 poll_fn(|cx| {
1553 state.waker.register(cx.waker()); 1569 state.waker.register(cx.waker());
1554 1570
1555 match Self::check_and_clear_error_flags(info) { 1571 match Self::check_and_clear_error_flags(info) {
1556 Err(e) => Poll::Ready(Err(e)), 1572 Err(e) => {
1573 error!("I2C slave: error while discarding excess bytes: {:?}", e);
1574 Poll::Ready(Err(e))
1575 },
1557 Ok(sr1) => { 1576 Ok(sr1) => {
1558 // Check for transaction termination first
1559 if let Some(termination) = Self::check_slave_termination_conditions(sr1) { 1577 if let Some(termination) = Self::check_slave_termination_conditions(sr1) {
1560 match termination { 1578 match termination {
1561 SlaveTermination::Stop => Self::clear_stop_flag(info), 1579 SlaveTermination::Stop => Self::clear_stop_flag(info),
1562 SlaveTermination::Restart => {}, // Leave ADDR for next operation 1580 SlaveTermination::Restart => {},
1563 SlaveTermination::Nack => unreachable!("NACK not expected during receive"), 1581 SlaveTermination::Nack => unreachable!("NACK not expected during receive"),
1564 } 1582 }
1583 if discarded_count > 0 {
1584 trace!("I2C slave: discarded {} excess bytes", discarded_count);
1585 }
1565 return Poll::Ready(Ok(())); 1586 return Poll::Ready(Ok(()));
1566 } 1587 }
1567 1588
1568 // If there's data to read, discard it
1569 if sr1.rxne() { 1589 if sr1.rxne() {
1570 let _discarded_byte = info.regs.dr().read().dr(); 1590 let _discarded_byte = info.regs.dr().read().dr();
1591 discarded_count += 1;
1571 Self::enable_interrupts(info); 1592 Self::enable_interrupts(info);
1572 return Poll::Pending; 1593 return Poll::Pending;
1573 } 1594 }
@@ -1589,14 +1610,16 @@ impl<'d> I2c<'d, Async, MultiMaster> {
1589 state.waker.register(cx.waker()); 1610 state.waker.register(cx.waker());
1590 1611
1591 match Self::check_and_clear_error_flags(info) { 1612 match Self::check_and_clear_error_flags(info) {
1592 Err(Error::Nack) => Poll::Ready(Ok(padding_count)), // Normal termination 1613 Err(Error::Nack) => Poll::Ready(Ok(padding_count)),
1593 Err(e) => Poll::Ready(Err(e)), 1614 Err(e) => {
1615 error!("I2C slave: error while sending padding bytes: {:?}", e);
1616 Poll::Ready(Err(e))
1617 },
1594 Ok(sr1) => { 1618 Ok(sr1) => {
1595 // Check for transaction termination first
1596 if let Some(termination) = Self::check_slave_termination_conditions(sr1) { 1619 if let Some(termination) = Self::check_slave_termination_conditions(sr1) {
1597 match termination { 1620 match termination {
1598 SlaveTermination::Stop => Self::clear_stop_flag(info), 1621 SlaveTermination::Stop => Self::clear_stop_flag(info),
1599 SlaveTermination::Restart => {}, // Leave ADDR for next operation 1622 SlaveTermination::Restart => {},
1600 SlaveTermination::Nack => { 1623 SlaveTermination::Nack => {
1601 info.regs.sr1().write(|reg| { 1624 info.regs.sr1().write(|reg| {
1602 reg.0 = !0; 1625 reg.0 = !0;
@@ -1607,7 +1630,6 @@ impl<'d> I2c<'d, Async, MultiMaster> {
1607 return Poll::Ready(Ok(padding_count)); 1630 return Poll::Ready(Ok(padding_count));
1608 } 1631 }
1609 1632
1610 // If transmit buffer is empty, send padding byte
1611 if sr1.txe() { 1633 if sr1.txe() {
1612 info.regs.dr().write(|w| w.set_dr(0x00)); 1634 info.regs.dr().write(|w| w.set_dr(0x00));
1613 padding_count += 1; 1635 padding_count += 1;