Skip to content

Commit b7cdb95

Browse files
committed
extend init example, add docs, ci
1 parent 21ed7e8 commit b7cdb95

15 files changed

Lines changed: 233 additions & 45 deletions

File tree

Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
[workspace]
22
resolver = "3"
33
members = ["embedded-sdmmc", "embedded-sdmmc-types"]
4+
5+
[workspace.dependencies]
6+
bitbybit = "2"
7+
arbitrary-int = "2"
8+
defmt = "1"
9+
thiserror = { version = "2", default-features = false }
10+
bitflags = "2"
11+
hex-literal = "1"

README.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ library. It is written in pure-Rust, is `#![no_std]` and does not use `alloc`
66
or `collections` to keep the memory footprint low. In the first instance it is
77
designed for readability and simplicity over performance.
88

9-
## Using the crate
9+
## Using the crate in an application
1010

11-
You will need something that implements the `BlockDevice` trait, which can read and write the 512-byte blocks (or sectors) from your card. If you were to implement this over USB Mass Storage, there's no reason this crate couldn't work with a USB Thumb Drive, but we only supply a `BlockDevice` suitable for reading SD and SDHC cards over SPI.
11+
You will need something that implements the `BlockDevice` trait, which can read and write the
12+
512-byte blocks (or sectors) from your card. If you were to implement this over USB Mass Storage,
13+
there's no reason this crate couldn't work with a USB Thumb Drive, but we only supply a
14+
`BlockDevice` implementation suitable for reading SD and SDHC cards over SPI.
1215

1316
```rust
1417
use embedded_sdmmc::{SdCard, VolumeManager, Mode, VolumeIdx};
@@ -60,6 +63,20 @@ By default the `VolumeManager` will initialize with a maximum number of `4` open
6063
let cont: VolumeManager<_, _, 6, 12, 4> = VolumeManager::new_with_limits(block, time_source);
6164
```
6265

