diff options
| author | HybridChild <[email protected]> | 2025-11-13 21:23:13 +0100 |
|---|---|---|
| committer | HybridChild <[email protected]> | 2025-11-13 21:23:13 +0100 |
| commit | 42f38d5b3209134baa8bf424cdb754e1901ac0da (patch) | |
| tree | f1b89a87c0126d3a4071b59fca1339f7b2a59470 /embassy-stm32/src | |
| parent | de16754a2d340eca49885238e265f50bfc3ec2e5 (diff) | |
stm32/i2c: Implement async DMA for transaction write groups
Diffstat (limited to 'embassy-stm32/src')
| -rw-r--r-- | embassy-stm32/src/i2c/v2.rs | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index c35f3694c..8f51627ff 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs | |||
| @@ -1222,9 +1222,53 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | |||
| 1222 | is_last_group: bool, | 1222 | is_last_group: bool, |
| 1223 | timeout: Timeout, | 1223 | timeout: Timeout, |
| 1224 | ) -> Result<(), Error> { | 1224 | ) -> Result<(), Error> { |
| 1225 | // For now, use blocking implementation for write groups | 1225 | // Calculate total bytes across all operations in this group |
| 1226 | // This avoids complexity of handling multiple non-contiguous buffers with DMA | 1226 | let total_bytes = Self::total_operation_bytes(operations); |
| 1227 | self.execute_write_group(address, operations, is_first_group, is_last_group, timeout) | 1227 | |
| 1228 | if total_bytes == 0 { | ||
| 1229 | // Handle empty write group using blocking call | ||
| 1230 | if is_first_group { | ||
| 1231 | Self::master_write(self.info, address, 0, Stop::Software, false, !is_first_group, timeout)?; | ||
| 1232 | } | ||
| 1233 | if is_last_group { | ||
| 1234 | self.master_stop(); | ||
| 1235 | } | ||
| 1236 | return Ok(()); | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | // Collect all write buffers | ||
| 1240 | let mut write_buffers: heapless::Vec<&[u8], 16> = heapless::Vec::new(); | ||
| 1241 | for operation in operations { | ||
| 1242 | if let Operation::Write(buffer) = operation { | ||
| 1243 | if !buffer.is_empty() { | ||
| 1244 | let _ = write_buffers.push(buffer); | ||
| 1245 | } | ||
| 1246 | } | ||
| 1247 | } | ||
| 1248 | |||
| 1249 | if write_buffers.is_empty() { | ||
| 1250 | return Ok(()); | ||
| 1251 | } | ||
| 1252 | |||
| 1253 | // Send each buffer using DMA | ||
| 1254 | let num_buffers = write_buffers.len(); | ||
| 1255 | for (idx, buffer) in write_buffers.iter().enumerate() { | ||
| 1256 | let is_first_buffer = idx == 0; | ||
| 1257 | let is_last_buffer = idx == num_buffers - 1; | ||
| 1258 | |||
| 1259 | let fut = self.write_dma_internal( | ||
| 1260 | address, | ||
| 1261 | buffer, | ||
| 1262 | is_first_buffer, // first_slice | ||
| 1263 | is_last_buffer, // last_slice | ||
| 1264 | is_last_buffer && is_last_group, // send_stop | ||
| 1265 | is_first_buffer && !is_first_group, // restart (only for first buffer if not first group) | ||
| 1266 | timeout, | ||
| 1267 | ); | ||
| 1268 | timeout.with(fut).await?; | ||
| 1269 | } | ||
| 1270 | |||
| 1271 | Ok(()) | ||
| 1228 | } | 1272 | } |
| 1229 | 1273 | ||
| 1230 | async fn execute_read_group_async( | 1274 | async fn execute_read_group_async( |
