gallery works

This commit is contained in:
2025-09-29 12:35:54 -06:00
parent f353cad108
commit 15a09b52d7
8 changed files with 72 additions and 28 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -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
} }

View File

@@ -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();

View File

@@ -1,6 +1,6 @@
MEMORY MEMORY
{ {
RAM : ORIGIN = 0x0, LENGTH = 100K RAM : ORIGIN = 0x0, LENGTH = 150K
} }
SECTIONS SECTIONS