aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/src/sdmmc/mod.rs285
1 files changed, 114 insertions, 171 deletions
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs
index f862d73b1..ad00b4398 100644
--- a/embassy-stm32/src/sdmmc/mod.rs
+++ b/embassy-stm32/src/sdmmc/mod.rs
@@ -164,7 +164,9 @@ pub enum Error {
164 StBitErr, 164 StBitErr,
165} 165}
166 166
167pub trait Addressable: Sized { 167/// Represents either an SD or EMMC card
168pub trait Addressable: Sized + Clone {
169 /// Associated type
168 type Ext; 170 type Ext;
169 171
170 /// Get this peripheral's address on the SDMMC bus 172 /// Get this peripheral's address on the SDMMC bus
@@ -175,41 +177,60 @@ pub trait Addressable: Sized {
175 177
176 /// Size in bytes 178 /// Size in bytes
177 fn size(&self) -> u64; 179 fn size(&self) -> u64;
180}
178 181
179 async fn write_block<'a>( 182/// Storage Device
180 &mut self, 183pub struct StorageDevice<'a, 'b, T: Addressable> {
181 sdmmc: &mut Sdmmc<'a>, 184 info: T,
182 block_idx: u32, 185 /// Inner member
183 buffer: &DataBlock, 186 pub sdmmc: &'a mut Sdmmc<'b>,
184 ) -> Result<(), Error> { 187}
185 sdmmc.write_block(self, block_idx, buffer).await 188
189/// Card Storage Device
190impl<'a, 'b> StorageDevice<'a, 'b, Card> {
191 /// Create a new SD card
192 pub async fn new_sd_card(sdmmc: &'a mut Sdmmc<'b>, cmd_block: &mut CmdBlock, freq: Hertz) -> Result<Self, Error> {
193 let info = sdmmc.init_sd_card(cmd_block, freq).await?;
194
195 Ok(Self { info, sdmmc })
186 } 196 }
197}
187 198
188 async fn write_blocks<'a>( 199/// Emmc storage device
189 &mut self, 200impl<'a, 'b> StorageDevice<'a, 'b, Emmc> {
190 sdmmc: &mut Sdmmc<'a>, 201 /// Create a new EMMC card
191 block_idx: u32, 202 pub async fn new_emmc(sdmmc: &'a mut Sdmmc<'b>, cmd_block: &mut CmdBlock, freq: Hertz) -> Result<Self, Error> {
192 blocks: &[DataBlock], 203 let info = sdmmc.init_emmc(cmd_block, freq).await?;
193 ) -> Result<(), Error> { 204
194 sdmmc.write_blocks(self, block_idx, blocks).await 205 Ok(Self { info, sdmmc })
195 } 206 }
207}
196 208
197 async fn read_block<'a>( 209/// Card or Emmc storage device
198 &mut self, 210impl<'a, 'b, T: Addressable> StorageDevice<'a, 'b, T> {
199 sdmmc: &mut Sdmmc<'a>, 211 /// Write a block
200 block_idx: u32, 212 pub fn card(&self) -> T {
201 buffer: &mut DataBlock, 213 self.info.clone()
202 ) -> Result<(), Error> {
203 sdmmc.read_block(self, block_idx, buffer).await
204 } 214 }
205 215
206 async fn read_blocks<'a>( 216 /// Write a block
207 &mut self, 217 pub async fn write_block(&mut self, block_idx: u32, buffer: &DataBlock) -> Result<(), Error> {
208 sdmmc: &mut Sdmmc<'a>, 218 self.sdmmc.write_block(&mut self.info, block_idx, buffer).await
209 block_idx: u32, 219 }
210 blocks: &mut [DataBlock], 220
211 ) -> Result<(), Error> { 221 /// Write a block
212 sdmmc.read_blocks(self, block_idx, blocks).await 222 pub async fn write_blocks(&mut self, block_idx: u32, blocks: &[DataBlock]) -> Result<(), Error> {
223 self.sdmmc.write_blocks(&mut self.info, block_idx, blocks).await
224 }
225
226 /// Read a block
227 pub async fn read_block(&mut self, block_idx: u32, buffer: &mut DataBlock) -> Result<(), Error> {
228 self.sdmmc.read_block(&mut self.info, block_idx, buffer).await
229 }
230
231 /// Read a block
232 pub async fn read_blocks(&mut self, block_idx: u32, blocks: &mut [DataBlock]) -> Result<(), Error> {
233 self.sdmmc.read_blocks(&mut self.info, block_idx, blocks).await
213 } 234 }
214} 235}
215 236
@@ -240,7 +261,7 @@ impl Card {
240 /// frequency to be > 12.5MHz. 261 /// frequency to be > 12.5MHz.
241 /// 262 ///
242 /// SD only. 263 /// SD only.
243 pub async fn switch_signalling_mode<'a>( 264 async fn switch_signalling_mode<'a>(
244 &mut self, 265 &mut self,
245 sdmmc: &mut Sdmmc<'a>, 266 sdmmc: &mut Sdmmc<'a>,
246 cmd_block: &mut CmdBlock, 267 cmd_block: &mut CmdBlock,
@@ -262,14 +283,7 @@ impl Card {
262 // Arm `OnDrop` after the buffer, so it will be dropped first 283 // Arm `OnDrop` after the buffer, so it will be dropped first
263 let on_drop = OnDrop::new(|| sdmmc.on_drop()); 284 let on_drop = OnDrop::new(|| sdmmc.on_drop());
264 285
265 let transfer = sdmmc.prepare_datapath_read( 286 let transfer = sdmmc.prepare_datapath_read(&sdmmc.config, cmd_block.as_mut(), 64, 6);
266 &sdmmc.config,
267 #[cfg(sdmmc_v1)]
268 &mut self.dma,
269 cmd_block.as_mut(),
270 64,
271 6,
272 );
273 sdmmc.enable_interrupts(); 287 sdmmc.enable_interrupts();
274 sdmmc.cmd(sd_cmd::cmd6(set_function), true)?; // CMD6 288 sdmmc.cmd(sd_cmd::cmd6(set_function), true)?; // CMD6
275 289
@@ -308,7 +322,7 @@ impl Card {
308 /// Reads the SCR register. 322 /// Reads the SCR register.
309 /// 323 ///
310 /// SD only. 324 /// SD only.
311 pub async fn get_scr<'a>(&mut self, sdmmc: &mut Sdmmc<'a>, cmd_block: &mut CmdBlock) -> Result<(), Error> { 325 async fn get_scr<'a>(&mut self, sdmmc: &mut Sdmmc<'a>, cmd_block: &mut CmdBlock) -> Result<(), Error> {
312 // Read the 64-bit SCR register 326 // Read the 64-bit SCR register
313 sdmmc.cmd(common_cmd::set_block_length(8), false)?; // CMD16 327 sdmmc.cmd(common_cmd::set_block_length(8), false)?; // CMD16
314 sdmmc.cmd(common_cmd::app_cmd(self.rca), false)?; 328 sdmmc.cmd(common_cmd::app_cmd(self.rca), false)?;
@@ -318,14 +332,7 @@ impl Card {
318 // Arm `OnDrop` after the buffer, so it will be dropped first 332 // Arm `OnDrop` after the buffer, so it will be dropped first
319 let on_drop = OnDrop::new(|| sdmmc.on_drop()); 333 let on_drop = OnDrop::new(|| sdmmc.on_drop());
320 334
321 let transfer = sdmmc.prepare_datapath_read( 335 let transfer = sdmmc.prepare_datapath_read(&sdmmc.config, scr, 8, 3);
322 &sdmmc.config,
323 #[cfg(sdmmc_v1)]
324 &mut self.dma,
325 scr,
326 8,
327 3,
328 );
329 sdmmc.enable_interrupts(); 336 sdmmc.enable_interrupts();
330 sdmmc.cmd(sd_cmd::send_scr(), true)?; 337 sdmmc.cmd(sd_cmd::send_scr(), true)?;
331 338
@@ -347,7 +354,7 @@ impl Card {
347 /// Reads the SD Status (ACMD13) 354 /// Reads the SD Status (ACMD13)
348 /// 355 ///
349 /// SD only. 356 /// SD only.
350 pub async fn read_sd_status<'a>(&mut self, sdmmc: &mut Sdmmc<'a>, cmd_block: &mut CmdBlock) -> Result<(), Error> { 357 async fn read_sd_status<'a>(&mut self, sdmmc: &mut Sdmmc<'a>, cmd_block: &mut CmdBlock) -> Result<(), Error> {
351 let rca = self.rca; 358 let rca = self.rca;
352 359
353 sdmmc.cmd(common_cmd::set_block_length(64), false)?; // CMD16 360 sdmmc.cmd(common_cmd::set_block_length(64), false)?; // CMD16
@@ -358,14 +365,7 @@ impl Card {
358 // Arm `OnDrop` after the buffer, so it will be dropped first 365 // Arm `OnDrop` after the buffer, so it will be dropped first
359 let on_drop = OnDrop::new(|| sdmmc.on_drop()); 366 let on_drop = OnDrop::new(|| sdmmc.on_drop());
360 367
361 let transfer = sdmmc.prepare_datapath_read( 368 let transfer = sdmmc.prepare_datapath_read(&sdmmc.config, status.as_mut(), 64, 6);
362 &sdmmc.config,
363 #[cfg(sdmmc_v1)]
364 &mut self.dma,
365 status.as_mut(),
366 64,
367 6,
368 );
369 sdmmc.enable_interrupts(); 369 sdmmc.enable_interrupts();
370 sdmmc.cmd(sd_cmd::sd_status(), true)?; 370 sdmmc.cmd(sd_cmd::sd_status(), true)?;
371 371
@@ -434,14 +434,7 @@ impl Emmc {
434 434
435 sdmmc.cmd(common_cmd::set_block_length(512), false).unwrap(); // CMD16 435 sdmmc.cmd(common_cmd::set_block_length(512), false).unwrap(); // CMD16
436 436
437 let transfer = sdmmc.prepare_datapath_read( 437 let transfer = sdmmc.prepare_datapath_read(&sdmmc.config, buffer, 512, 9);
438 &sdmmc.config,
439 #[cfg(sdmmc_v1)]
440 &mut self.dma,
441 buffer,
442 512,
443 9,
444 );
445 sdmmc.enable_interrupts(); 438 sdmmc.enable_interrupts();
446 sdmmc.cmd(emmc_cmd::send_ext_csd(), true)?; 439 sdmmc.cmd(emmc_cmd::send_ext_csd(), true)?;
447 440
@@ -604,42 +597,6 @@ impl SdmmcPeripheral {
604 Self::Emmc(e) => e.rca, 597 Self::Emmc(e) => e.rca,
605 } 598 }
606 } 599 }
607 /// Is this a standard or high capacity peripheral?
608 fn get_capacity(&self) -> CardCapacity {
609 match self {
610 Self::SdCard(c) => c.card_type,
611 Self::Emmc(e) => e.capacity,
612 }
613 }
614 /// Size in bytes
615 fn size(&self) -> u64 {
616 match self {
617 // SDHC / SDXC / SDUC
618 Self::SdCard(c) => u64::from(c.csd.block_count()) * 512,
619 // capacity > 2GB
620 Self::Emmc(e) => u64::from(e.ext_csd.sector_count()) * 512,
621 }
622 }
623
624 /// Get a mutable reference to the SD Card.
625 ///
626 /// Panics if there is another peripheral instead.
627 fn get_sd_card(&mut self) -> &mut Card {
628 match *self {
629 Self::SdCard(ref mut c) => c,
630 _ => unreachable!("SD only"),
631 }
632 }
633
634 /// Get a mutable reference to the eMMC.
635 ///
636 /// Panics if there is another peripheral instead.
637 fn get_emmc(&mut self) -> &mut Emmc {
638 match *self {
639 Self::Emmc(ref mut e) => e,
640 _ => unreachable!("eMMC only"),
641 }
642 }
643} 600}
644 601
645/// Sdmmc device 602/// Sdmmc device
@@ -1037,9 +994,8 @@ impl<'d> Sdmmc<'d> {
1037 /// `buffer` must be valid for the whole transfer and word aligned 994 /// `buffer` must be valid for the whole transfer and word aligned
1038 #[allow(unused_variables)] 995 #[allow(unused_variables)]
1039 fn prepare_datapath_read<'a>( 996 fn prepare_datapath_read<'a>(
1040 &self, 997 &'a self,
1041 config: &Config, 998 config: &Config,
1042 #[cfg(sdmmc_v1)] dma: &'a mut ChannelAndRequest<'d>,
1043 buffer: &'a mut [u32], 999 buffer: &'a mut [u32],
1044 length_bytes: u32, 1000 length_bytes: u32,
1045 block_size: u8, 1001 block_size: u8,
@@ -1053,8 +1009,12 @@ impl<'d> Sdmmc<'d> {
1053 1009
1054 regs.dlenr().write(|w| w.set_datalength(length_bytes)); 1010 regs.dlenr().write(|w| w.set_datalength(length_bytes));
1055 1011
1012 // SAFETY: No other functions use the dma
1056 #[cfg(sdmmc_v1)] 1013 #[cfg(sdmmc_v1)]
1057 let transfer = unsafe { dma.read(regs.fifor().as_ptr() as *mut u32, buffer, DMA_TRANSFER_OPTIONS) }; 1014 let transfer = unsafe {
1015 self.dma
1016 .read_unchecked(regs.fifor().as_ptr() as *mut u32, buffer, DMA_TRANSFER_OPTIONS)
1017 };
1058 #[cfg(sdmmc_v2)] 1018 #[cfg(sdmmc_v2)]
1059 let transfer = { 1019 let transfer = {
1060 regs.idmabase0r().write(|w| w.set_idmabase0(buffer.as_mut_ptr() as u32)); 1020 regs.idmabase0r().write(|w| w.set_idmabase0(buffer.as_mut_ptr() as u32));
@@ -1080,7 +1040,7 @@ impl<'d> Sdmmc<'d> {
1080 /// # Safety 1040 /// # Safety
1081 /// 1041 ///
1082 /// `buffer` must be valid for the whole transfer and word aligned 1042 /// `buffer` must be valid for the whole transfer and word aligned
1083 fn prepare_datapath_write<'a>(&self, buffer: &'a [u32], length_bytes: u32, block_size: u8) -> Transfer<'a> { 1043 fn prepare_datapath_write<'a>(&'a self, buffer: &'a [u32], length_bytes: u32, block_size: u8) -> Transfer<'a> {
1084 assert!(block_size <= 14, "Block size up to 2^14 bytes"); 1044 assert!(block_size <= 14, "Block size up to 2^14 bytes");
1085 let regs = self.info.regs; 1045 let regs = self.info.regs;
1086 1046
@@ -1090,10 +1050,11 @@ impl<'d> Sdmmc<'d> {
1090 1050
1091 regs.dlenr().write(|w| w.set_datalength(length_bytes)); 1051 regs.dlenr().write(|w| w.set_datalength(length_bytes));
1092 1052
1053 // SAFETY: No other functions use the dma
1093 #[cfg(sdmmc_v1)] 1054 #[cfg(sdmmc_v1)]
1094 let transfer = unsafe { 1055 let transfer = unsafe {
1095 self.dma 1056 self.dma
1096 .write(buffer, regs.fifor().as_ptr() as *mut u32, DMA_TRANSFER_OPTIONS) 1057 .write_unchecked(buffer, regs.fifor().as_ptr() as *mut u32, DMA_TRANSFER_OPTIONS)
1097 }; 1058 };
1098 #[cfg(sdmmc_v2)] 1059 #[cfg(sdmmc_v2)]
1099 let transfer = { 1060 let transfer = {
@@ -1374,14 +1335,7 @@ impl<'d> Sdmmc<'d> {
1374 1335
1375 let on_drop = OnDrop::new(|| self.on_drop()); 1336 let on_drop = OnDrop::new(|| self.on_drop());
1376 1337
1377 let transfer = self.prepare_datapath_read( 1338 let transfer = self.prepare_datapath_read(&self.config, buffer, 512, 9);
1378 &self.config,
1379 #[cfg(sdmmc_v1)]
1380 &mut self.dma,
1381 buffer,
1382 512,
1383 9,
1384 );
1385 self.enable_interrupts(); 1339 self.enable_interrupts();
1386 self.cmd(common_cmd::read_single_block(address), true)?; 1340 self.cmd(common_cmd::read_single_block(address), true)?;
1387 1341
@@ -1423,14 +1377,7 @@ impl<'d> Sdmmc<'d> {
1423 1377
1424 let on_drop = OnDrop::new(|| self.on_drop()); 1378 let on_drop = OnDrop::new(|| self.on_drop());
1425 1379
1426 let transfer = self.prepare_datapath_read( 1380 let transfer = self.prepare_datapath_read(&self.config, buffer, 512 * blocks.len() as u32, 9);
1427 &self.config,
1428 #[cfg(sdmmc_v1)]
1429 &mut self.dma,
1430 buffer,
1431 512 * blocks.len() as u32,
1432 9,
1433 );
1434 self.enable_interrupts(); 1381 self.enable_interrupts();
1435 1382
1436 self.cmd(common_cmd::read_multiple_blocks(address), true)?; 1383 self.cmd(common_cmd::read_multiple_blocks(address), true)?;
@@ -1588,6 +1535,8 @@ impl<'d> Sdmmc<'d> {
1588 freq: Hertz, 1535 freq: Hertz,
1589 card: &mut SdmmcPeripheral, 1536 card: &mut SdmmcPeripheral,
1590 ) -> Result<(), Error> { 1537 ) -> Result<(), Error> {
1538 let _scoped_block_stop = self.info.rcc.block_stop();
1539
1591 let regs = self.info.regs; 1540 let regs = self.info.regs;
1592 1541
1593 let bus_width = match (self.d3.is_some(), self.d7.is_some()) { 1542 let bus_width = match (self.d3.is_some(), self.d7.is_some()) {
@@ -1824,9 +1773,7 @@ impl<'d> Sdmmc<'d> {
1824 /// Initializes card (if present) and sets the bus at the specified frequency. 1773 /// Initializes card (if present) and sets the bus at the specified frequency.
1825 /// 1774 ///
1826 /// SD only. 1775 /// SD only.
1827 pub async fn init_sd_card(&mut self, cmd_block: &mut CmdBlock, freq: Hertz) -> Result<Card, Error> { 1776 async fn init_sd_card(&mut self, cmd_block: &mut CmdBlock, freq: Hertz) -> Result<Card, Error> {
1828 let _scoped_block_stop = self.info.rcc.block_stop();
1829
1830 let mut card = SdmmcPeripheral::SdCard(Card::default()); 1777 let mut card = SdmmcPeripheral::SdCard(Card::default());
1831 self.init_internal(cmd_block, freq, &mut card).await?; 1778 self.init_internal(cmd_block, freq, &mut card).await?;
1832 1779
@@ -1841,9 +1788,7 @@ impl<'d> Sdmmc<'d> {
1841 /// Initializes eMMC and sets the bus at the specified frequency. 1788 /// Initializes eMMC and sets the bus at the specified frequency.
1842 /// 1789 ///
1843 /// eMMC only. 1790 /// eMMC only.
1844 pub async fn init_emmc(&mut self, cmd_block: &mut CmdBlock, freq: Hertz) -> Result<Emmc, Error> { 1791 async fn init_emmc(&mut self, cmd_block: &mut CmdBlock, freq: Hertz) -> Result<Emmc, Error> {
1845 let _scoped_block_stop = self.info.rcc.block_stop();
1846
1847 let mut card = SdmmcPeripheral::Emmc(Emmc::default()); 1792 let mut card = SdmmcPeripheral::Emmc(Emmc::default());
1848 self.init_internal(cmd_block, freq, &mut card).await?; 1793 self.init_internal(cmd_block, freq, &mut card).await?;
1849 1794
@@ -1960,47 +1905,45 @@ foreach_peripheral!(
1960 }; 1905 };
1961); 1906);
1962 1907
1963// impl<'d, A: Addressable> block_device_driver::BlockDevice<512> for Sdmmc<'d>, A { 1908impl<'d, 'e, A: Addressable> block_device_driver::BlockDevice<512> for StorageDevice<'d, 'e, A> {
1964// type Error = Error; 1909 type Error = Error;
1965// type Align = aligned::A4; 1910 type Align = aligned::A4;
1966// 1911
1967// async fn read( 1912 async fn read(
1968// &mut self, 1913 &mut self,
1969// block_address: u32, 1914 block_address: u32,
1970// buf: &mut [aligned::Aligned<Self::Align, [u8; 512]>], 1915 buf: &mut [aligned::Aligned<Self::Align, [u8; 512]>],
1971// ) -> Result<(), Self::Error> { 1916 ) -> Result<(), Self::Error> {
1972// let _scoped_block_stop = self.info.rcc.block_stop(); 1917 // TODO: I think block_address needs to be adjusted by the partition start offset
1973// // TODO: I think block_address needs to be adjusted by the partition start offset 1918 if buf.len() == 1 {
1974// if buf.len() == 1 { 1919 let block = unsafe { &mut *(&mut buf[0] as *mut _ as *mut crate::sdmmc::DataBlock) };
1975// let block = unsafe { &mut *(&mut buf[0] as *mut _ as *mut crate::sdmmc::DataBlock) }; 1920 self.read_block(block_address, block).await?;
1976// self.read_block(block_address, block).await?; 1921 } else {
1977// } else { 1922 let blocks: &mut [DataBlock] =
1978// let blocks: &mut [DataBlock] = 1923 unsafe { core::slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut DataBlock, buf.len()) };
1979// unsafe { core::slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut DataBlock, buf.len()) }; 1924 self.read_blocks(block_address, blocks).await?;
1980// self.read_blocks(block_address, blocks).await?; 1925 }
1981// } 1926 Ok(())
1982// Ok(()) 1927 }
1983// } 1928
1984// 1929 async fn write(
1985// async fn write( 1930 &mut self,
1986// &mut self, 1931 block_address: u32,
1987// block_address: u32, 1932 buf: &[aligned::Aligned<Self::Align, [u8; 512]>],
1988// buf: &[aligned::Aligned<Self::Align, [u8; 512]>], 1933 ) -> Result<(), Self::Error> {
1989// ) -> Result<(), Self::Error> { 1934 // TODO: I think block_address needs to be adjusted by the partition start offset
1990// let _scoped_block_stop = self.info.rcc.block_stop(); 1935 if buf.len() == 1 {
1991// // TODO: I think block_address needs to be adjusted by the partition start offset 1936 let block = unsafe { &*(&buf[0] as *const _ as *const crate::sdmmc::DataBlock) };
1992// if buf.len() == 1 { 1937 self.write_block(block_address, block).await?;
1993// let block = unsafe { &*(&buf[0] as *const _ as *const crate::sdmmc::DataBlock) }; 1938 } else {
1994// self.write_block(block_address, block).await?; 1939 let blocks: &[DataBlock] =
1995// } else { 1940 unsafe { core::slice::from_raw_parts(buf.as_ptr() as *const DataBlock, buf.len()) };
1996// let blocks: &[DataBlock] = 1941 self.write_blocks(block_address, blocks).await?;
1997// unsafe { core::slice::from_raw_parts(buf.as_ptr() as *const DataBlock, buf.len()) }; 1942 }
1998// self.write_blocks(block_address, blocks).await?; 1943 Ok(())
1999// } 1944 }
2000// Ok(()) 1945
2001// } 1946 async fn size(&mut self) -> Result<u64, Self::Error> {
2002// 1947 Ok(self.info.size())
2003// async fn size(&mut self) -> Result<u64, Self::Error> { 1948 }
2004// Ok(self.card()?.size()) 1949}
2005// }
2006// }