From 359aaa5aeb83cc073c9a1ebc41318e79e00c1669 Mon Sep 17 00:00:00 2001 From: Thales Fragoso Date: Wed, 12 May 2021 21:59:48 -0300 Subject: [PATCH] Implement embedded-sdmmc traits --- embassy-stm32/Cargo.toml | 5 ++- embassy-stm32/gen.py | 1 + embassy-stm32/src/sdmmc_v2.rs | 63 +++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index c2e6c7a5f..4735a34f0 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -17,7 +17,8 @@ cortex-m = "0.7.1" embedded-hal = { version = "0.2.4" } futures = { version = "0.3.5", default-features = false, features = ["async-await"] } rand_core = { version = "0.6.2", optional = true } -sdio-host = "0.5.0" +sdio-host = { version = "0.5.0", optional = true } +embedded-sdmmc = { git = "https://github.com/thalesfragoso/embedded-sdmmc-rs", branch = "async", optional = true } [build-dependencies] regex = "1.4.6" @@ -333,6 +334,8 @@ _rng_v1 = [] _spi = [] _spi_v1 = [] _spi_v2 = [] +_sdmmc = [ "sdio-host",] +_sdmmc_v2 = [] _stm32f4 = [] _stm32l4 = [] _stm32l4p = [] diff --git a/embassy-stm32/gen.py b/embassy-stm32/gen.py index 23a4c7eb8..96275df9a 100644 --- a/embassy-stm32/gen.py +++ b/embassy-stm32/gen.py @@ -248,6 +248,7 @@ for chip in chips.values(): feature_optional_deps = {} feature_optional_deps['_rng'] = ['rand_core'] +feature_optional_deps['_sdmmc'] = ['sdio-host'] features = {} extra_features = set() diff --git a/embassy-stm32/src/sdmmc_v2.rs b/embassy-stm32/src/sdmmc_v2.rs index 182add6f6..ba849008d 100644 --- a/embassy-stm32/src/sdmmc_v2.rs +++ b/embassy-stm32/src/sdmmc_v2.rs @@ -1,9 +1,11 @@ +use core::future::Future; use core::marker::PhantomData; use core::task::Poll; use embassy::interrupt::InterruptExt; use embassy::util::{AtomicWaker, OnDrop, Unborrow}; use embassy_extras::unborrow; +use embedded_sdmmc::{Block, BlockCount, BlockDevice, BlockIdx}; use futures::future::poll_fn; use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; @@ -1356,3 +1358,64 @@ macro_rules! impl_sdmmc_pin { impl crate::sdmmc_v2::$func for peripherals::$pin {} }; } + +impl<'d, T: Instance, P: Pins> BlockDevice for Sdmmc<'d, T, P> { + type Error = Error; + #[rustfmt::skip] + type ReadFuture<'a> where Self: 'a = impl Future> + 'a; + #[rustfmt::skip] + type WriteFuture<'a> where Self: 'a = impl Future> + 'a; + + fn read<'a>( + &'a mut self, + blocks: &'a mut [Block], + start_block_idx: BlockIdx, + _reason: &str, + ) -> Self::ReadFuture<'a> { + async move { + let card_capacity = self.card()?.card_type; + let inner = T::inner(); + let state = T::state(); + let mut address = start_block_idx.0; + + for block in blocks.iter_mut() { + let block: &mut [u8; 512] = &mut block.contents; + + // NOTE(unsafe) Block uses align(4) + let buf = unsafe { &mut *(block as *mut [u8; 512] as *mut [u32; 128]) }; + inner.read_block(address, buf, card_capacity, state).await?; + address += 1; + } + Ok(()) + } + } + + fn write<'a>( + &'a mut self, + blocks: &'a [Block], + start_block_idx: BlockIdx, + ) -> Self::WriteFuture<'a> { + async move { + let card = self.card.as_mut().ok_or(Error::NoCard)?; + let inner = T::inner(); + let state = T::state(); + let mut address = start_block_idx.0; + + for block in blocks.iter() { + let block: &[u8; 512] = &block.contents; + + // NOTE(unsafe) DataBlock uses align 4 + let buf = unsafe { &*(block as *const [u8; 512] as *const [u32; 128]) }; + inner.write_block(address, buf, card, state).await?; + address += 1; + } + Ok(()) + } + } + + fn num_blocks(&self) -> Result { + let card = self.card()?; + let count = card.csd.block_count(); + Ok(BlockCount(count)) + } +}