#![no_std] #![no_main] use core::convert::TryInto; use cortex_m_rt::entry; use embedded_graphics::{ fonts::{Font24x32 as Font, Text}, image::Image, pixelcolor::BinaryColor, prelude::*, primitives::{Circle, Line, Triangle}, style::{PrimitiveStyle, PrimitiveStyleBuilder, TextStyleBuilder}, }; use embedded_hal::digital::v2::OutputPin; use embedded_sdmmc::{ sdmmc::CardType, Block, BlockDevice, BlockIdx, Controller, Error, SdMmcError, SdMmcSpi, VolumeIdx, }; use embedded_time::fixed_point::FixedPoint; use embedded_time::rate::Extensions; use epd_waveshare::{ color::*, epd7in5_v2::Display7in5 as EPDisplay, epd7in5_v2::EPD7in5 as EPD, epd7in5_v2::HEIGHT, epd7in5_v2::WIDTH, graphics::DisplayRotation, prelude::*, }; use num_format::{Buffer, Locale}; use panic_probe as _; use rp2040_hal as hal; use tinytga::Tga; use hal::{ clocks::{init_clocks_and_plls, Clock}, pac, sio::Sio, watchdog::Watchdog, }; fn error_to_str<'a>(error: SdMmcError) -> &'a str { match error { SdMmcError::Transport => "Transport", SdMmcError::CantEnableCRC => "Cant Enable CRC", SdMmcError::TimeoutReadBuffer => "TimeoutReadBuffer", SdMmcError::TimeoutWaitNotBusy => "Timeout Wait Not Busy", SdMmcError::TimeoutCommand(_) => "Timeout Command", SdMmcError::TimeoutACommand(_) => "Timeout A Command", SdMmcError::Cmd58Error => "Cmd 58 Error", SdMmcError::RegisterReadError => "Register Read Error", SdMmcError::CrcError(_, _) => "CRC Error", SdMmcError::ReadError => "Read Error", SdMmcError::WriteError => "Write Error", SdMmcError::BadState => "Bad State", SdMmcError::CardNotFound => "Card Not Found", SdMmcError::GpioError => "GPIO Error", } } fn error2_to_str<'a, E: core::fmt::Debug>(error: Error) -> Result<&'a str, Buffer> { match error { Error::DeviceError(_) => Ok("Device Error"), Error::FormatError(s) => Ok(s), Error::SignatureError(s) => Err(s), Error::NoSuchVolume => Ok("No Such Volume"), Error::FilenameError(_) => Ok("Filename Error"), Error::TooManyOpenDirs => Ok("Too Many Open Dirs"), Error::TooManyOpenFiles => Ok("Too Many Oopen Files"), Error::FileNotFound => Ok("File Not Found"), Error::FileAlreadyOpen => Ok("File Already Open"), Error::DirAlreadyOpen => Ok("Dir Already Open"), Error::OpenedDirAsFile => Ok("Opened Dir As File"), Error::Unsupported => Ok("Unsopported"), Error::EndOfFile => Ok("End Of File"), Error::BadCluster => Ok("Bad Cluster"), Error::ConversionError => Ok("Conversion Error"), Error::NotEnoughSpace => Ok("Not EnoughSpace"), Error::AllocationError => Ok("Allocation Error"), Error::JumpedFree => Ok("Jumped Free"), Error::ReadOnly => Ok("Read Only"), Error::FileAlreadyExists => Ok("File Already Exists"), Error::DeleteDirAsFile => Ok("Delete Dir As File"), Error::FileIsOpen => Ok("File Is Open"), Error::BadBlockSize(_) => Ok("Bad Block Size"), Error::NotInBlock => Ok("Not In Block"), } } #[link_section = ".boot2"] #[used] pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; struct ClockSD; impl embedded_sdmmc::TimeSource for ClockSD { fn get_timestamp(&self) -> embedded_sdmmc::Timestamp { embedded_sdmmc::Timestamp { year_since_1970: 0, zero_indexed_month: 0, zero_indexed_day: 0, hours: 0, minutes: 0, seconds: 0, } } } #[entry] fn main() -> ! { let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let sio = Sio::new(pac.SIO); // External high-speed crystal on the pico board is 12Mhz let external_xtal_freq_hz = 12_000_000u32; let clocks = init_clocks_and_plls( external_xtal_freq_hz, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().integer()); let pins = hal::gpio::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // SPI screen declaration let _spi1_sclk = pins.gpio10.into_mode::(); let _spi1_mosi = pins.gpio11.into_mode::(); let spi = hal::spi::Spi::<_, _, 8>::new(pac.SPI1); // Exchange the uninitialised SPI driver for an initialised one let mut spi = spi.init( &mut pac.RESETS, clocks.peripheral_clock.freq(), 4_000_000u32.Hz(), // 16_000_000u32.Hz(), &embedded_hal::spi::MODE_0, ); let mut cs = pins.gpio9.into_push_pull_output(); // CS cs.set_high().unwrap(); let busy = pins.gpio13.into_pull_up_input(); // BUSY let dc = pins.gpio8.into_push_pull_output(); // DC let rst = pins.gpio12.into_push_pull_output(); // RST let _spi1_sclk = pins.gpio18.into_mode::(); let _spi1_mosi = pins.gpio19.into_mode::(); let _spi1_miso = pins.gpio16.into_mode::(); let spi_sd = hal::spi::Spi::<_, _, 8>::new(pac.SPI0); // Exchange the uninitialised SPI driver for an initialised one let mut spi_sd = spi_sd.init( &mut pac.RESETS, clocks.peripheral_clock.freq(), 100_000u32.Hz(), &embedded_hal::spi::MODE_0, ); let mut cs_sd = pins.gpio17.into_push_pull_output(); // CS // cs_sd.set_low().unwrap(); let mut epd = EPD::new( &mut spi, // SPI cs, // CS busy, // BUSY dc, // DC rst, // RST &mut delay, // DELAY ) .unwrap(); let mut display = EPDisplay::default(); /* Clear the full screen */ epd.wake_up(&mut spi, &mut delay).unwrap(); // epd.set_background_color(epd_waveshare::color::Color::Black); // epd.clear_frame(&mut spi).unwrap(); // epd.set_background_color(epd_waveshare::color::Color::White); epd.clear_frame(&mut spi).unwrap(); // epd.display_frame(&mut spi).unwrap(); display.clear_buffer(Color::Black); for i in 0..100 { Pixel(Point::new(100, i), BinaryColor::Off) .draw(&mut display) .unwrap(); } let style_text = TextStyleBuilder::new(Font) .text_color(BinaryColor::Off) .background_color(BinaryColor::On) .build(); let style_forms = PrimitiveStyleBuilder::new() .stroke_width(10) .stroke_color(BinaryColor::Off) .fill_color(BinaryColor::Off) .build(); for i in 0..(WIDTH / 10) as i32 { Line::new(Point::new(i * 10, 0), Point::new(i * 10, HEIGHT as i32)) .into_styled(PrimitiveStyle::with_stroke(BinaryColor::Off, 1)) .draw(&mut display) .unwrap(); } for i in 0..(HEIGHT / 10) as i32 { Line::new(Point::new(0, i * 10), Point::new(WIDTH as i32, i * 10)) .into_styled(PrimitiveStyle::with_stroke(BinaryColor::Off, 1)) .draw(&mut display) .unwrap(); } display.set_rotation(DisplayRotation::Rotate270); // let mut cont = Controller::new(SdMmcSpi::new(spi_sd, cs_sd), ClockSD); let mut sd_mmc = SdMmcSpi::new(spi_sd, cs_sd); let mut controller = Controller::new(sd_mmc, ClockSD); match controller.device().init() { Ok(_) => { Text::new("Device detected", Point::new(1, 1)) .into_styled(style_text) .draw(&mut display) .unwrap(); let sd_type = match controller.device().card_type { CardType::SD1 => "SD1", CardType::SD2 => "SD2", CardType::SDHC => "SDHC", }; Text::new(sd_type, Point::new(1, 70)) .into_styled(style_text) .draw(&mut display) .unwrap(); controller .device() .spi() .set_baudrate(clocks.peripheral_clock.freq(), 16_000_000u32.Hz()); match controller.device().card_size_bytes() { Ok(size) => { let mut buffer = Buffer::default(); buffer.write_formatted(&size, &Locale::en); let s = buffer.as_str(); Text::new(s, Point::new(1, 35)) .into_styled(style_text) .draw(&mut display) .unwrap(); } Err(e) => { Text::new(error_to_str(e), Point::new(1, 35)) .into_styled(style_text) .draw(&mut display) .unwrap(); } } let block_count = controller.device().num_blocks().unwrap(); let mut block = [Block::new()]; controller .device() .read(&mut block, BlockIdx(0), "") .unwrap(); // for volume_idx in 0..=3 { // let volume = controller.get_volume(VolumeIdx(volume_idx)); // match volume { // Ok(volume) => { // let root_dir = controller.open_root_dir(&volume).unwrap(); // let mut idx = 0; // controller // .iterate_dir(&volume, &root_dir, |x| { // Text::new("Found!!", Point::new(1, (idx * 35) + 70)) // .into_styled(style_text) // .draw(&mut display) // .unwrap(); // idx += 1; // }) // .unwrap(); // } // Err(e) => { // let b = error2_to_str(e); // let mut buff = Buffer::default(); // let mut s = match b { // Ok(s) => s, // Err(e) => { // buff = e; // "" // } // }; // if s.len() == 0 { // s = buff.as_str(); // } // Text::new( // // error2_to_str(e), // s, // Point::new(1, 400 + (volume_idx as i32 * 35)), // ) // .into_styled(style_text) // .draw(&mut display) // .unwrap(); // } // } // } // } Err(e) => { Text::new(error_to_str(e), Point::new(1, 1)) .into_styled(style_text) .draw(&mut display) .unwrap(); } } epd.update_frame(&mut spi, display.buffer()).unwrap(); epd.display_frame(&mut spi).unwrap(); delay.delay_ms(1000); let mut led_pin = pins.gpio25.into_push_pull_output(); loop { led_pin.set_high().unwrap(); delay.delay_ms(500); led_pin.set_low().unwrap(); delay.delay_ms(500); } }