aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/i2c/mod.rs2
-rw-r--r--embassy-stm32/src/i2c/v2.rs255
2 files changed, 169 insertions, 88 deletions
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index d2da8c310..daf7e31e8 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,
@@ -13,6 +14,7 @@ pub enum Error {
13 Timeout, 14 Timeout,
14 Crc, 15 Crc,
15 Overrun, 16 Overrun,
17 ZeroLengthTransfer,
16} 18}
17 19
18pub(crate) mod sealed { 20pub(crate) mod sealed {
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 2f70d4263..3179211ec 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -81,30 +81,40 @@ impl<'d, T: Instance> I2c<'d, T> {
81 } 81 }
82 } 82 }
83 83
84 fn master_read(&mut self, address: u8, length: usize, stop: Stop) { 84 fn master_read(&mut self, address: u8, length: usize, stop: Stop, reload: bool, restart: bool) {
85 assert!(length < 256 && length > 0); 85 assert!(length < 256 && length > 0);
86 86
87 // Wait for any previous address sequence to end 87 if !restart {
88 // automatically. This could be up to 50% of a bus 88 // Wait for any previous address sequence to end
89 // cycle (ie. up to 0.5/freq) 89 // automatically. This could be up to 50% of a bus
90 while unsafe { T::regs().cr2().read().start() == i2c::vals::Start::START } {} 90 // cycle (ie. up to 0.5/freq)
91 while unsafe { T::regs().cr2().read().start() == i2c::vals::Start::START } {}
92 }
91 93
92 // Set START and prepare to receive bytes into 94 // Set START and prepare to receive bytes into
93 // `buffer`. The START bit can be set even if the bus 95 // `buffer`. The START bit can be set even if the bus
94 // is BUSY or I2C is in slave mode. 96 // is BUSY or I2C is in slave mode.
95 97
98 let reload = if reload {
99 i2c::vals::Reload::NOTCOMPLETED
100 } else {
101 i2c::vals::Reload::COMPLETED
102 };
103
96 unsafe { 104 unsafe {
97 T::regs().cr2().modify(|w| { 105 T::regs().cr2().modify(|w| {
98 w.set_sadd((address << 1 | 0) as u16); 106 w.set_sadd((address << 1 | 0) as u16);
107 w.set_add10(i2c::vals::Add::BIT7);
99 w.set_rd_wrn(i2c::vals::RdWrn::READ); 108 w.set_rd_wrn(i2c::vals::RdWrn::READ);
100 w.set_nbytes(length as u8); 109 w.set_nbytes(length as u8);
101 w.set_start(i2c::vals::Start::START); 110 w.set_start(i2c::vals::Start::START);
102 w.set_autoend(stop.autoend()); 111 w.set_autoend(stop.autoend());
112 w.set_reload(reload);
103 }); 113 });
104 } 114 }
105 } 115 }
106 116
107 fn master_write(&mut self, address: u8, length: usize, stop: Stop) { 117 fn master_write(&mut self, address: u8, length: usize, stop: Stop, reload: bool) {
108 assert!(length < 256 && length > 0); 118 assert!(length < 256 && length > 0);
109 119
110 // Wait for any previous address sequence to end 120 // Wait for any previous address sequence to end
@@ -112,6 +122,12 @@ impl<'d, T: Instance> I2c<'d, T> {
112 // cycle (ie. up to 0.5/freq) 122 // cycle (ie. up to 0.5/freq)
113 while unsafe { T::regs().cr2().read().start() == i2c::vals::Start::START } {} 123 while unsafe { T::regs().cr2().read().start() == i2c::vals::Start::START } {}
114 124
125 let reload = if reload {
126 i2c::vals::Reload::NOTCOMPLETED
127 } else {
128 i2c::vals::Reload::COMPLETED
129 };
130
115 // Set START and prepare to send `bytes`. The 131 // Set START and prepare to send `bytes`. The
116 // START bit can be set even if the bus is BUSY or 132 // START bit can be set even if the bus is BUSY or
117 // I2C is in slave mode. 133 // I2C is in slave mode.
@@ -123,21 +139,26 @@ impl<'d, T: Instance> I2c<'d, T> {
123 w.set_nbytes(length as u8); 139 w.set_nbytes(length as u8);
124 w.set_start(i2c::vals::Start::START); 140 w.set_start(i2c::vals::Start::START);
125 w.set_autoend(stop.autoend()); 141 w.set_autoend(stop.autoend());
142 w.set_reload(reload);
126 }); 143 });
127 } 144 }
128 } 145 }
129 146
130 fn master_re_start(&mut self, address: u8, length: usize, stop: Stop) { 147 fn master_continue(&mut self, length: usize, reload: bool) {
131 assert!(length < 256 && length > 0); 148 assert!(length < 256 && length > 0);
132 149
150 while unsafe { !T::regs().isr().read().tcr() } {}
151
152 let reload = if reload {
153 i2c::vals::Reload::NOTCOMPLETED
154 } else {
155 i2c::vals::Reload::COMPLETED
156 };
157
133 unsafe { 158 unsafe {
134 T::regs().cr2().modify(|w| { 159 T::regs().cr2().modify(|w| {
135 w.set_sadd((address << 1 | 1) as u16);
136 w.set_add10(i2c::vals::Add::BIT7);
137 w.set_rd_wrn(i2c::vals::RdWrn::READ);
138 w.set_nbytes(length as u8); 160 w.set_nbytes(length as u8);
139 w.set_start(i2c::vals::Start::START); 161 w.set_reload(reload);
140 w.set_autoend(stop.autoend());
141 }); 162 });
142 } 163 }
143 } 164 }
@@ -224,117 +245,175 @@ impl<'d, T: Instance> I2c<'d, T> {
224 } 245 }
225 } 246 }
226 } 247 }
227}
228
229impl<'d, T: Instance> Read for I2c<'d, T> {
230 type Error = Error;
231 248
232 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { 249 fn read(&mut self, address: u8, buffer: &mut [u8], restart: bool) -> Result<(), Error> {
233 assert!(buffer.len() < 256 && buffer.len() > 0); 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);
257
258 self.master_read(
259 address,
260 buffer.len().min(255),
261 Stop::Automatic,
262 last_chunk_idx != 0,
263 restart,
264 );
234 265
235 self.master_read(address, buffer.len(), Stop::Automatic); 266 for (number, chunk) in buffer.chunks_mut(255).enumerate() {
267 if number != 0 {
268 self.master_continue(chunk.len(), number != last_chunk_idx);
269 }
236 270
237 for byte in buffer { 271 for byte in chunk {
238 // Wait until we have received something 272 // Wait until we have received something
239 self.wait_rxne()?; 273 self.wait_rxne()?;
240 274
241 //*byte = self.i2c.rxdr.read().rxdata().bits(); 275 unsafe {
242 unsafe { 276 *byte = T::regs().rxdr().read().rxdata();
243 *byte = T::regs().rxdr().read().rxdata(); 277 }
244 } 278 }
245 } 279 }
246
247 // automatic STOP
248 Ok(()) 280 Ok(())
249 } 281 }
250}
251
252impl<'d, T: Instance> Write for I2c<'d, T> {
253 type Error = Error;
254 282
255 fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> { 283 fn write(&mut self, address: u8, bytes: &[u8], send_stop: bool) -> Result<(), Error> {
256 // TODO support transfers of more than 255 bytes 284 let completed_chunks = bytes.len() / 255;
257 assert!(bytes.len() < 256 && bytes.len() > 0); 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);
258 291
259 // I2C start 292 // I2C start
260 // 293 //
261 // ST SAD+W 294 // ST SAD+W
262 self.master_write(address, bytes.len(), Stop::Software); 295 self.master_write(
296 address,
297 bytes.len().min(255),
298 Stop::Software,
299 last_chunk_idx != 0,
300 );
301
302 for (number, chunk) in bytes.chunks(255).enumerate() {
303 if number != 0 {
304 self.master_continue(chunk.len(), number != last_chunk_idx);
305 }
263 306
264 for byte in bytes { 307 for byte in chunk {
265 // Wait until we are allowed to send data 308 // Wait until we are allowed to send data
266 // (START has been ACKed or last byte when 309 // (START has been ACKed or last byte when
267 // through) 310 // through)
268 self.wait_txe()?; 311 self.wait_txe()?;
269 312
270 // Put byte on the wire 313 unsafe {
271 //self.i2c.txdr.write(|w| w.txdata().bits(*byte)); 314 T::regs().txdr().write(|w| w.set_txdata(*byte));
272 unsafe { 315 }
273 T::regs().txdr().write(|w| w.set_txdata(*byte));
274 } 316 }
275 } 317 }
276
277 // Wait until the write finishes 318 // Wait until the write finishes
278 self.wait_tc()?; 319 self.wait_tc()?;
279 320
280 // Stop 321 if send_stop {
281 self.master_stop(); 322 self.master_stop();
282 323 }
283 Ok(()) 324 Ok(())
284 } 325 }
285}
286 326
287impl<'d, T: Instance> WriteRead for I2c<'d, T> { 327 pub fn write_vectored(&mut self, address: u8, bytes: &[&[u8]]) -> Result<(), Error> {
288 type Error = Error; 328 if bytes.is_empty() {
329 return Err(Error::ZeroLengthTransfer);
330 }
331 let first_length = bytes[0].len();
332 let last_slice_index = bytes.len() - 1;
333
334 self.master_write(
335 address,
336 first_length.min(255),
337 Stop::Software,
338 (first_length > 255) || (last_slice_index != 0),
339 );
289 340
290 fn write_read( 341 for (idx, slice) in bytes.iter().enumerate() {
291 &mut self, 342 let slice_len = slice.len();
292 address: u8, 343 let completed_chunks = slice_len / 255;
293 bytes: &[u8], 344 let total_chunks = if completed_chunks * 255 == slice_len {
294 buffer: &mut [u8], 345 completed_chunks
295 ) -> Result<(), Self::Error> { 346 } else {
296 // TODO support transfers of more than 255 bytes 347 completed_chunks + 1
297 assert!(bytes.len() < 256 && bytes.len() > 0); 348 };
298 assert!(buffer.len() < 256 && buffer.len() > 0); 349 let last_chunk_idx = total_chunks.saturating_sub(1);
299 350
300 // I2C start 351 if idx != 0 {
301 // 352 self.master_continue(
302 // ST SAD+W 353 slice_len.min(255),
303 self.master_write(address, bytes.len(), Stop::Software); 354 (idx != last_slice_index) || (slice_len > 255),
355 );
356 }
304 357
305 for byte in bytes { 358 for (number, chunk) in slice.chunks(255).enumerate() {
306 // Wait until we are allowed to send data 359 if number != 0 {
307 // (START has been ACKed or last byte went through) 360 self.master_continue(
308 self.wait_txe()?; 361 chunk.len(),
362 (number != last_chunk_idx) || (idx != last_slice_index),
363 );
364 }
309 365
310 // Put byte on the wire 366 for byte in chunk {
311 //self.i2c.txdr.write(|w| w.txdata().bits(*byte)); 367 // Wait until we are allowed to send data
312 unsafe { 368 // (START has been ACKed or last byte when
313 T::regs().txdr().write(|w| w.set_txdata(*byte)); 369 // through)
370 self.wait_txe()?;
371
372 // Put byte on the wire
373 //self.i2c.txdr.write(|w| w.txdata().bits(*byte));
374 unsafe {
375 T::regs().txdr().write(|w| w.set_txdata(*byte));
376 }
377 }
314 } 378 }
315 } 379 }
316 380 // Wait until the write finishes
317 // Wait until the write finishes before beginning to read.
318 self.wait_tc()?; 381 self.wait_tc()?;
382 self.master_stop();
319 383
320 // I2C re-start 384 Ok(())
321 // 385 }
322 // SR SAD+R 386}
323 self.master_re_start(address, buffer.len(), Stop::Automatic);
324 387
325 for byte in buffer { 388impl<'d, T: Instance> Read for I2c<'d, T> {
326 // Wait until we have received something 389 type Error = Error;
327 self.wait_rxne()?;
328 390
329 //*byte = self.i2c.rxdr.read().rxdata().bits(); 391 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
330 unsafe { 392 self.read(address, buffer, false)
331 *byte = T::regs().rxdr().read().rxdata(); 393 // Automatic Stop
332 } 394 }
333 } 395}
334 396
335 // automatic STOP 397impl<'d, T: Instance> Write for I2c<'d, T> {
398 type Error = Error;
336 399
337 Ok(()) 400 fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
401 self.write(address, bytes, true)
402 }
403}
404
405impl<'d, T: Instance> WriteRead for I2c<'d, T> {
406 type Error = Error;
407
408 fn write_read(
409 &mut self,
410 address: u8,
411 bytes: &[u8],
412 buffer: &mut [u8],
413 ) -> Result<(), Self::Error> {
414 self.write(address, bytes, false)?;
415 self.read(address, buffer, true)
416 // Automatic Stop
338 } 417 }
339} 418}
340 419