This commit is contained in:
2025-09-13 13:57:41 -06:00
parent 70ecbcafc3
commit 1994d74a17
12 changed files with 154 additions and 139 deletions

2
Cargo.lock generated
View File

@@ -1941,7 +1941,7 @@ dependencies = [
[[package]] [[package]]
name = "st7365p-lcd" name = "st7365p-lcd"
version = "0.11.0" version = "0.11.0"
source = "git+https://github.com/legitcamper/st7365p-lcd-rs?rev=87abf450404865dcb535292e9e1a6a2457fd4599#87abf450404865dcb535292e9e1a6a2457fd4599" source = "git+https://github.com/legitcamper/st7365p-lcd-rs?rev=2a484aaab5f6b9824cc813fe4ae087250c9e39c1#2a484aaab5f6b9824cc813fe4ae087250c9e39c1"
dependencies = [ dependencies = [
"bitvec", "bitvec",
"embedded-graphics-core", "embedded-graphics-core",

View File

@@ -1,7 +1,7 @@
#![no_std] #![no_std]
use abi_sys::draw_iter; use abi_sys::draw_iter;
pub use abi_sys::{get_key, print}; pub use abi_sys::{get_key, print, sleep};
pub use embassy_time; pub use embassy_time;
pub use shared::keyboard::{KeyCode, KeyEvent, KeyState, Modifiers}; pub use shared::keyboard::{KeyCode, KeyEvent, KeyState, Modifiers};
use talc::*; use talc::*;

View File

@@ -21,12 +21,13 @@ pub static mut CALL_ABI_TABLE: [usize; CallAbiTable::COUNT] = [0; CallAbiTable::
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum CallAbiTable { pub enum CallAbiTable {
Print = 0, Print = 0,
DrawIter = 1, Sleep = 1,
GetKey = 2, DrawIter = 2,
GetKey = 3,
} }
impl CallAbiTable { impl CallAbiTable {
pub const COUNT: usize = 3; pub const COUNT: usize = 4;
} }
pub type PrintAbi = extern "Rust" fn(msg: &str); pub type PrintAbi = extern "Rust" fn(msg: &str);
@@ -39,6 +40,16 @@ pub fn print(msg: &str) {
} }
} }
pub type SleepAbi = extern "Rust" fn(ticks: u64);
pub fn sleep(ticks: u64) {
unsafe {
let ptr = CALL_ABI_TABLE[CallAbiTable::Print as usize];
let f: SleepAbi = core::mem::transmute(ptr);
f(ticks);
}
}
pub type DrawIterAbi = extern "Rust" fn(pixels: &[Pixel<Rgb565>]); pub type DrawIterAbi = extern "Rust" fn(pixels: &[Pixel<Rgb565>]);
pub fn draw_iter(pixels: &[Pixel<Rgb565>]) { pub fn draw_iter(pixels: &[Pixel<Rgb565>]) {

View File

@@ -70,7 +70,7 @@ defmt = { version = "0.3", optional = true }
defmt-rtt = "0.4.2" defmt-rtt = "0.4.2"
embedded-sdmmc = { version = "0.9", default-features = false } embedded-sdmmc = { version = "0.9", default-features = false }
st7365p-lcd = { git = "https://github.com/legitcamper/st7365p-lcd-rs", rev = "87abf450404865dcb535292e9e1a6a2457fd4599" } # async branch st7365p-lcd = { git = "https://github.com/legitcamper/st7365p-lcd-rs", rev = "2a484aaab5f6b9824cc813fe4ae087250c9e39c1" } # async branch
embedded-graphics = { version = "0.8.1" } embedded-graphics = { version = "0.8.1" }
embedded-text = "0.7.2" embedded-text = "0.7.2"
embedded-layout = "0.4.2" embedded-layout = "0.4.2"

View File

@@ -1,9 +1,10 @@
use core::pin::Pin; use core::{pin::Pin, time::Duration};
use abi_sys::{DrawIterAbi, GetKeyAbi, Pixel, PrintAbi}; use abi_sys::{DrawIterAbi, GetKeyAbi, Pixel, PrintAbi, SleepAbi};
use alloc::boxed::Box; use alloc::boxed::Box;
use defmt::info; use defmt::info;
use embassy_futures::block_on; use embassy_futures::block_on;
use embassy_time::Timer;
use embedded_graphics::{ use embedded_graphics::{
Drawable, Drawable,
draw_target::DrawTarget, draw_target::DrawTarget,
@@ -17,6 +18,7 @@ use crate::{KEY_CACHE, display::FRAMEBUFFER};
// ensure the abi and the kernel fn signatures are the same // ensure the abi and the kernel fn signatures are the same
const _: PrintAbi = print; const _: PrintAbi = print;
const _: SleepAbi = sleep;
const _: DrawIterAbi = draw_iter; const _: DrawIterAbi = draw_iter;
const _: GetKeyAbi = get_key; const _: GetKeyAbi = get_key;
@@ -24,20 +26,23 @@ pub extern "Rust" fn print(msg: &str) {
defmt::info!("{:?}", msg); defmt::info!("{:?}", msg);
} }
pub extern "Rust" fn sleep(ticks: u64) {
for _ in 0..ticks {
for _ in 0..100 {
cortex_m::asm::nop();
}
}
}
// TODO: maybe return result // TODO: maybe return result
pub extern "Rust" fn draw_iter(pixels: &[Pixel<Rgb565>]) { pub extern "Rust" fn draw_iter(pixels: &[Pixel<Rgb565>]) {
for _ in 0..10 { loop {
if let Some(mut framebuffer) = FRAMEBUFFER.try_lock().ok() { let fb = FRAMEBUFFER.get().try_lock();
for _ in 0..10 { if let Ok(mut fb) = fb {
// kernel takes() framebuffer fb.draw_iter(pixels.iter().copied()).unwrap();
if let Some(framebuffer) = framebuffer.as_mut() { return;
framebuffer.draw_iter(pixels.iter().copied()).unwrap();
} }
break; sleep(1)
}
break;
}
cortex_m::asm::nop();
} }
} }

View File

@@ -3,11 +3,16 @@ use embassy_rp::{
peripherals::{PIN_13, PIN_14, PIN_15, SPI1}, peripherals::{PIN_13, PIN_14, PIN_15, SPI1},
spi::{Async, Spi}, spi::{Async, Spi},
}; };
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex}; use embassy_sync::{
blocking_mutex::raw::CriticalSectionRawMutex, lazy_lock::LazyLock, mutex::Mutex,
};
use embassy_time::{Delay, Timer}; use embassy_time::{Delay, Timer};
use embedded_graphics::{
draw_target::DrawTarget,
pixelcolor::{Rgb565, RgbColor},
};
use embedded_hal_bus::spi::ExclusiveDevice; use embedded_hal_bus::spi::ExclusiveDevice;
use st7365p_lcd::{FrameBuffer, ST7365P}; use st7365p_lcd::{FrameBuffer, ST7365P};
use static_cell::StaticCell;
type DISPLAY = ST7365P< type DISPLAY = ST7365P<
ExclusiveDevice<Spi<'static, SPI1, Async>, Output<'static>, Delay>, ExclusiveDevice<Spi<'static, SPI1, Async>, Output<'static>, Delay>,
@@ -20,8 +25,8 @@ pub const SCREEN_WIDTH: usize = 320;
pub const SCREEN_HEIGHT: usize = 320; pub const SCREEN_HEIGHT: usize = 320;
type FB = FrameBuffer<SCREEN_WIDTH, SCREEN_HEIGHT, { SCREEN_WIDTH * SCREEN_HEIGHT }>; type FB = FrameBuffer<SCREEN_WIDTH, SCREEN_HEIGHT, { SCREEN_WIDTH * SCREEN_HEIGHT }>;
static FRAMEBUFFER_CELL: StaticCell<FB> = StaticCell::new(); pub static FRAMEBUFFER: LazyLock<Mutex<CriticalSectionRawMutex, FB>> =
pub static FRAMEBUFFER: Mutex<CriticalSectionRawMutex, Option<&'static mut FB>> = Mutex::new(None); LazyLock::new(|| Mutex::new(FrameBuffer::new()));
pub async fn init_display( pub async fn init_display(
spi: Spi<'static, SPI1, Async>, spi: Spi<'static, SPI1, Async>,
@@ -38,27 +43,27 @@ pub async fn init_display(
true, true,
Delay, Delay,
); );
let framebuffer = FRAMEBUFFER_CELL.init(FrameBuffer::new()); let mut fb = FRAMEBUFFER.get().lock().await;
display.init().await.unwrap(); display.init().await.unwrap();
display.set_custom_orientation(0x40).await.unwrap(); display.set_custom_orientation(0x40).await.unwrap();
framebuffer.draw(&mut display).await.unwrap(); display.draw(&mut fb).await.unwrap();
display.set_on().await.unwrap(); display.set_on().await.unwrap();
FRAMEBUFFER.lock().await.replace(framebuffer);
display display
} }
pub async fn clear_fb() {
let mut fb = FRAMEBUFFER.get().lock().await;
let fb = &mut *fb;
fb.clear(Rgb565::BLACK).unwrap();
}
pub async fn display_handler(mut display: DISPLAY) { pub async fn display_handler(mut display: DISPLAY) {
loop { loop {
let fb: &mut FB = { {
let mut guard = FRAMEBUFFER.lock().await; let mut fb = FRAMEBUFFER.get().lock().await;
guard.take().unwrap() // take ownership display.partial_draw_batched(&mut fb).await.unwrap();
}; // guard dropped }
fb.partial_draw_batched(&mut display).await.unwrap();
// Put it back
FRAMEBUFFER.lock().await.replace(fb);
Timer::after_millis(32).await; // 30 fps Timer::after_millis(32).await; // 30 fps
} }

View File

@@ -53,6 +53,7 @@ pub async unsafe fn load_binary(name: &ShortFileName) -> Result<EntryFn, &str> {
// MUST MATCH ABI EXACTLY // MUST MATCH ABI EXACTLY
let entries: &[(CallAbiTable, usize)] = &[ let entries: &[(CallAbiTable, usize)] = &[
(CallAbiTable::Print, abi::print as usize), (CallAbiTable::Print, abi::print as usize),
(CallAbiTable::Sleep, abi::sleep as usize),
(CallAbiTable::DrawIter, abi::draw_iter as usize), (CallAbiTable::DrawIter, abi::draw_iter as usize),
(CallAbiTable::GetKey, abi::get_key as usize), (CallAbiTable::GetKey, abi::get_key as usize),
]; ];

View File

@@ -20,7 +20,7 @@ mod utils;
use core::sync::atomic::Ordering; use core::sync::atomic::Ordering;
use crate::{ use crate::{
display::{display_handler, init_display}, display::{FRAMEBUFFER, clear_fb, display_handler, init_display},
elf::load_binary, elf::load_binary,
peripherals::{ peripherals::{
conf_peripherals, conf_peripherals,
@@ -49,7 +49,9 @@ use embassy_rp::{
spi::{self, Spi}, spi::{self, Spi},
usb as embassy_rp_usb, usb as embassy_rp_usb,
}; };
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, channel::Channel, mutex::Mutex}; use embassy_sync::{
blocking_mutex::raw::CriticalSectionRawMutex, channel::Channel, mutex::Mutex, signal::Signal,
};
use embassy_time::{Delay, Timer}; use embassy_time::{Delay, Timer};
use embedded_hal_bus::spi::ExclusiveDevice; use embedded_hal_bus::spi::ExclusiveDevice;
use embedded_sdmmc::SdCard as SdmmcSdCard; use embedded_sdmmc::SdCard as SdmmcSdCard;
@@ -75,7 +77,9 @@ static ALLOCATOR: Talck<spin::Mutex<()>, ClaimOnOom> =
.lock(); .lock();
static TASK_STATE: Mutex<CriticalSectionRawMutex, TaskState> = Mutex::new(TaskState::Ui); static TASK_STATE: Mutex<CriticalSectionRawMutex, TaskState> = Mutex::new(TaskState::Ui);
static TASK_STATE_CHANGED: Signal<CriticalSectionRawMutex, ()> = Signal::new();
#[derive(Copy, Clone, PartialEq)]
enum TaskState { enum TaskState {
Ui, Ui,
Kernel, Kernel,
@@ -131,6 +135,7 @@ async fn userland_task() {
let recv = BINARY_CH.receiver(); let recv = BINARY_CH.receiver();
loop { loop {
let entry = recv.receive().await; let entry = recv.receive().await;
defmt::info!("Got Entry");
// disable kernel ui // disable kernel ui
{ {
@@ -138,6 +143,8 @@ async fn userland_task() {
*state = TaskState::Kernel; *state = TaskState::Kernel;
} }
// clear_fb().await; // blocks future exec?
defmt::info!("Executing Binary"); defmt::info!("Executing Binary");
entry().await; entry().await;
@@ -237,8 +244,8 @@ async fn kernel_task(display: Display, sd: Sd, mcu: Mcu, usb: USB) {
SDCARD.get().lock().await.replace(SdCard::new(sdcard, det)); SDCARD.get().lock().await.replace(SdCard::new(sdcard, det));
}; };
// let usb = embassy_rp_usb::Driver::new(usb, Irqs); let usb = embassy_rp_usb::Driver::new(usb, Irqs);
// let usb_fut = usb_handler(usb); let usb_fut = usb_handler(usb);
let key_abi_fut = async { let key_abi_fut = async {
loop { loop {
@@ -247,7 +254,7 @@ async fn kernel_task(display: Display, sd: Sd, mcu: Mcu, usb: USB) {
} }
}; };
join4(display_fut, ui_fut, binary_search_fut, key_abi_fut).await; join5(display_fut, ui_fut, usb_fut, binary_search_fut, key_abi_fut).await;
} }
static mut KEY_CACHE: Queue<KeyEvent, 32> = Queue::new(); static mut KEY_CACHE: Queue<KeyEvent, 32> = Queue::new();

View File

@@ -8,18 +8,17 @@ use heapless::Vec;
mod scsi_types; mod scsi_types;
use scsi_types::*; use scsi_types::*;
use crate::storage::SdCard; use crate::storage::{SDCARD, SdCard};
const BULK_ENDPOINT_PACKET_SIZE: usize = 64; const BULK_ENDPOINT_PACKET_SIZE: usize = 64;
pub struct MassStorageClass<'d, 's, D: Driver<'d>> { pub struct MassStorageClass<'d, D: Driver<'d>> {
sdcard: &'s SdCard,
bulk_out: D::EndpointOut, bulk_out: D::EndpointOut,
bulk_in: D::EndpointIn, bulk_in: D::EndpointIn,
} }
impl<'d, 's, D: Driver<'d>> MassStorageClass<'d, 's, D> { impl<'d, 's, D: Driver<'d>> MassStorageClass<'d, D> {
pub fn new(builder: &mut Builder<'d, D>, sdcard: &'s SdCard) -> Self { pub fn new(builder: &mut Builder<'d, D>) -> Self {
let mut function = builder.function(0x08, SUBCLASS_SCSI, 0x50); // Mass Storage class let mut function = builder.function(0x08, SUBCLASS_SCSI, 0x50); // Mass Storage class
let mut interface = function.interface(); let mut interface = function.interface();
let mut alt = interface.alt_setting(0x08, SUBCLASS_SCSI, 0x50, None); let mut alt = interface.alt_setting(0x08, SUBCLASS_SCSI, 0x50, None);
@@ -27,11 +26,7 @@ impl<'d, 's, D: Driver<'d>> MassStorageClass<'d, 's, D> {
let bulk_out = alt.endpoint_bulk_out(BULK_ENDPOINT_PACKET_SIZE as u16); let bulk_out = alt.endpoint_bulk_out(BULK_ENDPOINT_PACKET_SIZE as u16);
let bulk_in = alt.endpoint_bulk_in(BULK_ENDPOINT_PACKET_SIZE as u16); let bulk_in = alt.endpoint_bulk_in(BULK_ENDPOINT_PACKET_SIZE as u16);
Self { Self { bulk_out, bulk_in }
bulk_out,
bulk_in,
sdcard,
}
} }
pub async fn poll(&mut self) { pub async fn poll(&mut self) {
@@ -139,7 +134,9 @@ impl<'d, 's, D: Driver<'d>> MassStorageClass<'d, 's, D> {
self.bulk_in.write(&response[..len]).await.map_err(|_| ()) self.bulk_in.write(&response[..len]).await.map_err(|_| ())
} }
ScsiCommand::TestUnitReady => { ScsiCommand::TestUnitReady => {
if self.sdcard.is_attached() { let guard = SDCARD.get().lock().await;
let sdcard = guard.as_ref().unwrap();
if sdcard.is_attached() {
Ok(()) Ok(())
} else { } else {
Err(()) Err(())
@@ -185,8 +182,11 @@ impl<'d, 's, D: Driver<'d>> MassStorageClass<'d, 's, D> {
self.bulk_in.write(&response[..len]).await.map_err(|_| ()) self.bulk_in.write(&response[..len]).await.map_err(|_| ())
} }
ScsiCommand::ReadCapacity10 => { ScsiCommand::ReadCapacity10 => {
let guard = SDCARD.get().lock().await;
let sdcard = guard.as_ref().unwrap();
let block_size = SdCard::BLOCK_SIZE as u64; let block_size = SdCard::BLOCK_SIZE as u64;
let total_blocks = self.sdcard.size() / block_size; let total_blocks = sdcard.size() / block_size;
let last_lba = total_blocks.checked_sub(1).unwrap_or(0); let last_lba = total_blocks.checked_sub(1).unwrap_or(0);
@@ -196,8 +196,11 @@ impl<'d, 's, D: Driver<'d>> MassStorageClass<'d, 's, D> {
self.bulk_in.write(&response).await.map_err(|_| ()) self.bulk_in.write(&response).await.map_err(|_| ())
} }
ScsiCommand::ReadCapacity16 { alloc_len } => { ScsiCommand::ReadCapacity16 { alloc_len } => {
let guard = SDCARD.get().lock().await;
let sdcard = guard.as_ref().unwrap();
let block_size = SdCard::BLOCK_SIZE as u64; let block_size = SdCard::BLOCK_SIZE as u64;
let total_blocks = self.sdcard.size() / block_size; let total_blocks = sdcard.size() / block_size;
let last_lba = total_blocks.checked_sub(1).unwrap_or(0); let last_lba = total_blocks.checked_sub(1).unwrap_or(0);
@@ -209,9 +212,12 @@ impl<'d, 's, D: Driver<'d>> MassStorageClass<'d, 's, D> {
self.bulk_in.write(&response[..len]).await.map_err(|_| ()) self.bulk_in.write(&response[..len]).await.map_err(|_| ())
} }
ScsiCommand::Read { lba, len } => { ScsiCommand::Read { lba, len } => {
let guard = SDCARD.get().lock().await;
let sdcard = guard.as_ref().unwrap();
for i in 0..len { for i in 0..len {
let block_idx = BlockIdx(lba as u32 + i as u32); let block_idx = BlockIdx(lba as u32 + i as u32);
self.sdcard.read_blocks(&mut block, block_idx)?; sdcard.read_blocks(&mut block, block_idx)?;
for chunk in block[0].contents.chunks(BULK_ENDPOINT_PACKET_SIZE.into()) { for chunk in block[0].contents.chunks(BULK_ENDPOINT_PACKET_SIZE.into()) {
self.bulk_in.write(chunk).await.map_err(|_| ())?; self.bulk_in.write(chunk).await.map_err(|_| ())?;
} }
@@ -219,6 +225,9 @@ impl<'d, 's, D: Driver<'d>> MassStorageClass<'d, 's, D> {
Ok(()) Ok(())
} }
ScsiCommand::Write { lba, len } => { ScsiCommand::Write { lba, len } => {
let guard = SDCARD.get().lock().await;
let sdcard = guard.as_ref().unwrap();
for i in 0..len { for i in 0..len {
let block_idx = BlockIdx(lba as u32 + i as u32); let block_idx = BlockIdx(lba as u32 + i as u32);
for chunk in block[0] for chunk in block[0]
@@ -227,13 +236,16 @@ impl<'d, 's, D: Driver<'d>> MassStorageClass<'d, 's, D> {
{ {
self.bulk_out.read(chunk).await.map_err(|_| ())?; self.bulk_out.read(chunk).await.map_err(|_| ())?;
} }
self.sdcard.write_blocks(&mut block, block_idx)?; sdcard.write_blocks(&mut block, block_idx)?;
} }
Ok(()) Ok(())
} }
ScsiCommand::ReadFormatCapacities { alloc_len } => { ScsiCommand::ReadFormatCapacities { alloc_len } => {
let guard = SDCARD.get().lock().await;
let sdcard = guard.as_ref().unwrap();
let block_size = SdCard::BLOCK_SIZE as u32; let block_size = SdCard::BLOCK_SIZE as u32;
let num_blocks = (self.sdcard.size() / block_size as u64) as u32; let num_blocks = (sdcard.size() / block_size as u64) as u32;
let mut response = [0u8; 12]; let mut response = [0u8; 12];

View File

@@ -5,36 +5,21 @@ use crate::{
format, format,
peripherals::keyboard, peripherals::keyboard,
storage::FileName, storage::FileName,
usb::RESTART_USB,
}; };
use alloc::{string::String, vec::Vec}; use alloc::{string::String, vec::Vec};
use core::{fmt::Debug, str::FromStr, sync::atomic::Ordering}; use core::{fmt::Debug, str::FromStr, sync::atomic::Ordering};
use defmt::info;
use embassy_rp::{
gpio::{Level, Output},
peripherals::{PIN_13, PIN_14, PIN_15, SPI1},
spi::{Async, Spi},
};
use embassy_sync::{ use embassy_sync::{
blocking_mutex::raw::{CriticalSectionRawMutex, ThreadModeRawMutex}, blocking_mutex::raw::{CriticalSectionRawMutex, ThreadModeRawMutex},
mutex::Mutex, mutex::Mutex,
signal::Signal,
}; };
use embassy_time::{Delay, Timer};
use embedded_graphics::{ use embedded_graphics::{
Drawable, Drawable,
draw_target::DrawTarget, mono_font::{MonoTextStyle, ascii::FONT_9X15},
mono_font::{
MonoTextStyle,
ascii::{FONT_6X9, FONT_6X10, FONT_9X15, FONT_10X20},
},
pixelcolor::Rgb565, pixelcolor::Rgb565,
prelude::{Dimensions, Point, Primitive, RgbColor, Size}, prelude::{Dimensions, Point, RgbColor, Size},
primitives::{PrimitiveStyle, Rectangle, StyledDrawable}, primitives::Rectangle,
text::Text, text::Text,
}; };
use embedded_hal_async::spi::SpiDevice;
use embedded_hal_bus::spi::{ExclusiveDevice, NoDelay};
use embedded_layout::{ use embedded_layout::{
align::{horizontal, vertical}, align::{horizontal, vertical},
layout::linear::LinearLayout, layout::linear::LinearLayout,
@@ -77,6 +62,8 @@ pub async fn ui_handler() {
} }
draw_selection().await; draw_selection().await;
} else {
embassy_time::Timer::after_millis(50).await;
} }
} }
} }
@@ -87,8 +74,7 @@ async fn draw_selection() {
guard.selections.clone() guard.selections.clone()
}; };
let mut fb_lock = FRAMEBUFFER.lock().await; let mut fb = FRAMEBUFFER.get().lock().await;
if let Some(fb) = fb_lock.as_mut() {
let text_style = MonoTextStyle::new(&FONT_9X15, Rgb565::WHITE); let text_style = MonoTextStyle::new(&FONT_9X15, Rgb565::WHITE);
let display_area = fb.bounding_box(); let display_area = fb.bounding_box();
@@ -104,13 +90,14 @@ async fn draw_selection() {
), ),
text_style, text_style,
) )
.draw(*fb) .draw(&mut *fb)
.unwrap(); .unwrap();
} else { } else {
let mut file_names = file_names.iter(); let mut file_names = file_names.iter();
let Some(first) = file_names.next() else { let Some(first) = file_names.next() else {
Text::new("No Programs found on SD Card\nEnsure programs end with '.bin',\nand are located in the root directory", Text::new(NO_BINS, Point::zero(), text_style)
Point::zero(), text_style).draw(*fb).unwrap(); .draw(&mut *fb)
.unwrap();
return; return;
}; };
@@ -129,9 +116,8 @@ async fn draw_selection() {
.with_alignment(horizontal::Center) .with_alignment(horizontal::Center)
.arrange() .arrange()
.align_to(&display_area, horizontal::Center, vertical::Center) .align_to(&display_area, horizontal::Center, vertical::Center)
.draw(*fb) .draw(&mut *fb)
.unwrap(); .unwrap();
};
} }
} }

View File

@@ -1,6 +1,5 @@
use core::sync::atomic::Ordering;
use crate::{ use crate::{
TASK_STATE, TASK_STATE_CHANGED, TaskState,
scsi::MassStorageClass, scsi::MassStorageClass,
storage::{SDCARD, SdCard}, storage::{SDCARD, SdCard},
}; };
@@ -13,9 +12,6 @@ use embassy_sync::{blocking_mutex::raw::ThreadModeRawMutex, signal::Signal};
use embassy_usb::{Builder, Config}; use embassy_usb::{Builder, Config};
use portable_atomic::AtomicBool; use portable_atomic::AtomicBool;
pub static RESTART_USB: Signal<ThreadModeRawMutex, ()> = Signal::new();
pub static ENABLE_SCSI: AtomicBool = AtomicBool::new(false);
pub async fn usb_handler(driver: Driver<'static, USB>) { pub async fn usb_handler(driver: Driver<'static, USB>) {
let mut config = Config::new(0xc0de, 0xbabe); let mut config = Config::new(0xc0de, 0xbabe);
config.manufacturer = Some("LegitCamper"); config.manufacturer = Some("LegitCamper");
@@ -37,27 +33,17 @@ pub async fn usb_handler(driver: Driver<'static, USB>) {
&mut control_buf, &mut control_buf,
); );
let lock = SDCARD.get().lock().await; let mut scsi = MassStorageClass::new(&mut builder);
let sdcard = lock.as_ref().unwrap();
let mut scsi = MassStorageClass::new(&mut builder, &sdcard);
let mut usb = builder.build(); let mut usb = builder.build();
loop { loop {
select3( defmt::info!("in: {}", *TASK_STATE.lock().await as u32);
async { if *TASK_STATE.lock().await == TaskState::Ui {
loop { defmt::info!("running scsi and usb");
RESTART_USB.wait().await; select(join(usb.run(), scsi.poll()), TASK_STATE_CHANGED.wait()).await;
return; } else {
defmt::info!("not in ui state");
TASK_STATE_CHANGED.wait().await;
} }
},
usb.run(),
async {
if ENABLE_SCSI.load(Ordering::Acquire) {
scsi.poll().await
}
},
)
.await;
} }
} }

View File

@@ -37,6 +37,8 @@ pub async fn main() {
.draw(&mut display) .draw(&mut display)
.unwrap(); .unwrap();
embassy_time::Timer::after_millis(1000).await;
if let Some(event) = get_key() { if let Some(event) = get_key() {
print("User got event"); print("User got event");
match event.key { match event.key {