aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Lazarev <[email protected]>2025-03-28 15:54:47 -0700
committerAnton Lazarev <[email protected]>2025-03-31 12:47:41 -0700
commitdc31bfd8295c3626794e0b1b38804af2acc59053 (patch)
tree85a3290398cb513667d1cf5e59ee5f888cd9d6b5
parent0a231505d8225f3f36f39b0be1ded4304fb7ccca (diff)
refactor to reduce code duplication
-rw-r--r--embassy-stm32/src/sdmmc/mod.rs549
-rw-r--r--examples/stm32f4/src/bin/sdmmc.rs2
-rw-r--r--examples/stm32f7/src/bin/sdmmc.rs2
-rw-r--r--examples/stm32h7/src/bin/sdmmc.rs2
-rw-r--r--tests/stm32/src/bin/sdmmc.rs4
5 files changed, 217 insertions, 342 deletions
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs
index a0c3573a9..63868e5ae 100644
--- a/embassy-stm32/src/sdmmc/mod.rs
+++ b/embassy-stm32/src/sdmmc/mod.rs
@@ -1010,6 +1010,37 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1010 Self::stop_datapath(); 1010 Self::stop_datapath();
1011 } 1011 }
1012 1012
1013 /// Wait for a previously started datapath transfer to complete from an interrupt.
1014 #[inline]
1015 async fn complete_datapath_transfer() -> Result<(), Error> {
1016 let regs = T::regs();
1017
1018 let res = poll_fn(|cx| {
1019 T::state().register(cx.waker());
1020 let status = regs.star().read();
1021
1022 if status.dcrcfail() {
1023 return Poll::Ready(Err(Error::Crc));
1024 }
1025 if status.dtimeout() {
1026 return Poll::Ready(Err(Error::Timeout));
1027 }
1028 #[cfg(sdmmc_v1)]
1029 if status.stbiterr() {
1030 return Poll::Ready(Err(Error::StBitErr));
1031 }
1032 if status.dataend() {
1033 return Poll::Ready(Ok(()));
1034 }
1035 Poll::Pending
1036 })
1037 .await;
1038
1039 Self::clear_interrupt_flags();
1040
1041 res
1042 }
1043
1013 /// Read a data block. 1044 /// Read a data block.
1014 #[inline] 1045 #[inline]
1015 pub async fn read_block(&mut self, block_idx: u32, buffer: &mut DataBlock) -> Result<(), Error> { 1046 pub async fn read_block(&mut self, block_idx: u32, buffer: &mut DataBlock) -> Result<(), Error> {
@@ -1026,7 +1057,6 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1026 }; 1057 };
1027 Self::cmd(common_cmd::set_block_length(512), false)?; // CMD16 1058 Self::cmd(common_cmd::set_block_length(512), false)?; // CMD16
1028 1059
1029 let regs = T::regs();
1030 let on_drop = OnDrop::new(|| Self::on_drop()); 1060 let on_drop = OnDrop::new(|| Self::on_drop());
1031 1061
1032 let transfer = Self::prepare_datapath_read( 1062 let transfer = Self::prepare_datapath_read(
@@ -1040,27 +1070,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1040 InterruptHandler::<T>::data_interrupts(true); 1070 InterruptHandler::<T>::data_interrupts(true);
1041 Self::cmd(common_cmd::read_single_block(address), true)?; 1071 Self::cmd(common_cmd::read_single_block(address), true)?;
1042 1072
1043 let res = poll_fn(|cx| { 1073 let res = Self::complete_datapath_transfer().await;
1044 T::state().register(cx.waker());
1045 let status = regs.star().read();
1046
1047 if status.dcrcfail() {
1048 return Poll::Ready(Err(Error::Crc));
1049 }
1050 if status.dtimeout() {
1051 return Poll::Ready(Err(Error::Timeout));
1052 }
1053 #[cfg(sdmmc_v1)]
1054 if status.stbiterr() {
1055 return Poll::Ready(Err(Error::StBitErr));
1056 }
1057 if status.dataend() {
1058 return Poll::Ready(Ok(()));
1059 }
1060 Poll::Pending
1061 })
1062 .await;
1063 Self::clear_interrupt_flags();
1064 1074
1065 if res.is_ok() { 1075 if res.is_ok() {
1066 on_drop.defuse(); 1076 on_drop.defuse();
@@ -1085,7 +1095,6 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1085 }; 1095 };
1086 Self::cmd(common_cmd::set_block_length(512), false)?; // CMD16 1096 Self::cmd(common_cmd::set_block_length(512), false)?; // CMD16
1087 1097
1088 let regs = T::regs();
1089 let on_drop = OnDrop::new(|| Self::on_drop()); 1098 let on_drop = OnDrop::new(|| Self::on_drop());
1090 1099
1091 // sdmmc_v1 uses different cmd/dma order than v2, but only for writes 1100 // sdmmc_v1 uses different cmd/dma order than v2, but only for writes
@@ -1098,27 +1107,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1098 #[cfg(sdmmc_v2)] 1107 #[cfg(sdmmc_v2)]
1099 Self::cmd(common_cmd::write_single_block(address), true)?; 1108 Self::cmd(common_cmd::write_single_block(address), true)?;
1100 1109
1101 let res = poll_fn(|cx| { 1110 let res = Self::complete_datapath_transfer().await;
1102 T::state().register(cx.waker());
1103 let status = regs.star().read();
1104
1105 if status.dcrcfail() {
1106 return Poll::Ready(Err(Error::Crc));
1107 }
1108 if status.dtimeout() {
1109 return Poll::Ready(Err(Error::Timeout));
1110 }
1111 #[cfg(sdmmc_v1)]
1112 if status.stbiterr() {
1113 return Poll::Ready(Err(Error::StBitErr));
1114 }
1115 if status.dataend() {
1116 return Poll::Ready(Ok(()));
1117 }
1118 Poll::Pending
1119 })
1120 .await;
1121 Self::clear_interrupt_flags();
1122 1111
1123 match res { 1112 match res {
1124 Ok(_) => { 1113 Ok(_) => {
@@ -1151,8 +1140,8 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1151 /// 1140 ///
1152 /// # Errors 1141 /// # Errors
1153 /// 1142 ///
1154 /// Returns Error::NoCard if [`init_card`](#method.init_card) 1143 /// Returns Error::NoCard if [`init_sd_card`](#method.init_sd_card) or
1155 /// has not previously succeeded 1144 /// [`init_emmc`](#method.init_emmc) has not previously succeeded
1156 #[inline] 1145 #[inline]
1157 pub fn card(&self) -> Result<&SdmmcPeripheral, Error> { 1146 pub fn card(&self) -> Result<&SdmmcPeripheral, Error> {
1158 self.card.as_ref().ok_or(Error::NoCard) 1147 self.card.as_ref().ok_or(Error::NoCard)
@@ -1170,22 +1159,20 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1170 pub fn set_cmd_block(&mut self, cmd_block: &'d mut CmdBlock) { 1159 pub fn set_cmd_block(&mut self, cmd_block: &'d mut CmdBlock) {
1171 self.cmd_block = Some(cmd_block) 1160 self.cmd_block = Some(cmd_block)
1172 } 1161 }
1173}
1174
1175/// SD only
1176impl<'d, T: Instance> Sdmmc<'d, T> {
1177 /// Initializes card (if present) and sets the bus at the specified frequency.
1178 pub async fn init_card(&mut self, freq: Hertz) -> Result<(), Error> {
1179 if self.d7.is_some() {
1180 return Err(Error::BusWidth);
1181 }
1182 1162
1163 async fn init_internal(&mut self, freq: Hertz, mut card: SdmmcPeripheral) -> Result<(), Error> {
1183 let regs = T::regs(); 1164 let regs = T::regs();
1184 let ker_ck = T::frequency(); 1165 let ker_ck = T::frequency();
1185 1166
1186 let bus_width = match self.d3.is_some() { 1167 let bus_width = match (self.d3.is_some(), self.d7.is_some()) {
1187 true => BusWidth::Four, 1168 (true, true) => {
1188 false => BusWidth::One, 1169 if matches!(card, SdmmcPeripheral::SdCard(_)) {
1170 return Err(Error::BusWidth);
1171 }
1172 BusWidth::Eight
1173 }
1174 (true, false) => BusWidth::Four,
1175 _ => BusWidth::One,
1189 }; 1176 };
1190 1177
1191 // While the SD/SDIO card or eMMC is in identification mode, 1178 // While the SD/SDIO card or eMMC is in identification mode,
@@ -1206,47 +1193,75 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1206 regs.power().modify(|w| w.set_pwrctrl(PowerCtrl::On as u8)); 1193 regs.power().modify(|w| w.set_pwrctrl(PowerCtrl::On as u8));
1207 Self::cmd(common_cmd::idle(), false)?; 1194 Self::cmd(common_cmd::idle(), false)?;
1208 1195
1209 // Check if cards supports CMD8 (with pattern) 1196 match card {
1210 Self::cmd(sd_cmd::send_if_cond(1, 0xAA), false)?; 1197 SdmmcPeripheral::SdCard(ref mut card) => {
1211 let cic = CIC::from(regs.respr(0).read().cardstatus()); 1198 // Check if cards supports CMD8 (with pattern)
1212 1199 Self::cmd(sd_cmd::send_if_cond(1, 0xAA), false)?;
1213 if cic.pattern() != 0xAA { 1200 let cic = CIC::from(regs.respr(0).read().cardstatus());
1214 return Err(Error::UnsupportedCardVersion);
1215 }
1216 1201
1217 if cic.voltage_accepted() & 1 == 0 { 1202 if cic.pattern() != 0xAA {
1218 return Err(Error::UnsupportedVoltage); 1203 return Err(Error::UnsupportedCardVersion);
1219 } 1204 }
1220 1205
1221 let mut card = Card::default(); 1206 if cic.voltage_accepted() & 1 == 0 {
1207 return Err(Error::UnsupportedVoltage);
1208 }
1222 1209
1223 let ocr = loop { 1210 let ocr = loop {
1224 // Signal that next command is a app command 1211 // Signal that next command is a app command
1225 Self::cmd(common_cmd::app_cmd(0), false)?; // CMD55 1212 Self::cmd(common_cmd::app_cmd(0), false)?; // CMD55
1213
1214 // 3.2-3.3V
1215 let voltage_window = 1 << 5;
1216 // Initialize card
1217 match Self::cmd(sd_cmd::sd_send_op_cond(true, false, true, voltage_window), false) {
1218 // ACMD41
1219 Ok(_) => (),
1220 Err(Error::Crc) => (),
1221 Err(err) => return Err(err),
1222 }
1223 let ocr: OCR<SD> = regs.respr(0).read().cardstatus().into();
1224 if !ocr.is_busy() {
1225 // Power up done
1226 break ocr;
1227 }
1228 };
1226 1229
1227 // 3.2-3.3V 1230 if ocr.high_capacity() {
1228 let voltage_window = 1 << 5; 1231 // Card is SDHC or SDXC or SDUC
1229 // Initialize card 1232 card.card_type = CardCapacity::HighCapacity;
1230 match Self::cmd(sd_cmd::sd_send_op_cond(true, false, true, voltage_window), false) { 1233 } else {
1231 // ACMD41 1234 card.card_type = CardCapacity::StandardCapacity;
1232 Ok(_) => (), 1235 }
1233 Err(Error::Crc) => (), 1236 card.ocr = ocr;
1234 Err(err) => return Err(err),
1235 } 1237 }
1236 let ocr: OCR<SD> = regs.respr(0).read().cardstatus().into(); 1238 SdmmcPeripheral::Emmc(ref mut emmc) => {
1237 if !ocr.is_busy() { 1239 let ocr = loop {
1238 // Power up done 1240 let high_voltage = 0b0 << 7;
1239 break ocr; 1241 let access_mode = 0b10 << 29;
1242 let op_cond = high_voltage | access_mode | 0b1_1111_1111 << 15;
1243 // Initialize card
1244 match Self::cmd(emmc_cmd::send_op_cond(op_cond), false) {
1245 Ok(_) => (),
1246 Err(Error::Crc) => (),
1247 Err(err) => return Err(err),
1248 }
1249 let ocr: OCR<EMMC> = regs.respr(0).read().cardstatus().into();
1250 if !ocr.is_busy() {
1251 // Power up done
1252 break ocr;
1253 }
1254 };
1255
1256 emmc.capacity = if ocr.access_mode() == 0b10 {
1257 // Card is SDHC or SDXC or SDUC
1258 CardCapacity::HighCapacity
1259 } else {
1260 CardCapacity::StandardCapacity
1261 };
1262 emmc.ocr = ocr;
1240 } 1263 }
1241 };
1242
1243 if ocr.high_capacity() {
1244 // Card is SDHC or SDXC or SDUC
1245 card.card_type = CardCapacity::HighCapacity;
1246 } else {
1247 card.card_type = CardCapacity::StandardCapacity;
1248 } 1264 }
1249 card.ocr = ocr;
1250 1265
1251 Self::cmd(common_cmd::all_send_cid(), false)?; // CMD2 1266 Self::cmd(common_cmd::all_send_cid(), false)?; // CMD2
1252 let cid0 = regs.respr(0).read().cardstatus() as u128; 1267 let cid0 = regs.respr(0).read().cardstatus() as u128;
@@ -1254,79 +1269,139 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1254 let cid2 = regs.respr(2).read().cardstatus() as u128; 1269 let cid2 = regs.respr(2).read().cardstatus() as u128;
1255 let cid3 = regs.respr(3).read().cardstatus() as u128; 1270 let cid3 = regs.respr(3).read().cardstatus() as u128;
1256 let cid = (cid0 << 96) | (cid1 << 64) | (cid2 << 32) | (cid3); 1271 let cid = (cid0 << 96) | (cid1 << 64) | (cid2 << 32) | (cid3);
1257 card.cid = cid.into();
1258 1272
1259 Self::cmd(sd_cmd::send_relative_address(), false)?; 1273 match card {
1260 let rca = RCA::<SD>::from(regs.respr(0).read().cardstatus()); 1274 SdmmcPeripheral::SdCard(ref mut card) => {
1261 card.rca = rca.address(); 1275 card.cid = cid.into();
1276
1277 Self::cmd(sd_cmd::send_relative_address(), false)?;
1278 let rca = RCA::<SD>::from(regs.respr(0).read().cardstatus());
1279 card.rca = rca.address();
1280 }
1281 SdmmcPeripheral::Emmc(ref mut emmc) => {
1282 emmc.cid = cid.into();
1283
1284 emmc.rca = 1u16.into();
1285 Self::cmd(emmc_cmd::assign_relative_address(emmc.rca), false)?;
1286 }
1287 }
1262 1288
1263 Self::cmd(common_cmd::send_csd(card.rca), false)?; 1289 Self::cmd(common_cmd::send_csd(card.get_address()), false)?;
1264 let csd0 = regs.respr(0).read().cardstatus() as u128; 1290 let csd0 = regs.respr(0).read().cardstatus() as u128;
1265 let csd1 = regs.respr(1).read().cardstatus() as u128; 1291 let csd1 = regs.respr(1).read().cardstatus() as u128;
1266 let csd2 = regs.respr(2).read().cardstatus() as u128; 1292 let csd2 = regs.respr(2).read().cardstatus() as u128;
1267 let csd3 = regs.respr(3).read().cardstatus() as u128; 1293 let csd3 = regs.respr(3).read().cardstatus() as u128;
1268 let csd = (csd0 << 96) | (csd1 << 64) | (csd2 << 32) | (csd3); 1294 let csd = (csd0 << 96) | (csd1 << 64) | (csd2 << 32) | (csd3);
1269 card.csd = csd.into();
1270 1295
1271 self.select_card(Some(card.rca))?; 1296 self.select_card(Some(card.get_address()))?;
1297
1298 let bus_width = match card {
1299 SdmmcPeripheral::SdCard(ref mut card) => {
1300 card.csd = csd.into();
1301
1302 self.get_scr(card).await?;
1272 1303
1273 self.get_scr(&mut card).await?; 1304 if !card.scr.bus_width_four() {
1305 BusWidth::One
1306 } else {
1307 BusWidth::Four
1308 }
1309 }
1310 SdmmcPeripheral::Emmc(ref mut emmc) => {
1311 emmc.csd = csd.into();
1312
1313 bus_width
1314 }
1315 };
1274 1316
1275 // Set bus width 1317 // Set bus width
1276 let (width, acmd_arg) = match bus_width { 1318 let widbus = match bus_width {
1277 BusWidth::Eight => unimplemented!(), 1319 BusWidth::Eight => 2,
1278 BusWidth::Four if card.scr.bus_width_four() => (BusWidth::Four, 2), 1320 BusWidth::Four => 1,
1279 _ => (BusWidth::One, 0), 1321 BusWidth::One => 0,
1322 _ => unreachable!(),
1280 }; 1323 };
1281 Self::cmd(common_cmd::app_cmd(card.rca), false)?; 1324
1282 Self::cmd(sd_cmd::cmd6(acmd_arg), false)?; 1325 match card {
1326 SdmmcPeripheral::SdCard(ref mut card) => {
1327 let acmd_arg = match bus_width {
1328 BusWidth::Four if card.scr.bus_width_four() => 2,
1329 _ => 0,
1330 };
1331 Self::cmd(common_cmd::app_cmd(card.rca), false)?;
1332 Self::cmd(sd_cmd::cmd6(acmd_arg), false)?;
1333 }
1334 SdmmcPeripheral::Emmc(_) => {
1335 // Write bus width to ExtCSD byte 183
1336 Self::cmd(
1337 emmc_cmd::modify_ext_csd(emmc_cmd::AccessMode::WriteByte, 183, widbus),
1338 false,
1339 )?;
1340
1341 // Wait for ready after R1b response
1342 loop {
1343 let status = self.read_status::<EMMC>(&card)?;
1344
1345 if status.ready_for_data() {
1346 break;
1347 }
1348 }
1349 }
1350 }
1283 1351
1284 // CPSMACT and DPSMACT must be 0 to set WIDBUS 1352 // CPSMACT and DPSMACT must be 0 to set WIDBUS
1285 Self::wait_idle(); 1353 Self::wait_idle();
1286 1354
1287 regs.clkcr().modify(|w| { 1355 regs.clkcr().modify(|w| w.set_widbus(widbus));
1288 w.set_widbus(match width {
1289 BusWidth::One => 0,
1290 BusWidth::Four => 1,
1291 BusWidth::Eight => 2,
1292 _ => panic!("Invalid Bus Width"),
1293 })
1294 });
1295 1356
1296 // Set Clock 1357 // Set Clock
1297 if freq.0 <= 25_000_000 { 1358 if freq.0 <= 25_000_000 {
1298 // Final clock frequency 1359 // Final clock frequency
1299 self.clkcr_set_clkdiv(freq.0, width)?; 1360 self.clkcr_set_clkdiv(freq.0, bus_width)?;
1300 } else { 1361 } else {
1301 // Switch to max clock for SDR12 1362 // Switch to max clock for SDR12
1302 self.clkcr_set_clkdiv(25_000_000, width)?; 1363 self.clkcr_set_clkdiv(25_000_000, bus_width)?;
1303 } 1364 }
1304 1365
1305 self.card = Some(SdmmcPeripheral::SdCard(card)); 1366 self.card = Some(card);
1306 1367
1307 // Read status 1368 match card {
1308 self.read_sd_status().await?; 1369 SdmmcPeripheral::SdCard(_) => {
1370 // Read status
1371 self.read_sd_status().await?;
1309 1372
1310 if freq.0 > 25_000_000 { 1373 if freq.0 > 25_000_000 {
1311 // Switch to SDR25 1374 // Switch to SDR25
1312 self.signalling = self.switch_signalling_mode(Signalling::SDR25).await?; 1375 self.signalling = self.switch_signalling_mode(Signalling::SDR25).await?;
1313 1376
1314 if self.signalling == Signalling::SDR25 { 1377 if self.signalling == Signalling::SDR25 {
1315 // Set final clock frequency 1378 // Set final clock frequency
1316 self.clkcr_set_clkdiv(freq.0, width)?; 1379 self.clkcr_set_clkdiv(freq.0, bus_width)?;
1317 1380
1318 if self.read_status::<SD>(self.card.as_ref().unwrap())?.state() != CurrentState::Transfer { 1381 if self.read_status::<SD>(self.card.as_ref().unwrap())?.state() != CurrentState::Transfer {
1319 return Err(Error::SignalingSwitchFailed); 1382 return Err(Error::SignalingSwitchFailed);
1383 }
1384 }
1320 } 1385 }
1386
1387 // Read status after signalling change
1388 self.read_sd_status().await?;
1389 }
1390 SdmmcPeripheral::Emmc(_) => {
1391 self.read_ext_csd().await?;
1321 } 1392 }
1322 } 1393 }
1323 1394
1324 // Read status after signalling change
1325 self.read_sd_status().await?;
1326
1327 Ok(()) 1395 Ok(())
1328 } 1396 }
1329 1397
1398 /// Initializes card (if present) and sets the bus at the specified frequency.
1399 ///
1400 /// SD only.
1401 pub async fn init_sd_card(&mut self, freq: Hertz) -> Result<(), Error> {
1402 self.init_internal(freq, SdmmcPeripheral::SdCard(Card::default())).await
1403 }
1404
1330 /// Switch mode using CMD6. 1405 /// Switch mode using CMD6.
1331 /// 1406 ///
1332 /// Attempt to set a new signalling mode. The selected 1407 /// Attempt to set a new signalling mode. The selected
@@ -1355,7 +1430,6 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1355 }; 1430 };
1356 1431
1357 // Arm `OnDrop` after the buffer, so it will be dropped first 1432 // Arm `OnDrop` after the buffer, so it will be dropped first
1358 let regs = T::regs();
1359 let on_drop = OnDrop::new(|| Self::on_drop()); 1433 let on_drop = OnDrop::new(|| Self::on_drop());
1360 1434
1361 let transfer = Self::prepare_datapath_read( 1435 let transfer = Self::prepare_datapath_read(
@@ -1369,27 +1443,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1369 InterruptHandler::<T>::data_interrupts(true); 1443 InterruptHandler::<T>::data_interrupts(true);
1370 Self::cmd(sd_cmd::cmd6(set_function), true)?; // CMD6 1444 Self::cmd(sd_cmd::cmd6(set_function), true)?; // CMD6
1371 1445
1372 let res = poll_fn(|cx| { 1446 let res = Self::complete_datapath_transfer().await;
1373 T::state().register(cx.waker());
1374 let status = regs.star().read();
1375
1376 if status.dcrcfail() {
1377 return Poll::Ready(Err(Error::Crc));
1378 }
1379 if status.dtimeout() {
1380 return Poll::Ready(Err(Error::Timeout));
1381 }
1382 #[cfg(sdmmc_v1)]
1383 if status.stbiterr() {
1384 return Poll::Ready(Err(Error::StBitErr));
1385 }
1386 if status.dataend() {
1387 return Poll::Ready(Ok(()));
1388 }
1389 Poll::Pending
1390 })
1391 .await;
1392 Self::clear_interrupt_flags();
1393 1447
1394 // Host is allowed to use the new functions at least 8 1448 // Host is allowed to use the new functions at least 8
1395 // clocks after the end of the switch command 1449 // clocks after the end of the switch command
@@ -1436,7 +1490,6 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1436 let scr = &mut cmd_block.0[..2]; 1490 let scr = &mut cmd_block.0[..2];
1437 1491
1438 // Arm `OnDrop` after the buffer, so it will be dropped first 1492 // Arm `OnDrop` after the buffer, so it will be dropped first
1439 let regs = T::regs();
1440 let on_drop = OnDrop::new(|| Self::on_drop()); 1493 let on_drop = OnDrop::new(|| Self::on_drop());
1441 1494
1442 let transfer = Self::prepare_datapath_read( 1495 let transfer = Self::prepare_datapath_read(
@@ -1450,27 +1503,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1450 InterruptHandler::<T>::data_interrupts(true); 1503 InterruptHandler::<T>::data_interrupts(true);
1451 Self::cmd(sd_cmd::send_scr(), true)?; 1504 Self::cmd(sd_cmd::send_scr(), true)?;
1452 1505
1453 let res = poll_fn(|cx| { 1506 let res = Self::complete_datapath_transfer().await;
1454 T::state().register(cx.waker());
1455 let status = regs.star().read();
1456
1457 if status.dcrcfail() {
1458 return Poll::Ready(Err(Error::Crc));
1459 }
1460 if status.dtimeout() {
1461 return Poll::Ready(Err(Error::Timeout));
1462 }
1463 #[cfg(sdmmc_v1)]
1464 if status.stbiterr() {
1465 return Poll::Ready(Err(Error::StBitErr));
1466 }
1467 if status.dataend() {
1468 return Poll::Ready(Ok(()));
1469 }
1470 Poll::Pending
1471 })
1472 .await;
1473 Self::clear_interrupt_flags();
1474 1507
1475 if res.is_ok() { 1508 if res.is_ok() {
1476 on_drop.defuse(); 1509 on_drop.defuse();
@@ -1503,7 +1536,6 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1503 let status = cmd_block; 1536 let status = cmd_block;
1504 1537
1505 // Arm `OnDrop` after the buffer, so it will be dropped first 1538 // Arm `OnDrop` after the buffer, so it will be dropped first
1506 let regs = T::regs();
1507 let on_drop = OnDrop::new(|| Self::on_drop()); 1539 let on_drop = OnDrop::new(|| Self::on_drop());
1508 1540
1509 let transfer = Self::prepare_datapath_read( 1541 let transfer = Self::prepare_datapath_read(
@@ -1517,27 +1549,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1517 InterruptHandler::<T>::data_interrupts(true); 1549 InterruptHandler::<T>::data_interrupts(true);
1518 Self::cmd(sd_cmd::sd_status(), true)?; 1550 Self::cmd(sd_cmd::sd_status(), true)?;
1519 1551
1520 let res = poll_fn(|cx| { 1552 let res = Self::complete_datapath_transfer().await;
1521 T::state().register(cx.waker());
1522 let status = regs.star().read();
1523
1524 if status.dcrcfail() {
1525 return Poll::Ready(Err(Error::Crc));
1526 }
1527 if status.dtimeout() {
1528 return Poll::Ready(Err(Error::Timeout));
1529 }
1530 #[cfg(sdmmc_v1)]
1531 if status.stbiterr() {
1532 return Poll::Ready(Err(Error::StBitErr));
1533 }
1534 if status.dataend() {
1535 return Poll::Ready(Ok(()));
1536 }
1537 Poll::Pending
1538 })
1539 .await;
1540 Self::clear_interrupt_flags();
1541 1553
1542 if res.is_ok() { 1554 if res.is_ok() {
1543 on_drop.defuse(); 1555 on_drop.defuse();
@@ -1551,128 +1563,12 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1551 } 1563 }
1552 res 1564 res
1553 } 1565 }
1554}
1555 1566
1556/// eMMC only.
1557impl<'d, T: Instance> Sdmmc<'d, T> {
1558 /// Initializes eMMC and sets the bus at the specified frequency. 1567 /// Initializes eMMC and sets the bus at the specified frequency.
1568 ///
1569 /// eMMC only.
1559 pub async fn init_emmc(&mut self, freq: Hertz) -> Result<(), Error> { 1570 pub async fn init_emmc(&mut self, freq: Hertz) -> Result<(), Error> {
1560 let regs = T::regs(); 1571 self.init_internal(freq, SdmmcPeripheral::Emmc(Emmc::default())).await
1561 let ker_ck = T::frequency();
1562
1563 let bus_width = match (self.d3.is_some(), self.d7.is_some()) {
1564 (true, true) => BusWidth::Eight,
1565 (true, false) => BusWidth::Four,
1566 _ => BusWidth::One,
1567 };
1568
1569 // While the SD/SDIO card or eMMC is in identification mode,
1570 // the SDMMC_CK frequency must be no more than 400 kHz.
1571 let (_bypass, clkdiv, init_clock) = unwrap!(clk_div(ker_ck, SD_INIT_FREQ.0));
1572 self.clock = init_clock;
1573
1574 // CPSMACT and DPSMACT must be 0 to set WIDBUS
1575 Self::wait_idle();
1576
1577 regs.clkcr().modify(|w| {
1578 w.set_widbus(0);
1579 w.set_clkdiv(clkdiv);
1580 #[cfg(sdmmc_v1)]
1581 w.set_bypass(_bypass);
1582 });
1583
1584 regs.power().modify(|w| w.set_pwrctrl(PowerCtrl::On as u8));
1585 Self::cmd(common_cmd::idle(), false)?;
1586
1587 let mut card = Emmc::default();
1588
1589 let ocr = loop {
1590 let high_voltage = 0b0 << 7;
1591 let access_mode = 0b10 << 29;
1592 let op_cond = high_voltage | access_mode | 0b1_1111_1111 << 15;
1593 // Initialize card
1594 match Self::cmd(emmc_cmd::send_op_cond(op_cond), false) {
1595 Ok(_) => (),
1596 Err(Error::Crc) => (),
1597 Err(err) => return Err(err),
1598 }
1599 let ocr: OCR<EMMC> = regs.respr(0).read().cardstatus().into();
1600 if !ocr.is_busy() {
1601 // Power up done
1602 break ocr;
1603 }
1604 };
1605
1606 card.capacity = if ocr.access_mode() == 0b10 {
1607 // Card is SDHC or SDXC or SDUC
1608 CardCapacity::HighCapacity
1609 } else {
1610 CardCapacity::StandardCapacity
1611 };
1612 card.ocr = ocr;
1613
1614 Self::cmd(common_cmd::all_send_cid(), false)?; // CMD2
1615 let cid0 = regs.respr(0).read().cardstatus() as u128;
1616 let cid1 = regs.respr(1).read().cardstatus() as u128;
1617 let cid2 = regs.respr(2).read().cardstatus() as u128;
1618 let cid3 = regs.respr(3).read().cardstatus() as u128;
1619 let cid = (cid0 << 96) | (cid1 << 64) | (cid2 << 32) | (cid3);
1620 card.cid = cid.into();
1621
1622 card.rca = 1u16.into();
1623 Self::cmd(emmc_cmd::assign_relative_address(card.rca), false)?;
1624
1625 Self::cmd(common_cmd::send_csd(card.rca), false)?;
1626 let csd0 = regs.respr(0).read().cardstatus() as u128;
1627 let csd1 = regs.respr(1).read().cardstatus() as u128;
1628 let csd2 = regs.respr(2).read().cardstatus() as u128;
1629 let csd3 = regs.respr(3).read().cardstatus() as u128;
1630 let csd = (csd0 << 96) | (csd1 << 64) | (csd2 << 32) | (csd3);
1631 card.csd = csd.into();
1632
1633 self.select_card(Some(card.rca))?;
1634
1635 // Set bus width
1636 let (width, widbus) = match bus_width {
1637 BusWidth::Eight => (BusWidth::Eight, 2),
1638 BusWidth::Four => (BusWidth::Four, 1),
1639 _ => (BusWidth::One, 0),
1640 };
1641 // Write bus width to ExtCSD byte 183
1642 Self::cmd(
1643 emmc_cmd::modify_ext_csd(emmc_cmd::AccessMode::WriteByte, 183, widbus),
1644 false,
1645 )?;
1646
1647 self.card = Some(SdmmcPeripheral::Emmc(card));
1648
1649 // Wait for ready after R1b response
1650 loop {
1651 let status = self.read_status::<EMMC>(self.card.as_ref().unwrap())?;
1652
1653 if status.ready_for_data() {
1654 break;
1655 }
1656 }
1657
1658 // CPSMACT and DPSMACT must be 0 to set WIDBUS
1659 Self::wait_idle();
1660
1661 regs.clkcr().modify(|w| w.set_widbus(widbus));
1662
1663 // Set Clock
1664 if freq.0 <= 25_000_000 {
1665 // Final clock frequency
1666 self.clkcr_set_clkdiv(freq.0, width)?;
1667 } else {
1668 // Switch to max clock for SDR12
1669 self.clkcr_set_clkdiv(25_000_000, width)?;
1670 }
1671
1672 // Read status
1673 self.read_ext_csd().await?;
1674
1675 Ok(())
1676 } 1572 }
1677 1573
1678 /// Gets the EXT_CSD register. 1574 /// Gets the EXT_CSD register.
@@ -1690,7 +1586,6 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1690 Self::cmd(common_cmd::set_block_length(512), false).unwrap(); // CMD16 1586 Self::cmd(common_cmd::set_block_length(512), false).unwrap(); // CMD16
1691 1587
1692 // Arm `OnDrop` after the buffer, so it will be dropped first 1588 // Arm `OnDrop` after the buffer, so it will be dropped first
1693 let regs = T::regs();
1694 let on_drop = OnDrop::new(|| Self::on_drop()); 1589 let on_drop = OnDrop::new(|| Self::on_drop());
1695 1590
1696 let transfer = Self::prepare_datapath_read( 1591 let transfer = Self::prepare_datapath_read(
@@ -1704,27 +1599,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1704 InterruptHandler::<T>::data_interrupts(true); 1599 InterruptHandler::<T>::data_interrupts(true);
1705 Self::cmd(emmc_cmd::send_ext_csd(), true)?; 1600 Self::cmd(emmc_cmd::send_ext_csd(), true)?;
1706 1601
1707 let res = poll_fn(|cx| { 1602 let res = Self::complete_datapath_transfer().await;
1708 T::state().register(cx.waker());
1709 let status = regs.star().read();
1710
1711 if status.dcrcfail() {
1712 return Poll::Ready(Err(Error::Crc));
1713 }
1714 if status.dtimeout() {
1715 return Poll::Ready(Err(Error::Timeout));
1716 }
1717 #[cfg(sdmmc_v1)]
1718 if status.stbiterr() {
1719 return Poll::Ready(Err(Error::StBitErr));
1720 }
1721 if status.dataend() {
1722 return Poll::Ready(Ok(()));
1723 }
1724 Poll::Pending
1725 })
1726 .await;
1727 Self::clear_interrupt_flags();
1728 1603
1729 if res.is_ok() { 1604 if res.is_ok() {
1730 on_drop.defuse(); 1605 on_drop.defuse();
diff --git a/examples/stm32f4/src/bin/sdmmc.rs b/examples/stm32f4/src/bin/sdmmc.rs
index 66e4e527c..e97b63925 100644
--- a/examples/stm32f4/src/bin/sdmmc.rs
+++ b/examples/stm32f4/src/bin/sdmmc.rs
@@ -59,7 +59,7 @@ async fn main(_spawner: Spawner) {
59 59
60 let mut err = None; 60 let mut err = None;
61 loop { 61 loop {
62 match sdmmc.init_card(mhz(24)).await { 62 match sdmmc.init_sd_card(mhz(24)).await {
63 Ok(_) => break, 63 Ok(_) => break,
64 Err(e) => { 64 Err(e) => {
65 if err != Some(e) { 65 if err != Some(e) {
diff --git a/examples/stm32f7/src/bin/sdmmc.rs b/examples/stm32f7/src/bin/sdmmc.rs
index 6d36ef518..787bef25e 100644
--- a/examples/stm32f7/src/bin/sdmmc.rs
+++ b/examples/stm32f7/src/bin/sdmmc.rs
@@ -54,7 +54,7 @@ async fn main(_spawner: Spawner) {
54 // Should print 400kHz for initialization 54 // Should print 400kHz for initialization
55 info!("Configured clock: {}", sdmmc.clock().0); 55 info!("Configured clock: {}", sdmmc.clock().0);
56 56
57 unwrap!(sdmmc.init_card(mhz(25)).await); 57 unwrap!(sdmmc.init_sd_card(mhz(25)).await);
58 58
59 let card = unwrap!(sdmmc.card()); 59 let card = unwrap!(sdmmc.card());
60 60
diff --git a/examples/stm32h7/src/bin/sdmmc.rs b/examples/stm32h7/src/bin/sdmmc.rs
index abe2d4ba7..96840d8ff 100644
--- a/examples/stm32h7/src/bin/sdmmc.rs
+++ b/examples/stm32h7/src/bin/sdmmc.rs
@@ -53,7 +53,7 @@ async fn main(_spawner: Spawner) -> ! {
53 // Should print 400kHz for initialization 53 // Should print 400kHz for initialization
54 info!("Configured clock: {}", sdmmc.clock().0); 54 info!("Configured clock: {}", sdmmc.clock().0);
55 55
56 unwrap!(sdmmc.init_card(mhz(25)).await); 56 unwrap!(sdmmc.init_sd_card(mhz(25)).await);
57 57
58 let card = unwrap!(sdmmc.card()); 58 let card = unwrap!(sdmmc.card());
59 59
diff --git a/tests/stm32/src/bin/sdmmc.rs b/tests/stm32/src/bin/sdmmc.rs
index 07f17b569..c1ed45588 100644
--- a/tests/stm32/src/bin/sdmmc.rs
+++ b/tests/stm32/src/bin/sdmmc.rs
@@ -54,7 +54,7 @@ async fn main(_spawner: Spawner) {
54 54
55 let mut err = None; 55 let mut err = None;
56 loop { 56 loop {
57 match s.init_card(mhz(24)).await { 57 match s.init_sd_card(mhz(24)).await {
58 Ok(_) => break, 58 Ok(_) => break,
59 Err(e) => { 59 Err(e) => {
60 if err != Some(e) { 60 if err != Some(e) {
@@ -100,7 +100,7 @@ async fn main(_spawner: Spawner) {
100 100
101 let mut err = None; 101 let mut err = None;
102 loop { 102 loop {
103 match s.init_card(mhz(24)).await { 103 match s.init_sd_card(mhz(24)).await {
104 Ok(_) => break, 104 Ok(_) => break,
105 Err(e) => { 105 Err(e) => {
106 if err != Some(e) { 106 if err != Some(e) {