-
Notifications
You must be signed in to change notification settings - Fork 203
/
sd_card.rs
139 lines (119 loc) · 4.34 KB
/
sd_card.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! Place a series of bitmap images on the screen
//!
//! Ferris pngs from <https://rustacean.net/> , convert png to .bmp bytes:
//! * Resize and export images directly from image editor by saving as .bmp and
//! choosing 16bit R5 G6 B5
//! * OR Convert with imagemagick: convert rustacean-flat-noshadow.png -type
//! truecolor -define bmp:subtype=RGB565 -depth 16 -strip -resize 86x64
//! ferris.bmp
//! * SD card should have one (or at least, the first) primary partition of type
//! W95 FAT32, formatted eg `sudo mkfs.fat /dev/path/to/sdcardp1`
//! * Put assets/ferris*.bmp in the root directory of the sd card `cp
//! assets/ferris*.bmp /Volumes/SDCARD/`
#![no_std]
#![no_main]
use bsp::{entry, hal, pac, Pins, RedLed};
#[cfg(not(feature = "panic_led"))]
use panic_halt as _;
use pygamer as bsp;
use embedded_graphics::prelude::*;
use embedded_graphics::primitives::{PrimitiveStyleBuilder, Rectangle};
use embedded_graphics::{image::Image, pixelcolor::Rgb565};
use embedded_hal_bus::spi::ExclusiveDevice;
use embedded_sdmmc::{Mode, TimeSource, Timestamp, VolumeIdx, VolumeManager};
use hal::clock::GenericClockController;
use hal::delay::Delay;
use hal::nb;
use hal::prelude::*;
use hal::time::Hertz;
use hal::timer::TimerCounter;
use pac::{CorePeripherals, Peripherals};
use tinybmp::Bmp;
#[entry]
fn main() -> ! {
let mut peripherals = Peripherals::take().unwrap();
let core = CorePeripherals::take().unwrap();
let mut clocks = GenericClockController::with_internal_32kosc(
peripherals.gclk,
&mut peripherals.mclk,
&mut peripherals.osc32kctrl,
&mut peripherals.oscctrl,
&mut peripherals.nvmctrl,
);
let mut delay = Delay::new(core.SYST, &mut clocks);
let pins = Pins::new(peripherals.port).split();
let mut red_led: RedLed = pins.led_pin.into();
let (mut display, _backlight) = pins
.display
.init(
&mut clocks,
peripherals.sercom4,
&mut peripherals.mclk,
peripherals.tc2,
&mut delay,
)
.unwrap();
// black out the screen
Rectangle::with_corners(Point::new(0, 0), Point::new(160, 128))
.into_styled(
PrimitiveStyleBuilder::new()
.fill_color(Rgb565::BLACK)
.build(),
)
.draw(&mut display)
.unwrap();
let gclk0 = clocks.gclk0();
let timer_clock = clocks.tc4_tc5(&gclk0).unwrap();
let mut khz_timer = TimerCounter::tc4_(&timer_clock, peripherals.tc4, &mut peripherals.mclk);
InterruptDrivenTimer::start(&mut khz_timer, Hertz::kHz(1).into_duration());
let sdmmc_cs = pins.sd_cs_pin.into_push_pull_output();
let sdmmc_spi_bus = pins.spi.init(
&mut clocks,
3.MHz(),
peripherals.sercom1,
&mut peripherals.mclk,
);
let sdmmc_spi =
ExclusiveDevice::new_no_delay(sdmmc_spi_bus, sdmmc_cs).expect("Failed to create SpiDevice");
let card = embedded_sdmmc::SdCard::new(sdmmc_spi, delay);
let mut volume_mgr = VolumeManager::new(card, Clock {});
let mut volume = volume_mgr
.open_volume(VolumeIdx(0))
.expect("Failed to open volume");
let mut dir = volume.open_root_dir().expect("Failed to open root dir");
let mut scratch = [0u8; 11008];
// "animation" order of files to open
let images = ["ferris.bmp", "ferris1.bmp", "ferris2.bmp", "ferris1.bmp"];
loop {
for image in images.iter() {
match dir.open_file_in_dir(*image, Mode::ReadOnly) {
Ok(mut f) => {
let _ = f.read(&mut scratch);
let raw_image: Bmp<Rgb565> = Bmp::from_slice(&scratch).unwrap();
let ferris = Image::new(&raw_image, Point::new(32, 32));
let _ = ferris.draw(&mut display);
let _ = f.close();
}
Err(_err) => {
red_led.set_high().ok();
}
}
for _ in 0..100 {
nb::block!(InterruptDrivenTimer::wait(&mut khz_timer)).unwrap();
}
}
}
}
struct Clock;
impl TimeSource for Clock {
fn get_timestamp(&self) -> Timestamp {
Timestamp {
year_since_1970: 0,
zero_indexed_month: 0,
zero_indexed_day: 0,
hours: 0,
minutes: 0,
seconds: 0,
}
}
}