|
2 | 2 | //!
|
3 | 3 | //! > An SD/MMC Library written in Embedded Rust
|
4 | 4 | //!
|
5 |
| -//! This crate is intended to allow you to read/write files on a FAT formatted SD |
6 |
| -//! card on your Rust Embedded device, as easily as using the `SdFat` Arduino |
7 |
| -//! library. It is written in pure-Rust, is `#![no_std]` and does not use `alloc` |
8 |
| -//! or `collections` to keep the memory footprint low. In the first instance it is |
9 |
| -//! designed for readability and simplicity over performance. |
| 5 | +//! This crate is intended to allow you to read/write files on a FAT formatted |
| 6 | +//! SD card on your Rust Embedded device, as easily as using the `SdFat` Arduino |
| 7 | +//! library. It is written in pure-Rust, is `#![no_std]` and does not use |
| 8 | +//! `alloc` or `collections` to keep the memory footprint low. In the first |
| 9 | +//! instance it is designed for readability and simplicity over performance. |
10 | 10 | //!
|
11 | 11 | //! ## Using the crate
|
12 | 12 | //!
|
13 |
| -//! 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. |
| 13 | +//! You will need something that implements the `BlockDevice` trait, which can |
| 14 | +//! read and write the 512-byte blocks (or sectors) from your card. If you were |
| 15 | +//! to implement this over USB Mass Storage, there's no reason this crate |
| 16 | +//! couldn't work with a USB Thumb Drive, but we only supply a `BlockDevice` |
| 17 | +//! suitable for reading SD and SDHC cards over SPI. |
14 | 18 | //!
|
15 |
| -//! ```rust |
| 19 | +//! ```rust,no_run |
16 | 20 | //! # struct DummySpi;
|
17 | 21 | //! # struct DummyCsPin;
|
18 | 22 | //! # struct DummyUart;
|
|
32 | 36 | //! # impl std::fmt::Write for DummyUart { fn write_str(&mut self, s: &str) -> std::fmt::Result { Ok(()) } }
|
33 | 37 | //! # use std::fmt::Write;
|
34 | 38 | //! # use embedded_sdmmc::VolumeManager;
|
35 |
| -//! # let mut uart = DummyUart; |
| 39 | +//! # fn main() -> Result<(), embedded_sdmmc::Error<embedded_sdmmc::SdMmcError>> { |
36 | 40 | //! # let mut sdmmc_spi = DummySpi;
|
37 | 41 | //! # let mut sdmmc_cs = DummyCsPin;
|
38 | 42 | //! # let time_source = DummyTimeSource;
|
39 | 43 | //! let mut spi_dev = embedded_sdmmc::SdMmcSpi::new(sdmmc_spi, sdmmc_cs);
|
40 |
| -//! write!(uart, "Init SD card...").unwrap(); |
41 |
| -//! match spi_dev.acquire() { |
42 |
| -//! Ok(block) => { |
43 |
| -//! let mut volume_mgr: VolumeManager< |
44 |
| -//! embedded_sdmmc::BlockSpi<DummySpi, DummyCsPin>, |
45 |
| -//! DummyTimeSource, |
46 |
| -//! 4, |
47 |
| -//! 4, |
48 |
| -//! > = VolumeManager::new(block, time_source); |
49 |
| -//! write!(uart, "OK!\nCard size...").unwrap(); |
50 |
| -//! match volume_mgr.device().card_size_bytes() { |
51 |
| -//! Ok(size) => writeln!(uart, "{}", size).unwrap(), |
52 |
| -//! Err(e) => writeln!(uart, "Err: {:?}", e).unwrap(), |
53 |
| -//! } |
54 |
| -//! write!(uart, "Volume 0...").unwrap(); |
55 |
| -//! match volume_mgr.get_volume(embedded_sdmmc::VolumeIdx(0)) { |
56 |
| -//! Ok(v) => writeln!(uart, "{:?}", v).unwrap(), |
57 |
| -//! Err(e) => writeln!(uart, "Err: {:?}", e).unwrap(), |
58 |
| -//! } |
| 44 | +//! let block = spi_dev.acquire()?; |
| 45 | +//! println!("Card size {} bytes", block.card_size_bytes()?); |
| 46 | +//! let mut volume_mgr = VolumeManager::new(block, time_source); |
| 47 | +//! println!("Card size is still {} bytes", volume_mgr.device().card_size_bytes()?); |
| 48 | +//! let mut volume0 = volume_mgr.get_volume(embedded_sdmmc::VolumeIdx(0))?; |
| 49 | +//! println!("Volume 0: {:?}", volume0); |
| 50 | +//! let root_dir = volume_mgr.open_root_dir(&volume0)?; |
| 51 | +//! let mut my_file = volume_mgr.open_file_in_dir( |
| 52 | +//! &mut volume0, &root_dir, "MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)?; |
| 53 | +//! while !my_file.eof() { |
| 54 | +//! let mut buffer = [0u8; 32]; |
| 55 | +//! let num_read = volume_mgr.read(&volume0, &mut my_file, &mut buffer)?; |
| 56 | +//! for b in &buffer[0..num_read] { |
| 57 | +//! print!("{}", *b as char); |
59 | 58 | //! }
|
60 |
| -//! Err(e) => writeln!(uart, "{:?}!", e).unwrap(), |
61 |
| -//! }; |
| 59 | +//! } |
| 60 | +//! volume_mgr.close_file(&volume0, my_file)?; |
| 61 | +//! volume_mgr.close_dir(&volume0, root_dir); |
| 62 | +//! # Ok(()) |
| 63 | +//! # } |
62 | 64 | //! ```
|
63 | 65 | //!
|
64 | 66 | //! ## Features
|
65 | 67 | //!
|
66 |
| -//! * `defmt-log`: By turning off the default features and enabling the `defmt-log` feature you can |
67 |
| -//! configure this crate to log messages over defmt instead. |
| 68 | +//! * `defmt-log`: By turning off the default features and enabling the |
| 69 | +//! `defmt-log` feature you can configure this crate to log messages over defmt |
| 70 | +//! instead. |
68 | 71 | //!
|
69 |
| -//! Make sure that either the `log` feature or the `defmt-log` feature is enabled. |
| 72 | +//! Make sure that either the `log` feature or the `defmt-log` feature is |
| 73 | +//! enabled. |
70 | 74 |
|
71 | 75 | #![cfg_attr(not(test), no_std)]
|
72 | 76 | #![deny(missing_docs)]
|
@@ -99,6 +103,12 @@ pub use crate::filesystem::{
|
99 | 103 | pub use crate::sdmmc::Error as SdMmcError;
|
100 | 104 | pub use crate::sdmmc::{BlockSpi, SdMmcSpi};
|
101 | 105 |
|
| 106 | +mod volume_mgr; |
| 107 | +pub use volume_mgr::VolumeManager; |
| 108 | + |
| 109 | +#[deprecated] |
| 110 | +pub use volume_mgr::VolumeManager as Controller; |
| 111 | + |
102 | 112 | // ****************************************************************************
|
103 | 113 | //
|
104 | 114 | // Public Types
|
@@ -160,8 +170,14 @@ where
|
160 | 170 | NotInBlock,
|
161 | 171 | }
|
162 | 172 |
|
163 |
| -mod volume_mgr; |
164 |
| -pub use volume_mgr::VolumeManager; |
| 173 | +impl<E> From<E> for Error<E> |
| 174 | +where |
| 175 | + E: core::fmt::Debug, |
| 176 | +{ |
| 177 | + fn from(value: E) -> Error<E> { |
| 178 | + Error::DeviceError(value) |
| 179 | + } |
| 180 | +} |
165 | 181 |
|
166 | 182 | /// Represents a partition with a filesystem within it.
|
167 | 183 | #[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
|
|
0 commit comments