/ firmware / examples / sdcard_read.rs
sdcard_read.rs
  1  #![no_std]
  2  #![no_main]
  3  
  4  use core::ops::ControlFlow;
  5  use defmt::info;
  6  use embassy_executor::Spawner;
  7  use embassy_time::{Duration, Timer};
  8  use embedded_hal_bus::spi::ExclusiveDevice;
  9  use embedded_sdmmc::{Mode, SdCard, TimeSource, Timestamp, VolumeIdx, VolumeManager};
 10  use esp_hal::{
 11      clock::CpuClock,
 12      delay::Delay,
 13      gpio::{Level, Output, OutputConfig},
 14      interrupt::software::SoftwareInterruptControl,
 15      spi::master::{Config as SpiConfig, Spi},
 16      time::Rate,
 17      timer::timg::TimerGroup,
 18  };
 19  use panic_rtt_target as _;
 20  
 21  const SD_SPI_FREQUENCY_KHZ: u32 = 400;
 22  
 23  esp_bootloader_esp_idf::esp_app_desc!();
 24  
 25  #[derive(Default)]
 26  pub struct DummyTimesource;
 27  
 28  impl TimeSource for DummyTimesource {
 29      fn get_timestamp(&self) -> Timestamp {
 30          Timestamp {
 31              year_since_1970: 0,
 32              zero_indexed_month: 0,
 33              zero_indexed_day: 0,
 34              hours: 0,
 35              minutes: 0,
 36              seconds: 0,
 37          }
 38      }
 39  }
 40  
 41  #[esp_rtos::main]
 42  async fn main(_spawner: Spawner) -> ! {
 43      rtt_target::rtt_init_defmt!();
 44  
 45      let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
 46      let peripherals = esp_hal::init(config);
 47  
 48      esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 64 * 1024);
 49      esp_alloc::heap_allocator!(size: 64 * 1024);
 50  
 51      let timer_group0 = TimerGroup::new(peripherals.TIMG0);
 52      let sw_ints = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
 53      esp_rtos::start(timer_group0.timer0, sw_ints.software_interrupt0);
 54  
 55      info!("SD card read example initialized");
 56  
 57      let spi_bus = Spi::new(
 58          peripherals.SPI2,
 59          SpiConfig::default()
 60              .with_frequency(Rate::from_khz(SD_SPI_FREQUENCY_KHZ))
 61              .with_mode(esp_hal::spi::Mode::_0),
 62      )
 63      .unwrap()
 64      .with_sck(peripherals.GPIO12)
 65      .with_mosi(peripherals.GPIO11)
 66      .with_miso(peripherals.GPIO13)
 67      .into_async();
 68  
 69      let chip_select = Output::new(peripherals.GPIO10, Level::High, OutputConfig::default());
 70  
 71      let spi_device = ExclusiveDevice::new(spi_bus, chip_select, Delay::new()).unwrap();
 72      let sd_card = SdCard::new(spi_device, Delay::new());
 73  
 74      let card_size_bytes = sd_card.num_bytes().unwrap();
 75      let card_size_megabytes = card_size_bytes / (1024 * 1024);
 76      info!("SD card detected: {} MiB", card_size_megabytes);
 77  
 78      let volume_manager = VolumeManager::new(sd_card, DummyTimesource::default());
 79      let volume0 = volume_manager.open_volume(VolumeIdx(0)).unwrap();
 80      let root_directory = volume0.open_root_dir().unwrap();
 81  
 82      info!("listing root directory:");
 83      root_directory
 84          .iterate_dir(|directory_entry| {
 85              info!(
 86                  "  {:?} ({} bytes)",
 87                  directory_entry.name, directory_entry.size
 88              );
 89              ControlFlow::Continue(())
 90          })
 91          .unwrap();
 92  
 93      let test_file_result = root_directory.open_file_in_dir("FERRIS.TXT", Mode::ReadOnly);
 94  
 95      match test_file_result {
 96          Ok(file) => {
 97              info!("reading FERRIS.TXT:");
 98              let mut buffer = [0u8; 64];
 99  
100              while !file.is_eof() {
101                  if let Ok(bytes_read) = file.read(&mut buffer) {
102                      for byte in &buffer[..bytes_read] {
103                          info!("{}", *byte as char);
104                      }
105                  }
106              }
107          }
108          Err(_) => {
109              info!("FERRIS.TXT not found, creating it");
110              let new_file = root_directory
111                  .open_file_in_dir("FERRIS.TXT", Mode::ReadWriteCreateOrTruncate)
112                  .unwrap();
113  
114              let greeting = b"Hello, World!";
115              new_file.write(greeting).unwrap();
116  
117              info!("created FERRIS.TXT with: Hello, World!");
118  
119              let read_file = root_directory
120                  .open_file_in_dir("FERRIS.TXT", Mode::ReadOnly)
121                  .unwrap();
122  
123              let mut buffer = [0u8; 64];
124              while !read_file.is_eof() {
125                  if let Ok(bytes_read) = read_file.read(&mut buffer) {
126                      for byte in &buffer[..bytes_read] {
127                          info!("{}", *byte as char);
128                      }
129                  }
130              }
131          }
132      }
133  
134      loop {
135          Timer::after(Duration::from_secs(30)).await;
136      }
137  }