aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThales Fragoso <[email protected]>2021-07-08 19:53:47 -0300
committerThales Fragoso <[email protected]>2021-07-14 23:39:50 -0300
commitf2e78e9c3413994fa264345ceacc44463e5bb0ec (patch)
tree9493657ef0b0442b59d68596fe0fe8b1e3236603
parent8c7f8a61e327078cf68a32a5f282f301f335ffd1 (diff)
i2c-v2: Correct number of chunks calculation
-rw-r--r--embassy-stm32/src/i2c/mod.rs1
-rw-r--r--embassy-stm32/src/i2c/v2.rs26
2 files changed, 21 insertions, 6 deletions
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index d2da8c310..fc154a953 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -6,6 +6,7 @@ mod _version;
6use crate::peripherals; 6use crate::peripherals;
7pub use _version::*; 7pub use _version::*;
8 8
9#[cfg_attr(feature = "defmt", derive(defmt::Format))]
9pub enum Error { 10pub enum Error {
10 Bus, 11 Bus,
11 Arbitration, 12 Arbitration,
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index b7aa84586..787bf679a 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -147,6 +147,8 @@ impl<'d, T: Instance> I2c<'d, T> {
147 fn master_continue(&mut self, length: usize, reload: bool) { 147 fn master_continue(&mut self, length: usize, reload: bool) {
148 assert!(length < 256 && length > 0); 148 assert!(length < 256 && length > 0);
149 149
150 while unsafe { !T::regs().isr().read().tcr() } {}
151
150 let reload = if reload { 152 let reload = if reload {
151 i2c::vals::Reload::NOTCOMPLETED 153 i2c::vals::Reload::NOTCOMPLETED
152 } else { 154 } else {
@@ -245,19 +247,25 @@ impl<'d, T: Instance> I2c<'d, T> {
245 } 247 }
246 248
247 fn read(&mut self, address: u8, buffer: &mut [u8], restart: bool) -> Result<(), Error> { 249 fn read(&mut self, address: u8, buffer: &mut [u8], restart: bool) -> Result<(), Error> {
248 let last_chunk = (buffer.len() / 255).saturating_sub(1); 250 let completed_chunks = buffer.len() / 255;
251 let total_chunks = if completed_chunks * 255 == buffer.len() {
252 completed_chunks
253 } else {
254 completed_chunks + 1
255 };
256 let last_chunk_idx = total_chunks.saturating_sub(1);
249 257
250 self.master_read( 258 self.master_read(
251 address, 259 address,
252 buffer.len().min(255), 260 buffer.len().min(255),
253 Stop::Automatic, 261 Stop::Automatic,
254 last_chunk != 0, 262 last_chunk_idx != 0,
255 restart, 263 restart,
256 ); 264 );
257 265
258 for (number, chunk) in buffer.chunks_mut(255).enumerate() { 266 for (number, chunk) in buffer.chunks_mut(255).enumerate() {
259 if number != 0 { 267 if number != 0 {
260 self.master_continue(chunk.len(), number != last_chunk); 268 self.master_continue(chunk.len(), number != last_chunk_idx);
261 } 269 }
262 270
263 for byte in chunk { 271 for byte in chunk {
@@ -273,7 +281,13 @@ impl<'d, T: Instance> I2c<'d, T> {
273 } 281 }
274 282
275 fn write(&mut self, address: u8, bytes: &[u8], send_stop: bool) -> Result<(), Error> { 283 fn write(&mut self, address: u8, bytes: &[u8], send_stop: bool) -> Result<(), Error> {
276 let last_chunk = (bytes.len() / 255).saturating_sub(1); 284 let completed_chunks = bytes.len() / 255;
285 let total_chunks = if completed_chunks * 255 == bytes.len() {
286 completed_chunks
287 } else {
288 completed_chunks + 1
289 };
290 let last_chunk_idx = total_chunks.saturating_sub(1);
277 291
278 // I2C start 292 // I2C start
279 // 293 //
@@ -282,12 +296,12 @@ impl<'d, T: Instance> I2c<'d, T> {
282 address, 296 address,
283 bytes.len().min(255), 297 bytes.len().min(255),
284 Stop::Software, 298 Stop::Software,
285 last_chunk != 0, 299 last_chunk_idx != 0,
286 ); 300 );
287 301
288 for (number, chunk) in bytes.chunks(255).enumerate() { 302 for (number, chunk) in bytes.chunks(255).enumerate() {
289 if number != 0 { 303 if number != 0 {
290 self.master_continue(chunk.len(), number != last_chunk); 304 self.master_continue(chunk.len(), number != last_chunk_idx);
291 } 305 }
292 306
293 for byte in chunk { 307 for byte in chunk {