From d16739e1b9e1d6407bf66f02d35a8504a146e99b Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Sun, 22 Dec 2024 15:05:43 +0000 Subject: [PATCH] Updated the README and added minor typo fixes --- README.md | 26 +++++++++++++++++--------- src/lib.rs | 5 +---- src/sdcard/mod.rs | 37 +++++++++++++++++++++---------------- src/sdcard/spi.rs | 15 ++++++++++++--- 4 files changed, 51 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index ab1de0e..c7d1170 100644 --- a/README.md +++ b/README.md @@ -46,17 +46,25 @@ By default the `VolumeManager` will initialize with a maximum number of `4` open let cont: VolumeManager<_, _, 6, 12, 4> = VolumeManager::new_with_limits(block, time_source); ``` +### Accessing SD Cards using an SD Host Controller + +The `SdCard` type requires something that implements `Transport` in order to speak to the SD Card. We supply a generic `SpiTransport` that implements `Transport` using some underlying user-supplied implementation of `embedded_hal::spi::SpiDevice`. That will work for most applications. + +However, if your MCU has a full SD Host Controller peripheral, and if you need high-performance access to your SD Card, you may wish to instead implement `Transport` in a way that uses that peripheral. SD Host Controllers, for example, often support a 4-bit wide interface instead of the 1-bit wide SPI interface, and run at higher clock rates. + ## Supported features -* Open files in all supported methods from an open directory -* Open an arbitrary number of directories and files -* Read data from open files -* Write data to open files -* Close files -* Delete files -* Iterate root directory -* Iterate sub-directories -* Log over defmt or the common log interface (feature flags). +* Talking to SD Cards over SPI (using the `embedded-hal::spi::SpiDevice` trait) +* Talking to SD Cards over a custom transport (using our `Transport` trait) +* Opening files in all supported modes from an open directory +* Opening an arbitrary number of directories and files +* Reading data from open files +* Writing data to open files +* Closing files +* Deleting files +* Iterating the root directory +* Iterating sub-directories +* Logging over defmt or the common log interface (see feature flags). ## No-std usage diff --git a/src/lib.rs b/src/lib.rs index d45b3aa..e4dd6b3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -92,10 +92,7 @@ pub use crate::filesystem::{ use filesystem::DirectoryInfo; #[doc(inline)] -pub use crate::sdcard::Error as SdCardError; - -#[doc(inline)] -pub use crate::sdcard::SdCard; +pub use crate::sdcard::{Error as SdCardError, SdCard, SpiTransport, Transport}; mod volume_mgr; #[doc(inline)] diff --git a/src/sdcard/mod.rs b/src/sdcard/mod.rs index e59c0bd..04d84d8 100644 --- a/src/sdcard/mod.rs +++ b/src/sdcard/mod.rs @@ -5,6 +5,8 @@ pub mod proto; mod spi; + +#[doc(inline)] pub use spi::SpiTransport; use crate::{Block, BlockCount, BlockDevice, BlockIdx}; @@ -20,18 +22,7 @@ use crate::debug; // Types and Implementations // **************************************************************************** -/// Driver for an SD Card on an SPI bus. -/// -/// Built from an [`SpiDevice`] implementation and a Chip Select pin. -/// -/// Before talking to the SD Card, the caller needs to send 74 clocks cycles on -/// the SPI Clock line, at 400 kHz, with no chip-select asserted (or at least, -/// not the chip-select of the SD Card). -/// -/// This kind of breaks the embedded-hal model, so how to do this is left to -/// the caller. You could drive the SpiBus directly, or use an SpiDevice with -/// a dummy chip-select pin. Or you could try just not doing the 74 clocks and -/// see if your card works anyway - some do, some don't. +/// Driver for an SD Card using some generic SD Card [`Transport`]. /// /// All the APIs take `&self` - mutability is handled using an inner `RefCell`. /// @@ -56,6 +47,12 @@ where { /// Create a new SD/MMC Card driver using a raw SPI interface. /// + /// This is just a short-cut method to provide backwards compatibility with + /// our old API. + /// + /// It creates an [`SpiTransport`] for you, so refer to the documentation + /// there for important details. + /// /// The card will not be initialised at this time. Initialisation is /// deferred until a method is called on the object. /// @@ -64,10 +61,14 @@ where Self::new_spi_with_options(spi, delayer, AcquireOpts::default()) } - /// Construct a new SD/MMC Card driver, using a raw SPI interface and the given options. + /// Construct a new SD/MMC Card driver, using a raw SPI interface and the + /// given options. /// - /// See the docs of the [`SdCard`] struct for more information about - /// how to construct the needed `SPI` and `CS` types. + /// This is just a short-cut method to provide backwards compatibility with + /// our old API. + /// + /// It creates an [`SpiTransport`] for you, so refer to the documentation + /// there for important details. /// /// The card will not be initialised at this time. Initialisation is /// deferred until a method is called on the object. @@ -184,7 +185,11 @@ impl BlockDevice for SdCard { } } -/// Abstract SD card transportation interface. +/// Abstract SD Card Transport interface. +/// +/// We implement this trait to produce an SPI based transport over in +/// [`SpiTransport`]. You can implement it yourself to support your favourite SD +/// Host Controller if you prefer. pub trait Transport { /// Read one or more blocks, starting at the given block index. fn read(&mut self, blocks: &mut [Block], start_block_idx: BlockIdx) -> Result<(), Error>; diff --git a/src/sdcard/spi.rs b/src/sdcard/spi.rs index a7846c0..b6e98d4 100644 --- a/src/sdcard/spi.rs +++ b/src/sdcard/spi.rs @@ -1,4 +1,4 @@ -//! Implements the BlockDevice trait for an SD/MMC Protocol over SPI. +//! Implements the [`Transport`] trait for speaking SD/MMC Protocol over SPI. //! //! This is currently optimised for readability and debugability, not //! performance. @@ -7,9 +7,9 @@ use super::{proto::*, AcquireOpts, CardType, Delay, Error}; use crate::blockdevice::{Block, BlockCount, BlockIdx}; use crate::{debug, trace, warn}; -/// SPI transportation for the SD Card driver. +/// An SPI-based implementation of [`Transport`](crate::Transport). /// -/// All the APIs required `&mut self`. +/// All the APIs require `&mut self`. pub struct SpiTransport where SPI: embedded_hal::spi::SpiDevice, @@ -27,6 +27,15 @@ where DELAYER: embedded_hal::delay::DelayNs, { /// Construct a new raw SPI transport interface for SD/MMC Card. + /// + /// Before talking to the SD Card, the caller needs to send 74 clocks cycles + /// on the SPI Clock line, at 400 kHz, with no chip-select asserted (or at + /// least, not the chip-select of the SD Card). + /// + /// This kind of breaks the embedded-hal model, so how to do this is left to + /// the caller. You could drive the SpiBus directly, or use an SpiDevice + /// with a dummy chip-select pin. Or you could try just not doing the 74 + /// clocks and see if your card works anyway - some do, some don't. pub fn new(spi: SPI, delayer: DELAYER, options: AcquireOpts) -> Self { SpiTransport { spi,