Skip to content

Commit

Permalink
Introduce SDMMC write_blocks
Browse files Browse the repository at this point in the history
`write_block` needs to be called for every 512 bytes long block that is
to be written to the SD card. Each of these calls requires the overhead
of negotiating the write command.

With this patch, `write_blocks` is introduced, mirroring the behavior
of `read_block` and `read_blocks`. This new method helped me to improve
write speed of the original 9492 kB/s to 66252 kB/s.

Signed-off-by: Petr Horacek <petr@zlosynth.com>
  • Loading branch information
phoracek committed Sep 18, 2023
1 parent 89b90ad commit d01305a
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 11 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
* Update `smoltcp` dependency to `0.9.0`
* MSRV increased to 1.65.0
* add `IntoAf` trait to restrict `into_alternate` [#346]
* sdmmc: Fix read speed test.
* sdmmc: Introduce `write_blocks`
* sdmmc: Fix read speed test

## [v0.14.0] 2023-03-22

Expand Down
8 changes: 2 additions & 6 deletions examples/sdmmc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,10 @@ fn main() -> ! {
info!("Read 10 blocks at {} bytes/s", 5120. / duration);
info!("");

let write_buffer = [0x34; 512];
let write_buffer = [0x34; 512 * 10];
let start = pac::DWT::cycle_count();

for i in 0..10 {
if let Err(err) = sdmmc.write_block(i, &write_buffer) {
info!("Failed to write block {}: {:?}", i, err);
}
}
sdmmc.write_blocks(0, &write_buffer).unwrap();

let end = pac::DWT::cycle_count();
let duration = (end - start) as f32 / ccdr.clocks.c_ck().raw() as f32;
Expand Down
14 changes: 10 additions & 4 deletions src/sdmmc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -739,20 +739,24 @@ macro_rules! sdmmc {
}

/// Write block to card. Buffer must be 512 bytes
pub fn write_block(
pub fn write_blocks(
&mut self,
address: u32,
buffer: &[u8; 512]
buffer: &[u8]
) -> Result<(), Error> {
let _card = self.card()?;

assert!(buffer.len() % 512 == 0,
"Buffer length must be a multiple of 512");
let n_blocks = buffer.len() / 512;

if !self.cmd16_illegal {
self.cmd(common_cmd::set_block_length(512))?; // CMD16
}

// Setup write command
self.start_datapath_transfer(512, 9, Dir::HostToCard);
self.cmd(common_cmd::write_single_block(address))?; // CMD24
self.start_datapath_transfer(512 * n_blocks as u32, 9, Dir::HostToCard);
self.cmd(common_cmd::write_multiple_blocks(address))?; // CMD25

let mut i = 0;
let mut status;
Expand All @@ -778,6 +782,8 @@ macro_rules! sdmmc {
}
}

self.cmd(common_cmd::stop_transmission())?; // CMD12

err_from_datapath_sm!(status);
self.clear_static_interrupt_flags();

Expand Down

0 comments on commit d01305a

Please sign in to comment.