aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/xspi/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32/src/xspi/mod.rs')
-rw-r--r--embassy-stm32/src/xspi/mod.rs104
1 files changed, 59 insertions, 45 deletions
diff --git a/embassy-stm32/src/xspi/mod.rs b/embassy-stm32/src/xspi/mod.rs
index 901569f64..466e1a9b4 100644
--- a/embassy-stm32/src/xspi/mod.rs
+++ b/embassy-stm32/src/xspi/mod.rs
@@ -11,15 +11,15 @@ use embassy_embedded_hal::{GetConfig, SetConfig};
11use embassy_hal_internal::PeripheralType; 11use embassy_hal_internal::PeripheralType;
12pub use enums::*; 12pub use enums::*;
13 13
14use crate::dma::{word, ChannelAndRequest}; 14use crate::dma::{ChannelAndRequest, word};
15use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; 15use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed};
16use crate::mode::{Async, Blocking, Mode as PeriMode}; 16use crate::mode::{Async, Blocking, Mode as PeriMode};
17use crate::pac::xspi::vals::*;
18use crate::pac::xspi::Xspi as Regs; 17use crate::pac::xspi::Xspi as Regs;
18use crate::pac::xspi::vals::*;
19#[cfg(xspim_v1)] 19#[cfg(xspim_v1)]
20use crate::pac::xspim::Xspim; 20use crate::pac::xspim::Xspim;
21use crate::rcc::{self, RccPeripheral}; 21use crate::rcc::{self, RccPeripheral};
22use crate::{peripherals, Peri}; 22use crate::{Peri, peripherals};
23 23
24/// XPSI driver config. 24/// XPSI driver config.
25#[derive(Clone, Copy)] 25#[derive(Clone, Copy)]
@@ -420,9 +420,9 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
420 return Err(XspiError::InvalidCommand); 420 return Err(XspiError::InvalidCommand);
421 } 421 }
422 422
423 T::REGS.cr().modify(|w| { 423 T::REGS
424 w.set_fmode(0.into()); 424 .cr()
425 }); 425 .modify(|w| w.set_fmode(Fmode::from_bits(XspiMode::IndirectWrite.into())));
426 426
427 // Configure alternate bytes 427 // Configure alternate bytes
428 if let Some(ab) = command.alternate_bytes { 428 if let Some(ab) = command.alternate_bytes {
@@ -538,8 +538,8 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
538 w.set_dmaen(false); 538 w.set_dmaen(false);
539 }); 539 });
540 540
541 // self.configure_command(&transaction, Some(buf.len()))?; 541 let transfer_size_bytes = buf.len() * W::size().bytes();
542 self.configure_command(&transaction, Some(buf.len())).unwrap(); 542 self.configure_command(&transaction, Some(transfer_size_bytes))?;
543 543
544 let current_address = T::REGS.ar().read().address(); 544 let current_address = T::REGS.ar().read().address();
545 let current_instruction = T::REGS.ir().read().instruction(); 545 let current_instruction = T::REGS.ir().read().instruction();
@@ -578,7 +578,8 @@ impl<'d, T: Instance, M: PeriMode> Xspi<'d, T, M> {
578 w.set_dmaen(false); 578 w.set_dmaen(false);
579 }); 579 });
580 580
581 self.configure_command(&transaction, Some(buf.len()))?; 581 let transfer_size_bytes = buf.len() * W::size().bytes();
582 self.configure_command(&transaction, Some(transfer_size_bytes))?;
582 583
583 T::REGS 584 T::REGS
584 .cr() 585 .cr()
@@ -1145,7 +1146,8 @@ impl<'d, T: Instance> Xspi<'d, T, Async> {
1145 // Wait for peripheral to be free 1146 // Wait for peripheral to be free
1146 while T::REGS.sr().read().busy() {} 1147 while T::REGS.sr().read().busy() {}
1147 1148
1148 self.configure_command(&transaction, Some(buf.len()))?; 1149 let transfer_size_bytes = buf.len() * W::size().bytes();
1150 self.configure_command(&transaction, Some(transfer_size_bytes))?;
1149 1151
1150 let current_address = T::REGS.ar().read().address(); 1152 let current_address = T::REGS.ar().read().address();
1151 let current_instruction = T::REGS.ir().read().instruction(); 1153 let current_instruction = T::REGS.ir().read().instruction();
@@ -1160,16 +1162,18 @@ impl<'d, T: Instance> Xspi<'d, T, Async> {
1160 T::REGS.ar().write(|v| v.set_address(current_address)); 1162 T::REGS.ar().write(|v| v.set_address(current_address));
1161 } 1163 }
1162 1164
1163 let transfer = unsafe { 1165 for chunk in buf.chunks_mut(0xFFFF / W::size().bytes()) {
1164 self.dma 1166 let transfer = unsafe {
1165 .as_mut() 1167 self.dma
1166 .unwrap() 1168 .as_mut()
1167 .read(T::REGS.dr().as_ptr() as *mut W, buf, Default::default()) 1169 .unwrap()
1168 }; 1170 .read(T::REGS.dr().as_ptr() as *mut W, chunk, Default::default())
1171 };
1169 1172
1170 T::REGS.cr().modify(|w| w.set_dmaen(true)); 1173 T::REGS.cr().modify(|w| w.set_dmaen(true));
1171 1174
1172 transfer.blocking_wait(); 1175 transfer.blocking_wait();
1176 }
1173 1177
1174 finish_dma(T::REGS); 1178 finish_dma(T::REGS);
1175 1179
@@ -1185,21 +1189,24 @@ impl<'d, T: Instance> Xspi<'d, T, Async> {
1185 // Wait for peripheral to be free 1189 // Wait for peripheral to be free
1186 while T::REGS.sr().read().busy() {} 1190 while T::REGS.sr().read().busy() {}
1187 1191
1188 self.configure_command(&transaction, Some(buf.len()))?; 1192 let transfer_size_bytes = buf.len() * W::size().bytes();
1193 self.configure_command(&transaction, Some(transfer_size_bytes))?;
1189 T::REGS 1194 T::REGS
1190 .cr() 1195 .cr()
1191 .modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectWrite.into()))); 1196 .modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectWrite.into())));
1192 1197
1193 let transfer = unsafe { 1198 for chunk in buf.chunks(0xFFFF / W::size().bytes()) {
1194 self.dma 1199 let transfer = unsafe {
1195 .as_mut() 1200 self.dma
1196 .unwrap() 1201 .as_mut()
1197 .write(buf, T::REGS.dr().as_ptr() as *mut W, Default::default()) 1202 .unwrap()
1198 }; 1203 .write(chunk, T::REGS.dr().as_ptr() as *mut W, Default::default())
1204 };
1199 1205
1200 T::REGS.cr().modify(|w| w.set_dmaen(true)); 1206 T::REGS.cr().modify(|w| w.set_dmaen(true));
1201 1207
1202 transfer.blocking_wait(); 1208 transfer.blocking_wait();
1209 }
1203 1210
1204 finish_dma(T::REGS); 1211 finish_dma(T::REGS);
1205 1212
@@ -1215,7 +1222,8 @@ impl<'d, T: Instance> Xspi<'d, T, Async> {
1215 // Wait for peripheral to be free 1222 // Wait for peripheral to be free
1216 while T::REGS.sr().read().busy() {} 1223 while T::REGS.sr().read().busy() {}
1217 1224
1218 self.configure_command(&transaction, Some(buf.len()))?; 1225 let transfer_size_bytes = buf.len() * W::size().bytes();
1226 self.configure_command(&transaction, Some(transfer_size_bytes))?;
1219 1227
1220 let current_address = T::REGS.ar().read().address(); 1228 let current_address = T::REGS.ar().read().address();
1221 let current_instruction = T::REGS.ir().read().instruction(); 1229 let current_instruction = T::REGS.ir().read().instruction();
@@ -1230,16 +1238,18 @@ impl<'d, T: Instance> Xspi<'d, T, Async> {
1230 T::REGS.ar().write(|v| v.set_address(current_address)); 1238 T::REGS.ar().write(|v| v.set_address(current_address));
1231 } 1239 }
1232 1240
1233 let transfer = unsafe { 1241 for chunk in buf.chunks_mut(0xFFFF / W::size().bytes()) {
1234 self.dma 1242 let transfer = unsafe {
1235 .as_mut() 1243 self.dma
1236 .unwrap() 1244 .as_mut()
1237 .read(T::REGS.dr().as_ptr() as *mut W, buf, Default::default()) 1245 .unwrap()
1238 }; 1246 .read(T::REGS.dr().as_ptr() as *mut W, chunk, Default::default())
1247 };
1239 1248
1240 T::REGS.cr().modify(|w| w.set_dmaen(true)); 1249 T::REGS.cr().modify(|w| w.set_dmaen(true));
1241 1250
1242 transfer.await; 1251 transfer.await;
1252 }
1243 1253
1244 finish_dma(T::REGS); 1254 finish_dma(T::REGS);
1245 1255
@@ -1255,21 +1265,25 @@ impl<'d, T: Instance> Xspi<'d, T, Async> {
1255 // Wait for peripheral to be free 1265 // Wait for peripheral to be free
1256 while T::REGS.sr().read().busy() {} 1266 while T::REGS.sr().read().busy() {}
1257 1267
1258 self.configure_command(&transaction, Some(buf.len()))?; 1268 let transfer_size_bytes = buf.len() * W::size().bytes();
1269 self.configure_command(&transaction, Some(transfer_size_bytes))?;
1259 T::REGS 1270 T::REGS
1260 .cr() 1271 .cr()
1261 .modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectWrite.into()))); 1272 .modify(|v| v.set_fmode(Fmode::from_bits(XspiMode::IndirectWrite.into())));
1262 1273
1263 let transfer = unsafe { 1274 // TODO: implement this using a LinkedList DMA to offload the whole transfer off the CPU.
1264 self.dma 1275 for chunk in buf.chunks(0xFFFF / W::size().bytes()) {
1265 .as_mut() 1276 let transfer = unsafe {
1266 .unwrap() 1277 self.dma
1267 .write(buf, T::REGS.dr().as_ptr() as *mut W, Default::default()) 1278 .as_mut()
1268 }; 1279 .unwrap()
1280 .write(chunk, T::REGS.dr().as_ptr() as *mut W, Default::default())
1281 };
1269 1282
1270 T::REGS.cr().modify(|w| w.set_dmaen(true)); 1283 T::REGS.cr().modify(|w| w.set_dmaen(true));
1271 1284
1272 transfer.await; 1285 transfer.await;
1286 }
1273 1287
1274 finish_dma(T::REGS); 1288 finish_dma(T::REGS);
1275 1289