commit
d6345c67a4
|
@ -1 +1,7 @@
|
||||||
/target
|
/target
|
||||||
|
|
||||||
|
/.cargo
|
||||||
|
|
||||||
|
Cargo.lock
|
||||||
|
|
||||||
|
*.uf2
|
30
Cargo.toml
30
Cargo.toml
|
@ -3,7 +3,37 @@ name = "analte"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["kirbylife <kirbylife@protonmail.com>"]
|
authors = ["kirbylife <kirbylife@protonmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
resolver = "2"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
# Low level things
|
||||||
|
num-format = { version = "0.4", default-features = false }
|
||||||
|
cortex-m = "0.7.3"
|
||||||
|
cortex-m-rt = "0.7.0"
|
||||||
|
embedded-hal = { version = "0.2", features=["unproven"] }
|
||||||
|
embedded-time = "0.12.0"
|
||||||
|
panic-probe = { version = "0.2.0" }
|
||||||
|
rp2040-hal = { git = "https://github.com/rp-rs/rp-hal", branch="main", features=["rt"] }
|
||||||
|
rp2040-boot2 = { git = "https://github.com/rp-rs/rp2040-boot2-rs", branch="main" }
|
||||||
|
|
||||||
|
# Graphics things
|
||||||
|
embedded-graphics = "0.6.1"
|
||||||
|
epd-waveshare = "0.4.0"
|
||||||
|
tinytga = { version = "0.3.2", features = [ "graphics" ] }
|
||||||
|
|
||||||
|
# Storage things
|
||||||
|
# embedded-sdmmc = "0.3.0"
|
||||||
|
# embedded-sdmmc = { git = "https://github.com/kirbylife/embedded-sdmmc-rs", branch="develop" }
|
||||||
|
embedded-sdmmc = { path = "../embedded-sdmmc-rs" }
|
||||||
|
|
||||||
|
# cargo build/run --release
|
||||||
|
[profile.release]
|
||||||
|
codegen-units = 1
|
||||||
|
debug = 2
|
||||||
|
debug-assertions = false
|
||||||
|
incremental = false
|
||||||
|
lto = 'fat'
|
||||||
|
opt-level = 3
|
||||||
|
overflow-checks = false
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
MEMORY {
|
||||||
|
BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100
|
||||||
|
FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100
|
||||||
|
RAM : ORIGIN = 0x20000000, LENGTH = 256K
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
/* ### Boot loader */
|
||||||
|
.boot2 ORIGIN(BOOT2) :
|
||||||
|
{
|
||||||
|
KEEP(*(.boot2));
|
||||||
|
} > BOOT2
|
||||||
|
} INSERT BEFORE .text;
|
335
src/main.rs
335
src/main.rs
|
@ -1,3 +1,334 @@
|
||||||
fn main() {
|
#![no_std]
|
||||||
println!("Hello, world!");
|
#![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<E>) -> 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::<hal::gpio::FunctionSpi>();
|
||||||
|
let _spi1_mosi = pins.gpio11.into_mode::<hal::gpio::FunctionSpi>();
|
||||||
|
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::<hal::gpio::FunctionSpi>();
|
||||||
|
let _spi1_mosi = pins.gpio19.into_mode::<hal::gpio::FunctionSpi>();
|
||||||
|
let _spi1_miso = pins.gpio16.into_mode::<hal::gpio::FunctionSpi>();
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue