aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThales Fragoso <[email protected]>2021-07-07 21:35:56 -0300
committerThales Fragoso <[email protected]>2021-07-14 23:39:50 -0300
commit8c7f8a61e327078cf68a32a5f282f301f335ffd1 (patch)
tree359fe71a73bb28e8ac68fdc74e11e401d7abd586
parent8a172ac12325ddc382e5ac0ffa637120a166d057 (diff)
i2c-v2: Support transfers with more than 255 bytes
-rw-r--r--embassy-stm32/src/i2c/v2.rs185
1 files changed, 96 insertions, 89 deletions
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 2f70d4263..b7aa84586 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,24 @@ 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 let reload = if reload {
151 i2c::vals::Reload::NOTCOMPLETED
152 } else {
153 i2c::vals::Reload::COMPLETED
154 };
155
133 unsafe { 156 unsafe {
134 T::regs().cr2().modify(|w| { 157 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); 158 w.set_nbytes(length as u8);
139 w.set_start(i2c::vals::Start::START); 159 w.set_reload(reload);
140 w.set_autoend(stop.autoend());
141 }); 160 });
142 } 161 }
143 } 162 }
@@ -224,66 +243,93 @@ impl<'d, T: Instance> I2c<'d, T> {
224 } 243 }
225 } 244 }
226 } 245 }
227}
228 246
229impl<'d, T: Instance> Read for I2c<'d, T> { 247 fn read(&mut self, address: u8, buffer: &mut [u8], restart: bool) -> Result<(), Error> {
230 type Error = Error; 248 let last_chunk = (buffer.len() / 255).saturating_sub(1);
231 249
232 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { 250 self.master_read(
233 assert!(buffer.len() < 256 && buffer.len() > 0); 251 address,
252 buffer.len().min(255),
253 Stop::Automatic,
254 last_chunk != 0,
255 restart,
256 );
234 257
235 self.master_read(address, buffer.len(), Stop::Automatic); 258 for (number, chunk) in buffer.chunks_mut(255).enumerate() {
259 if number != 0 {
260 self.master_continue(chunk.len(), number != last_chunk);
261 }
236 262
237 for byte in buffer { 263 for byte in chunk {
238 // Wait until we have received something 264 // Wait until we have received something
239 self.wait_rxne()?; 265 self.wait_rxne()?;
240 266
241 //*byte = self.i2c.rxdr.read().rxdata().bits(); 267 unsafe {
242 unsafe { 268 *byte = T::regs().rxdr().read().rxdata();
243 *byte = T::regs().rxdr().read().rxdata(); 269 }
244 } 270 }
245 } 271 }
246
247 // automatic STOP
248 Ok(()) 272 Ok(())
249 } 273 }
250}
251 274
252impl<'d, T: Instance> Write for I2c<'d, T> { 275 fn write(&mut self, address: u8, bytes: &[u8], send_stop: bool) -> Result<(), Error> {
253 type Error = Error; 276 let last_chunk = (bytes.len() / 255).saturating_sub(1);
254
255 fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
256 // TODO support transfers of more than 255 bytes
257 assert!(bytes.len() < 256 && bytes.len() > 0);
258 277
259 // I2C start 278 // I2C start
260 // 279 //
261 // ST SAD+W 280 // ST SAD+W
262 self.master_write(address, bytes.len(), Stop::Software); 281 self.master_write(
282 address,
283 bytes.len().min(255),
284 Stop::Software,
285 last_chunk != 0,
286 );
263 287
264 for byte in bytes { 288 for (number, chunk) in bytes.chunks(255).enumerate() {
265 // Wait until we are allowed to send data 289 if number != 0 {
266 // (START has been ACKed or last byte when 290 self.master_continue(chunk.len(), number != last_chunk);
267 // through) 291 }
268 self.wait_txe()?;
269 292
270 // Put byte on the wire 293 for byte in chunk {
271 //self.i2c.txdr.write(|w| w.txdata().bits(*byte)); 294 // Wait until we are allowed to send data
272 unsafe { 295 // (START has been ACKed or last byte when
273 T::regs().txdr().write(|w| w.set_txdata(*byte)); 296 // through)
297 self.wait_txe()?;
298
299 // Put byte on the wire
300 //self.i2c.txdr.write(|w| w.txdata().bits(*byte));
301 unsafe {
302 T::regs().txdr().write(|w| w.set_txdata(*byte));
303 }
274 } 304 }
275 } 305 }
276
277 // Wait until the write finishes 306 // Wait until the write finishes
278 self.wait_tc()?; 307 self.wait_tc()?;
279 308
280 // Stop 309 if send_stop {
281 self.master_stop(); 310 self.master_stop();
282 311 }
283 Ok(()) 312 Ok(())
284 } 313 }
285} 314}
286 315
316impl<'d, T: Instance> Read for I2c<'d, T> {
317 type Error = Error;
318
319 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
320 self.read(address, buffer, false)
321 // Automatic Stop
322 }
323}
324
325impl<'d, T: Instance> Write for I2c<'d, T> {
326 type Error = Error;
327
328 fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
329 self.write(address, bytes, true)
330 }
331}
332
287impl<'d, T: Instance> WriteRead for I2c<'d, T> { 333impl<'d, T: Instance> WriteRead for I2c<'d, T> {
288 type Error = Error; 334 type Error = Error;
289 335
@@ -293,48 +339,9 @@ impl<'d, T: Instance> WriteRead for I2c<'d, T> {
293 bytes: &[u8], 339 bytes: &[u8],
294 buffer: &mut [u8], 340 buffer: &mut [u8],
295 ) -> Result<(), Self::Error> { 341 ) -> Result<(), Self::Error> {
296 // TODO support transfers of more than 255 bytes 342 self.write(address, bytes, false)?;
297 assert!(bytes.len() < 256 && bytes.len() > 0); 343 self.read(address, buffer, true)
298 assert!(buffer.len() < 256 && buffer.len() > 0); 344 // Automatic Stop
299
300 // I2C start
301 //
302 // ST SAD+W
303 self.master_write(address, bytes.len(), Stop::Software);
304
305 for byte in bytes {
306 // Wait until we are allowed to send data
307 // (START has been ACKed or last byte went through)
308 self.wait_txe()?;
309
310 // Put byte on the wire
311 //self.i2c.txdr.write(|w| w.txdata().bits(*byte));
312 unsafe {
313 T::regs().txdr().write(|w| w.set_txdata(*byte));
314 }
315 }
316
317 // Wait until the write finishes before beginning to read.
318 self.wait_tc()?;
319
320 // I2C re-start
321 //
322 // SR SAD+R
323 self.master_re_start(address, buffer.len(), Stop::Automatic);
324
325 for byte in buffer {
326 // Wait until we have received something
327 self.wait_rxne()?;
328
329 //*byte = self.i2c.rxdr.read().rxdata().bits();
330 unsafe {
331 *byte = T::regs().rxdr().read().rxdata();
332 }
333 }
334
335 // automatic STOP
336
337 Ok(())
338 } 345 }
339} 346}
340 347