aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThales Fragoso <[email protected]>2021-05-13 22:23:05 -0300
committerThales Fragoso <[email protected]>2021-05-14 23:43:11 -0300
commitad720f83df0c4312759443f011f0252c535006d9 (patch)
tree7ce4137702cf23840f3514a8ed2f2e357f599d79
parent359aaa5aeb83cc073c9a1ebc41318e79e00c1669 (diff)
Expose data transfer timeout and implement configuration for BusWidth one
-rw-r--r--embassy-stm32/Cargo.toml3
-rw-r--r--embassy-stm32/src/sdmmc_v2.rs303
2 files changed, 218 insertions, 88 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 4735a34f0..bd06abee1 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -24,12 +24,13 @@ embedded-sdmmc = { git = "https://github.com/thalesfragoso/embedded-sdmmc-rs", b
24regex = "1.4.6" 24regex = "1.4.6"
25 25
26[features] 26[features]
27default = ["stm32h750vb", "defmt-debug", "defmt"] 27default = ["stm32h750vb", "defmt-debug", "defmt", "sdmmc-rs"]
28defmt-trace = [ ] 28defmt-trace = [ ]
29defmt-debug = [ ] 29defmt-debug = [ ]
30defmt-info = [ ] 30defmt-info = [ ]
31defmt-warn = [ ] 31defmt-warn = [ ]
32defmt-error = [ ] 32defmt-error = [ ]
33sdmmc-rs = ["embedded-sdmmc"]
33 34
34# BEGIN GENERATED FEATURES 35# BEGIN GENERATED FEATURES
35stm32f401cb = [ "_dma", "_dma_v2", "_exti", "_exti_v1", "_gpio", "_gpio_v2", "_spi", "_spi_v1", "_stm32f4", "_syscfg", "_syscfg_f4", "_usart", "_usart_v1",] 36stm32f401cb = [ "_dma", "_dma_v2", "_exti", "_exti_v1", "_gpio", "_gpio_v2", "_spi", "_spi_v1", "_stm32f4", "_syscfg", "_syscfg_f4", "_usart", "_usart_v1",]
diff --git a/embassy-stm32/src/sdmmc_v2.rs b/embassy-stm32/src/sdmmc_v2.rs
index ba849008d..215a2a6a2 100644
--- a/embassy-stm32/src/sdmmc_v2.rs
+++ b/embassy-stm32/src/sdmmc_v2.rs
@@ -5,7 +5,6 @@ use core::task::Poll;
5use embassy::interrupt::InterruptExt; 5use embassy::interrupt::InterruptExt;
6use embassy::util::{AtomicWaker, OnDrop, Unborrow}; 6use embassy::util::{AtomicWaker, OnDrop, Unborrow};
7use embassy_extras::unborrow; 7use embassy_extras::unborrow;
8use embedded_sdmmc::{Block, BlockCount, BlockDevice, BlockIdx};
9use futures::future::poll_fn; 8use futures::future::poll_fn;
10use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; 9use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR};
11 10
@@ -151,6 +150,8 @@ pub struct Sdmmc<'d, T: Instance, P: Pins<T>> {
151 signalling: Signalling, 150 signalling: Signalling,
152 /// Card 151 /// Card
153 card: Option<Card>, 152 card: Option<Card>,
153 /// The timeout to be set for data transfers, in card bus clock periods
154 data_transfer_timeout: u32,
154} 155}
155 156
156impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P> { 157impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P> {
@@ -164,6 +165,7 @@ impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P> {
164 irq: impl Unborrow<Target = T::Interrupt>, 165 irq: impl Unborrow<Target = T::Interrupt>,
165 hclk: Hertz, 166 hclk: Hertz,
166 kernel_clk: Hertz, 167 kernel_clk: Hertz,
168 data_transfer_timeout: u32,
167 ) -> Self { 169 ) -> Self {
168 unborrow!(irq, pins); 170 unborrow!(irq, pins);
169 pins.configure(); 171 pins.configure();
@@ -184,6 +186,7 @@ impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P> {
184 clock, 186 clock,
185 signalling: Default::default(), 187 signalling: Default::default(),
186 card: None, 188 card: None,
189 data_transfer_timeout,
187 } 190 }
188 } 191 }
189 192
@@ -202,6 +205,7 @@ impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P> {
202 self.ker_ck, 205 self.ker_ck,
203 &mut self.clock, 206 &mut self.clock,
204 T::state(), 207 T::state(),
208 self.data_transfer_timeout,
205 ) 209 )
206 .await 210 .await
207 } 211 }
@@ -218,7 +222,15 @@ impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P> {
218 222
219 // NOTE(unsafe) DataBlock uses align 4 223 // NOTE(unsafe) DataBlock uses align 4
220 let buf = unsafe { &mut *((&mut buffer.0) as *mut [u8; 512] as *mut [u32; 128]) }; 224 let buf = unsafe { &mut *((&mut buffer.0) as *mut [u8; 512] as *mut [u32; 128]) };
221 inner.read_block(block_idx, buf, card_capacity, state).await 225 inner
226 .read_block(
227 block_idx,
228 buf,
229 card_capacity,
230 state,
231 self.data_transfer_timeout,
232 )
233 .await
222 } 234 }
223 235
224 pub async fn write_block(&mut self, block_idx: u32, buffer: &DataBlock) -> Result<(), Error> { 236 pub async fn write_block(&mut self, block_idx: u32, buffer: &DataBlock) -> Result<(), Error> {
@@ -228,7 +240,9 @@ impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P> {
228 240
229 // NOTE(unsafe) DataBlock uses align 4 241 // NOTE(unsafe) DataBlock uses align 4
230 let buf = unsafe { &*((&buffer.0) as *const [u8; 512] as *const [u32; 128]) }; 242 let buf = unsafe { &*((&buffer.0) as *const [u8; 512] as *const [u32; 128]) };
231 inner.write_block(block_idx, buf, card, state).await 243 inner
244 .write_block(block_idx, buf, card, state, self.data_transfer_timeout)
245 .await
232 } 246 }
233 247
234 /// Get a reference to the initialized card 248 /// Get a reference to the initialized card
@@ -302,6 +316,7 @@ impl SdmmcInner {
302 ker_ck: Hertz, 316 ker_ck: Hertz,
303 clock: &mut Hertz, 317 clock: &mut Hertz,
304 waker_reg: &AtomicWaker, 318 waker_reg: &AtomicWaker,
319 data_transfer_timeout: u32,
305 ) -> Result<(), Error> { 320 ) -> Result<(), Error> {
306 let regs = self.0; 321 let regs = self.0;
307 322
@@ -371,7 +386,8 @@ impl SdmmcInner {
371 card.csd = csd.into(); 386 card.csd = csd.into();
372 387
373 self.select_card(Some(&card))?; 388 self.select_card(Some(&card))?;
374 self.get_scr(&mut card, waker_reg).await?; 389 self.get_scr(&mut card, waker_reg, data_transfer_timeout)
390 .await?;
375 391
376 // Set bus width 392 // Set bus width
377 let (width, acmd_arg) = match bus_width { 393 let (width, acmd_arg) = match bus_width {
@@ -404,12 +420,13 @@ impl SdmmcInner {
404 } 420 }
405 421
406 // Read status 422 // Read status
407 self.read_sd_status(&mut card, waker_reg).await?; 423 self.read_sd_status(&mut card, waker_reg, data_transfer_timeout)
424 .await?;
408 425
409 if freq.0 > 25_000_000 { 426 if freq.0 > 25_000_000 {
410 // Switch to SDR25 427 // Switch to SDR25
411 *signalling = self 428 *signalling = self
412 .switch_signalling_mode(Signalling::SDR25, waker_reg) 429 .switch_signalling_mode(Signalling::SDR25, waker_reg, data_transfer_timeout)
413 .await?; 430 .await?;
414 431
415 if *signalling == Signalling::SDR25 { 432 if *signalling == Signalling::SDR25 {
@@ -422,7 +439,8 @@ impl SdmmcInner {
422 } 439 }
423 } 440 }
424 // Read status after signalling change 441 // Read status after signalling change
425 self.read_sd_status(&mut card, waker_reg).await?; 442 self.read_sd_status(&mut card, waker_reg, data_transfer_timeout)
443 .await?;
426 old_card.replace(card); 444 old_card.replace(card);
427 } 445 }
428 446
@@ -435,6 +453,7 @@ impl SdmmcInner {
435 buffer: &mut [u32; 128], 453 buffer: &mut [u32; 128],
436 capacity: CardCapacity, 454 capacity: CardCapacity,
437 waker_reg: &AtomicWaker, 455 waker_reg: &AtomicWaker,
456 data_transfer_timeout: u32,
438 ) -> Result<(), Error> { 457 ) -> Result<(), Error> {
439 // Always read 1 block of 512 bytes 458 // Always read 1 block of 512 bytes
440 // SDSC cards are byte addressed hence the blockaddress is in multiples of 512 bytes 459 // SDSC cards are byte addressed hence the blockaddress is in multiples of 512 bytes
@@ -449,7 +468,13 @@ impl SdmmcInner {
449 468
450 let buf_addr = buffer as *mut [u32; 128] as u32; 469 let buf_addr = buffer as *mut [u32; 128] as u32;
451 unsafe { 470 unsafe {
452 self.prepare_datapath_transfer(buf_addr, 512, 9, Dir::CardToHost); 471 self.prepare_datapath_transfer(
472 buf_addr,
473 512,
474 9,
475 Dir::CardToHost,
476 data_transfer_timeout,
477 );
453 self.data_interrupts(true); 478 self.data_interrupts(true);
454 } 479 }
455 self.cmd(Cmd::read_single_block(address), true)?; 480 self.cmd(Cmd::read_single_block(address), true)?;
@@ -485,6 +510,7 @@ impl SdmmcInner {
485 buffer: &[u32; 128], 510 buffer: &[u32; 128],
486 card: &mut Card, 511 card: &mut Card,
487 waker_reg: &AtomicWaker, 512 waker_reg: &AtomicWaker,
513 data_transfer_timeout: u32,
488 ) -> Result<(), Error> { 514 ) -> Result<(), Error> {
489 // Always read 1 block of 512 bytes 515 // Always read 1 block of 512 bytes
490 // SDSC cards are byte addressed hence the blockaddress is in multiples of 512 bytes 516 // SDSC cards are byte addressed hence the blockaddress is in multiples of 512 bytes
@@ -499,7 +525,13 @@ impl SdmmcInner {
499 525
500 let buf_addr = buffer as *const [u32; 128] as u32; 526 let buf_addr = buffer as *const [u32; 128] as u32;
501 unsafe { 527 unsafe {
502 self.prepare_datapath_transfer(buf_addr, 512, 9, Dir::HostToCard); 528 self.prepare_datapath_transfer(
529 buf_addr,
530 512,
531 9,
532 Dir::HostToCard,
533 data_transfer_timeout,
534 );
503 self.data_interrupts(true); 535 self.data_interrupts(true);
504 } 536 }
505 self.cmd(Cmd::write_single_block(address), true)?; 537 self.cmd(Cmd::write_single_block(address), true)?;
@@ -527,16 +559,18 @@ impl SdmmcInner {
527 regs.idmactrlr().modify(|w| w.set_idmaen(false)); 559 regs.idmactrlr().modify(|w| w.set_idmaen(false));
528 } 560 }
529 // TODO: Make this configurable 561 // TODO: Make this configurable
530 let mut timeout: u32 = 0xFFFF_FFFF; 562 let mut timeout: u32 = 0x00FF_FFFF;
531 563
532 // Try to read card status (ACMD13) 564 // Try to read card status (ACMD13)
533 while timeout > 0 { 565 while timeout > 0 {
534 match self.read_sd_status(card, waker_reg).await { 566 match self
567 .read_sd_status(card, waker_reg, data_transfer_timeout)
568 .await
569 {
535 Ok(_) => return Ok(()), 570 Ok(_) => return Ok(()),
536 Err(Error::Timeout) => (), // Try again 571 Err(Error::Timeout) => (), // Try again
537 Err(e) => return Err(e), 572 Err(e) => return Err(e),
538 } 573 }
539
540 timeout -= 1; 574 timeout -= 1;
541 } 575 }
542 Err(Error::SoftwareTimeout) 576 Err(Error::SoftwareTimeout)
@@ -573,6 +607,7 @@ impl SdmmcInner {
573 length_bytes: u32, 607 length_bytes: u32,
574 block_size: u8, 608 block_size: u8,
575 direction: Dir, 609 direction: Dir,
610 data_transfer_timeout: u32,
576 ) { 611 ) {
577 self::assert!(block_size <= 14, "Block size up to 2^14 bytes"); 612 self::assert!(block_size <= 14, "Block size up to 2^14 bytes");
578 let regs = self.0; 613 let regs = self.0;
@@ -588,8 +623,8 @@ impl SdmmcInner {
588 623
589 // NOTE(unsafe) We have exclusive access to the regisers 624 // NOTE(unsafe) We have exclusive access to the regisers
590 625
591 // TODO: Make this configurable 626 regs.dtimer()
592 regs.dtimer().write(|w| w.set_datatime(5_000_000)); 627 .write(|w| w.set_datatime(data_transfer_timeout));
593 regs.dlenr().write(|w| w.set_datalength(length_bytes)); 628 regs.dlenr().write(|w| w.set_datalength(length_bytes));
594 629
595 regs.idmabase0r().write(|w| w.set_idmabase0(buffer_addr)); 630 regs.idmabase0r().write(|w| w.set_idmabase0(buffer_addr));
@@ -637,6 +672,7 @@ impl SdmmcInner {
637 &self, 672 &self,
638 signalling: Signalling, 673 signalling: Signalling,
639 waker_reg: &AtomicWaker, 674 waker_reg: &AtomicWaker,
675 data_transfer_timeout: u32,
640 ) -> Result<Signalling, Error> { 676 ) -> Result<Signalling, Error> {
641 // NB PLSS v7_10 4.3.10.4: "the use of SET_BLK_LEN command is not 677 // NB PLSS v7_10 4.3.10.4: "the use of SET_BLK_LEN command is not
642 // necessary" 678 // necessary"
@@ -659,7 +695,13 @@ impl SdmmcInner {
659 let on_drop = OnDrop::new(|| unsafe { self.on_drop() }); 695 let on_drop = OnDrop::new(|| unsafe { self.on_drop() });
660 696
661 unsafe { 697 unsafe {
662 self.prepare_datapath_transfer(status_addr, 64, 6, Dir::CardToHost); 698 self.prepare_datapath_transfer(
699 status_addr,
700 64,
701 6,
702 Dir::CardToHost,
703 data_transfer_timeout,
704 );
663 self.data_interrupts(true); 705 self.data_interrupts(true);
664 } 706 }
665 self.cmd(Cmd::cmd6(set_function), true)?; // CMD6 707 self.cmd(Cmd::cmd6(set_function), true)?; // CMD6
@@ -724,7 +766,12 @@ impl SdmmcInner {
724 } 766 }
725 767
726 /// Reads the SD Status (ACMD13) 768 /// Reads the SD Status (ACMD13)
727 async fn read_sd_status(&self, card: &mut Card, waker_reg: &AtomicWaker) -> Result<(), Error> { 769 async fn read_sd_status(
770 &self,
771 card: &mut Card,
772 waker_reg: &AtomicWaker,
773 data_transfer_timeout: u32,
774 ) -> Result<(), Error> {
728 let rca = card.rca; 775 let rca = card.rca;
729 self.cmd(Cmd::set_block_length(64), false)?; // CMD16 776 self.cmd(Cmd::set_block_length(64), false)?; // CMD16
730 self.cmd(Cmd::app_cmd(rca << 16), false)?; // APP 777 self.cmd(Cmd::app_cmd(rca << 16), false)?; // APP
@@ -737,7 +784,13 @@ impl SdmmcInner {
737 let on_drop = OnDrop::new(|| unsafe { self.on_drop() }); 784 let on_drop = OnDrop::new(|| unsafe { self.on_drop() });
738 785
739 unsafe { 786 unsafe {
740 self.prepare_datapath_transfer(status_addr, 64, 6, Dir::CardToHost); 787 self.prepare_datapath_transfer(
788 status_addr,
789 64,
790 6,
791 Dir::CardToHost,
792 data_transfer_timeout,
793 );
741 self.data_interrupts(true); 794 self.data_interrupts(true);
742 } 795 }
743 self.cmd(Cmd::card_status(0), true)?; 796 self.cmd(Cmd::card_status(0), true)?;
@@ -832,7 +885,12 @@ impl SdmmcInner {
832 } 885 }
833 } 886 }
834 887
835 async fn get_scr(&self, card: &mut Card, waker_reg: &AtomicWaker) -> Result<(), Error> { 888 async fn get_scr(
889 &self,
890 card: &mut Card,
891 waker_reg: &AtomicWaker,
892 data_transfer_timeout: u32,
893 ) -> Result<(), Error> {
836 // Read the the 64-bit SCR register 894 // Read the the 64-bit SCR register
837 self.cmd(Cmd::set_block_length(8), false)?; // CMD16 895 self.cmd(Cmd::set_block_length(8), false)?; // CMD16
838 self.cmd(Cmd::app_cmd(card.rca << 16), false)?; 896 self.cmd(Cmd::app_cmd(card.rca << 16), false)?;
@@ -845,7 +903,7 @@ impl SdmmcInner {
845 let on_drop = OnDrop::new(move || unsafe { self.on_drop() }); 903 let on_drop = OnDrop::new(move || unsafe { self.on_drop() });
846 904
847 unsafe { 905 unsafe {
848 self.prepare_datapath_transfer(scr_addr, 8, 3, Dir::CardToHost); 906 self.prepare_datapath_transfer(scr_addr, 8, 3, Dir::CardToHost, data_transfer_timeout);
849 self.data_interrupts(true); 907 self.data_interrupts(true);
850 } 908 }
851 self.cmd(Cmd::cmd51(), true)?; 909 self.cmd(Cmd::cmd51(), true)?;
@@ -905,36 +963,26 @@ impl SdmmcInner {
905 w.set_cmdtrans(data); 963 w.set_cmdtrans(data);
906 }); 964 });
907 965
908 // TODO: Check if this timeout is necessary
909 let mut timeout: u32 = 0xFFFF_FFFF;
910
911 let mut status; 966 let mut status;
912 if cmd.resp == Response::None { 967 if cmd.resp == Response::None {
913 // Wait for CMDSENT or a timeout 968 // Wait for CMDSENT or a timeout
914 while { 969 while {
915 status = regs.star().read(); 970 status = regs.star().read();
916 !(status.ctimeout() || status.cmdsent()) && timeout > 0 971 !(status.ctimeout() || status.cmdsent())
917 } { 972 } {}
918 timeout -= 1;
919 }
920 } else { 973 } else {
921 // Wait for CMDREND or CCRCFAIL or a timeout 974 // Wait for CMDREND or CCRCFAIL or a timeout
922 while { 975 while {
923 status = regs.star().read(); 976 status = regs.star().read();
924 !(status.ctimeout() || status.cmdrend() || status.ccrcfail()) && timeout > 0 977 !(status.ctimeout() || status.cmdrend() || status.ccrcfail())
925 } { 978 } {}
926 timeout -= 1;
927 }
928 } 979 }
929 980
930 if status.ctimeout() { 981 if status.ctimeout() {
931 return Err(Error::Timeout); 982 return Err(Error::Timeout);
932 } else if timeout == 0 {
933 return Err(Error::SoftwareTimeout);
934 } else if status.ccrcfail() { 983 } else if status.ccrcfail() {
935 return Err(Error::Crc); 984 return Err(Error::Crc);
936 } 985 }
937
938 Ok(()) 986 Ok(())
939 } 987 }
940 } 988 }
@@ -1321,11 +1369,76 @@ where
1321 const BUSWIDTH: BusWidth = BusWidth::One; 1369 const BUSWIDTH: BusWidth = BusWidth::One;
1322 1370
1323 fn configure(&mut self) { 1371 fn configure(&mut self) {
1324 self::todo!() 1372 let (clk_pin, cmd_pin, d0_pin) = self;
1373
1374 cortex_m::interrupt::free(|_| unsafe {
1375 // clk
1376 let block = clk_pin.block();
1377 let n = clk_pin.pin() as usize;
1378 let afr_num = CLK::AF_NUM;
1379 configure_pin(block, n, afr_num, false);
1380
1381 // cmd
1382 let block = cmd_pin.block();
1383 let n = cmd_pin.pin() as usize;
1384 let afr_num = CMD::AF_NUM;
1385 configure_pin(block, n, afr_num, true);
1386
1387 // d0
1388 let block = d0_pin.block();
1389 let n = d0_pin.pin() as usize;
1390 let afr_num = D0::AF_NUM;
1391 configure_pin(block, n, afr_num, true);
1392 });
1325 } 1393 }
1326 1394
1327 fn deconfigure(&mut self) { 1395 fn deconfigure(&mut self) {
1328 self::todo!() 1396 use pac::gpio::vals::{Moder, Ospeedr, Pupdr};
1397
1398 let (clk_pin, cmd_pin, d0_pin) = self;
1399
1400 cortex_m::interrupt::free(|_| unsafe {
1401 // clk
1402 let n = clk_pin.pin().into();
1403 clk_pin
1404 .block()
1405 .moder()
1406 .modify(|w| w.set_moder(n, Moder::ANALOG));
1407 clk_pin
1408 .block()
1409 .ospeedr()
1410 .modify(|w| w.set_ospeedr(n, Ospeedr::LOWSPEED));
1411
1412 // cmd
1413 let n = cmd_pin.pin().into();
1414 cmd_pin
1415 .block()
1416 .moder()
1417 .modify(|w| w.set_moder(n, Moder::ANALOG));
1418 cmd_pin
1419 .block()
1420 .ospeedr()
1421 .modify(|w| w.set_ospeedr(n, Ospeedr::LOWSPEED));
1422 cmd_pin
1423 .block()
1424 .pupdr()
1425 .modify(|w| w.set_pupdr(n, Pupdr::FLOATING));
1426
1427 // d0
1428 let n = d0_pin.pin().into();
1429 d0_pin
1430 .block()
1431 .moder()
1432 .modify(|w| w.set_moder(n, Moder::ANALOG));
1433 d0_pin
1434 .block()
1435 .ospeedr()
1436 .modify(|w| w.set_ospeedr(n, Ospeedr::LOWSPEED));
1437 d0_pin
1438 .block()
1439 .pupdr()
1440 .modify(|w| w.set_pupdr(n, Pupdr::FLOATING));
1441 });
1329 } 1442 }
1330} 1443}
1331 1444
@@ -1359,63 +1472,79 @@ macro_rules! impl_sdmmc_pin {
1359 }; 1472 };
1360} 1473}
1361 1474
1362impl<'d, T: Instance, P: Pins<T>> BlockDevice for Sdmmc<'d, T, P> { 1475#[cfg(feature = "sdmmc-rs")]
1363 type Error = Error; 1476mod sdmmc_rs {
1364 #[rustfmt::skip] 1477 use super::*;
1365 type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; 1478 use embedded_sdmmc::{Block, BlockCount, BlockDevice, BlockIdx};
1366 #[rustfmt::skip] 1479
1367 type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; 1480 impl<'d, T: Instance, P: Pins<T>> BlockDevice for Sdmmc<'d, T, P> {
1368 1481 type Error = Error;
1369 fn read<'a>( 1482 #[rustfmt::skip]
1370 &'a mut self, 1483 type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a;
1371 blocks: &'a mut [Block], 1484 #[rustfmt::skip]
1372 start_block_idx: BlockIdx, 1485 type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a;
1373 _reason: &str, 1486
1374 ) -> Self::ReadFuture<'a> { 1487 fn read<'a>(
1375 async move { 1488 &'a mut self,
1376 let card_capacity = self.card()?.card_type; 1489 blocks: &'a mut [Block],
1377 let inner = T::inner(); 1490 start_block_idx: BlockIdx,
1378 let state = T::state(); 1491 _reason: &str,
1379 let mut address = start_block_idx.0; 1492 ) -> Self::ReadFuture<'a> {
1380 1493 async move {
1381 for block in blocks.iter_mut() { 1494 let card_capacity = self.card()?.card_type;
1382 let block: &mut [u8; 512] = &mut block.contents; 1495 let inner = T::inner();
1383 1496 let state = T::state();
1384 // NOTE(unsafe) Block uses align(4) 1497 let mut address = start_block_idx.0;
1385 let buf = unsafe { &mut *(block as *mut [u8; 512] as *mut [u32; 128]) }; 1498
1386 inner.read_block(address, buf, card_capacity, state).await?; 1499 for block in blocks.iter_mut() {
1387 address += 1; 1500 let block: &mut [u8; 512] = &mut block.contents;
1501
1502 // NOTE(unsafe) Block uses align(4)
1503 let buf = unsafe { &mut *(block as *mut [u8; 512] as *mut [u32; 128]) };
1504 inner
1505 .read_block(
1506 address,
1507 buf,
1508 card_capacity,
1509 state,
1510 self.data_transfer_timeout,
1511 )
1512 .await?;
1513 address += 1;
1514 }
1515 Ok(())
1388 } 1516 }
1389 Ok(())
1390 } 1517 }
1391 }
1392 1518
1393 fn write<'a>( 1519 fn write<'a>(
1394 &'a mut self, 1520 &'a mut self,
1395 blocks: &'a [Block], 1521 blocks: &'a [Block],
1396 start_block_idx: BlockIdx, 1522 start_block_idx: BlockIdx,
1397 ) -> Self::WriteFuture<'a> { 1523 ) -> Self::WriteFuture<'a> {
1398 async move { 1524 async move {
1399 let card = self.card.as_mut().ok_or(Error::NoCard)?; 1525 let card = self.card.as_mut().ok_or(Error::NoCard)?;
1400 let inner = T::inner(); 1526 let inner = T::inner();
1401 let state = T::state(); 1527 let state = T::state();
1402 let mut address = start_block_idx.0; 1528 let mut address = start_block_idx.0;
1403 1529
1404 for block in blocks.iter() { 1530 for block in blocks.iter() {
1405 let block: &[u8; 512] = &block.contents; 1531 let block: &[u8; 512] = &block.contents;
1406 1532
1407 // NOTE(unsafe) DataBlock uses align 4 1533 // NOTE(unsafe) DataBlock uses align 4
1408 let buf = unsafe { &*(block as *const [u8; 512] as *const [u32; 128]) }; 1534 let buf = unsafe { &*(block as *const [u8; 512] as *const [u32; 128]) };
1409 inner.write_block(address, buf, card, state).await?; 1535 inner
1410 address += 1; 1536 .write_block(address, buf, card, state, self.data_transfer_timeout)
1537 .await?;
1538 address += 1;
1539 }
1540 Ok(())
1411 } 1541 }
1412 Ok(())
1413 } 1542 }
1414 }
1415 1543
1416 fn num_blocks(&self) -> Result<BlockCount, Self::Error> { 1544 fn num_blocks(&self) -> Result<BlockCount, Self::Error> {
1417 let card = self.card()?; 1545 let card = self.card()?;
1418 let count = card.csd.block_count(); 1546 let count = card.csd.block_count();
1419 Ok(BlockCount(count)) 1547 Ok(BlockCount(count))
1548 }
1420 } 1549 }
1421} 1550}