aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThales Fragoso <[email protected]>2021-07-09 02:57:34 -0300
committerThales Fragoso <[email protected]>2021-07-14 23:39:50 -0300
commitaa8c7f990f3d00ddf8305dae7d278399d9573ecb (patch)
tree5cb27dc2a39096ea30c4fb6b6233f9782bcd5614
parentf2e78e9c3413994fa264345ceacc44463e5bb0ec (diff)
i2c-v2: Implement write_vectored
-rw-r--r--embassy-stm32/src/i2c/mod.rs1
-rw-r--r--embassy-stm32/src/i2c/v2.rs60
2 files changed, 61 insertions, 0 deletions
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index fc154a953..daf7e31e8 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -14,6 +14,7 @@ pub enum Error {
14 Timeout, 14 Timeout,
15 Crc, 15 Crc,
16 Overrun, 16 Overrun,
17 ZeroLengthTransfer,
17} 18}
18 19
19pub(crate) mod sealed { 20pub(crate) mod sealed {
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 787bf679a..a5eb5612d 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -325,6 +325,66 @@ impl<'d, T: Instance> I2c<'d, T> {
325 } 325 }
326 Ok(()) 326 Ok(())
327 } 327 }
328
329 pub fn write_vectored(&mut self, address: u8, bytes: &[&[u8]]) -> Result<(), Error> {
330 if bytes.is_empty() {
331 return Err(Error::ZeroLengthTransfer);
332 }
333 let first_length = bytes[0].len();
334 let last_slice_index = bytes.len() - 1;
335
336 self.master_write(
337 address,
338 first_length.min(255),
339 Stop::Software,
340 (first_length > 255) || (last_slice_index != 0),
341 );
342
343 for (idx, slice) in bytes.iter().enumerate() {
344 let slice_len = slice.len();
345 let completed_chunks = slice_len / 255;
346 let total_chunks = if completed_chunks * 255 == slice_len {
347 completed_chunks
348 } else {
349 completed_chunks + 1
350 };
351 let last_chunk_idx = total_chunks.saturating_sub(1);
352
353 if idx != 0 {
354 self.master_continue(
355 slice_len.min(255),
356 (idx != last_slice_index) || (slice_len > 255),
357 );
358 }
359
360 for (number, chunk) in slice.chunks(255).enumerate() {
361 if number != 0 {
362 self.master_continue(
363 chunk.len(),
364 (number != last_chunk_idx) || (idx != last_slice_index),
365 );
366 }
367
368 for byte in chunk {
369 // Wait until we are allowed to send data
370 // (START has been ACKed or last byte when
371 // through)
372 self.wait_txe()?;
373
374 // Put byte on the wire
375 //self.i2c.txdr.write(|w| w.txdata().bits(*byte));
376 unsafe {
377 T::regs().txdr().write(|w| w.set_txdata(*byte));
378 }
379 }
380 }
381 }
382 // Wait until the write finishes
383 self.wait_tc()?;
384 self.master_stop();
385
386 Ok(())
387 }
328} 388}
329 389
330impl<'d, T: Instance> Read for I2c<'d, T> { 390impl<'d, T: Instance> Read for I2c<'d, T> {