diff options
| -rw-r--r-- | embassy-stm32/src/sdmmc/mod.rs | 64 | ||||
| -rw-r--r-- | embassy-stm32/src/sdmmc/sd.rs | 58 | ||||
| -rw-r--r-- | embassy-stm32/src/sdmmc/sdio.rs | 27 |
3 files changed, 97 insertions, 52 deletions
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index 12086cd3a..e716fc348 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs | |||
| @@ -7,6 +7,7 @@ use core::marker::PhantomData; | |||
| 7 | use core::slice; | 7 | use core::slice; |
| 8 | use core::task::Poll; | 8 | use core::task::Poll; |
| 9 | 9 | ||
| 10 | use aligned::{A4, Aligned}; | ||
| 10 | use embassy_hal_internal::{Peri, PeripheralType}; | 11 | use embassy_hal_internal::{Peri, PeripheralType}; |
| 11 | use embassy_sync::waitqueue::AtomicWaker; | 12 | use embassy_sync::waitqueue::AtomicWaker; |
| 12 | use sdio_host::Cmd; | 13 | use sdio_host::Cmd; |
| @@ -139,16 +140,38 @@ impl Default for Signalling { | |||
| 139 | } | 140 | } |
| 140 | } | 141 | } |
| 141 | 142 | ||
| 143 | const fn aligned_mut(x: &mut [u32]) -> &mut Aligned<A4, [u8]> { | ||
| 144 | let len = x.len() * 4; | ||
| 145 | unsafe { core::mem::transmute(slice::from_raw_parts_mut(x.as_mut_ptr() as _, len)) } | ||
| 146 | } | ||
| 147 | |||
| 142 | const fn slice8_mut(x: &mut [u32]) -> &mut [u8] { | 148 | const fn slice8_mut(x: &mut [u32]) -> &mut [u8] { |
| 143 | let len = x.len() * 4; | 149 | let len = x.len() * 4; |
| 144 | unsafe { slice::from_raw_parts_mut(x.as_mut_ptr() as _, len) } | 150 | unsafe { slice::from_raw_parts_mut(x.as_mut_ptr() as _, len) } |
| 145 | } | 151 | } |
| 146 | 152 | ||
| 153 | #[allow(unused)] | ||
| 154 | const fn slice32_mut(x: &mut Aligned<A4, [u8]>) -> &mut [u32] { | ||
| 155 | let len = (size_of_val(x) + 4 - 1) / 4; | ||
| 156 | unsafe { slice::from_raw_parts_mut(x as *mut Aligned<A4, [u8]> as *mut _, len) } | ||
| 157 | } | ||
| 158 | |||
| 159 | const fn aligned_ref(x: &[u32]) -> &Aligned<A4, [u8]> { | ||
| 160 | let len = x.len() * 4; | ||
| 161 | unsafe { core::mem::transmute(slice::from_raw_parts(x.as_ptr() as _, len)) } | ||
| 162 | } | ||
| 163 | |||
| 147 | const fn slice8_ref(x: &[u32]) -> &[u8] { | 164 | const fn slice8_ref(x: &[u32]) -> &[u8] { |
| 148 | let len = x.len() * 4; | 165 | let len = x.len() * 4; |
| 149 | unsafe { slice::from_raw_parts(x.as_ptr() as _, len) } | 166 | unsafe { slice::from_raw_parts(x.as_ptr() as _, len) } |
| 150 | } | 167 | } |
| 151 | 168 | ||
| 169 | #[allow(unused)] | ||
| 170 | const fn slice32_ref(x: &Aligned<A4, [u8]>) -> &[u32] { | ||
| 171 | let len = (size_of_val(x) + 4 - 1) / 4; | ||
| 172 | unsafe { slice::from_raw_parts(x as *const Aligned<A4, [u8]> as *const _, len) } | ||
| 173 | } | ||
| 174 | |||
| 152 | /// Errors | 175 | /// Errors |
| 153 | #[non_exhaustive] | 176 | #[non_exhaustive] |
| 154 | #[derive(Debug, Copy, Clone, PartialEq, Eq)] | 177 | #[derive(Debug, Copy, Clone, PartialEq, Eq)] |
| @@ -187,6 +210,11 @@ enum PowerCtrl { | |||
| 187 | On = 0b11, | 210 | On = 0b11, |
| 188 | } | 211 | } |
| 189 | 212 | ||
| 213 | enum DatapathMode { | ||
| 214 | Block(BlockSize), | ||
| 215 | Byte, | ||
| 216 | } | ||
| 217 | |||
| 190 | fn get_waitresp_val(rlen: ResponseLen) -> u8 { | 218 | fn get_waitresp_val(rlen: ResponseLen) -> u8 { |
| 191 | match rlen { | 219 | match rlen { |
| 192 | common_cmd::ResponseLen::Zero => 0, | 220 | common_cmd::ResponseLen::Zero => 0, |
| @@ -768,12 +796,16 @@ impl<'d> Sdmmc<'d> { | |||
| 768 | #[allow(unused_variables)] | 796 | #[allow(unused_variables)] |
| 769 | fn prepare_datapath_read<'a>( | 797 | fn prepare_datapath_read<'a>( |
| 770 | &'a self, | 798 | &'a self, |
| 771 | buffer: &'a mut [u32], | 799 | buffer: &'a mut Aligned<A4, [u8]>, |
| 772 | block_size: BlockSize, | 800 | mode: DatapathMode, |
| 773 | byte_mode: bool, | ||
| 774 | ) -> WrappedTransfer<'a> { | 801 | ) -> WrappedTransfer<'a> { |
| 775 | let regs = self.info.regs; | 802 | let regs = self.info.regs; |
| 776 | 803 | ||
| 804 | let (byte_mode, block_size) = match mode { | ||
| 805 | DatapathMode::Block(block_size) => (false, block_size as u8), | ||
| 806 | DatapathMode::Byte => (true, 0), | ||
| 807 | }; | ||
| 808 | |||
| 777 | // Command AND Data state machines must be idle | 809 | // Command AND Data state machines must be idle |
| 778 | self.wait_idle(); | 810 | self.wait_idle(); |
| 779 | self.clear_interrupt_flags(); | 811 | self.clear_interrupt_flags(); |
| @@ -783,8 +815,11 @@ impl<'d> Sdmmc<'d> { | |||
| 783 | // SAFETY: No other functions use the dma | 815 | // SAFETY: No other functions use the dma |
| 784 | #[cfg(sdmmc_v1)] | 816 | #[cfg(sdmmc_v1)] |
| 785 | let transfer = unsafe { | 817 | let transfer = unsafe { |
| 786 | self.dma | 818 | self.dma.read_unchecked( |
| 787 | .read_unchecked(regs.fifor().as_ptr() as *mut u32, buffer, DMA_TRANSFER_OPTIONS) | 819 | regs.fifor().as_ptr() as *mut u32, |
| 820 | slice32_mut(buffer), | ||
| 821 | DMA_TRANSFER_OPTIONS, | ||
| 822 | ) | ||
| 788 | }; | 823 | }; |
| 789 | #[cfg(sdmmc_v2)] | 824 | #[cfg(sdmmc_v2)] |
| 790 | let transfer = { | 825 | let transfer = { |
| @@ -817,14 +852,14 @@ impl<'d> Sdmmc<'d> { | |||
| 817 | /// # Safety | 852 | /// # Safety |
| 818 | /// | 853 | /// |
| 819 | /// `buffer` must be valid for the whole transfer and word aligned | 854 | /// `buffer` must be valid for the whole transfer and word aligned |
| 820 | fn prepare_datapath_write<'a>( | 855 | fn prepare_datapath_write<'a>(&'a self, buffer: &'a Aligned<A4, [u8]>, mode: DatapathMode) -> WrappedTransfer<'a> { |
| 821 | &'a self, | ||
| 822 | buffer: &'a [u32], | ||
| 823 | block_size: BlockSize, | ||
| 824 | byte_mode: bool, | ||
| 825 | ) -> WrappedTransfer<'a> { | ||
| 826 | let regs = self.info.regs; | 856 | let regs = self.info.regs; |
| 827 | 857 | ||
| 858 | let (byte_mode, block_size) = match mode { | ||
| 859 | DatapathMode::Block(block_size) => (false, block_size as u8), | ||
| 860 | DatapathMode::Byte => (true, 0), | ||
| 861 | }; | ||
| 862 | |||
| 828 | // Command AND Data state machines must be idle | 863 | // Command AND Data state machines must be idle |
| 829 | self.wait_idle(); | 864 | self.wait_idle(); |
| 830 | self.clear_interrupt_flags(); | 865 | self.clear_interrupt_flags(); |
| @@ -834,8 +869,11 @@ impl<'d> Sdmmc<'d> { | |||
| 834 | // SAFETY: No other functions use the dma | 869 | // SAFETY: No other functions use the dma |
| 835 | #[cfg(sdmmc_v1)] | 870 | #[cfg(sdmmc_v1)] |
| 836 | let transfer = unsafe { | 871 | let transfer = unsafe { |
| 837 | self.dma | 872 | self.dma.write_unchecked( |
| 838 | .write_unchecked(buffer, regs.fifor().as_ptr() as *mut u32, DMA_TRANSFER_OPTIONS) | 873 | slice32_ref(buffer), |
| 874 | regs.fifor().as_ptr() as *mut u32, | ||
| 875 | DMA_TRANSFER_OPTIONS, | ||
| 876 | ) | ||
| 839 | }; | 877 | }; |
| 840 | #[cfg(sdmmc_v2)] | 878 | #[cfg(sdmmc_v2)] |
| 841 | let transfer = { | 879 | let transfer = { |
diff --git a/embassy-stm32/src/sdmmc/sd.rs b/embassy-stm32/src/sdmmc/sd.rs index 6190226b8..20318bbfa 100644 --- a/embassy-stm32/src/sdmmc/sd.rs +++ b/embassy-stm32/src/sdmmc/sd.rs | |||
| @@ -5,7 +5,10 @@ use sdio_host::emmc::{EMMC, ExtCSD}; | |||
| 5 | use sdio_host::sd::{BusWidth, CIC, CID, CSD, CardCapacity, CardStatus, CurrentState, OCR, RCA, SCR, SD, SDStatus}; | 5 | use sdio_host::sd::{BusWidth, CIC, CID, CSD, CardCapacity, CardStatus, CurrentState, OCR, RCA, SCR, SD, SDStatus}; |
| 6 | use sdio_host::{common_cmd, emmc_cmd, sd_cmd}; | 6 | use sdio_host::{common_cmd, emmc_cmd, sd_cmd}; |
| 7 | 7 | ||
| 8 | use crate::sdmmc::{BlockSize, Error, Sdmmc, Signalling, block_size, bus_width_vals, slice8_mut, slice8_ref}; | 8 | use crate::sdmmc::{ |
| 9 | BlockSize, DatapathMode, Error, Sdmmc, Signalling, aligned_mut, aligned_ref, block_size, bus_width_vals, | ||
| 10 | slice8_mut, slice8_ref, | ||
| 11 | }; | ||
| 9 | use crate::time::{Hertz, mhz}; | 12 | use crate::time::{Hertz, mhz}; |
| 10 | 13 | ||
| 11 | /// Aligned data block for SDMMC transfers. | 14 | /// Aligned data block for SDMMC transfers. |
| @@ -230,10 +233,8 @@ impl<'a, 'b> StorageDevice<'a, 'b, Card> { | |||
| 230 | }; | 233 | }; |
| 231 | 234 | ||
| 232 | let buffer = &mut cmd_block.0[..64 / 4]; | 235 | let buffer = &mut cmd_block.0[..64 / 4]; |
| 233 | 236 | let mode = DatapathMode::Block(block_size(size_of_val(buffer))); | |
| 234 | let transfer = self | 237 | let transfer = self.sdmmc.prepare_datapath_read(aligned_mut(buffer), mode); |
| 235 | .sdmmc | ||
| 236 | .prepare_datapath_read(buffer, block_size(size_of_val(buffer)), false); | ||
| 237 | 238 | ||
| 238 | self.sdmmc.cmd(sd_cmd::cmd6(set_function), true)?; // CMD6 | 239 | self.sdmmc.cmd(sd_cmd::cmd6(set_function), true)?; // CMD6 |
| 239 | 240 | ||
| @@ -272,7 +273,9 @@ impl<'a, 'b> StorageDevice<'a, 'b, Card> { | |||
| 272 | 273 | ||
| 273 | // Arm `OnDrop` after the buffer, so it will be dropped first | 274 | // Arm `OnDrop` after the buffer, so it will be dropped first |
| 274 | 275 | ||
| 275 | let transfer = self.sdmmc.prepare_datapath_read(scr, BlockSize::Size8, false); | 276 | let transfer = self |
| 277 | .sdmmc | ||
| 278 | .prepare_datapath_read(aligned_mut(scr), DatapathMode::Block(BlockSize::Size8)); | ||
| 276 | self.sdmmc.cmd(sd_cmd::send_scr(), true)?; | 279 | self.sdmmc.cmd(sd_cmd::send_scr(), true)?; |
| 277 | 280 | ||
| 278 | self.sdmmc.complete_datapath_transfer(transfer, true).await?; | 281 | self.sdmmc.complete_datapath_transfer(transfer, true).await?; |
| @@ -290,10 +293,9 @@ impl<'a, 'b> StorageDevice<'a, 'b, Card> { | |||
| 290 | self.sdmmc.cmd(common_cmd::app_cmd(rca), false)?; // APP | 293 | self.sdmmc.cmd(common_cmd::app_cmd(rca), false)?; // APP |
| 291 | 294 | ||
| 292 | let buffer = &mut cmd_block.as_mut()[..64 / 4]; | 295 | let buffer = &mut cmd_block.as_mut()[..64 / 4]; |
| 296 | let mode = DatapathMode::Block(block_size(size_of_val(buffer))); | ||
| 293 | 297 | ||
| 294 | let transfer = self | 298 | let transfer = self.sdmmc.prepare_datapath_read(aligned_mut(buffer), mode); |
| 295 | .sdmmc | ||
| 296 | .prepare_datapath_read(buffer, block_size(size_of_val(buffer)), false); | ||
| 297 | self.sdmmc.cmd(sd_cmd::sd_status(), true)?; | 299 | self.sdmmc.cmd(sd_cmd::sd_status(), true)?; |
| 298 | 300 | ||
| 299 | self.sdmmc.complete_datapath_transfer(transfer, true).await?; | 301 | self.sdmmc.complete_datapath_transfer(transfer, true).await?; |
| @@ -398,9 +400,10 @@ impl<'a, 'b> StorageDevice<'a, 'b, Emmc> { | |||
| 398 | .cmd(common_cmd::set_block_length(size_of::<DataBlock>() as u32), false) | 400 | .cmd(common_cmd::set_block_length(size_of::<DataBlock>() as u32), false) |
| 399 | .unwrap(); // CMD16 | 401 | .unwrap(); // CMD16 |
| 400 | 402 | ||
| 401 | let transfer = self | 403 | let transfer = self.sdmmc.prepare_datapath_read( |
| 402 | .sdmmc | 404 | aligned_mut(&mut data_block.0), |
| 403 | .prepare_datapath_read(&mut data_block.0, block_size(size_of::<DataBlock>()), false); | 405 | DatapathMode::Block(block_size(size_of::<DataBlock>())), |
| 406 | ); | ||
| 404 | self.sdmmc.cmd(emmc_cmd::send_ext_csd(), true)?; | 407 | self.sdmmc.cmd(emmc_cmd::send_ext_csd(), true)?; |
| 405 | 408 | ||
| 406 | self.sdmmc.complete_datapath_transfer(transfer, true).await?; | 409 | self.sdmmc.complete_datapath_transfer(transfer, true).await?; |
| @@ -418,7 +421,7 @@ impl<'a, 'b, A: Addressable> StorageDevice<'a, 'b, A> { | |||
| 418 | 421 | ||
| 419 | /// Read a data block. | 422 | /// Read a data block. |
| 420 | #[inline] | 423 | #[inline] |
| 421 | pub async fn read_block(&mut self, block_idx: u32, buffer: &mut DataBlock) -> Result<(), Error> { | 424 | pub async fn read_block(&mut self, block_idx: u32, data_block: &mut DataBlock) -> Result<(), Error> { |
| 422 | let _scoped_block_stop = self.sdmmc.info.rcc.block_stop(); | 425 | let _scoped_block_stop = self.sdmmc.info.rcc.block_stop(); |
| 423 | let card_capacity = self.info.get_capacity(); | 426 | let card_capacity = self.info.get_capacity(); |
| 424 | 427 | ||
| @@ -431,9 +434,10 @@ impl<'a, 'b, A: Addressable> StorageDevice<'a, 'b, A> { | |||
| 431 | self.sdmmc | 434 | self.sdmmc |
| 432 | .cmd(common_cmd::set_block_length(size_of::<DataBlock>() as u32), false)?; // CMD16 | 435 | .cmd(common_cmd::set_block_length(size_of::<DataBlock>() as u32), false)?; // CMD16 |
| 433 | 436 | ||
| 434 | let transfer = self | 437 | let transfer = self.sdmmc.prepare_datapath_read( |
| 435 | .sdmmc | 438 | aligned_mut(&mut data_block.0), |
| 436 | .prepare_datapath_read(&mut buffer.0, block_size(size_of::<DataBlock>()), false); | 439 | DatapathMode::Block(block_size(size_of::<DataBlock>())), |
| 440 | ); | ||
| 437 | self.sdmmc.cmd(common_cmd::read_single_block(address), true)?; | 441 | self.sdmmc.cmd(common_cmd::read_single_block(address), true)?; |
| 438 | 442 | ||
| 439 | self.sdmmc.complete_datapath_transfer(transfer, true).await?; | 443 | self.sdmmc.complete_datapath_transfer(transfer, true).await?; |
| @@ -464,9 +468,10 @@ impl<'a, 'b, A: Addressable> StorageDevice<'a, 'b, A> { | |||
| 464 | self.sdmmc | 468 | self.sdmmc |
| 465 | .cmd(common_cmd::set_block_length(size_of::<DataBlock>() as u32), false)?; // CMD16 | 469 | .cmd(common_cmd::set_block_length(size_of::<DataBlock>() as u32), false)?; // CMD16 |
| 466 | 470 | ||
| 467 | let transfer = self | 471 | let transfer = self.sdmmc.prepare_datapath_read( |
| 468 | .sdmmc | 472 | aligned_mut(buffer), |
| 469 | .prepare_datapath_read(buffer, block_size(size_of::<DataBlock>()), false); | 473 | DatapathMode::Block(block_size(size_of::<DataBlock>())), |
| 474 | ); | ||
| 470 | self.sdmmc.cmd(common_cmd::read_multiple_blocks(address), true)?; | 475 | self.sdmmc.cmd(common_cmd::read_multiple_blocks(address), true)?; |
| 471 | 476 | ||
| 472 | self.sdmmc.complete_datapath_transfer(transfer, false).await?; | 477 | self.sdmmc.complete_datapath_transfer(transfer, false).await?; |
| @@ -497,9 +502,10 @@ impl<'a, 'b, A: Addressable> StorageDevice<'a, 'b, A> { | |||
| 497 | #[cfg(sdmmc_v1)] | 502 | #[cfg(sdmmc_v1)] |
| 498 | self.sdmmc.cmd(common_cmd::write_single_block(address), true)?; | 503 | self.sdmmc.cmd(common_cmd::write_single_block(address), true)?; |
| 499 | 504 | ||
| 500 | let transfer = self | 505 | let transfer = self.sdmmc.prepare_datapath_write( |
| 501 | .sdmmc | 506 | aligned_ref(&buffer.0), |
| 502 | .prepare_datapath_write(&buffer.0, block_size(size_of::<DataBlock>()), false); | 507 | DatapathMode::Block(block_size(size_of::<DataBlock>())), |
| 508 | ); | ||
| 503 | 509 | ||
| 504 | #[cfg(sdmmc_v2)] | 510 | #[cfg(sdmmc_v2)] |
| 505 | self.sdmmc.cmd(common_cmd::write_single_block(address), true)?; | 511 | self.sdmmc.cmd(common_cmd::write_single_block(address), true)?; |
| @@ -548,10 +554,10 @@ impl<'a, 'b, A: Addressable> StorageDevice<'a, 'b, A> { | |||
| 548 | self.sdmmc.cmd(common_cmd::write_multiple_blocks(address), true)?; // CMD25 | 554 | self.sdmmc.cmd(common_cmd::write_multiple_blocks(address), true)?; // CMD25 |
| 549 | 555 | ||
| 550 | // Setup write command | 556 | // Setup write command |
| 551 | let transfer = self | 557 | let transfer = self.sdmmc.prepare_datapath_write( |
| 552 | .sdmmc | 558 | aligned_ref(buffer), |
| 553 | .prepare_datapath_write(buffer, block_size(size_of::<DataBlock>()), false); | 559 | DatapathMode::Block(block_size(size_of::<DataBlock>())), |
| 554 | 560 | ); | |
| 555 | #[cfg(sdmmc_v2)] | 561 | #[cfg(sdmmc_v2)] |
| 556 | self.sdmmc.cmd(common_cmd::write_multiple_blocks(address), true)?; // CMD25 | 562 | self.sdmmc.cmd(common_cmd::write_multiple_blocks(address), true)?; // CMD25 |
| 557 | 563 | ||
diff --git a/embassy-stm32/src/sdmmc/sdio.rs b/embassy-stm32/src/sdmmc/sdio.rs index 1412b21fc..e436d68cb 100644 --- a/embassy-stm32/src/sdmmc/sdio.rs +++ b/embassy-stm32/src/sdmmc/sdio.rs | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | use core::ops::{Deref, DerefMut}; | 1 | use core::ops::{Deref, DerefMut}; |
| 2 | 2 | ||
| 3 | use aligned::{A4, Aligned}; | ||
| 3 | use sdio_host::common_cmd::{R1, Rz, cmd}; | 4 | use sdio_host::common_cmd::{R1, Rz, cmd}; |
| 4 | use sdio_host::sd::BusWidth; | 5 | use sdio_host::sd::BusWidth; |
| 5 | use sdio_host::sd_cmd; | 6 | use sdio_host::sd_cmd; |
| 6 | 7 | ||
| 7 | use crate::sdmmc::{Error, Sdmmc, block_size, slice8_mut, slice8_ref}; | 8 | use crate::sdmmc::{DatapathMode, Error, Sdmmc, aligned_mut, aligned_ref, block_size, slice8_mut, slice8_ref}; |
| 8 | use crate::time::Hertz; | 9 | use crate::time::Hertz; |
| 9 | 10 | ||
| 10 | /// Aligned data block for SDMMC transfers. | 11 | /// Aligned data block for SDMMC transfers. |
| @@ -39,7 +40,7 @@ impl DerefMut for DataBlock { | |||
| 39 | /// Storage Device | 40 | /// Storage Device |
| 40 | pub struct SerialDataInterface<'a, 'b> { | 41 | pub struct SerialDataInterface<'a, 'b> { |
| 41 | /// Inner member | 42 | /// Inner member |
| 42 | pub sdmmc: &'a mut Sdmmc<'b>, | 43 | sdmmc: &'a mut Sdmmc<'b>, |
| 43 | } | 44 | } |
| 44 | 45 | ||
| 45 | /// Card Storage Device | 46 | /// Card Storage Device |
| @@ -101,9 +102,10 @@ impl<'a, 'b> SerialDataInterface<'a, 'b> { | |||
| 101 | ) | 102 | ) |
| 102 | }; | 103 | }; |
| 103 | 104 | ||
| 104 | let transfer = self | 105 | let transfer = self.sdmmc.prepare_datapath_read( |
| 105 | .sdmmc | 106 | aligned_mut(buffer), |
| 106 | .prepare_datapath_read(buffer, block_size(size_of::<DataBlock>()), false); | 107 | DatapathMode::Block(block_size(size_of::<DataBlock>())), |
| 108 | ); | ||
| 107 | self.sdmmc.cmd(cmd::<Rz>(53, arg), true)?; | 109 | self.sdmmc.cmd(cmd::<Rz>(53, arg), true)?; |
| 108 | 110 | ||
| 109 | self.sdmmc.complete_datapath_transfer(transfer, false).await?; | 111 | self.sdmmc.complete_datapath_transfer(transfer, false).await?; |
| @@ -113,12 +115,10 @@ impl<'a, 'b> SerialDataInterface<'a, 'b> { | |||
| 113 | } | 115 | } |
| 114 | 116 | ||
| 115 | /// Read in multibyte mode using cmd53 | 117 | /// Read in multibyte mode using cmd53 |
| 116 | pub async fn cmd53_byte_read(&mut self, arg: u32, buffer: &mut [u32]) -> Result<(), Error> { | 118 | pub async fn cmd53_byte_read(&mut self, arg: u32, buffer: &mut Aligned<A4, [u8]>) -> Result<(), Error> { |
| 117 | let _scoped_block_stop = self.sdmmc.info.rcc.block_stop(); | 119 | let _scoped_block_stop = self.sdmmc.info.rcc.block_stop(); |
| 118 | 120 | ||
| 119 | let transfer = self | 121 | let transfer = self.sdmmc.prepare_datapath_read(buffer, DatapathMode::Byte); |
| 120 | .sdmmc | ||
| 121 | .prepare_datapath_read(buffer, block_size(size_of::<DataBlock>()), true); | ||
| 122 | self.sdmmc.cmd(cmd::<Rz>(53, arg), true)?; | 122 | self.sdmmc.cmd(cmd::<Rz>(53, arg), true)?; |
| 123 | 123 | ||
| 124 | self.sdmmc.complete_datapath_transfer(transfer, false).await?; | 124 | self.sdmmc.complete_datapath_transfer(transfer, false).await?; |
| @@ -142,9 +142,10 @@ impl<'a, 'b> SerialDataInterface<'a, 'b> { | |||
| 142 | #[cfg(sdmmc_v1)] | 142 | #[cfg(sdmmc_v1)] |
| 143 | self.sdmmc.cmd(cmd::<Rz>(53, arg), true)?; | 143 | self.sdmmc.cmd(cmd::<Rz>(53, arg), true)?; |
| 144 | 144 | ||
| 145 | let transfer = self | 145 | let transfer = self.sdmmc.prepare_datapath_write( |
| 146 | .sdmmc | 146 | aligned_ref(buffer), |
| 147 | .prepare_datapath_read(buffer, block_size(size_of::<DataBlock>()), false); | 147 | DatapathMode::Block(block_size(size_of::<DataBlock>())), |
| 148 | ); | ||
| 148 | 149 | ||
| 149 | #[cfg(sdmmc_v2)] | 150 | #[cfg(sdmmc_v2)] |
| 150 | self.sdmmc.cmd(cmd::<Rz>(53, arg), true)?; | 151 | self.sdmmc.cmd(cmd::<Rz>(53, arg), true)?; |
| @@ -164,7 +165,7 @@ impl<'a, 'b> SerialDataInterface<'a, 'b> { | |||
| 164 | 165 | ||
| 165 | let transfer = self | 166 | let transfer = self |
| 166 | .sdmmc | 167 | .sdmmc |
| 167 | .prepare_datapath_write(buffer, block_size(size_of::<DataBlock>()), true); | 168 | .prepare_datapath_write(aligned_ref(buffer), DatapathMode::Byte); |
| 168 | 169 | ||
| 169 | #[cfg(sdmmc_v2)] | 170 | #[cfg(sdmmc_v2)] |
| 170 | self.sdmmc.cmd(cmd::<Rz>(53, arg), true)?; | 171 | self.sdmmc.cmd(cmd::<Rz>(53, arg), true)?; |
