1#[cfg(all(feature = "async", feature = "async-trait"))]
2use alloc::boxed::Box;
3use core::time::Duration;
4use core::{convert::TryFrom, slice};
5
6use embedded_hal::digital::OutputPin;
7use embedded_timers::{clock::Clock, instant::Instant};
8
9use crate::{
10 bus::Read,
11 sd::{
12 command::Command,
13 registers::CSD,
14 transfer::{Token, TokenError},
15 BLOCK_SIZE,
16 },
17};
18
19use super::bus::{BUSError, Bus, Error, Transfer};
20
21impl<E, F, SPI, CS, C, I> Bus<SPI, CS, C>
22where
23 SPI: Transfer<Error = E> + Send,
24 CS: OutputPin<Error = F> + Send,
25 C: Clock<Instant = I> + Send,
26 I: Instant,
27{
28 #[cfg_attr(not(feature = "async"), deasync::deasync)]
29 pub(crate) async fn read_block(&mut self, block: &mut [u8]) -> Result<(), BUSError<E, F>> {
30 let deadline = self.clock.now() + Duration::from_millis(100);
31 let token = loop {
32 if self.clock.now() > deadline {
33 return Err(BUSError::Timeout);
34 }
35 let mut byte = 0u8;
36 self.rx(slice::from_mut(&mut byte)).await?;
37 if byte == 0xFF {
38 continue;
39 }
40 match Token::try_from(byte) {
41 Ok(token) => break token,
42 Err(TokenError::NotToken) => continue,
43 Err(e) => return Err(BUSError::Transfer(e)),
44 }
45 };
46 if token != Token::Start {
47 return Err(BUSError::Generic);
48 }
49 self.rx(block).await?;
50 let mut crc = [0u8; 2];
51 self.rx(&mut crc).await
52 }
53}
54
55#[cfg_attr(all(feature = "async", feature = "async-trait"), async_trait::async_trait)]
56#[cfg_attr(not(feature = "async"), deasync::deasync)]
57impl<E, F, SPI, CS, C, I> Read for Bus<SPI, CS, C>
58where
59 SPI: Transfer<Error = E> + Send,
60 CS: OutputPin<Error = F> + Send,
61 C: Clock<Instant = I> + Send,
62 I: Instant,
63{
64 type Error = Error<E, F>;
65
66 async fn read_csd(&mut self) -> Result<CSD, BUSError<E, F>> {
67 self.tx(&[0xFF; 5]).await?;
68 self.select()?;
69 self.send_command(Command::SendCSD(0)).await?;
70 let mut buffer = [0u8; 16];
71 self.read_block(&mut buffer).await?;
72 self.deselect()?;
73 self.tx(&[0xFF]).await?; CSD::try_from(u128::from_be_bytes(buffer)).ok_or(BUSError::Generic)
75 }
76
77 async fn read<'a, B>(&mut self, address: u32, blocks: B) -> Result<(), BUSError<E, F>>
78 where
79 B: core::iter::ExactSizeIterator<Item = &'a mut [u8; BLOCK_SIZE]> + Send,
80 {
81 self.tx(&[0xFF; 5]).await?;
82 self.select()?;
83 let num_blocks = blocks.len();
84 let cmd = match num_blocks {
85 1 => Command::ReadSingleBlock(address),
86 _ => Command::ReadMultipleBlock(address),
87 };
88 self.send_command(cmd).await?;
89 for block in blocks {
90 self.read_block(block).await?;
91 }
92 if num_blocks > 1 {
93 self.send_command(Command::StopTransmission).await?;
94 self.wait(Duration::from_millis(100)).await?;
95 }
96 self.deselect()?;
97 self.tx(&[0xFF]).await }
99}