Hi @FZs thanks for your reply.
I am using the embedded-sdmmc library and I am extending it to be able to read multiple blocks at once. Currently the library can do that but then I have to pass a pointer large as multiple blocks to the function which is not possible on embedded. So the idea is to split the reading of blocks from SDCard.
- Prepare
- Loop { Read block and do something with it }
- Stop reading
The prepare is done during creating of the object
Object 2:
pub struct SdCardMultiBlockRead<'a, SPI, CS, DELAYER>
where
SPI: embedded_hal_async::spi::SpiDevice<u8>,
CS: embedded_hal::digital::OutputPin,
DELAYER: embedded_hal_async::delay::DelayNs,
{
sd_card: &'a mut SdCard<SPI, CS, DELAYER>,
}
impl<'a, SPI, CS, DELAYER> SdCardMultiBlockRead<'a, SPI, CS, DELAYER>
where
SPI: embedded_hal_async::spi::SpiDevice<u8>,
CS: embedded_hal::digital::OutputPin,
DELAYER: embedded_hal_async::delay::DelayNs,
{
/// Create new object
pub async fn new(
sd_card: &'a mut SdCard<SPI, CS, DELAYER>,
start_block_idx: BlockIdx,
) -> Result<Self, Error> {
let mut inner = sd_card.inner.borrow_mut();
inner.check_init().await?;
inner.prepare_read(start_block_idx).await?;
drop(inner);
Ok(Self { sd_card })
}
/// Reading next block
pub async fn read(&mut self, block: &mut [u8]) -> Result<(), Error> {
let mut inner = self.sd_card.inner.borrow_mut();
inner.read_data(block).await
}
/// Ending a multiblock read
/// IMPORTANT: This function must be called before destroying this object!
pub async fn stop(&mut self) -> Result<(), Error> {
let mut inner = self.sd_card.inner.borrow_mut();
inner.end_read().await
}
}
I could use RefCell, but if it is somehow possible to do it with direct references would be preferred
Object 3:
struct BlockDevice<'a, SPI: SpiDevice, CS: OutputPin, DELAYER: DelayNs> {
sd_card: SdCard<SPI, CS, DELAYER>,
sd_card_multiblock_read: Option<SdCardMultiBlockRead<'a, SPI, CS, DELAYER>>,
sd_card_multiblock_write: Option<SdCardMultiBlockWrite<'a, SPI, CS, DELAYER>>,
}
impl<'a, SPI: SpiDevice, CS: OutputPin, DELAYER: DelayNs> BlockDevice<'a, SPI, CS, DELAYER> {
fn new(sd_card: SdCard<SPI, CS, DELAYER>) -> Self {
Self {
sd_card,
sd_card_multiblock_read: None,
sd_card_multiblock_write: None,
}
}
}
impl<'a, SPI: SpiDevice, CS: OutputPin, DELAYER: DelayNs> block_device::BlockDevice
for BlockDevice<'a, SPI, CS, DELAYER>
{
async fn prepare_multiblock_write(
&mut self,
lba: u32,
blocks_count: u32,
) -> Result<(), BlockDeviceError> {
self.sd_card_multiblock_write = Some(
SdCardMultiBlockWrite::new(&mut self.sd_card, BlockIdx(lba), blocks_count)
.await
.map_err(|e| Self::sd_error_to_block_device_error(e))?,
);
Ok(())
}
}