gallery works
This commit is contained in:
BIN
assets/gallery/Sprite-0001.bmp
Normal file
BIN
assets/gallery/Sprite-0001.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
assets/gallery/Sprite-0002.bmp
Normal file
BIN
assets/gallery/Sprite-0002.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
assets/gallery/Sprite-0003.bmp
Normal file
BIN
assets/gallery/Sprite-0003.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
assets/gallery/Sprite-0004.bmp
Normal file
BIN
assets/gallery/Sprite-0004.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
assets/gallery/Sprite-0005.bmp
Normal file
BIN
assets/gallery/Sprite-0005.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -2,7 +2,7 @@ use abi_sys::{
|
|||||||
DrawIterAbi, FileLen, GenRand, GetKeyAbi, ListDir, LockDisplay, Modifiers, PrintAbi, ReadFile,
|
DrawIterAbi, FileLen, GenRand, GetKeyAbi, ListDir, LockDisplay, Modifiers, PrintAbi, ReadFile,
|
||||||
RngRequest, SleepAbi,
|
RngRequest, SleepAbi,
|
||||||
};
|
};
|
||||||
use alloc::{format, vec::Vec};
|
use alloc::{string::ToString, vec::Vec};
|
||||||
use core::sync::atomic::Ordering;
|
use core::sync::atomic::Ordering;
|
||||||
use embassy_rp::clocks::{RoscRng, clk_sys_freq};
|
use embassy_rp::clocks::{RoscRng, clk_sys_freq};
|
||||||
use embedded_graphics::{Pixel, draw_target::DrawTarget, pixelcolor::Rgb565};
|
use embedded_graphics::{Pixel, draw_target::DrawTarget, pixelcolor::Rgb565};
|
||||||
@@ -130,23 +130,30 @@ pub extern "C" fn list_dir(
|
|||||||
wrote
|
wrote
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recurse_file<T>(dir: &Dir, dirs: &[&str], mut access: impl FnMut(&mut File) -> T) -> T {
|
fn recurse_file<T>(
|
||||||
|
dir: &Dir,
|
||||||
|
dirs: &[&str],
|
||||||
|
mut access: impl FnMut(&mut File) -> T,
|
||||||
|
) -> Result<T, ()> {
|
||||||
if dirs.len() == 1 {
|
if dirs.len() == 1 {
|
||||||
let mut b = [0_u8; 50];
|
let mut b = [0_u8; 50];
|
||||||
let mut buf = LfnBuffer::new(&mut b);
|
let mut buf = LfnBuffer::new(&mut b);
|
||||||
let mut short_name = None;
|
let mut short_name = None;
|
||||||
dir.iterate_dir_lfn(&mut buf, |entry, name| {
|
dir.iterate_dir_lfn(&mut buf, |entry, name| {
|
||||||
if let Some(name) = name {
|
if let Some(name) = name {
|
||||||
if name == dirs[0] {
|
if name == dirs[0] || entry.name.to_string().as_str() == dirs[0] {
|
||||||
short_name = Some(entry.name.clone());
|
short_name = Some(entry.name.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut file = dir
|
if let Some(name) = short_name {
|
||||||
.open_file_in_dir(short_name.unwrap(), embedded_sdmmc::Mode::ReadWriteAppend)
|
let mut file = dir
|
||||||
.unwrap();
|
.open_file_in_dir(name, embedded_sdmmc::Mode::ReadWriteAppend)
|
||||||
return access(&mut file);
|
.map_err(|_| ())?;
|
||||||
|
return Ok(access(&mut file));
|
||||||
|
}
|
||||||
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let dir = dir.open_dir(dirs[0]).unwrap();
|
let dir = dir.open_dir(dirs[0]).unwrap();
|
||||||
@@ -161,25 +168,27 @@ pub extern "C" fn read_file(
|
|||||||
buf: *mut u8,
|
buf: *mut u8,
|
||||||
buf_len: usize,
|
buf_len: usize,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
// SAFETY: caller guarantees `ptr` is valid for `len` bytes
|
|
||||||
let mut buf = unsafe { core::slice::from_raw_parts_mut(buf, buf_len) };
|
|
||||||
// SAFETY: caller guarantees `ptr` is valid for `len` bytes
|
// SAFETY: caller guarantees `ptr` is valid for `len` bytes
|
||||||
let file = unsafe { core::str::from_raw_parts(str, len) };
|
let file = unsafe { core::str::from_raw_parts(str, len) };
|
||||||
let file: Vec<&str> = file.split('/').collect();
|
let file: Vec<&str> = file.split('/').collect();
|
||||||
|
// SAFETY: caller guarantees `ptr` is valid for `len` bytes
|
||||||
|
let mut buf = unsafe { core::slice::from_raw_parts_mut(buf, buf_len) };
|
||||||
|
|
||||||
let mut res = 0;
|
let mut read = 0;
|
||||||
|
|
||||||
let mut guard = SDCARD.get().try_lock().expect("Failed to get sdcard");
|
let mut guard = SDCARD.get().try_lock().expect("Failed to get sdcard");
|
||||||
let sd = guard.as_mut().unwrap();
|
let sd = guard.as_mut().unwrap();
|
||||||
if !file.is_empty() {
|
if !file.is_empty() {
|
||||||
sd.access_root_dir(|root| {
|
sd.access_root_dir(|root| {
|
||||||
res = recurse_file(&root, &file[1..], |file| {
|
if let Ok(result) = recurse_file(&root, &file[1..], |file| {
|
||||||
file.seek_from_start(start_from as u32).unwrap();
|
file.seek_from_start(start_from as u32).unwrap();
|
||||||
file.read(&mut buf).unwrap()
|
file.read(&mut buf).unwrap()
|
||||||
});
|
}) {
|
||||||
|
read = result
|
||||||
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
res
|
read
|
||||||
}
|
}
|
||||||
|
|
||||||
const _: FileLen = file_len;
|
const _: FileLen = file_len;
|
||||||
@@ -188,12 +197,16 @@ pub extern "C" fn file_len(str: *const u8, len: usize) -> usize {
|
|||||||
let file = unsafe { core::str::from_raw_parts(str, len) };
|
let file = unsafe { core::str::from_raw_parts(str, len) };
|
||||||
let file: Vec<&str> = file.split('/').collect();
|
let file: Vec<&str> = file.split('/').collect();
|
||||||
|
|
||||||
let mut res = 0;
|
let mut len = 0;
|
||||||
|
|
||||||
let mut guard = SDCARD.get().try_lock().expect("Failed to get sdcard");
|
let mut guard = SDCARD.get().try_lock().expect("Failed to get sdcard");
|
||||||
let sd = guard.as_mut().unwrap();
|
let sd = guard.as_mut().unwrap();
|
||||||
if !file.is_empty() {
|
if !file.is_empty() {
|
||||||
sd.access_root_dir(|root| res = recurse_file(&root, &file[1..], |file| file.length()));
|
sd.access_root_dir(|root| {
|
||||||
|
if let Ok(result) = recurse_file(&root, &file[1..], |file| file.length()) {
|
||||||
|
len = result
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
res as usize
|
len as usize
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
#![allow(static_mut_refs)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
use abi::{
|
use abi::{
|
||||||
@@ -8,7 +9,7 @@ use abi::{
|
|||||||
file_len, get_key, list_dir, lock_display, print, read_file, sleep,
|
file_len, get_key, list_dir, lock_display, print, read_file, sleep,
|
||||||
};
|
};
|
||||||
use alloc::{format, vec::Vec};
|
use alloc::{format, vec::Vec};
|
||||||
use core::panic::PanicInfo;
|
use core::{cell::RefCell, panic::PanicInfo};
|
||||||
use embedded_graphics::{Drawable, image::Image, prelude::*};
|
use embedded_graphics::{Drawable, image::Image, prelude::*};
|
||||||
use tinybmp::Bmp;
|
use tinybmp::Bmp;
|
||||||
|
|
||||||
@@ -29,20 +30,50 @@ pub extern "Rust" fn _start() {
|
|||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
print("Starting Gallery app");
|
print("Starting Gallery app");
|
||||||
|
static mut BMP_BUF: [u8; 100_000] = [0_u8; 100_000];
|
||||||
let mut display = Display;
|
let mut display = Display;
|
||||||
|
|
||||||
let file = "/images/ferriseyes_tiny.bmp";
|
// Grid parameters
|
||||||
|
let grid_cols = 3;
|
||||||
|
let grid_rows = 3;
|
||||||
|
let cell_width = 64;
|
||||||
|
let cell_height = 64;
|
||||||
|
|
||||||
let mut bmp_buf = [0_u8; 3_000];
|
let mut images_drawn = 0;
|
||||||
let read = read_file(file, 0, &mut bmp_buf);
|
|
||||||
let bmp = Bmp::from_slice(&bmp_buf[..read]).unwrap();
|
|
||||||
|
|
||||||
// ensure all draws show up at once
|
let mut files = [const { None }; 18];
|
||||||
lock_display(true);
|
let files_num = list_dir("/images", &mut files);
|
||||||
Image::new(&bmp, Point::new(10, 20))
|
|
||||||
.draw(&mut display)
|
for file in &files[2..files_num] {
|
||||||
.unwrap();
|
if images_drawn >= grid_cols * grid_rows {
|
||||||
lock_display(false);
|
break; // only draw 3x3
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(f) = file {
|
||||||
|
print(&format!("file: {}", f.name));
|
||||||
|
if f.name.extension() == b"bmp" || f.name.extension() == b"BMP" {
|
||||||
|
let file = format!("/images/{}", f.name);
|
||||||
|
|
||||||
|
let read = read_file(&file, 0, &mut unsafe { &mut BMP_BUF[..] });
|
||||||
|
if read > 0 {
|
||||||
|
let bmp = Bmp::from_slice(unsafe { &BMP_BUF }).expect("failed to parse bmp");
|
||||||
|
|
||||||
|
let row = images_drawn / grid_cols;
|
||||||
|
let col = images_drawn % grid_cols;
|
||||||
|
let x = (col * cell_width) as i32 + 10; // 10px margin
|
||||||
|
let y = (row * cell_height) as i32 + 10;
|
||||||
|
|
||||||
|
lock_display(true);
|
||||||
|
Image::new(&bmp, Point::new(x, y))
|
||||||
|
.draw(&mut display)
|
||||||
|
.unwrap();
|
||||||
|
lock_display(false);
|
||||||
|
|
||||||
|
images_drawn += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let event = get_key();
|
let event = get_key();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
RAM : ORIGIN = 0x0, LENGTH = 100K
|
RAM : ORIGIN = 0x0, LENGTH = 150K
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
|
|||||||
Reference in New Issue
Block a user