66+
## Providing support for the library
67+
68+
If you are a hardware abstraction library author, you might be interested in adding support for
69+
`embedded-sdmmc` for your SD card interface. This can be done by implementing the `BlockDevice`
70+
trait provided by the `embedded-sdmmc-types` crate.
71+
72+
The [`sd_card_init` example](./embedded-sdmmc/examples/sd_card_init.rs) provides more information
73+
on how such an implementation could look like for SD card host controllers. If you are
74+
interfacing with a SD card via SPI, `embedded-sdmmc` provides an implementation which only
75+
requires you to provide a SPI driver implementing the
76+
[`SpiDevice` trait](https://docs.rs/embedded-hal/latest/embedded_hal/spi/trait.SpiDevice.html).
77+
78+
The [`embedded-sdmmc-types` README](./embedded-sdmmc-types/README.md) provides some more information.
79+
6380
## Supported features
6481

6582
* Open files in all supported methods from an open directory

embedded-sdmmc-types/Cargo.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ version = "0.1.0"
44
edition = "2024"
55

66
[dependencies]
7-
bitbybit = "2"
8-
arbitrary-int = "2"
9-
defmt = { version = "1", optional = true }
10-
thiserror = { version = "2", default-features = false }
11-
bitflags = "2"
7+
bitbybit.workspace = true
8+
arbitrary-int.workspace = true
9+
defmt = { workspace = true, optional = true }
10+
thiserror.workspace = true
11+
bitflags.workspace = true
1212

1313
[dev-dependencies]
14-
hex-literal = "1.0.0"
14+
hex-literal.workspace = true

embedded-sdmmc-types/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Embedded SD/MMC [![crates.io](https://img.shields.io/crates/v/embedded-sdmmc-types.svg)](https://crates.io/crates/embedded-sdmmc-types) [![Documentation](https://docs.rs/embedded-sdmmc-types/badge.svg)](https://docs.rs/embedded-sdmmc-types)
2+
3+
Embedded SD/MMC Types Library
4+
=======
5+
6+
This library contains some common types and abstractions required for implementing
7+
support for `embedded-sdmmc` inside your hardware abstraction layer library.
8+
9+
This also allows HAL library to only depend on this library instead of the higher-level
10+
`embedded-sdmmc` which might have more frequent breaking changes.
11+
12+
Check out the [documentation](https://docs.rs/embedded-sdmmc-types) for more information on the
13+
available types and traits.

embedded-sdmmc-types/src/blockdevice.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ impl BlockCount {
256256
/// How many blocks are required to hold this many bytes.
257257
///
258258
/// ```
259-
/// # use embedded_sdmmc::BlockCount;
259+
/// # use embedded_sdmmc_types::blockdevice::BlockCount;
260260
/// assert_eq!(BlockCount::from_bytes(511), BlockCount(1));
261261
/// assert_eq!(BlockCount::from_bytes(512), BlockCount(1));
262262
/// assert_eq!(BlockCount::from_bytes(513), BlockCount(2));

embedded-sdmmc-types/src/lib.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,29 @@
1+
//! # Embedded SD/MMC Types Library
2+
//!
3+
//! This library contains some common types and abstractions required for implementing
4+
//! support for `embedded-sdmmc` inside your hardware abstraction layer library.
5+
//!
6+
//! This also allows HAL library to only depend on this library instead of the higher-level
7+
//! `embedded-sdmmc` which might have more frequent breaking changes.
8+
//!
9+
//! Adding `embedded-sdmmc` support for you SD card structure only involves implementing
10+
//! the [BlockDevice] trait for your SD card structure. Once you have an initialized SD card
11+
//! driver structure, implementing this trait is usually relatively easy.
12+
//!
13+
//! The [sdcard] module provides various data structures which are useful for implementing
14+
//! the SD card initialization sequence on a system with a dedicated SD card controller.
15+
//!
16+
//! The [`sd_card_init` example](https://github.com/rust-embedded-community/embedded-sdmmc-rs/blob/develop/examples/sd_card_init.rs)
17+
//! inside the `embedded-sdmmc` library provides an example of how the implementation of both
18+
//! the initialization sequence and the [BlockDevice] implementation could look like.
119
#![no_std]
20+
#![cfg_attr(docsrs, feature(doc_cfg))]
21+
#![deny(missing_docs)]
22+
223
pub mod blockdevice;
324
pub mod sdcard;
425

26+
pub use blockdevice::{Block, BlockCount, BlockDevice, BlockIdx};
27+
528
#[cfg(test)]
629
mod tests {}

embedded-sdmmc-types/src/sdcard/csd.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,8 @@ impl CsdV3 {
556556

557557
#[cfg(test)]
558558
mod tests {
559+
use hex_literal::hex;
560+
559561
use super::*;
560562

561563
#[test]

embedded-sdmmc-types/src/sdcard/mock.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ impl From<State> for super::response::State {
9494

9595
/// SD card mock.
9696
///
97-
/// This basically behaves like a virtual SD card. Currently, this mock simulates a Ver2.00 or later
97+
/// This basically behaves like a virtual SD card controller with a connected virtual SD card.s
98+
/// Currently, this mock simulates a Ver2.00 or later
9899
/// SDHC memory card. As such, it responds to the CMD8 command as well. Furthermore, while this
99100
/// mock is capable of performing a transition until the [super::response::State::Tran] transmission
100101
/// state is reached, it does not implement / mock file operations yet.
@@ -232,6 +233,35 @@ impl SdCardMock {
232233
}
233234
}
234235

236+
/// Current state of the SD card. A library implementation of this function would send CMD13 to
237+
/// retrieve the card status, which contains the current SD card state.
238+
pub fn read_current_state(&self) -> State {
239+
self.state
240+
}
241+
242+
/// Hypotehtical function to write a word of data, assuming that the controller hardware has
243+
/// something like a FIFO.
244+
///
245+
/// Other hardware implementations might also use DMA.
246+
pub fn write_data_word(&mut self, _word: u32) {}
247+
248+
/// Hypotehtical function to read a word of data, assuming that the controller hardware has
249+
/// something like a FIFO.
250+
///
251+
/// Other hardware implementations might also use DMA.
252+
pub fn read_data_word(&mut self) -> u32 {
253+
0
254+
}
255+
256+
/// Hypothetical function which retruns whether a RX word can be read.
257+
pub fn word_available(&self) -> bool {
258+
true
259+
}
260+
261+
/// Hypothetical function which waits for the SD casrd controller to complete the TX data
262+
/// transfer.
263+
pub fn wait_until_data_transfer_done(&self) {}
264+
235265
/// Read [u32] reply from the SD card mock.
236266
pub fn read_reply_u32(&self) -> u32 {
237267
u32::from_be_bytes(self.reply_buf[0..4].try_into().unwrap())

embedded-sdmmc-types/src/sdcard/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
//! SD card support module.
22
pub mod argument;
3-
pub mod response;
43
pub mod cid;
54
pub mod csd;
65
pub mod mock;
6+
pub mod response;
77

88
/// The different types of card we support.
99
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -147,6 +147,8 @@ pub fn crc16(data: &[u8]) -> u16 {
147147

148148
#[cfg(test)]
149149
mod test {
150+
use hex_literal::hex;
151+
150152
use super::*;
151153
use crate::sdcard::csd::*;
152154

embedded-sdmmc/Cargo.toml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,29 @@ rust-version = "1.87"
1515

1616
[dependencies]
1717
byteorder = {version = "1", default-features = false}
18-
defmt = {version = "1.0.1", optional = true}
18+
defmt = { workspace = true, optional = true }
1919
embedded-hal = "1.0.0"
2020
embedded-io = "0.7"
21-
bitbybit = "2"
22-
arbitrary-int = "2"
21+
bitbybit.workspace = true
22+
arbitrary-int.workspace = true
2323
bitflags = "2"
2424
heapless = "0.9.1"
25-
log = { version = "0.4", default-features = false, optional = true}
26-
thiserror = { version = "2", default-features = false}
25+
log = { version = "0.4", default-features = false, optional = true }
26+
thiserror.workspace = true
2727
embedded-sdmmc-types = { version = "0.1", path = "../embedded-sdmmc-types" }
28+
hex-literal = "1"
2829

2930
[dev-dependencies]
3031
chrono = "0.4"
3132
embedded-hal-bus = "0.3.0"
3233
env_logger = "0.11.8"
3334
flate2 = "1.0"
34-
hex-literal = "1.0.0"
35-
sha2 = "0.10"
35+
sha2 = "0.11"
3636
anyhow = "1"
37+
hex-literal.workspace = true
3738

3839
[features]
3940
default = ["log"]
40-
defmt-log = ["dep:defmt", "arbitrary-int/defmt"]
41+
defmt-log = ["dep:defmt", "arbitrary-int/defmt", "embedded-sdmmc-types/defmt"]
4142
log = ["dep:log"]
4243

0 commit comments

Comments
 (0)