Skip to content

Commit

Permalink
Updated the README and added minor typo fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
thejpster committed Dec 22, 2024
1 parent 5f4b3e7 commit d16739e
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 32 deletions.
26 changes: 17 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8>`. 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

Expand Down
5 changes: 1 addition & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
37 changes: 21 additions & 16 deletions src/sdcard/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
pub mod proto;
mod spi;

#[doc(inline)]
pub use spi::SpiTransport;

use crate::{Block, BlockCount, BlockDevice, BlockIdx};
Expand All @@ -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`.
///
Expand All @@ -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.
///
Expand All @@ -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.
Expand Down Expand Up @@ -184,7 +185,11 @@ impl<T: Transport> BlockDevice for SdCard<T> {
}
}

/// 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>;
Expand Down
15 changes: 12 additions & 3 deletions src/sdcard/spi.rs
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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<SPI, DELAYER>
where
SPI: embedded_hal::spi::SpiDevice<u8>,
Expand All @@ -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,
Expand Down

0 comments on commit d16739e

Please sign in to comment.