aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHybridChild <[email protected]>2025-11-11 20:33:00 +0100
committerHybridChild <[email protected]>2025-11-12 09:34:05 +0100
commit5e76be83cf693d2de4608fec4ef11fbeb32722d4 (patch)
tree43ebdca03a20147dc978a7e114eadc2effe637f2
parentf078c85454f09f28a85aa834a9496b37058695e0 (diff)
stm32/i2c_v2: Add initial transaction implementation
-rw-r--r--embassy-stm32/src/i2c/v2.rs502
1 files changed, 474 insertions, 28 deletions
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 4527e55b9..061f4ff3a 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -172,20 +172,23 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
172 length: usize, 172 length: usize,
173 stop: Stop, 173 stop: Stop,
174 reload: bool, 174 reload: bool,
175 restart: bool,
175 timeout: Timeout, 176 timeout: Timeout,
176 ) -> Result<(), Error> { 177 ) -> Result<(), Error> {
177 assert!(length < 256); 178 assert!(length < 256);
178 179
179 // Wait for any previous address sequence to end 180 if !restart {
180 // automatically. This could be up to 50% of a bus 181 // Wait for any previous address sequence to end
181 // cycle (ie. up to 0.5/freq) 182 // automatically. This could be up to 50% of a bus
182 while info.regs.cr2().read().start() { 183 // cycle (ie. up to 0.5/freq)
183 timeout.check()?; 184 while info.regs.cr2().read().start() {
184 } 185 timeout.check()?;
186 }
185 187
186 // Wait for the bus to be free 188 // Wait for the bus to be free
187 while info.regs.isr().read().busy() { 189 while info.regs.isr().read().busy() {
188 timeout.check()?; 190 timeout.check()?;
191 }
189 } 192 }
190 193
191 let reload = if reload { 194 let reload = if reload {
@@ -210,7 +213,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
210 Ok(()) 213 Ok(())
211 } 214 }
212 215
213 fn reload(info: &'static Info, length: usize, will_reload: bool, timeout: Timeout) -> Result<(), Error> { 216 fn reload(info: &'static Info, length: usize, will_reload: bool, stop: Stop, timeout: Timeout) -> Result<(), Error> {
214 assert!(length < 256 && length > 0); 217 assert!(length < 256 && length > 0);
215 218
216 while !info.regs.isr().read().tcr() { 219 while !info.regs.isr().read().tcr() {
@@ -226,6 +229,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
226 info.regs.cr2().modify(|w| { 229 info.regs.cr2().modify(|w| {
227 w.set_nbytes(length as u8); 230 w.set_nbytes(length as u8);
228 w.set_reload(will_reload); 231 w.set_reload(will_reload);
232 w.set_autoend(stop.autoend());
229 }); 233 });
230 234
231 Ok(()) 235 Ok(())
@@ -403,7 +407,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
403 407
404 for (number, chunk) in read.chunks_mut(255).enumerate() { 408 for (number, chunk) in read.chunks_mut(255).enumerate() {
405 if number != 0 { 409 if number != 0 {
406 Self::reload(self.info, chunk.len(), number != last_chunk_idx, timeout)?; 410 Self::reload(self.info, chunk.len(), number != last_chunk_idx, Stop::Automatic, timeout)?;
407 } 411 }
408 412
409 for byte in chunk { 413 for byte in chunk {
@@ -441,6 +445,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
441 write.len().min(255), 445 write.len().min(255),
442 Stop::Software, 446 Stop::Software,
443 last_chunk_idx != 0, 447 last_chunk_idx != 0,
448 false, // restart
444 timeout, 449 timeout,
445 ) { 450 ) {
446 if send_stop { 451 if send_stop {
@@ -451,7 +456,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
451 456
452 for (number, chunk) in write.chunks(255).enumerate() { 457 for (number, chunk) in write.chunks(255).enumerate() {
453 if number != 0 { 458 if number != 0 {
454 Self::reload(self.info, chunk.len(), number != last_chunk_idx, timeout)?; 459 Self::reload(self.info, chunk.len(), number != last_chunk_idx, Stop::Software, timeout)?;
455 } 460 }
456 461
457 for byte in chunk { 462 for byte in chunk {
@@ -507,9 +512,219 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
507 /// 512 ///
508 /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction 513 /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction
509 pub fn blocking_transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> { 514 pub fn blocking_transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> {
510 let _ = addr; 515 if operations.is_empty() {
511 let _ = operations; 516 return Err(Error::ZeroLengthTransfer);
512 todo!() 517 }
518
519 let address = addr.into();
520 let timeout = self.timeout();
521
522 // Group consecutive operations of the same type
523 let mut op_idx = 0;
524 let mut is_first_group = true;
525
526 while op_idx < operations.len() {
527 // Determine the type of current group and find all consecutive operations of same type
528 let is_read = matches!(operations[op_idx], Operation::Read(_));
529 let group_start = op_idx;
530
531 // Find end of this group (consecutive operations of same type)
532 while op_idx < operations.len() && matches!(operations[op_idx], Operation::Read(_)) == is_read {
533 op_idx += 1;
534 }
535 let group_end = op_idx;
536 let is_last_group = op_idx >= operations.len();
537
538 // Execute this group of operations
539 if is_read {
540 self.execute_read_group(
541 address,
542 &mut operations[group_start..group_end],
543 is_first_group,
544 is_last_group,
545 timeout,
546 )?;
547 } else {
548 self.execute_write_group(
549 address,
550 &operations[group_start..group_end],
551 is_first_group,
552 is_last_group,
553 timeout,
554 )?;
555 }
556
557 is_first_group = false;
558 }
559
560 Ok(())
561 }
562
563 fn execute_write_group(
564 &mut self,
565 address: Address,
566 operations: &[Operation<'_>],
567 is_first_group: bool,
568 is_last_group: bool,
569 timeout: Timeout,
570 ) -> Result<(), Error> {
571 // Calculate total bytes across all operations in this group
572 let total_bytes: usize = operations
573 .iter()
574 .map(|op| match op {
575 Operation::Write(buf) => buf.len(),
576 _ => 0,
577 })
578 .sum();
579
580 if total_bytes == 0 {
581 // Handle empty write group - just send address
582 if is_first_group {
583 Self::master_write(self.info, address, 0, Stop::Software, false, !is_first_group, timeout)?;
584 }
585 if is_last_group {
586 self.master_stop();
587 }
588 return Ok(());
589 }
590
591 let mut total_remaining = total_bytes;
592 let mut first_chunk = true;
593
594 for operation in operations {
595 if let Operation::Write(buffer) = operation {
596 for chunk in buffer.chunks(255) {
597 let chunk_len = chunk.len();
598 total_remaining -= chunk_len;
599 let is_last_chunk = total_remaining == 0;
600 let will_reload = !is_last_chunk;
601
602 if first_chunk {
603 // First chunk: initiate transfer
604 // If not first group, use RESTART instead of START
605 Self::master_write(self.info, address, chunk_len, Stop::Software, will_reload, !is_first_group, timeout)?;
606 first_chunk = false;
607 } else {
608 // Subsequent chunks: use reload
609 // Always use Software stop for writes
610 Self::reload(self.info, chunk_len, will_reload, Stop::Software, timeout)?;
611 }
612
613 // Send data bytes
614 for byte in chunk {
615 self.wait_txis(timeout)?;
616 self.info.regs.txdr().write(|w| w.set_txdata(*byte));
617 }
618 }
619 }
620 }
621
622 // Wait for transfer to complete
623 if is_last_group {
624 self.wait_tc(timeout)?;
625 self.master_stop();
626 self.wait_stop(timeout)?;
627 } else {
628 // Wait for TC before next group (enables RESTART)
629 self.wait_tc(timeout)?;
630 }
631
632 Ok(())
633 }
634
635 fn execute_read_group(
636 &mut self,
637 address: Address,
638 operations: &mut [Operation<'_>],
639 is_first_group: bool,
640 is_last_group: bool,
641 timeout: Timeout,
642 ) -> Result<(), Error> {
643 // Calculate total bytes across all operations in this group
644 let total_bytes: usize = operations
645 .iter()
646 .map(|op| match op {
647 Operation::Read(buf) => buf.len(),
648 _ => 0,
649 })
650 .sum();
651
652 if total_bytes == 0 {
653 // Handle empty read group
654 if is_first_group {
655 Self::master_read(
656 self.info,
657 address,
658 0,
659 if is_last_group { Stop::Automatic } else { Stop::Software },
660 false,
661 !is_first_group,
662 timeout,
663 )?;
664 }
665 if is_last_group {
666 self.wait_stop(timeout)?;
667 }
668 return Ok(());
669 }
670
671 let mut total_remaining = total_bytes;
672 let mut first_chunk = true;
673
674 for operation in operations {
675 if let Operation::Read(buffer) = operation {
676 for chunk in buffer.chunks_mut(255) {
677 let chunk_len = chunk.len();
678 total_remaining -= chunk_len;
679 let is_last_chunk = total_remaining == 0;
680 let will_reload = !is_last_chunk;
681
682 if first_chunk {
683 // First chunk: initiate transfer
684 let stop = if is_last_group && is_last_chunk {
685 Stop::Automatic
686 } else {
687 Stop::Software
688 };
689
690 Self::master_read(
691 self.info,
692 address,
693 chunk_len,
694 stop,
695 will_reload,
696 !is_first_group, // restart if not first group
697 timeout,
698 )?;
699 first_chunk = false;
700 } else {
701 // Subsequent chunks: use reload
702 let stop = if is_last_group && is_last_chunk {
703 Stop::Automatic
704 } else {
705 Stop::Software
706 };
707 Self::reload(self.info, chunk_len, will_reload, stop, timeout)?;
708 }
709
710 // Receive data bytes
711 for byte in chunk {
712 self.wait_rxne(timeout)?;
713 *byte = self.info.regs.rxdr().read().rxdata();
714 }
715 }
716 }
717 }
718
719 // Wait for transfer to complete
720 if is_last_group {
721 self.wait_stop(timeout)?;
722 }
723 // For non-last read groups, don't wait for TC - the peripheral may hold SCL low
724 // in Software AUTOEND mode until the next START is issued. Just proceed directly
725 // to the next group which will issue RESTART and release the clock.
726
727 Ok(())
513 } 728 }
514 729
515 /// Blocking write multiple buffers. 730 /// Blocking write multiple buffers.
@@ -531,6 +746,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
531 first_length.min(255), 746 first_length.min(255),
532 Stop::Software, 747 Stop::Software,
533 (first_length > 255) || (last_slice_index != 0), 748 (first_length > 255) || (last_slice_index != 0),
749 false, // restart
534 timeout, 750 timeout,
535 ) { 751 ) {
536 self.master_stop(); 752 self.master_stop();
@@ -552,6 +768,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
552 self.info, 768 self.info,
553 slice_len.min(255), 769 slice_len.min(255),
554 (idx != last_slice_index) || (slice_len > 255), 770 (idx != last_slice_index) || (slice_len > 255),
771 Stop::Software,
555 timeout, 772 timeout,
556 ) { 773 ) {
557 if err != Error::Nack { 774 if err != Error::Nack {
@@ -567,6 +784,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
567 self.info, 784 self.info,
568 chunk.len(), 785 chunk.len(),
569 (number != last_chunk_idx) || (idx != last_slice_index), 786 (number != last_chunk_idx) || (idx != last_slice_index),
787 Stop::Software,
570 timeout, 788 timeout,
571 ) { 789 ) {
572 if err != Error::Nack { 790 if err != Error::Nack {
@@ -610,6 +828,7 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
610 first_slice: bool, 828 first_slice: bool,
611 last_slice: bool, 829 last_slice: bool,
612 send_stop: bool, 830 send_stop: bool,
831 restart: bool,
613 timeout: Timeout, 832 timeout: Timeout,
614 ) -> Result<(), Error> { 833 ) -> Result<(), Error> {
615 let total_len = write.len(); 834 let total_len = write.len();
@@ -676,10 +895,11 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
676 total_len.min(255), 895 total_len.min(255),
677 Stop::Software, 896 Stop::Software,
678 (total_len > 255) || !last_slice, 897 (total_len > 255) || !last_slice,
898 restart,
679 timeout, 899 timeout,
680 )?; 900 )?;
681 } else { 901 } else {
682 Self::reload(self.info, total_len.min(255), (total_len > 255) || !last_slice, timeout)?; 902 Self::reload(self.info, total_len.min(255), (total_len > 255) || !last_slice, Stop::Software, timeout)?;
683 self.info.regs.cr1().modify(|w| w.set_tcie(true)); 903 self.info.regs.cr1().modify(|w| w.set_tcie(true));
684 } 904 }
685 } else if !(isr.tcr() || isr.tc()) { 905 } else if !(isr.tcr() || isr.tc()) {
@@ -690,7 +910,7 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
690 } else { 910 } else {
691 let last_piece = (remaining_len <= 255) && last_slice; 911 let last_piece = (remaining_len <= 255) && last_slice;
692 912
693 if let Err(e) = Self::reload(self.info, remaining_len.min(255), !last_piece, timeout) { 913 if let Err(e) = Self::reload(self.info, remaining_len.min(255), !last_piece, Stop::Software, timeout) {
694 return Poll::Ready(Err(e)); 914 return Poll::Ready(Err(e));
695 } 915 }
696 self.info.regs.cr1().modify(|w| w.set_tcie(true)); 916 self.info.regs.cr1().modify(|w| w.set_tcie(true));
@@ -793,7 +1013,7 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
793 } else { 1013 } else {
794 let last_piece = remaining_len <= 255; 1014 let last_piece = remaining_len <= 255;
795 1015
796 if let Err(e) = Self::reload(self.info, remaining_len.min(255), !last_piece, timeout) { 1016 if let Err(e) = Self::reload(self.info, remaining_len.min(255), !last_piece, Stop::Automatic, timeout) {
797 return Poll::Ready(Err(e)); 1017 return Poll::Ready(Err(e));
798 } 1018 }
799 // Return here if we are on last chunk, 1019 // Return here if we are on last chunk,
@@ -826,7 +1046,7 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
826 self.write_internal(address.into(), write, true, timeout) 1046 self.write_internal(address.into(), write, true, timeout)
827 } else { 1047 } else {
828 timeout 1048 timeout
829 .with(self.write_dma_internal(address.into(), write, true, true, true, timeout)) 1049 .with(self.write_dma_internal(address.into(), write, true, true, true, false, timeout))
830 .await 1050 .await
831 } 1051 }
832 } 1052 }
@@ -850,7 +1070,7 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
850 let next = iter.next(); 1070 let next = iter.next();
851 let is_last = next.is_none(); 1071 let is_last = next.is_none();
852 1072
853 let fut = self.write_dma_internal(address, c, first, is_last, is_last, timeout); 1073 let fut = self.write_dma_internal(address, c, first, is_last, is_last, false, timeout);
854 timeout.with(fut).await?; 1074 timeout.with(fut).await?;
855 first = false; 1075 first = false;
856 current = next; 1076 current = next;
@@ -881,7 +1101,7 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
881 if write.is_empty() { 1101 if write.is_empty() {
882 self.write_internal(address.into(), write, false, timeout)?; 1102 self.write_internal(address.into(), write, false, timeout)?;
883 } else { 1103 } else {
884 let fut = self.write_dma_internal(address.into(), write, true, true, false, timeout); 1104 let fut = self.write_dma_internal(address.into(), write, true, true, false, false, timeout);
885 timeout.with(fut).await?; 1105 timeout.with(fut).await?;
886 } 1106 }
887 1107
@@ -903,9 +1123,235 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
903 pub async fn transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> { 1123 pub async fn transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> {
904 #[cfg(all(feature = "low-power", stm32wlex))] 1124 #[cfg(all(feature = "low-power", stm32wlex))]
905 let _device_busy = crate::low_power::DeviceBusy::new_stop1(); 1125 let _device_busy = crate::low_power::DeviceBusy::new_stop1();
906 let _ = addr; 1126
907 let _ = operations; 1127 if operations.is_empty() {
908 todo!() 1128 return Err(Error::ZeroLengthTransfer);
1129 }
1130
1131 let address = addr.into();
1132 let timeout = self.timeout();
1133
1134 // Group consecutive operations of the same type
1135 let mut op_idx = 0;
1136 let mut is_first_group = true;
1137
1138 while op_idx < operations.len() {
1139 // Determine the type of current group and find all consecutive operations of same type
1140 let is_read = matches!(operations[op_idx], Operation::Read(_));
1141 let group_start = op_idx;
1142
1143 // Find end of this group (consecutive operations of same type)
1144 while op_idx < operations.len() && matches!(operations[op_idx], Operation::Read(_)) == is_read {
1145 op_idx += 1;
1146 }
1147 let group_end = op_idx;
1148 let is_last_group = op_idx >= operations.len();
1149
1150 // Execute this group of operations
1151 if is_read {
1152 self.execute_read_group_async(
1153 address,
1154 &mut operations[group_start..group_end],
1155 is_first_group,
1156 is_last_group,
1157 timeout,
1158 )
1159 .await?;
1160 } else {
1161 self.execute_write_group_async(
1162 address,
1163 &operations[group_start..group_end],
1164 is_first_group,
1165 is_last_group,
1166 timeout,
1167 )
1168 .await?;
1169 }
1170
1171 is_first_group = false;
1172 }
1173
1174 Ok(())
1175 }
1176
1177 async fn execute_write_group_async(
1178 &mut self,
1179 address: Address,
1180 operations: &[Operation<'_>],
1181 is_first_group: bool,
1182 is_last_group: bool,
1183 timeout: Timeout,
1184 ) -> Result<(), Error> {
1185 // Calculate total bytes across all operations in this group
1186 let total_bytes: usize = operations
1187 .iter()
1188 .map(|op| match op {
1189 Operation::Write(buf) => buf.len(),
1190 _ => 0,
1191 })
1192 .sum();
1193
1194 if total_bytes == 0 {
1195 // Handle empty write group using blocking call
1196 if is_first_group {
1197 Self::master_write(self.info, address, 0, Stop::Software, false, !is_first_group, timeout)?;
1198 }
1199 if is_last_group {
1200 self.master_stop();
1201 }
1202 return Ok(());
1203 }
1204
1205 let send_stop = is_last_group;
1206
1207 // Use DMA for each operation in the group
1208 let mut first_in_group = true;
1209 let mut remaining_operations = operations.len();
1210
1211 for operation in operations {
1212 if let Operation::Write(buffer) = operation {
1213 remaining_operations -= 1;
1214 let is_last_in_group = remaining_operations == 0;
1215
1216 if buffer.is_empty() {
1217 // Skip empty buffers
1218 continue;
1219 }
1220
1221 let fut = self.write_dma_internal(
1222 address,
1223 buffer,
1224 first_in_group && is_first_group, // first_slice
1225 is_last_in_group && is_last_group, // last_slice
1226 send_stop && is_last_in_group, // send_stop
1227 !is_first_group && first_in_group, // restart
1228 timeout,
1229 );
1230 timeout.with(fut).await?;
1231 first_in_group = false;
1232 }
1233 }
1234
1235 // If not last group, wait for TC to enable RESTART
1236 if !is_last_group {
1237 self.wait_tc(timeout)?;
1238 }
1239
1240 Ok(())
1241 }
1242
1243 async fn execute_read_group_async(
1244 &mut self,
1245 address: Address,
1246 operations: &mut [Operation<'_>],
1247 is_first_group: bool,
1248 is_last_group: bool,
1249 timeout: Timeout,
1250 ) -> Result<(), Error> {
1251 // Calculate total bytes across all operations in this group
1252 let total_bytes: usize = operations
1253 .iter()
1254 .map(|op| match op {
1255 Operation::Read(buf) => buf.len(),
1256 _ => 0,
1257 })
1258 .sum();
1259
1260 if total_bytes == 0 {
1261 // Handle empty read group using blocking call
1262 if is_first_group {
1263 Self::master_read(
1264 self.info,
1265 address,
1266 0,
1267 if is_last_group { Stop::Automatic } else { Stop::Software },
1268 false,
1269 !is_first_group,
1270 timeout,
1271 )?;
1272 }
1273 if is_last_group {
1274 self.wait_stop(timeout)?;
1275 }
1276 return Ok(());
1277 }
1278
1279 // For read operations, we need to handle them differently since read_dma_internal
1280 // expects a single buffer. We'll iterate through operations and use DMA for each.
1281 let mut total_remaining = total_bytes;
1282 let restart = !is_first_group;
1283
1284 for operation in operations {
1285 if let Operation::Read(buffer) = operation {
1286 if buffer.is_empty() {
1287 // Skip empty buffers
1288 continue;
1289 }
1290
1291 let is_first_read = total_remaining == total_bytes;
1292 let buf_len = buffer.len();
1293 total_remaining -= buf_len;
1294 let is_last_read = total_remaining == 0;
1295
1296 if is_first_read {
1297 // First read in the group
1298 let completed_chunks = buf_len / 255;
1299 let total_chunks = if completed_chunks * 255 == buf_len {
1300 completed_chunks
1301 } else {
1302 completed_chunks + 1
1303 };
1304 let last_chunk_idx = total_chunks.saturating_sub(1);
1305
1306 // Use master_read to initiate, then DMA for data
1307 Self::master_read(
1308 self.info,
1309 address,
1310 buf_len.min(255),
1311 if is_last_group && is_last_read {
1312 Stop::Automatic
1313 } else {
1314 Stop::Software
1315 },
1316 last_chunk_idx != 0 || !is_last_read,
1317 restart,
1318 timeout,
1319 )?;
1320 }
1321
1322 // Use the existing read_dma_internal, but we need to handle the reload logic ourselves
1323 // For simplicity with consecutive reads, fall back to blocking for now
1324 // This maintains correctness while keeping complexity manageable
1325 for (chunk_idx, chunk) in buffer.chunks_mut(255).enumerate() {
1326 let chunk_len = chunk.len();
1327 let is_very_last = total_remaining == 0 && chunk_len == chunk.len();
1328
1329 if !is_first_read || chunk_idx != 0 {
1330 let stop = if is_last_group && is_very_last {
1331 Stop::Automatic
1332 } else {
1333 Stop::Software
1334 };
1335 Self::reload(self.info, chunk_len, !(is_last_group && is_very_last), stop, timeout)?;
1336 }
1337
1338 for byte in chunk {
1339 self.wait_rxne(timeout)?;
1340 *byte = self.info.regs.rxdr().read().rxdata();
1341 }
1342 }
1343 }
1344 }
1345
1346 // Wait for transfer to complete
1347 if is_last_group {
1348 self.wait_stop(timeout)?;
1349 }
1350 // For non-last read groups, don't wait for TC - the peripheral may hold SCL low
1351 // in Software AUTOEND mode until the next START is issued. Just proceed directly
1352 // to the next group which will issue RESTART and release the clock.
1353
1354 Ok(())
909 } 1355 }
910} 1356}
911 1357
@@ -1043,7 +1489,7 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
1043 if number == 0 { 1489 if number == 0 {
1044 Self::slave_start(self.info, chunk.len(), number != last_chunk_idx); 1490 Self::slave_start(self.info, chunk.len(), number != last_chunk_idx);
1045 } else { 1491 } else {
1046 Self::reload(self.info, chunk.len(), number != last_chunk_idx, timeout)?; 1492 Self::reload(self.info, chunk.len(), number != last_chunk_idx, Stop::Software, timeout)?;
1047 } 1493 }
1048 1494
1049 let mut index = 0; 1495 let mut index = 0;
@@ -1092,7 +1538,7 @@ impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
1092 if number == 0 { 1538 if number == 0 {
1093 Self::slave_start(self.info, chunk.len(), number != last_chunk_idx); 1539 Self::slave_start(self.info, chunk.len(), number != last_chunk_idx);
1094 } else { 1540 } else {
1095 Self::reload(self.info, chunk.len(), number != last_chunk_idx, timeout)?; 1541 Self::reload(self.info, chunk.len(), number != last_chunk_idx, Stop::Software, timeout)?;
1096 } 1542 }
1097 1543
1098 let mut index = 0; 1544 let mut index = 0;
@@ -1228,7 +1674,7 @@ impl<'d> I2c<'d, Async, MultiMaster> {
1228 Poll::Pending 1674 Poll::Pending
1229 } else if isr.tcr() { 1675 } else if isr.tcr() {
1230 let is_last_slice = remaining_len <= 255; 1676 let is_last_slice = remaining_len <= 255;
1231 if let Err(e) = Self::reload(self.info, remaining_len.min(255), !is_last_slice, timeout) { 1677 if let Err(e) = Self::reload(self.info, remaining_len.min(255), !is_last_slice, Stop::Software, timeout) {
1232 return Poll::Ready(Err(e)); 1678 return Poll::Ready(Err(e));
1233 } 1679 }
1234 remaining_len = remaining_len.saturating_sub(255); 1680 remaining_len = remaining_len.saturating_sub(255);
@@ -1292,7 +1738,7 @@ impl<'d> I2c<'d, Async, MultiMaster> {
1292 Poll::Pending 1738 Poll::Pending
1293 } else if isr.tcr() { 1739 } else if isr.tcr() {
1294 let is_last_slice = remaining_len <= 255; 1740 let is_last_slice = remaining_len <= 255;
1295 if let Err(e) = Self::reload(self.info, remaining_len.min(255), !is_last_slice, timeout) { 1741 if let Err(e) = Self::reload(self.info, remaining_len.min(255), !is_last_slice, Stop::Software, timeout) {
1296 return Poll::Ready(Err(e)); 1742 return Poll::Ready(Err(e));
1297 } 1743 }
1298 remaining_len = remaining_len.saturating_sub(255); 1744 remaining_len = remaining_len.saturating_sub(255);