aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHybridChild <[email protected]>2025-11-12 19:31:21 +0100
committerHybridChild <[email protected]>2025-11-12 19:57:56 +0100
commit74b5f14ede9a6b4349932bff41dac077afc47fa2 (patch)
tree991b5fe31e49f555b661643df0556442c26b8fd6
parentaa5c0c02425104fceea9e5dc773e3f5c346e9656 (diff)
stm32/i2c_v2: Refactor transaction implementation
-rw-r--r--embassy-stm32/src/i2c/v2.rs87
1 files changed, 33 insertions, 54 deletions
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 061f4ff3a..3c43887c0 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -98,6 +98,27 @@ pub(crate) unsafe fn on_interrupt<T: Instance>() {
98} 98}
99 99
100impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> { 100impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
101 #[inline]
102 fn to_reload(reload: bool) -> i2c::vals::Reload {
103 if reload {
104 i2c::vals::Reload::NOT_COMPLETED
105 } else {
106 i2c::vals::Reload::COMPLETED
107 }
108 }
109
110 /// Calculate total bytes in a group of operations
111 #[inline]
112 fn total_operation_bytes(operations: &[Operation<'_>]) -> usize {
113 operations
114 .iter()
115 .map(|op| match op {
116 Operation::Write(buf) => buf.len(),
117 Operation::Read(buf) => buf.len(),
118 })
119 .sum()
120 }
121
101 pub(crate) fn init(&mut self, config: Config) { 122 pub(crate) fn init(&mut self, config: Config) {
102 self.info.regs.cr1().modify(|reg| { 123 self.info.regs.cr1().modify(|reg| {
103 reg.set_pe(false); 124 reg.set_pe(false);
@@ -147,12 +168,6 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
147 // `buffer`. The START bit can be set even if the bus 168 // `buffer`. The START bit can be set even if the bus
148 // is BUSY or I2C is in slave mode. 169 // is BUSY or I2C is in slave mode.
149 170
150 let reload = if reload {
151 i2c::vals::Reload::NOT_COMPLETED
152 } else {
153 i2c::vals::Reload::COMPLETED
154 };
155
156 info.regs.cr2().modify(|w| { 171 info.regs.cr2().modify(|w| {
157 w.set_sadd(address.addr() << 1); 172 w.set_sadd(address.addr() << 1);
158 w.set_add10(address.add_mode()); 173 w.set_add10(address.add_mode());
@@ -160,7 +175,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
160 w.set_nbytes(length as u8); 175 w.set_nbytes(length as u8);
161 w.set_start(true); 176 w.set_start(true);
162 w.set_autoend(stop.autoend()); 177 w.set_autoend(stop.autoend());
163 w.set_reload(reload); 178 w.set_reload(Self::to_reload(reload));
164 }); 179 });
165 180
166 Ok(()) 181 Ok(())
@@ -191,12 +206,6 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
191 } 206 }
192 } 207 }
193 208
194 let reload = if reload {
195 i2c::vals::Reload::NOT_COMPLETED
196 } else {
197 i2c::vals::Reload::COMPLETED
198 };
199
200 // Set START and prepare to send `bytes`. The 209 // Set START and prepare to send `bytes`. The
201 // START bit can be set even if the bus is BUSY or 210 // START bit can be set even if the bus is BUSY or
202 // I2C is in slave mode. 211 // I2C is in slave mode.
@@ -207,7 +216,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
207 w.set_nbytes(length as u8); 216 w.set_nbytes(length as u8);
208 w.set_start(true); 217 w.set_start(true);
209 w.set_autoend(stop.autoend()); 218 w.set_autoend(stop.autoend());
210 w.set_reload(reload); 219 w.set_reload(Self::to_reload(reload));
211 }); 220 });
212 221
213 Ok(()) 222 Ok(())
@@ -220,15 +229,9 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
220 timeout.check()?; 229 timeout.check()?;
221 } 230 }
222 231
223 let will_reload = if will_reload {
224 i2c::vals::Reload::NOT_COMPLETED
225 } else {
226 i2c::vals::Reload::COMPLETED
227 };
228
229 info.regs.cr2().modify(|w| { 232 info.regs.cr2().modify(|w| {
230 w.set_nbytes(length as u8); 233 w.set_nbytes(length as u8);
231 w.set_reload(will_reload); 234 w.set_reload(Self::to_reload(will_reload));
232 w.set_autoend(stop.autoend()); 235 w.set_autoend(stop.autoend());
233 }); 236 });
234 237
@@ -400,7 +403,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
400 address, 403 address,
401 read.len().min(255), 404 read.len().min(255),
402 Stop::Automatic, 405 Stop::Automatic,
403 last_chunk_idx != 0, 406 last_chunk_idx != 0, // reload
404 restart, 407 restart,
405 timeout, 408 timeout,
406 )?; 409 )?;
@@ -569,13 +572,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
569 timeout: Timeout, 572 timeout: Timeout,
570 ) -> Result<(), Error> { 573 ) -> Result<(), Error> {
571 // Calculate total bytes across all operations in this group 574 // Calculate total bytes across all operations in this group
572 let total_bytes: usize = operations 575 let total_bytes = Self::total_operation_bytes(operations);
573 .iter()
574 .map(|op| match op {
575 Operation::Write(buf) => buf.len(),
576 _ => 0,
577 })
578 .sum();
579 576
580 if total_bytes == 0 { 577 if total_bytes == 0 {
581 // Handle empty write group - just send address 578 // Handle empty write group - just send address
@@ -641,13 +638,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
641 timeout: Timeout, 638 timeout: Timeout,
642 ) -> Result<(), Error> { 639 ) -> Result<(), Error> {
643 // Calculate total bytes across all operations in this group 640 // Calculate total bytes across all operations in this group
644 let total_bytes: usize = operations 641 let total_bytes = Self::total_operation_bytes(operations);
645 .iter()
646 .map(|op| match op {
647 Operation::Read(buf) => buf.len(),
648 _ => 0,
649 })
650 .sum();
651 642
652 if total_bytes == 0 { 643 if total_bytes == 0 {
653 // Handle empty read group 644 // Handle empty read group
@@ -657,7 +648,7 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
657 address, 648 address,
658 0, 649 0,
659 if is_last_group { Stop::Automatic } else { Stop::Software }, 650 if is_last_group { Stop::Automatic } else { Stop::Software },
660 false, 651 false, // reload
661 !is_first_group, 652 !is_first_group,
662 timeout, 653 timeout,
663 )?; 654 )?;
@@ -1000,7 +991,7 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
1000 address, 991 address,
1001 total_len.min(255), 992 total_len.min(255),
1002 Stop::Automatic, 993 Stop::Automatic,
1003 total_len > 255, 994 total_len > 255, // reload
1004 restart, 995 restart,
1005 timeout, 996 timeout,
1006 )?; 997 )?;
@@ -1183,13 +1174,7 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
1183 timeout: Timeout, 1174 timeout: Timeout,
1184 ) -> Result<(), Error> { 1175 ) -> Result<(), Error> {
1185 // Calculate total bytes across all operations in this group 1176 // Calculate total bytes across all operations in this group
1186 let total_bytes: usize = operations 1177 let total_bytes = Self::total_operation_bytes(operations);
1187 .iter()
1188 .map(|op| match op {
1189 Operation::Write(buf) => buf.len(),
1190 _ => 0,
1191 })
1192 .sum();
1193 1178
1194 if total_bytes == 0 { 1179 if total_bytes == 0 {
1195 // Handle empty write group using blocking call 1180 // Handle empty write group using blocking call
@@ -1249,13 +1234,7 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
1249 timeout: Timeout, 1234 timeout: Timeout,
1250 ) -> Result<(), Error> { 1235 ) -> Result<(), Error> {
1251 // Calculate total bytes across all operations in this group 1236 // Calculate total bytes across all operations in this group
1252 let total_bytes: usize = operations 1237 let total_bytes = Self::total_operation_bytes(operations);
1253 .iter()
1254 .map(|op| match op {
1255 Operation::Read(buf) => buf.len(),
1256 _ => 0,
1257 })
1258 .sum();
1259 1238
1260 if total_bytes == 0 { 1239 if total_bytes == 0 {
1261 // Handle empty read group using blocking call 1240 // Handle empty read group using blocking call
@@ -1265,7 +1244,7 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
1265 address, 1244 address,
1266 0, 1245 0,
1267 if is_last_group { Stop::Automatic } else { Stop::Software }, 1246 if is_last_group { Stop::Automatic } else { Stop::Software },
1268 false, 1247 false, // reload
1269 !is_first_group, 1248 !is_first_group,
1270 timeout, 1249 timeout,
1271 )?; 1250 )?;
@@ -1313,7 +1292,7 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
1313 } else { 1292 } else {
1314 Stop::Software 1293 Stop::Software
1315 }, 1294 },
1316 last_chunk_idx != 0 || !is_last_read, 1295 last_chunk_idx != 0 || !is_last_read, // reload
1317 restart, 1296 restart,
1318 timeout, 1297 timeout,
1319 )?; 1298 )?;