From d18fefab006d0ed641fb2c4c669a813c9d4382d2 Mon Sep 17 00:00:00 2001 From: Simon Struck Date: Mon, 23 Oct 2023 00:12:06 +0200 Subject: [PATCH 01/14] Update embedded hal --- Cargo.toml | 6 ++--- examples/readme_test.rs | 8 +++---- src/lib.rs | 8 +++---- src/sdcard/mod.rs | 53 +++++++++++++++++------------------------ 4 files changed, 33 insertions(+), 42 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e94d79e..a58d83f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,13 +13,13 @@ version = "0.6.0" [dependencies] byteorder = {version = "1", default-features = false} defmt = {version = "0.3", optional = true} -embedded-hal = "0.2.3" +embedded-hal = "1.0.0-rc.1" heapless = "0.7" log = {version = "0.4", default-features = false, optional = true} [dev-dependencies] -env_logger = "0.9" -hex-literal = "0.3" +env_logger = "0.10.0" +hex-literal = "0.4.1" flate2 = "1.0" sha2 = "0.10" chrono = "0.4" diff --git a/examples/readme_test.rs b/examples/readme_test.rs index 9fffca1..6ddf58f 100644 --- a/examples/readme_test.rs +++ b/examples/readme_test.rs @@ -5,14 +5,14 @@ struct FakeSpi(); -impl embedded_hal::blocking::spi::Transfer for FakeSpi { +impl embedded_hal::spi::SpiDevice for FakeSpi { type Error = core::convert::Infallible; fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { Ok(words) } } -impl embedded_hal::blocking::spi::Write for FakeSpi { +impl embedded_hal::spi::SpiDevice for FakeSpi { type Error = core::convert::Infallible; fn write(&mut self, _words: &[u8]) -> Result<(), Self::Error> { Ok(()) @@ -21,7 +21,7 @@ impl embedded_hal::blocking::spi::Write for FakeSpi { struct FakeCs(); -impl embedded_hal::digital::v2::OutputPin for FakeCs { +impl embedded_hal::digital::OutputPin for FakeCs { type Error = core::convert::Infallible; fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) @@ -34,7 +34,7 @@ impl embedded_hal::digital::v2::OutputPin for FakeCs { struct FakeDelayer(); -impl embedded_hal::blocking::delay::DelayUs for FakeDelayer { +impl embedded_hal::delay::DelayUs for FakeDelayer { fn delay_us(&mut self, us: u8) { std::thread::sleep(std::time::Duration::from_micros(u64::from(us))); } diff --git a/src/lib.rs b/src/lib.rs index 7aa9622..6c0225f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,15 +22,15 @@ //! # struct DummyUart; //! # struct DummyTimeSource; //! # struct DummyDelayer; -//! # impl embedded_hal::blocking::spi::Transfer for DummySpi { +//! # impl embedded_hal::spi::SpiDevice for DummySpi { //! # type Error = (); //! # fn transfer<'w>(&mut self, data: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { Ok(&[0]) } //! # } -//! # impl embedded_hal::blocking::spi::Write for DummySpi { +//! # impl embedded_hal::spi::SpiDevice for DummySpi { //! # type Error = (); //! # fn write(&mut self, data: &[u8]) -> Result<(), Self::Error> { Ok(()) } //! # } -//! # impl embedded_hal::digital::v2::OutputPin for DummyCsPin { +//! # impl embedded_hal::digital::OutputPin for DummyCsPin { //! # type Error = (); //! # fn set_low(&mut self) -> Result<(), ()> { Ok(()) } //! # fn set_high(&mut self) -> Result<(), ()> { Ok(()) } @@ -38,7 +38,7 @@ //! # impl embedded_sdmmc::TimeSource for DummyTimeSource { //! # fn get_timestamp(&self) -> embedded_sdmmc::Timestamp { embedded_sdmmc::Timestamp::from_fat(0, 0) } //! # } -//! # impl embedded_hal::blocking::delay::DelayUs for DummyDelayer { +//! # impl embedded_hal::delay::DelayUs for DummyDelayer { //! # fn delay_us(&mut self, us: u8) {} //! # } //! # impl std::fmt::Write for DummyUart { fn write_str(&mut self, s: &str) -> std::fmt::Result { Ok(()) } } diff --git a/src/sdcard/mod.rs b/src/sdcard/mod.rs index 517e19c..a678d68 100644 --- a/src/sdcard/mod.rs +++ b/src/sdcard/mod.rs @@ -30,22 +30,18 @@ use crate::{debug, warn}; /// All the APIs take `&self` - mutability is handled using an inner `RefCell`. pub struct SdCard where - SPI: embedded_hal::blocking::spi::Transfer + embedded_hal::blocking::spi::Write, - CS: embedded_hal::digital::v2::OutputPin, - >::Error: core::fmt::Debug, - >::Error: core::fmt::Debug, - DELAYER: embedded_hal::blocking::delay::DelayUs, + SPI: embedded_hal::spi::SpiDevice, + CS: embedded_hal::digital::OutputPin, + DELAYER: embedded_hal::delay::DelayUs, { inner: RefCell>, } impl SdCard where - SPI: embedded_hal::blocking::spi::Transfer + embedded_hal::blocking::spi::Write, - CS: embedded_hal::digital::v2::OutputPin, - >::Error: core::fmt::Debug, - >::Error: core::fmt::Debug, - DELAYER: embedded_hal::blocking::delay::DelayUs, + SPI: embedded_hal::spi::SpiDevice + embedded_hal::spi::SpiDevice, + CS: embedded_hal::digital::OutputPin, + DELAYER: embedded_hal::delay::DelayUs, { /// Create a new SD/MMC Card driver using a raw SPI interface. /// @@ -152,11 +148,9 @@ where impl BlockDevice for SdCard where - SPI: embedded_hal::blocking::spi::Transfer + embedded_hal::blocking::spi::Write, - CS: embedded_hal::digital::v2::OutputPin, - >::Error: core::fmt::Debug, - >::Error: core::fmt::Debug, - DELAYER: embedded_hal::blocking::delay::DelayUs, + SPI: embedded_hal::spi::SpiDevice + embedded_hal::spi::SpiDevice, + CS: embedded_hal::digital::OutputPin, + DELAYER: embedded_hal::delay::DelayUs, { type Error = Error; @@ -205,11 +199,9 @@ where /// All the APIs required `&mut self`. struct SdCardInner where - SPI: embedded_hal::blocking::spi::Transfer + embedded_hal::blocking::spi::Write, - CS: embedded_hal::digital::v2::OutputPin, - >::Error: core::fmt::Debug, - >::Error: core::fmt::Debug, - DELAYER: embedded_hal::blocking::delay::DelayUs, + SPI: embedded_hal::spi::SpiDevice + embedded_hal::spi::SpiDevice, + CS: embedded_hal::digital::OutputPin, + DELAYER: embedded_hal::delay::DelayUs, { spi: SPI, cs: CS, @@ -220,11 +212,9 @@ where impl SdCardInner where - SPI: embedded_hal::blocking::spi::Transfer + embedded_hal::blocking::spi::Write, - CS: embedded_hal::digital::v2::OutputPin, - >::Error: core::fmt::Debug, - >::Error: core::fmt::Debug, - DELAYER: embedded_hal::blocking::delay::DelayUs, + SPI: embedded_hal::spi::SpiDevice + embedded_hal::spi::SpiDevice, + CS: embedded_hal::digital::OutputPin, + DELAYER: embedded_hal::delay::DelayUs, { /// Read one or more blocks, starting at the given block index. fn read(&mut self, blocks: &mut [Block], start_block_idx: BlockIdx) -> Result<(), Error> { @@ -583,13 +573,14 @@ where /// Send one byte and receive one byte over the SPI bus. fn transfer_byte(&mut self, out: u8) -> Result { + let mut read_buf = [0u8;1]; self.spi - .transfer(&mut [out]) - .map(|b| b[0]) - .map_err(|_e| Error::Transport) + .transfer(&mut read_buf,&[out]) + .map_err(|_| Error::Transport)?; + Ok(read_buf[0]) } - /// Send mutiple bytes and ignore what comes back over the SPI bus. + /// Send multiple bytes and ignore what comes back over the SPI bus. fn write_bytes(&mut self, out: &[u8]) -> Result<(), Error> { self.spi.write(out).map_err(|_e| Error::Transport)?; Ok(()) @@ -597,7 +588,7 @@ where /// Send multiple bytes and replace them with what comes back over the SPI bus. fn transfer_bytes(&mut self, in_out: &mut [u8]) -> Result<(), Error> { - self.spi.transfer(in_out).map_err(|_e| Error::Transport)?; + self.spi.transfer_in_place(in_out).map_err(|_e| Error::Transport)?; Ok(()) } @@ -753,7 +744,7 @@ impl Delay { /// `Ok(())`. fn delay(&mut self, delayer: &mut T, err: Error) -> Result<(), Error> where - T: embedded_hal::blocking::delay::DelayUs, + T: embedded_hal::delay::DelayUs, { if self.retries_left == 0 { Err(err) From df3b86a96d3dc9e80deafc7f7fefc3dbe5e826c6 Mon Sep 17 00:00:00 2001 From: Simon Struck Date: Mon, 23 Oct 2023 00:41:01 +0200 Subject: [PATCH 02/14] Fix doctests --- src/lib.rs | 67 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6c0225f..c329898 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,16 +22,37 @@ //! # struct DummyUart; //! # struct DummyTimeSource; //! # struct DummyDelayer; -//! # impl embedded_hal::spi::SpiDevice for DummySpi { -//! # type Error = (); -//! # fn transfer<'w>(&mut self, data: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { Ok(&[0]) } +//! # use embedded_hal::spi::Operation; +//! # use embedded_hal::spi::ErrorType; +//! # impl ErrorType for DummySpi { +//! # type Error = (); //! # } -//! # impl embedded_hal::spi::SpiDevice for DummySpi { -//! # type Error = (); -//! # fn write(&mut self, data: &[u8]) -> Result<(), Self::Error> { Ok(()) } +//! # impl embedded_hal::spi::SpiDevice for DummySpi { +//! # +//! # fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> { +//! # Ok(()) +//! # } +//! # +//! # fn read(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> { +//! # Ok(()) +//! # } +//! # +//! # fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> { +//! # Ok(()) +//! # } +//! # +//! # fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { +//! # Ok(()) +//! # } +//! # +//! # fn transfer_in_place(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> { +//! # Ok(()) +//! # } +//! # } +//! # impl embedded_hal::digital::ErrorType for DummyCsPin { +//! # type Error = (); //! # } //! # impl embedded_hal::digital::OutputPin for DummyCsPin { -//! # type Error = (); //! # fn set_low(&mut self) -> Result<(), ()> { Ok(()) } //! # fn set_high(&mut self) -> Result<(), ()> { Ok(()) } //! # } @@ -41,7 +62,9 @@ //! # impl embedded_hal::delay::DelayUs for DummyDelayer { //! # fn delay_us(&mut self, us: u8) {} //! # } -//! # impl std::fmt::Write for DummyUart { fn write_str(&mut self, s: &str) -> std::fmt::Result { Ok(()) } } +//! # impl std::fmt::Write for DummyUart { +//! # fn write_str(&mut self, s: &str) -> std::fmt::Result { Ok(()) } +//! # } //! # use std::fmt::Write; //! # use embedded_sdmmc::VolumeManager; //! # fn main() -> Result<(), embedded_sdmmc::Error> { @@ -49,20 +72,20 @@ //! # let mut sdmmc_cs = DummyCsPin; //! # let time_source = DummyTimeSource; //! # let delayer = DummyDelayer; -//! let sdcard = embedded_sdmmc::SdCard::new(sdmmc_spi, sdmmc_cs, delayer); -//! println!("Card size is {} bytes", sdcard.num_bytes()?); -//! let mut volume_mgr = embedded_sdmmc::VolumeManager::new(sdcard, time_source); -//! let mut volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0))?; -//! println!("Volume 0: {:?}", volume0); -//! let mut root_dir = volume0.open_root_dir()?; -//! let mut my_file = root_dir.open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)?; -//! while !my_file.is_eof() { -//! let mut buffer = [0u8; 32]; -//! let num_read = my_file.read(&mut buffer)?; -//! for b in &buffer[0..num_read] { -//! print!("{}", *b as char); -//! } -//! } +//! # let sdcard = embedded_sdmmc::SdCard::new(sdmmc_spi, sdmmc_cs, delayer); +//! # println!("Card size is {} bytes", sdcard.num_bytes()?); +//! # let mut volume_mgr = embedded_sdmmc::VolumeManager::new(sdcard, time_source); +//! # let mut volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0))?; +//! # println!("Volume 0: {:?}", volume0); +//! # let mut root_dir = volume0.open_root_dir()?; +//! # let mut my_file = root_dir.open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)?; +//! # while !my_file.is_eof() { +//! # let mut buffer = [0u8; 32]; +//! # let num_read = my_file.read(&mut buffer)?; +//! # for b in &buffer[0..num_read] { +//! # print!("{}", *b as char); +//! # } +//! # } //! # Ok(()) //! # } //! ``` From 62fb7be314fd7977b20fc2ea6c8cfa0c454eb022 Mon Sep 17 00:00:00 2001 From: Simon Struck Date: Mon, 23 Oct 2023 03:38:17 +0200 Subject: [PATCH 03/14] Remove duplicate where clauses --- src/sdcard/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sdcard/mod.rs b/src/sdcard/mod.rs index a678d68..90d85f0 100644 --- a/src/sdcard/mod.rs +++ b/src/sdcard/mod.rs @@ -39,7 +39,7 @@ where impl SdCard where - SPI: embedded_hal::spi::SpiDevice + embedded_hal::spi::SpiDevice, + SPI: embedded_hal::spi::SpiDevice, CS: embedded_hal::digital::OutputPin, DELAYER: embedded_hal::delay::DelayUs, { @@ -148,7 +148,7 @@ where impl BlockDevice for SdCard where - SPI: embedded_hal::spi::SpiDevice + embedded_hal::spi::SpiDevice, + SPI: embedded_hal::spi::SpiDevice, CS: embedded_hal::digital::OutputPin, DELAYER: embedded_hal::delay::DelayUs, { @@ -199,7 +199,7 @@ where /// All the APIs required `&mut self`. struct SdCardInner where - SPI: embedded_hal::spi::SpiDevice + embedded_hal::spi::SpiDevice, + SPI: embedded_hal::spi::SpiDevice, CS: embedded_hal::digital::OutputPin, DELAYER: embedded_hal::delay::DelayUs, { @@ -212,7 +212,7 @@ where impl SdCardInner where - SPI: embedded_hal::spi::SpiDevice + embedded_hal::spi::SpiDevice, + SPI: embedded_hal::spi::SpiDevice, CS: embedded_hal::digital::OutputPin, DELAYER: embedded_hal::delay::DelayUs, { From 7fc0c6f145f6870b0dbb1f4938ec405bcc145e9a Mon Sep 17 00:00:00 2001 From: Simon Struck Date: Mon, 23 Oct 2023 00:12:06 +0200 Subject: [PATCH 04/14] Update embedded hal --- Cargo.toml | 6 ++--- examples/readme_test.rs | 8 +++---- src/lib.rs | 8 +++---- src/sdcard/mod.rs | 53 +++++++++++++++++------------------------ 4 files changed, 33 insertions(+), 42 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e94d79e..a58d83f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,13 +13,13 @@ version = "0.6.0" [dependencies] byteorder = {version = "1", default-features = false} defmt = {version = "0.3", optional = true} -embedded-hal = "0.2.3" +embedded-hal = "1.0.0-rc.1" heapless = "0.7" log = {version = "0.4", default-features = false, optional = true} [dev-dependencies] -env_logger = "0.9" -hex-literal = "0.3" +env_logger = "0.10.0" +hex-literal = "0.4.1" flate2 = "1.0" sha2 = "0.10" chrono = "0.4" diff --git a/examples/readme_test.rs b/examples/readme_test.rs index 9fffca1..6ddf58f 100644 --- a/examples/readme_test.rs +++ b/examples/readme_test.rs @@ -5,14 +5,14 @@ struct FakeSpi(); -impl embedded_hal::blocking::spi::Transfer for FakeSpi { +impl embedded_hal::spi::SpiDevice for FakeSpi { type Error = core::convert::Infallible; fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { Ok(words) } } -impl embedded_hal::blocking::spi::Write for FakeSpi { +impl embedded_hal::spi::SpiDevice for FakeSpi { type Error = core::convert::Infallible; fn write(&mut self, _words: &[u8]) -> Result<(), Self::Error> { Ok(()) @@ -21,7 +21,7 @@ impl embedded_hal::blocking::spi::Write for FakeSpi { struct FakeCs(); -impl embedded_hal::digital::v2::OutputPin for FakeCs { +impl embedded_hal::digital::OutputPin for FakeCs { type Error = core::convert::Infallible; fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) @@ -34,7 +34,7 @@ impl embedded_hal::digital::v2::OutputPin for FakeCs { struct FakeDelayer(); -impl embedded_hal::blocking::delay::DelayUs for FakeDelayer { +impl embedded_hal::delay::DelayUs for FakeDelayer { fn delay_us(&mut self, us: u8) { std::thread::sleep(std::time::Duration::from_micros(u64::from(us))); } diff --git a/src/lib.rs b/src/lib.rs index 7aa9622..6c0225f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,15 +22,15 @@ //! # struct DummyUart; //! # struct DummyTimeSource; //! # struct DummyDelayer; -//! # impl embedded_hal::blocking::spi::Transfer for DummySpi { +//! # impl embedded_hal::spi::SpiDevice for DummySpi { //! # type Error = (); //! # fn transfer<'w>(&mut self, data: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { Ok(&[0]) } //! # } -//! # impl embedded_hal::blocking::spi::Write for DummySpi { +//! # impl embedded_hal::spi::SpiDevice for DummySpi { //! # type Error = (); //! # fn write(&mut self, data: &[u8]) -> Result<(), Self::Error> { Ok(()) } //! # } -//! # impl embedded_hal::digital::v2::OutputPin for DummyCsPin { +//! # impl embedded_hal::digital::OutputPin for DummyCsPin { //! # type Error = (); //! # fn set_low(&mut self) -> Result<(), ()> { Ok(()) } //! # fn set_high(&mut self) -> Result<(), ()> { Ok(()) } @@ -38,7 +38,7 @@ //! # impl embedded_sdmmc::TimeSource for DummyTimeSource { //! # fn get_timestamp(&self) -> embedded_sdmmc::Timestamp { embedded_sdmmc::Timestamp::from_fat(0, 0) } //! # } -//! # impl embedded_hal::blocking::delay::DelayUs for DummyDelayer { +//! # impl embedded_hal::delay::DelayUs for DummyDelayer { //! # fn delay_us(&mut self, us: u8) {} //! # } //! # impl std::fmt::Write for DummyUart { fn write_str(&mut self, s: &str) -> std::fmt::Result { Ok(()) } } diff --git a/src/sdcard/mod.rs b/src/sdcard/mod.rs index 517e19c..a678d68 100644 --- a/src/sdcard/mod.rs +++ b/src/sdcard/mod.rs @@ -30,22 +30,18 @@ use crate::{debug, warn}; /// All the APIs take `&self` - mutability is handled using an inner `RefCell`. pub struct SdCard where - SPI: embedded_hal::blocking::spi::Transfer + embedded_hal::blocking::spi::Write, - CS: embedded_hal::digital::v2::OutputPin, - >::Error: core::fmt::Debug, - >::Error: core::fmt::Debug, - DELAYER: embedded_hal::blocking::delay::DelayUs, + SPI: embedded_hal::spi::SpiDevice, + CS: embedded_hal::digital::OutputPin, + DELAYER: embedded_hal::delay::DelayUs, { inner: RefCell>, } impl SdCard where - SPI: embedded_hal::blocking::spi::Transfer + embedded_hal::blocking::spi::Write, - CS: embedded_hal::digital::v2::OutputPin, - >::Error: core::fmt::Debug, - >::Error: core::fmt::Debug, - DELAYER: embedded_hal::blocking::delay::DelayUs, + SPI: embedded_hal::spi::SpiDevice + embedded_hal::spi::SpiDevice, + CS: embedded_hal::digital::OutputPin, + DELAYER: embedded_hal::delay::DelayUs, { /// Create a new SD/MMC Card driver using a raw SPI interface. /// @@ -152,11 +148,9 @@ where impl BlockDevice for SdCard where - SPI: embedded_hal::blocking::spi::Transfer + embedded_hal::blocking::spi::Write, - CS: embedded_hal::digital::v2::OutputPin, - >::Error: core::fmt::Debug, - >::Error: core::fmt::Debug, - DELAYER: embedded_hal::blocking::delay::DelayUs, + SPI: embedded_hal::spi::SpiDevice + embedded_hal::spi::SpiDevice, + CS: embedded_hal::digital::OutputPin, + DELAYER: embedded_hal::delay::DelayUs, { type Error = Error; @@ -205,11 +199,9 @@ where /// All the APIs required `&mut self`. struct SdCardInner where - SPI: embedded_hal::blocking::spi::Transfer + embedded_hal::blocking::spi::Write, - CS: embedded_hal::digital::v2::OutputPin, - >::Error: core::fmt::Debug, - >::Error: core::fmt::Debug, - DELAYER: embedded_hal::blocking::delay::DelayUs, + SPI: embedded_hal::spi::SpiDevice + embedded_hal::spi::SpiDevice, + CS: embedded_hal::digital::OutputPin, + DELAYER: embedded_hal::delay::DelayUs, { spi: SPI, cs: CS, @@ -220,11 +212,9 @@ where impl SdCardInner where - SPI: embedded_hal::blocking::spi::Transfer + embedded_hal::blocking::spi::Write, - CS: embedded_hal::digital::v2::OutputPin, - >::Error: core::fmt::Debug, - >::Error: core::fmt::Debug, - DELAYER: embedded_hal::blocking::delay::DelayUs, + SPI: embedded_hal::spi::SpiDevice + embedded_hal::spi::SpiDevice, + CS: embedded_hal::digital::OutputPin, + DELAYER: embedded_hal::delay::DelayUs, { /// Read one or more blocks, starting at the given block index. fn read(&mut self, blocks: &mut [Block], start_block_idx: BlockIdx) -> Result<(), Error> { @@ -583,13 +573,14 @@ where /// Send one byte and receive one byte over the SPI bus. fn transfer_byte(&mut self, out: u8) -> Result { + let mut read_buf = [0u8;1]; self.spi - .transfer(&mut [out]) - .map(|b| b[0]) - .map_err(|_e| Error::Transport) + .transfer(&mut read_buf,&[out]) + .map_err(|_| Error::Transport)?; + Ok(read_buf[0]) } - /// Send mutiple bytes and ignore what comes back over the SPI bus. + /// Send multiple bytes and ignore what comes back over the SPI bus. fn write_bytes(&mut self, out: &[u8]) -> Result<(), Error> { self.spi.write(out).map_err(|_e| Error::Transport)?; Ok(()) @@ -597,7 +588,7 @@ where /// Send multiple bytes and replace them with what comes back over the SPI bus. fn transfer_bytes(&mut self, in_out: &mut [u8]) -> Result<(), Error> { - self.spi.transfer(in_out).map_err(|_e| Error::Transport)?; + self.spi.transfer_in_place(in_out).map_err(|_e| Error::Transport)?; Ok(()) } @@ -753,7 +744,7 @@ impl Delay { /// `Ok(())`. fn delay(&mut self, delayer: &mut T, err: Error) -> Result<(), Error> where - T: embedded_hal::blocking::delay::DelayUs, + T: embedded_hal::delay::DelayUs, { if self.retries_left == 0 { Err(err) From a5eb76596cc025f1f1f120230cc17afd3006c37d Mon Sep 17 00:00:00 2001 From: Simon Struck Date: Mon, 23 Oct 2023 00:41:01 +0200 Subject: [PATCH 05/14] Fix doctests --- src/lib.rs | 67 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6c0225f..c329898 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,16 +22,37 @@ //! # struct DummyUart; //! # struct DummyTimeSource; //! # struct DummyDelayer; -//! # impl embedded_hal::spi::SpiDevice for DummySpi { -//! # type Error = (); -//! # fn transfer<'w>(&mut self, data: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { Ok(&[0]) } +//! # use embedded_hal::spi::Operation; +//! # use embedded_hal::spi::ErrorType; +//! # impl ErrorType for DummySpi { +//! # type Error = (); //! # } -//! # impl embedded_hal::spi::SpiDevice for DummySpi { -//! # type Error = (); -//! # fn write(&mut self, data: &[u8]) -> Result<(), Self::Error> { Ok(()) } +//! # impl embedded_hal::spi::SpiDevice for DummySpi { +//! # +//! # fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> { +//! # Ok(()) +//! # } +//! # +//! # fn read(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> { +//! # Ok(()) +//! # } +//! # +//! # fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> { +//! # Ok(()) +//! # } +//! # +//! # fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { +//! # Ok(()) +//! # } +//! # +//! # fn transfer_in_place(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> { +//! # Ok(()) +//! # } +//! # } +//! # impl embedded_hal::digital::ErrorType for DummyCsPin { +//! # type Error = (); //! # } //! # impl embedded_hal::digital::OutputPin for DummyCsPin { -//! # type Error = (); //! # fn set_low(&mut self) -> Result<(), ()> { Ok(()) } //! # fn set_high(&mut self) -> Result<(), ()> { Ok(()) } //! # } @@ -41,7 +62,9 @@ //! # impl embedded_hal::delay::DelayUs for DummyDelayer { //! # fn delay_us(&mut self, us: u8) {} //! # } -//! # impl std::fmt::Write for DummyUart { fn write_str(&mut self, s: &str) -> std::fmt::Result { Ok(()) } } +//! # impl std::fmt::Write for DummyUart { +//! # fn write_str(&mut self, s: &str) -> std::fmt::Result { Ok(()) } +//! # } //! # use std::fmt::Write; //! # use embedded_sdmmc::VolumeManager; //! # fn main() -> Result<(), embedded_sdmmc::Error> { @@ -49,20 +72,20 @@ //! # let mut sdmmc_cs = DummyCsPin; //! # let time_source = DummyTimeSource; //! # let delayer = DummyDelayer; -//! let sdcard = embedded_sdmmc::SdCard::new(sdmmc_spi, sdmmc_cs, delayer); -//! println!("Card size is {} bytes", sdcard.num_bytes()?); -//! let mut volume_mgr = embedded_sdmmc::VolumeManager::new(sdcard, time_source); -//! let mut volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0))?; -//! println!("Volume 0: {:?}", volume0); -//! let mut root_dir = volume0.open_root_dir()?; -//! let mut my_file = root_dir.open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)?; -//! while !my_file.is_eof() { -//! let mut buffer = [0u8; 32]; -//! let num_read = my_file.read(&mut buffer)?; -//! for b in &buffer[0..num_read] { -//! print!("{}", *b as char); -//! } -//! } +//! # let sdcard = embedded_sdmmc::SdCard::new(sdmmc_spi, sdmmc_cs, delayer); +//! # println!("Card size is {} bytes", sdcard.num_bytes()?); +//! # let mut volume_mgr = embedded_sdmmc::VolumeManager::new(sdcard, time_source); +//! # let mut volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0))?; +//! # println!("Volume 0: {:?}", volume0); +//! # let mut root_dir = volume0.open_root_dir()?; +//! # let mut my_file = root_dir.open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)?; +//! # while !my_file.is_eof() { +//! # let mut buffer = [0u8; 32]; +//! # let num_read = my_file.read(&mut buffer)?; +//! # for b in &buffer[0..num_read] { +//! # print!("{}", *b as char); +//! # } +//! # } //! # Ok(()) //! # } //! ``` From 69d80473adc0c84e1936d8e847df5a369608ca3e Mon Sep 17 00:00:00 2001 From: Simon Struck Date: Mon, 23 Oct 2023 03:38:17 +0200 Subject: [PATCH 06/14] Remove duplicate where clauses --- src/sdcard/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sdcard/mod.rs b/src/sdcard/mod.rs index a678d68..90d85f0 100644 --- a/src/sdcard/mod.rs +++ b/src/sdcard/mod.rs @@ -39,7 +39,7 @@ where impl SdCard where - SPI: embedded_hal::spi::SpiDevice + embedded_hal::spi::SpiDevice, + SPI: embedded_hal::spi::SpiDevice, CS: embedded_hal::digital::OutputPin, DELAYER: embedded_hal::delay::DelayUs, { @@ -148,7 +148,7 @@ where impl BlockDevice for SdCard where - SPI: embedded_hal::spi::SpiDevice + embedded_hal::spi::SpiDevice, + SPI: embedded_hal::spi::SpiDevice, CS: embedded_hal::digital::OutputPin, DELAYER: embedded_hal::delay::DelayUs, { @@ -199,7 +199,7 @@ where /// All the APIs required `&mut self`. struct SdCardInner where - SPI: embedded_hal::spi::SpiDevice + embedded_hal::spi::SpiDevice, + SPI: embedded_hal::spi::SpiDevice, CS: embedded_hal::digital::OutputPin, DELAYER: embedded_hal::delay::DelayUs, { @@ -212,7 +212,7 @@ where impl SdCardInner where - SPI: embedded_hal::spi::SpiDevice + embedded_hal::spi::SpiDevice, + SPI: embedded_hal::spi::SpiDevice, CS: embedded_hal::digital::OutputPin, DELAYER: embedded_hal::delay::DelayUs, { From 4d3aa31e4d40b057c86b7aaec802799de4ddbacf Mon Sep 17 00:00:00 2001 From: Gray Olson Date: Mon, 30 Oct 2023 10:12:41 +0100 Subject: [PATCH 07/14] Create and document DummyCsPin for use with e-h1.0 --- Cargo.toml | 1 + examples/readme_test.rs | 45 ++++++++++++++++++++++-------- src/sdcard/mod.rs | 61 ++++++++++++++++++++++++++++++++++++----- 3 files changed, 88 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a58d83f..83f1a7a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ hex-literal = "0.4.1" flate2 = "1.0" sha2 = "0.10" chrono = "0.4" +embedded-hal-bus = "0.1.0-rc.1" [features] default = ["log"] diff --git a/examples/readme_test.rs b/examples/readme_test.rs index 6ddf58f..14b7030 100644 --- a/examples/readme_test.rs +++ b/examples/readme_test.rs @@ -3,26 +3,45 @@ //! We add enough stuff to make it compile, but it won't run because our fake //! SPI doesn't do any replies. -struct FakeSpi(); +use core::cell::RefCell; -impl embedded_hal::spi::SpiDevice for FakeSpi { +use embedded_sdmmc::sdcard::DummyCsPin; + +struct FakeSpiBus(); + +impl embedded_hal::spi::ErrorType for FakeSpiBus { type Error = core::convert::Infallible; - fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { - Ok(words) - } } -impl embedded_hal::spi::SpiDevice for FakeSpi { - type Error = core::convert::Infallible; - fn write(&mut self, _words: &[u8]) -> Result<(), Self::Error> { +impl embedded_hal::spi::SpiBus for FakeSpiBus { + fn read(&mut self, _: &mut [u8]) -> Result<(), Self::Error> { + Ok(()) + } + + fn write(&mut self, _: &[u8]) -> Result<(), Self::Error> { + Ok(()) + } + + fn transfer(&mut self, _: &mut [u8], _: &[u8]) -> Result<(), Self::Error> { + Ok(()) + } + + fn transfer_in_place(&mut self, _: &mut [u8]) -> Result<(), Self::Error> { + Ok(()) + } + + fn flush(&mut self) -> Result<(), Self::Error> { Ok(()) } } struct FakeCs(); -impl embedded_hal::digital::OutputPin for FakeCs { +impl embedded_hal::digital::ErrorType for FakeCs { type Error = core::convert::Infallible; +} + +impl embedded_hal::digital::OutputPin for FakeCs { fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) } @@ -32,10 +51,11 @@ impl embedded_hal::digital::OutputPin for FakeCs { } } +#[derive(Clone, Copy)] struct FakeDelayer(); impl embedded_hal::delay::DelayUs for FakeDelayer { - fn delay_us(&mut self, us: u8) { + fn delay_us(&mut self, us: u32) { std::thread::sleep(std::time::Duration::from_micros(u64::from(us))); } } @@ -74,9 +94,10 @@ impl From for Error { } fn main() -> Result<(), Error> { - let sdmmc_spi = FakeSpi(); - let sdmmc_cs = FakeCs(); + let spi_bus = RefCell::new(FakeSpiBus()); let delay = FakeDelayer(); + let sdmmc_spi = embedded_hal_bus::spi::RefCellDevice::new(&spi_bus, DummyCsPin, delay); + let sdmmc_cs = FakeCs(); let time_source = FakeTimesource(); // Build an SD Card interface out of an SPI device, a chip-select pin and the delay object let sdcard = embedded_sdmmc::SdCard::new(sdmmc_spi, sdmmc_cs, delay); diff --git a/src/sdcard/mod.rs b/src/sdcard/mod.rs index 90d85f0..a343813 100644 --- a/src/sdcard/mod.rs +++ b/src/sdcard/mod.rs @@ -21,11 +21,50 @@ use crate::{debug, warn}; // Types and Implementations // **************************************************************************** +/// A dummy "CS pin" that does nothing when set high or low. +/// +/// Should be used when constructing an [`SpiDevice`] implementation for use with [`SdCard`]. +/// +/// Let the [`SpiDevice`] use this dummy CS pin that does not actually do anything, and pass the +/// card's real CS pin to [`SdCard`]'s constructor. This allows the driver to have more +/// fine-grained control of how the CS pin is managed than is allowed by default using the +/// [`SpiDevice`] trait, which is needed to implement the SD/MMC SPI communication spec correctly. +/// +/// If you're not sure how to get a [`SpiDevice`], you may use one of the implementations +/// in the [`embedded-hal-bus`] crate, providing a wrapped version of your platform's HAL-provided +/// [`SpiBus`] and [`DelayUs`] as well as our [`DummyCsPin`] in the constructor. +/// +/// [`SpiDevice`]: embedded_hal::spi::SpiDevice +/// [`SpiBus`]: embedded_hal::spi::SpiBus +/// [`DelayUs`]: embedded_hal::delay::DelayUs +/// [`embedded-hal-bus`]: https://docs.rs/embedded-hal-bus +pub struct DummyCsPin; + +impl embedded_hal::digital::ErrorType for DummyCsPin { + type Error = core::convert::Infallible; +} + +impl embedded_hal::digital::OutputPin for DummyCsPin { + #[inline(always)] + fn set_low(&mut self) -> Result<(), Self::Error> { + Ok(()) + } + + #[inline(always)] + fn set_high(&mut self) -> Result<(), Self::Error> { + Ok(()) + } +} + /// Represents an SD Card on an SPI bus. /// -/// Built from an SPI peripheral and a Chip Select pin. We need Chip Select to -/// be separate so we can clock out some bytes without Chip Select asserted -/// (which "flushes the SD cards registers" according to the spec). +/// Built from an [`SpiDevice`] implementation and a Chip Select pin. +/// Unfortunately, We need control of the chip select pin separately from the [`SpiDevice`] +/// implementation so we can clock out some bytes without Chip Select asserted +/// (which is necessary to make the SD card actually release the Spi bus after performing +/// operations on it, according to the spec). To support this, we provide [`DummyCsPin`] +/// which should be provided to your chosen [`SpiDevice`] implementation rather than the card's +/// actual CS pin. Then provide the actual CS pin to [`SdCard`]'s constructor. /// /// All the APIs take `&self` - mutability is handled using an inner `RefCell`. pub struct SdCard @@ -45,6 +84,9 @@ where { /// Create a new SD/MMC Card driver using a raw SPI interface. /// + /// See the docs of the [`SdCard`] struct for more information about + /// how to construct the needed `SPI` and `CS` types. + /// /// The card will not be initialised at this time. Initialisation is /// deferred until a method is called on the object. /// @@ -55,6 +97,9 @@ where /// 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. + /// /// The card will not be initialised at this time. Initialisation is /// deferred until a method is called on the object. pub fn new_with_options( @@ -573,9 +618,9 @@ where /// Send one byte and receive one byte over the SPI bus. fn transfer_byte(&mut self, out: u8) -> Result { - let mut read_buf = [0u8;1]; + let mut read_buf = [0u8; 1]; self.spi - .transfer(&mut read_buf,&[out]) + .transfer(&mut read_buf, &[out]) .map_err(|_| Error::Transport)?; Ok(read_buf[0]) } @@ -588,7 +633,9 @@ where /// Send multiple bytes and replace them with what comes back over the SPI bus. fn transfer_bytes(&mut self, in_out: &mut [u8]) -> Result<(), Error> { - self.spi.transfer_in_place(in_out).map_err(|_e| Error::Transport)?; + self.spi + .transfer_in_place(in_out) + .map_err(|_e| Error::Transport)?; Ok(()) } @@ -680,7 +727,7 @@ pub enum CardType { /// Uses byte-addressing internally, so limited to 2GiB in size. SD2, /// An high-capacity 'SDHC' Card. - /// + /// /// Uses block-addressing internally to support capacities above 2GiB. SDHC, } From 5d31339856977a07b4875071b06a6314c114af86 Mon Sep 17 00:00:00 2001 From: Simon Struck Date: Mon, 30 Oct 2023 13:55:21 +0100 Subject: [PATCH 08/14] Fix doctest --- src/lib.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c329898..7b41145 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,8 +24,10 @@ //! # struct DummyDelayer; //! # use embedded_hal::spi::Operation; //! # use embedded_hal::spi::ErrorType; +//! # use core::convert::Infallible; +//! # use core::fmt; //! # impl ErrorType for DummySpi { -//! # type Error = (); +//! # type Error = Infallible; //! # } //! # impl embedded_hal::spi::SpiDevice for DummySpi { //! # @@ -50,22 +52,21 @@ //! # } //! # } //! # impl embedded_hal::digital::ErrorType for DummyCsPin { -//! # type Error = (); +//! # type Error = Infallible; //! # } //! # impl embedded_hal::digital::OutputPin for DummyCsPin { -//! # fn set_low(&mut self) -> Result<(), ()> { Ok(()) } -//! # fn set_high(&mut self) -> Result<(), ()> { Ok(()) } +//! # fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) } +//! # fn set_high(&mut self) -> Result<(), Self::Error> { Ok(()) } //! # } //! # impl embedded_sdmmc::TimeSource for DummyTimeSource { //! # fn get_timestamp(&self) -> embedded_sdmmc::Timestamp { embedded_sdmmc::Timestamp::from_fat(0, 0) } //! # } //! # impl embedded_hal::delay::DelayUs for DummyDelayer { -//! # fn delay_us(&mut self, us: u8) {} +//! # fn delay_us(&mut self, us: u32) {} //! # } -//! # impl std::fmt::Write for DummyUart { -//! # fn write_str(&mut self, s: &str) -> std::fmt::Result { Ok(()) } +//! # impl fmt::Write for DummyUart { +//! # fn write_str(&mut self, s: &str) -> fmt::Result { Ok(()) } //! # } -//! # use std::fmt::Write; //! # use embedded_sdmmc::VolumeManager; //! # fn main() -> Result<(), embedded_sdmmc::Error> { //! # let mut sdmmc_spi = DummySpi; @@ -74,7 +75,7 @@ //! # let delayer = DummyDelayer; //! # let sdcard = embedded_sdmmc::SdCard::new(sdmmc_spi, sdmmc_cs, delayer); //! # println!("Card size is {} bytes", sdcard.num_bytes()?); -//! # let mut volume_mgr = embedded_sdmmc::VolumeManager::new(sdcard, time_source); +//! # let mut volume_mgr = VolumeManager::new(sdcard, time_source); //! # let mut volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0))?; //! # println!("Volume 0: {:?}", volume0); //! # let mut root_dir = volume0.open_root_dir()?; From 5fe01bf23f628d9462d65954df2df4a1c8306800 Mon Sep 17 00:00:00 2001 From: jakezhu9 Date: Wed, 10 Jan 2024 14:58:04 +0800 Subject: [PATCH 09/14] lib: update dependency embedded-hal to 1.0.0 Signed-off-by: jakezhu9 --- Cargo.toml | 4 ++-- examples/readme_test.rs | 6 +++--- src/lib.rs | 33 +++++++++------------------------ src/sdcard/mod.rs | 18 +++++++++--------- 4 files changed, 23 insertions(+), 38 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 83f1a7a..20322ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ version = "0.6.0" [dependencies] byteorder = {version = "1", default-features = false} defmt = {version = "0.3", optional = true} -embedded-hal = "1.0.0-rc.1" +embedded-hal = "1.0.0" heapless = "0.7" log = {version = "0.4", default-features = false, optional = true} @@ -23,7 +23,7 @@ hex-literal = "0.4.1" flate2 = "1.0" sha2 = "0.10" chrono = "0.4" -embedded-hal-bus = "0.1.0-rc.1" +embedded-hal-bus = "0.1.0" [features] default = ["log"] diff --git a/examples/readme_test.rs b/examples/readme_test.rs index 14b7030..4c8ee0c 100644 --- a/examples/readme_test.rs +++ b/examples/readme_test.rs @@ -54,9 +54,9 @@ impl embedded_hal::digital::OutputPin for FakeCs { #[derive(Clone, Copy)] struct FakeDelayer(); -impl embedded_hal::delay::DelayUs for FakeDelayer { - fn delay_us(&mut self, us: u32) { - std::thread::sleep(std::time::Duration::from_micros(u64::from(us))); +impl embedded_hal::delay::DelayNs for FakeDelayer { + fn delay_ns(&mut self, ns: u32) { + std::thread::sleep(std::time::Duration::from_nanos(u64::from(ns))); } } diff --git a/src/lib.rs b/src/lib.rs index 7b41145..be78233 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,32 +27,17 @@ //! # use core::convert::Infallible; //! # use core::fmt; //! # impl ErrorType for DummySpi { -//! # type Error = Infallible; +//! # type Error = Infallible; //! # } //! # impl embedded_hal::spi::SpiDevice for DummySpi { -//! # -//! # fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> { -//! # Ok(()) -//! # } -//! # -//! # fn read(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> { -//! # Ok(()) -//! # } -//! # -//! # fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> { -//! # Ok(()) -//! # } -//! # -//! # fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { -//! # Ok(()) -//! # } -//! # -//! # fn transfer_in_place(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> { -//! # Ok(()) -//! # } +//! # fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> { Ok(()) } +//! # fn read(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> { Ok(()) } +//! # fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> { Ok(()) } +//! # fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { Ok(()) } +//! # fn transfer_in_place(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> { Ok(()) } //! # } //! # impl embedded_hal::digital::ErrorType for DummyCsPin { -//! # type Error = Infallible; +//! # type Error = Infallible; //! # } //! # impl embedded_hal::digital::OutputPin for DummyCsPin { //! # fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) } @@ -61,8 +46,8 @@ //! # impl embedded_sdmmc::TimeSource for DummyTimeSource { //! # fn get_timestamp(&self) -> embedded_sdmmc::Timestamp { embedded_sdmmc::Timestamp::from_fat(0, 0) } //! # } -//! # impl embedded_hal::delay::DelayUs for DummyDelayer { -//! # fn delay_us(&mut self, us: u32) {} +//! # impl embedded_hal::delay::DelayNs for DummyDelayer { +//! # fn delay_ns(&mut self, ns: u32) {} //! # } //! # impl fmt::Write for DummyUart { //! # fn write_str(&mut self, s: &str) -> fmt::Result { Ok(()) } diff --git a/src/sdcard/mod.rs b/src/sdcard/mod.rs index 89e0310..ea302e2 100644 --- a/src/sdcard/mod.rs +++ b/src/sdcard/mod.rs @@ -32,11 +32,11 @@ use crate::{debug, warn}; /// /// If you're not sure how to get a [`SpiDevice`], you may use one of the implementations /// in the [`embedded-hal-bus`] crate, providing a wrapped version of your platform's HAL-provided -/// [`SpiBus`] and [`DelayUs`] as well as our [`DummyCsPin`] in the constructor. +/// [`SpiBus`] and [`DelayNs`] as well as our [`DummyCsPin`] in the constructor. /// /// [`SpiDevice`]: embedded_hal::spi::SpiDevice /// [`SpiBus`]: embedded_hal::spi::SpiBus -/// [`DelayUs`]: embedded_hal::delay::DelayUs +/// [`DelayNs`]: embedded_hal::delay::DelayNs /// [`embedded-hal-bus`]: https://docs.rs/embedded-hal-bus pub struct DummyCsPin; @@ -71,7 +71,7 @@ pub struct SdCard where SPI: embedded_hal::spi::SpiDevice, CS: embedded_hal::digital::OutputPin, - DELAYER: embedded_hal::delay::DelayUs, + DELAYER: embedded_hal::delay::DelayNs, { inner: RefCell>, } @@ -80,7 +80,7 @@ impl SdCard where SPI: embedded_hal::spi::SpiDevice, CS: embedded_hal::digital::OutputPin, - DELAYER: embedded_hal::delay::DelayUs, + DELAYER: embedded_hal::delay::DelayNs, { /// Create a new SD/MMC Card driver using a raw SPI interface. /// @@ -195,7 +195,7 @@ impl BlockDevice for SdCard where SPI: embedded_hal::spi::SpiDevice, CS: embedded_hal::digital::OutputPin, - DELAYER: embedded_hal::delay::DelayUs, + DELAYER: embedded_hal::delay::DelayNs, { type Error = Error; @@ -246,7 +246,7 @@ struct SdCardInner where SPI: embedded_hal::spi::SpiDevice, CS: embedded_hal::digital::OutputPin, - DELAYER: embedded_hal::delay::DelayUs, + DELAYER: embedded_hal::delay::DelayNs, { spi: SPI, cs: CS, @@ -259,7 +259,7 @@ impl SdCardInner where SPI: embedded_hal::spi::SpiDevice, CS: embedded_hal::digital::OutputPin, - DELAYER: embedded_hal::delay::DelayUs, + DELAYER: embedded_hal::delay::DelayNs, { /// Read one or more blocks, starting at the given block index. fn read(&mut self, blocks: &mut [Block], start_block_idx: BlockIdx) -> Result<(), Error> { @@ -620,7 +620,7 @@ where fn transfer_byte(&mut self, out: u8) -> Result { let mut read_buf = [0u8; 1]; self.spi - .transfer(&mut read_buf,&[out]) + .transfer(&mut read_buf, &[out]) .map_err(|_| Error::Transport)?; Ok(read_buf[0]) } @@ -791,7 +791,7 @@ impl Delay { /// `Ok(())`. fn delay(&mut self, delayer: &mut T, err: Error) -> Result<(), Error> where - T: embedded_hal::delay::DelayUs, + T: embedded_hal::delay::DelayNs, { if self.retries_left == 0 { Err(err) From 13712926d315eb9a170c488a937e2cef99668b0d Mon Sep 17 00:00:00 2001 From: Simon Struck Date: Thu, 11 Jan 2024 19:59:50 +0100 Subject: [PATCH 10/14] Fix doc warnings --- src/sdcard/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sdcard/mod.rs b/src/sdcard/mod.rs index ea302e2..8f0dbb9 100644 --- a/src/sdcard/mod.rs +++ b/src/sdcard/mod.rs @@ -67,6 +67,8 @@ impl embedded_hal::digital::OutputPin for DummyCsPin { /// actual CS pin. Then provide the actual CS pin to [`SdCard`]'s constructor. /// /// All the APIs take `&self` - mutability is handled using an inner `RefCell`. +/// +/// [`SpiDevice`]: embedded_hal::spi::SpiDevice pub struct SdCard where SPI: embedded_hal::spi::SpiDevice, From 7e3390613a4743e0bf9cf13f94a3ec345b181dee Mon Sep 17 00:00:00 2001 From: Simon Struck Date: Thu, 11 Jan 2024 20:14:24 +0100 Subject: [PATCH 11/14] Annotate readme_test.rs to make section clearer --- examples/readme_test.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/readme_test.rs b/examples/readme_test.rs index 4c8ee0c..153b758 100644 --- a/examples/readme_test.rs +++ b/examples/readme_test.rs @@ -94,11 +94,14 @@ impl From for Error { } fn main() -> Result<(), Error> { + // BEGIN Fake stuff that will be replaced with real peripherals let spi_bus = RefCell::new(FakeSpiBus()); let delay = FakeDelayer(); let sdmmc_spi = embedded_hal_bus::spi::RefCellDevice::new(&spi_bus, DummyCsPin, delay); let sdmmc_cs = FakeCs(); let time_source = FakeTimesource(); + // END Fake stuff that will be replaced with real peripherals + // Build an SD Card interface out of an SPI device, a chip-select pin and the delay object let sdcard = embedded_sdmmc::SdCard::new(sdmmc_spi, sdmmc_cs, delay); // Get the card size (this also triggers card initialisation because it's not been done yet) From fe739b45ef5793827c2aaafccf82701058e996dc Mon Sep 17 00:00:00 2001 From: Simon Struck Date: Thu, 11 Jan 2024 20:14:58 +0100 Subject: [PATCH 12/14] Commented in doctest --- src/lib.rs | 114 ++++++++++++++++++++++++++--------------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9247ea1..7cf671f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,63 +17,63 @@ //! suitable for reading SD and SDHC cards over SPI. //! //! ```rust,no_run -//! # struct DummySpi; -//! # struct DummyCsPin; -//! # struct DummyUart; -//! # struct DummyTimeSource; -//! # struct DummyDelayer; -//! # use embedded_hal::spi::Operation; -//! # use embedded_hal::spi::ErrorType; -//! # use core::convert::Infallible; -//! # use core::fmt; -//! # impl ErrorType for DummySpi { -//! # type Error = Infallible; -//! # } -//! # impl embedded_hal::spi::SpiDevice for DummySpi { -//! # fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> { Ok(()) } -//! # fn read(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> { Ok(()) } -//! # fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> { Ok(()) } -//! # fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { Ok(()) } -//! # fn transfer_in_place(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> { Ok(()) } -//! # } -//! # impl embedded_hal::digital::ErrorType for DummyCsPin { -//! # type Error = Infallible; -//! # } -//! # impl embedded_hal::digital::OutputPin for DummyCsPin { -//! # fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) } -//! # fn set_high(&mut self) -> Result<(), Self::Error> { Ok(()) } -//! # } -//! # impl embedded_sdmmc::TimeSource for DummyTimeSource { -//! # fn get_timestamp(&self) -> embedded_sdmmc::Timestamp { embedded_sdmmc::Timestamp::from_fat(0, 0) } -//! # } -//! # impl embedded_hal::delay::DelayNs for DummyDelayer { -//! # fn delay_ns(&mut self, ns: u32) {} -//! # } -//! # impl fmt::Write for DummyUart { -//! # fn write_str(&mut self, s: &str) -> fmt::Result { Ok(()) } -//! # } -//! # use embedded_sdmmc::VolumeManager; -//! # fn main() -> Result<(), embedded_sdmmc::Error> { -//! # let mut sdmmc_spi = DummySpi; -//! # let mut sdmmc_cs = DummyCsPin; -//! # let time_source = DummyTimeSource; -//! # let delayer = DummyDelayer; -//! # let sdcard = embedded_sdmmc::SdCard::new(sdmmc_spi, sdmmc_cs, delayer); -//! # println!("Card size is {} bytes", sdcard.num_bytes()?); -//! # let mut volume_mgr = VolumeManager::new(sdcard, time_source); -//! # let mut volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0))?; -//! # println!("Volume 0: {:?}", volume0); -//! # let mut root_dir = volume0.open_root_dir()?; -//! # let mut my_file = root_dir.open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)?; -//! # while !my_file.is_eof() { -//! # let mut buffer = [0u8; 32]; -//! # let num_read = my_file.read(&mut buffer)?; -//! # for b in &buffer[0..num_read] { -//! # print!("{}", *b as char); -//! # } -//! # } -//! # Ok(()) -//! # } +//! struct DummySpi; +//! struct DummyCsPin; +//! struct DummyUart; +//! struct DummyTimeSource; +//! struct DummyDelayer; +//! use embedded_hal::spi::Operation; +//! use embedded_hal::spi::ErrorType; +//! use core::convert::Infallible; +//! use core::fmt; +//! impl ErrorType for DummySpi { +//! type Error = Infallible; +//! } +//! impl embedded_hal::spi::SpiDevice for DummySpi { +//! fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> { Ok(()) } +//! fn read(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> { Ok(()) } +//! fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> { Ok(()) } +//! fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { Ok(()) } +//! fn transfer_in_place(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> { Ok(()) } +//! } +//! impl embedded_hal::digital::ErrorType for DummyCsPin { +//! type Error = Infallible; +//! } +//! impl embedded_hal::digital::OutputPin for DummyCsPin { +//! fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) } +//! fn set_high(&mut self) -> Result<(), Self::Error> { Ok(()) } +//! } +//! impl embedded_sdmmc::TimeSource for DummyTimeSource { +//! fn get_timestamp(&self) -> embedded_sdmmc::Timestamp { embedded_sdmmc::Timestamp::from_fat(0, 0) } +//! } +//! impl embedded_hal::delay::DelayNs for DummyDelayer { +//! fn delay_ns(&mut self, ns: u32) {} +//! } +//! impl fmt::Write for DummyUart { +//! fn write_str(&mut self, s: &str) -> fmt::Result { Ok(()) } +//! } +//! use embedded_sdmmc::VolumeManager; +//! fn main() -> Result<(), embedded_sdmmc::Error> { +//! let mut sdmmc_spi = DummySpi; +//! let mut sdmmc_cs = DummyCsPin; +//! let time_source = DummyTimeSource; +//! let delayer = DummyDelayer; +//! let sdcard = embedded_sdmmc::SdCard::new(sdmmc_spi, sdmmc_cs, delayer); +//! println!("Card size is {} bytes", sdcard.num_bytes()?); +//! let mut volume_mgr = VolumeManager::new(sdcard, time_source); +//! let mut volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0))?; +//! println!("Volume 0: {:?}", volume0); +//! let mut root_dir = volume0.open_root_dir()?; +//! let mut my_file = root_dir.open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)?; +//! while !my_file.is_eof() { +//! let mut buffer = [0u8; 32]; +//! let num_read = my_file.read(&mut buffer)?; +//! for b in &buffer[0..num_read] { +//! print!("{}", *b as char); +//! } +//! } +//! Ok(()) +//! } //! ``` //! //! ## Features From 4c31f43db99bf0ce9e6185d268b7242a1b9cc9bf Mon Sep 17 00:00:00 2001 From: Simon Struck Date: Thu, 11 Jan 2024 20:19:37 +0100 Subject: [PATCH 13/14] Improve formatting of doctest --- src/lib.rs | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 7cf671f..643a4c6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,6 +26,7 @@ //! use embedded_hal::spi::ErrorType; //! use core::convert::Infallible; //! use core::fmt; +//! //! impl ErrorType for DummySpi { //! type Error = Infallible; //! } @@ -53,26 +54,27 @@ //! fn write_str(&mut self, s: &str) -> fmt::Result { Ok(()) } //! } //! use embedded_sdmmc::VolumeManager; +//! //! fn main() -> Result<(), embedded_sdmmc::Error> { -//! let mut sdmmc_spi = DummySpi; -//! let mut sdmmc_cs = DummyCsPin; -//! let time_source = DummyTimeSource; -//! let delayer = DummyDelayer; -//! let sdcard = embedded_sdmmc::SdCard::new(sdmmc_spi, sdmmc_cs, delayer); -//! println!("Card size is {} bytes", sdcard.num_bytes()?); -//! let mut volume_mgr = VolumeManager::new(sdcard, time_source); -//! let mut volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0))?; -//! println!("Volume 0: {:?}", volume0); -//! let mut root_dir = volume0.open_root_dir()?; -//! let mut my_file = root_dir.open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)?; -//! while !my_file.is_eof() { -//! let mut buffer = [0u8; 32]; -//! let num_read = my_file.read(&mut buffer)?; -//! for b in &buffer[0..num_read] { -//! print!("{}", *b as char); +//! let mut sdmmc_spi = DummySpi; +//! let mut sdmmc_cs = DummyCsPin; +//! let time_source = DummyTimeSource; +//! let delayer = DummyDelayer; +//! let sdcard = embedded_sdmmc::SdCard::new(sdmmc_spi, sdmmc_cs, delayer); +//! println!("Card size is {} bytes", sdcard.num_bytes()?); +//! let mut volume_mgr = VolumeManager::new(sdcard, time_source); +//! let mut volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0))?; +//! println!("Volume 0: {:?}", volume0); +//! let mut root_dir = volume0.open_root_dir()?; +//! let mut my_file = root_dir.open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)?; +//! while !my_file.is_eof() { +//! let mut buffer = [0u8; 32]; +//! let num_read = my_file.read(&mut buffer)?; +//! for b in &buffer[0..num_read] { +//! print!("{}", *b as char); +//! } //! } -//! } -//! Ok(()) +//! Ok(()) //! } //! ``` //! From 959b670dd35aec05a074217ec120fbc74153573b Mon Sep 17 00:00:00 2001 From: "Jonathan Pallant (Ferrous Systems)" Date: Fri, 12 Jan 2024 09:37:07 +0000 Subject: [PATCH 14/14] Clean up example code. If we put it in a function we need much less boiler plate to make it compile. --- src/lib.rs | 60 ++++++++++++------------------------------------------ 1 file changed, 13 insertions(+), 47 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 643a4c6..11db6e2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,57 +16,23 @@ //! couldn't work with a USB Thumb Drive, but we only supply a `BlockDevice` //! suitable for reading SD and SDHC cards over SPI. //! -//! ```rust,no_run -//! struct DummySpi; -//! struct DummyCsPin; -//! struct DummyUart; -//! struct DummyTimeSource; -//! struct DummyDelayer; -//! use embedded_hal::spi::Operation; -//! use embedded_hal::spi::ErrorType; -//! use core::convert::Infallible; -//! use core::fmt; +//! ```rust +//! use embedded_sdmmc::{Error, Mode, SdCard, SdCardError, TimeSource, VolumeIdx, VolumeManager}; //! -//! impl ErrorType for DummySpi { -//! type Error = Infallible; -//! } -//! impl embedded_hal::spi::SpiDevice for DummySpi { -//! fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> { Ok(()) } -//! fn read(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> { Ok(()) } -//! fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> { Ok(()) } -//! fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { Ok(()) } -//! fn transfer_in_place(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> { Ok(()) } -//! } -//! impl embedded_hal::digital::ErrorType for DummyCsPin { -//! type Error = Infallible; -//! } -//! impl embedded_hal::digital::OutputPin for DummyCsPin { -//! fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) } -//! fn set_high(&mut self) -> Result<(), Self::Error> { Ok(()) } -//! } -//! impl embedded_sdmmc::TimeSource for DummyTimeSource { -//! fn get_timestamp(&self) -> embedded_sdmmc::Timestamp { embedded_sdmmc::Timestamp::from_fat(0, 0) } -//! } -//! impl embedded_hal::delay::DelayNs for DummyDelayer { -//! fn delay_ns(&mut self, ns: u32) {} -//! } -//! impl fmt::Write for DummyUart { -//! fn write_str(&mut self, s: &str) -> fmt::Result { Ok(()) } -//! } -//! use embedded_sdmmc::VolumeManager; -//! -//! fn main() -> Result<(), embedded_sdmmc::Error> { -//! let mut sdmmc_spi = DummySpi; -//! let mut sdmmc_cs = DummyCsPin; -//! let time_source = DummyTimeSource; -//! let delayer = DummyDelayer; -//! let sdcard = embedded_sdmmc::SdCard::new(sdmmc_spi, sdmmc_cs, delayer); +//! fn example(spi: S, cs: CS, delay: D, ts: T) -> Result<(), Error> +//! where +//! S: embedded_hal::spi::SpiDevice, +//! CS: embedded_hal::digital::OutputPin, +//! D: embedded_hal::delay::DelayNs, +//! T: TimeSource, +//! { +//! let sdcard = SdCard::new(spi, cs, delay); //! println!("Card size is {} bytes", sdcard.num_bytes()?); -//! let mut volume_mgr = VolumeManager::new(sdcard, time_source); -//! let mut volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0))?; +//! let mut volume_mgr = VolumeManager::new(sdcard, ts); +//! let mut volume0 = volume_mgr.open_volume(VolumeIdx(0))?; //! println!("Volume 0: {:?}", volume0); //! let mut root_dir = volume0.open_root_dir()?; -//! let mut my_file = root_dir.open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)?; +//! let mut my_file = root_dir.open_file_in_dir("MY_FILE.TXT", Mode::ReadOnly)?; //! while !my_file.is_eof() { //! let mut buffer = [0u8; 32]; //! let num_read = my_file.read(&mut buffer)?;