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 }