From 1c1000dfcb34fdc8f863f1bc0f4e3bd6f9bb8e56 Mon Sep 17 00:00:00 2001 From: sawyer bristol Date: Mon, 17 Nov 2025 08:10:03 -0700 Subject: [PATCH] fixes from nes --- .gitmodules | 6 ++++ Cargo.toml | 2 +- abi/src/lib.rs | 30 ++++++++++------ abi_sys/src/lib.rs | 23 ++++++++++-- justfile | 39 +++++++++++++++++++- kernel/Cargo.toml | 1 + kernel/src/abi.rs | 61 ++++++++++++++++++++++++++++---- kernel/src/display.rs | 20 ++++++++--- kernel/src/elf.rs | 1 + kernel/src/main.rs | 24 +++++++++---- kernel/src/storage.rs | 14 +++++++- kernel/src/ui.rs | 4 +-- picolibc | 1 + selection_ui/src/lib.rs | 6 ++-- user-apps/calculator/src/main.rs | 8 ++--- user-apps/gallery/src/main.rs | 8 ++--- user-apps/gif/Cargo.toml | 2 +- user-apps/gif/src/main.rs | 13 +++---- user-apps/snake/src/main.rs | 6 ++-- 19 files changed, 212 insertions(+), 57 deletions(-) create mode 100644 .gitmodules create mode 160000 picolibc diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..26531ce --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "picolibc"] + path = picolibc + url = https://github.com/picolibc/picolibc +[submodule "user-apps/gboy/Peanut-GB"] + path = user-apps/gboy/Peanut-GB + url = https://github.com/deltabeard/Peanut-GB diff --git a/Cargo.toml b/Cargo.toml index 05749bb..fbca13e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ codegen-units = 1 lto = true debug = false opt-level = "z" -panic = "abort" +panic = "unwind" [profile.dev] lto = true diff --git a/abi/src/lib.rs b/abi/src/lib.rs index d98c8bd..97805a6 100644 --- a/abi/src/lib.rs +++ b/abi/src/lib.rs @@ -3,8 +3,8 @@ extern crate alloc; -pub use abi_sys::{self, keyboard}; use abi_sys::{RngRequest, alloc, dealloc, keyboard::KeyEvent}; +pub use abi_sys::{keyboard, print}; pub use alloc::format; use core::alloc::{GlobalAlloc, Layout}; use rand_core::RngCore; @@ -25,10 +25,10 @@ unsafe impl GlobalAlloc for Alloc { } #[macro_export] -macro_rules! print { +macro_rules! println { ($($arg:tt)*) => {{ let s = $crate::format!($($arg)*); - $crate::abi_sys::print(s.as_ptr(), s.len()); + $crate::print(s.as_ptr(), s.len()); }}; } @@ -61,10 +61,8 @@ pub mod display { pub type Pixel565 = Pixel; - const BUF_SIZE: usize = 15 * 1024; // tune this for performance + const BUF_SIZE: usize = 1024; static mut BUF: [CPixel; BUF_SIZE] = [CPixel::new(); BUF_SIZE]; - // const BUF_SIZE: usize = 250 * 1024; // tune this for performance - // static mut BUF: Lazy> = Lazy::new(|| vec![const { CPixel::new() }; BUF_SIZE]); static DISPLAY_TAKEN: AtomicBool = AtomicBool::new(false); @@ -160,20 +158,30 @@ impl RngCore for Rng { } pub mod fs { + use alloc::vec::Vec; use core::fmt::Display; - use alloc::{format, vec::Vec}; - - pub fn read_file(file: &str, read_from: usize, buf: &mut [u8]) -> usize { + pub fn read_file(file: &str, start_from: usize, buf: &mut [u8]) -> usize { abi_sys::read_file( file.as_ptr(), file.len(), - read_from, + start_from, buf.as_mut_ptr(), buf.len(), ) } + pub fn write_file(file: &str, start_from: usize, buf: &[u8]) { + abi_sys::write_file( + file.as_ptr(), + file.len(), + start_from, + buf.as_ptr(), + buf.len(), + ) + } + + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct FileName<'a> { full: &'a str, base: &'a str, @@ -217,7 +225,7 @@ pub mod fs { const MAX_ENTRY_NAME_LEN: usize = 25; const MAX_ENTRIES: usize = 25; - #[derive(Clone, Copy)] + #[derive(Clone, Copy, Debug)] pub struct Entries([[u8; MAX_ENTRY_NAME_LEN]; MAX_ENTRIES]); impl Entries { diff --git a/abi_sys/src/lib.rs b/abi_sys/src/lib.rs index 3243771..af05c58 100644 --- a/abi_sys/src/lib.rs +++ b/abi_sys/src/lib.rs @@ -12,7 +12,7 @@ use strum::{EnumCount, EnumIter}; pub type EntryFn = fn(); -pub const ABI_CALL_TABLE_COUNT: usize = 11; +pub const ABI_CALL_TABLE_COUNT: usize = 12; const _: () = assert!(ABI_CALL_TABLE_COUNT == CallTable::COUNT); #[derive(Clone, Copy, EnumIter, EnumCount)] @@ -28,7 +28,8 @@ pub enum CallTable { GenRand = 7, ListDir = 8, ReadFile = 9, - FileLen = 10, + WriteFile = 10, + FileLen = 11, } #[unsafe(no_mangle)] @@ -438,6 +439,24 @@ pub extern "C" fn read_file( } } +pub type WriteFile = + extern "C" fn(str: *const u8, len: usize, write_from: usize, buf: *const u8, buf_len: usize); + +#[unsafe(no_mangle)] +pub extern "C" fn write_file( + str: *const u8, + len: usize, + write_from: usize, + buf: *const u8, + buf_len: usize, +) { + unsafe { + let ptr = CALL_ABI_TABLE[CallTable::WriteFile as usize]; + let f: WriteFile = core::mem::transmute(ptr); + f(str, len, write_from, buf, buf_len) + } +} + pub type FileLen = extern "C" fn(str: *const u8, len: usize) -> usize; #[unsafe(no_mangle)] diff --git a/justfile b/justfile index 0742af3..020d1ef 100644 --- a/justfile +++ b/justfile @@ -1,5 +1,7 @@ kernel-dev board: - cargo run --bin kernel --features {{board}} --features fps + cargo run --bin kernel --features {{board}} --features fps +kernel-release-probe board: + cargo run --bin kernel --profile release --features {{board}} --features fps kernel-release board: cargo build --bin kernel --release --no-default-features --features {{board}} elf2uf2-rs -d target/thumbv8m.main-none-eabihf/release/kernel @@ -9,6 +11,26 @@ binary-args := "RUSTFLAGS=\"-C link-arg=-pie -C relocation-model=pic\"" cbindgen: cbindgen abi_sys --output abi_sys.h -q +newlib: + #!/bin/bash + cd picolibc + mkdir build + cd build + CONFIG_PICOLIBC=true ../scripts/do-configure thumbv8m_main_fp-none-eabi \ + --buildtype=minsize \ + -Dtests=true \ + -Dtinystdio=false \ + -Dsingle-thread=true \ + -Db_pie=true \ + -Ddefault_library=static \ + -Dtinystdio=false \ + -Dnewlib-nano-malloc=true \ + -Dmultilib=false \ + -Dpicolib=true \ + "$@" + DESTDIR=./install meson install + ninja + userapp app: {{binary-args}} cargo build --bin {{app}} --profile release-binary @@ -17,3 +39,18 @@ userapps: cbindgen just userapp snake just userapp gallery just userapp gif + +copy-userapp app: + cp ./target/thumbv8m.main-none-eabihf/release-binary/{{app}} /run/media/$(whoami)/PICOCALC/{{app}}.bin + +copy-userapps: + #!/bin/bash + just userapps + just copy-userapp calculator + just copy-userapp snake + just copy-userapp gallery + just copy-userapp gif + + DEV=$(lsblk -o LABEL,NAME -nr | awk -v L="PICOCALC" '$1==L {print "/dev/" $2}') + udisksctl unmount -b "$DEV" + udisksctl power-off -b "$DEV" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index abc7926..a7229b6 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -17,6 +17,7 @@ pimoroni2w = ["rp235x", "psram"] rp235x = ["embassy-rp/rp235xb"] trouble = ["dep:bt-hci", "dep:cyw43", "dep:cyw43-pio", "dep:trouble-host"] psram = ["dep:embedded-alloc"] +overclock = [] fps = [] defmt = [ "dep:defmt", diff --git a/kernel/src/abi.rs b/kernel/src/abi.rs index fc78a93..5e17d76 100644 --- a/kernel/src/abi.rs +++ b/kernel/src/abi.rs @@ -1,6 +1,6 @@ use abi_sys::{ AllocAbi, CLayout, CPixel, DeallocAbi, DrawIterAbi, FileLen, GenRand, GetMsAbi, ListDir, - PrintAbi, ReadFile, RngRequest, SleepMsAbi, keyboard::*, + PrintAbi, ReadFile, RngRequest, SleepMsAbi, WriteFile, keyboard::*, }; use alloc::{string::ToString, vec::Vec}; use core::{ffi::c_char, ptr, sync::atomic::Ordering}; @@ -207,6 +207,7 @@ fn recurse_file( dirs: &[&str], mut access: impl FnMut(&mut File) -> T, ) -> Result { + defmt::info!("dir: {}, dirs: {}", dir, dirs); if dirs.len() == 1 { let mut b = [0_u8; 50]; let mut buf = LfnBuffer::new(&mut b); @@ -218,7 +219,8 @@ fn recurse_file( } } }) - .unwrap(); + .expect("Failed to iterate dir"); + if let Some(name) = short_name { let mut file = dir .open_file_in_dir(name, embedded_sdmmc::Mode::ReadWriteAppend) @@ -242,7 +244,17 @@ pub extern "C" fn read_file( ) -> usize { // SAFETY: caller guarantees `ptr` is valid for `len` bytes let file = unsafe { core::str::from_raw_parts(str, len) }; - let file: Vec<&str> = file.split('/').collect(); + + let mut components: [&str; 8] = [""; 8]; + let mut count = 0; + for part in file.split('/') { + if count >= components.len() { + break; + } + components[count] = part; + count += 1; + } + // SAFETY: caller guarantees `ptr` is valid for `len` bytes let mut buf = unsafe { core::slice::from_raw_parts_mut(buf, buf_len) }; @@ -252,8 +264,8 @@ pub extern "C" fn read_file( let sd = guard.as_mut().unwrap(); if !file.is_empty() { sd.access_root_dir(|root| { - if let Ok(result) = recurse_file(&root, &file[1..], |file| { - file.seek_from_start(start_from as u32).unwrap(); + if let Ok(result) = recurse_file(&root, &components[1..count], |file| { + file.seek_from_start(start_from as u32).unwrap_or(()); file.read(&mut buf).unwrap() }) { read = result @@ -263,9 +275,46 @@ pub extern "C" fn read_file( read } +const _: WriteFile = write_file; +pub extern "C" fn write_file( + str: *const u8, + len: usize, + start_from: usize, + buf: *const u8, + buf_len: usize, +) { + // SAFETY: caller guarantees str ptr is valid for `len` bytes + let file = unsafe { core::str::from_raw_parts(str, len) }; + + let mut components: [&str; 8] = [""; 8]; + let mut count = 0; + for part in file.split('/') { + if count >= components.len() { + break; + } + components[count] = part; + count += 1; + } + + // SAFETY: caller guarantees buf ptr is valid for `buf_len` bytes + let buf = unsafe { core::slice::from_raw_parts(buf, buf_len) }; + + let mut guard = SDCARD.get().try_lock().expect("Failed to get sdcard"); + let sd = guard.as_mut().unwrap(); + if !file.is_empty() { + sd.access_root_dir(|root| { + recurse_file(&root, &components[1..count], |file| { + file.seek_from_start(start_from as u32).unwrap(); + file.write(&buf).unwrap() + }) + .unwrap_or(()) + }); + }; +} + const _: FileLen = file_len; pub extern "C" fn file_len(str: *const u8, len: usize) -> usize { - // SAFETY: caller guarantees `ptr` is valid for `len` bytes + // SAFETY: caller guarantees str ptr is valid for `len` bytes let file = unsafe { core::str::from_raw_parts(str, len) }; let file: Vec<&str> = file.split('/').collect(); diff --git a/kernel/src/display.rs b/kernel/src/display.rs index 2fdd9f2..86c693f 100644 --- a/kernel/src/display.rs +++ b/kernel/src/display.rs @@ -87,8 +87,14 @@ pub async fn init_display( #[embassy_executor::task] pub async fn display_handler(mut display: DISPLAY) { + use embassy_time::{Instant, Timer}; + + // Target ~60 Hz refresh (≈16.67 ms per frame) + const FRAME_TIME_MS: u64 = 1000 / 60; + loop { - // renders fps text to canvas + let start = Instant::now(); + #[cfg(feature = "fps")] unsafe { if FPS_COUNTER.should_draw() { @@ -103,11 +109,15 @@ pub async fn display_handler(mut display: DISPLAY) { .unwrap() .partial_draw(&mut display) .await - .unwrap() - }; + .unwrap(); + } } - // small yield to allow other tasks to run - Timer::after_millis(10).await; + let elapsed = start.elapsed().as_millis() as u64; + if elapsed < FRAME_TIME_MS { + Timer::after_millis(FRAME_TIME_MS - elapsed).await; + } else { + Timer::after_millis(1).await; + } } } diff --git a/kernel/src/elf.rs b/kernel/src/elf.rs index bdc15de..ec180a4 100644 --- a/kernel/src/elf.rs +++ b/kernel/src/elf.rs @@ -206,6 +206,7 @@ fn patch_abi( CallTable::GenRand => abi::gen_rand as usize, CallTable::ListDir => abi::list_dir as usize, CallTable::ReadFile => abi::read_file as usize, + CallTable::WriteFile => abi::write_file as usize, CallTable::FileLen => abi::file_len as usize, }; unsafe { diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 9d864fc..8c1c757 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -47,6 +47,8 @@ use embassy_executor::{Executor, Spawner}; use embassy_futures::{join::join, select::select}; use embassy_rp::{ Peri, + clocks::ClockConfig, + config::Config, gpio::{Input, Level, Output, Pull}, i2c::{self, I2c}, multicore::{Stack, spawn_core1}, @@ -119,7 +121,13 @@ static UI_CHANGE: Signal = Signal::new(); #[embassy_executor::main] async fn main(_spawner: Spawner) { - let p = embassy_rp::init(Default::default()); + let p = if cfg!(feature = "overclock") { + let clocks = ClockConfig::system_freq(300_000_000).unwrap(); + let config = Config::new(clocks); + embassy_rp::init(config) + } else { + embassy_rp::init(Default::default()) + }; spawn_core1( p.CORE1, @@ -255,7 +263,7 @@ async fn setup_mcu(mcu: Mcu) { async fn setup_display(display: Display, spawner: Spawner) { let mut config = spi::Config::default(); - config.frequency = 64_000_000; + config.frequency = 192_000_000; let spi = Spi::new( display.spi, display.clk, @@ -331,6 +339,9 @@ async fn kernel_task( .spawn(watchdog_task(Watchdog::new(watchdog))) .unwrap(); + #[cfg(feature = "debug")] + defmt::info!("Clock: {}", embassy_rp::clocks::clk_sys_freq()); + setup_mcu(mcu).await; #[cfg(feature = "defmt")] @@ -364,7 +375,8 @@ async fn prog_search_handler() { let mut guard = SDCARD.get().lock().await; let sd = guard.as_mut().unwrap(); - let files = sd.list_files_by_extension(".bin").unwrap(); + let mut files = sd.list_files_by_extension(".bin").unwrap(); + files.sort(); let mut select = SELECTIONS.lock().await; if *select.selections() != files { @@ -379,10 +391,8 @@ async fn prog_search_handler() { async fn key_handler() { loop { if let Some(event) = read_keyboard_fifo().await { - if let KeyState::Pressed = event.state { - unsafe { - let _ = KEY_CACHE.enqueue(event); - } + unsafe { + let _ = KEY_CACHE.enqueue(event); } } Timer::after_millis(50).await; diff --git a/kernel/src/storage.rs b/kernel/src/storage.rs index 15093d8..0632fa5 100644 --- a/kernel/src/storage.rs +++ b/kernel/src/storage.rs @@ -35,12 +35,24 @@ impl TimeSource for DummyTimeSource { } } -#[derive(Clone, PartialEq)] +#[derive(Clone, PartialEq, Eq)] pub struct FileName { pub long_name: String, pub short_name: ShortFileName, } +impl PartialOrd for FileName { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.long_name.cmp(&other.long_name)) + } +} + +impl Ord for FileName { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + self.long_name.cmp(&other.long_name) + } +} + pub struct SdCard { det: Input<'static>, volume_mgr: VolMgr, diff --git a/kernel/src/ui.rs b/kernel/src/ui.rs index dc6017c..2a304a9 100644 --- a/kernel/src/ui.rs +++ b/kernel/src/ui.rs @@ -75,7 +75,7 @@ pub async fn clear_selection() { async fn draw_selection() { let mut guard = SELECTIONS.lock().await; - let file_names = &guard.selections.clone(); + let file_names = guard.selections.clone(); let text_style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE); let display_area = unsafe { FRAMEBUFFER.as_mut().unwrap().bounding_box() }; @@ -99,7 +99,7 @@ async fn draw_selection() { } else { let mut views: alloc::vec::Vec>> = Vec::new(); - for i in file_names { + for i in &file_names { views.push(Text::new(&i.long_name, Point::zero(), text_style)); } diff --git a/picolibc b/picolibc new file mode 160000 index 0000000..d664643 --- /dev/null +++ b/picolibc @@ -0,0 +1 @@ +Subproject commit d664643068a0a300858af29b2738bd7d38dd7ab5 diff --git a/selection_ui/src/lib.rs b/selection_ui/src/lib.rs index ccb175e..ac4e9ab 100644 --- a/selection_ui/src/lib.rs +++ b/selection_ui/src/lib.rs @@ -6,7 +6,6 @@ use abi::{ display::Display, get_key, keyboard::{KeyCode, KeyState}, - print, }; use alloc::vec::Vec; use embedded_graphics::{ @@ -55,6 +54,9 @@ impl<'a> SelectionUi<'a> { if key.state == KeyState::Pressed { if let Some(s) = self.update(display, key.key)? { selection = Some(s); + display + .clear(Rgb565::BLACK) + .map_err(|e| SelectionUiError::DisplayError(e))?; break; } } @@ -69,7 +71,6 @@ impl<'a> SelectionUi<'a> { display: &mut Display, key: KeyCode, ) -> Result, SelectionUiError<::Error>> { - print!("Got Key: {:?}", key); match key { KeyCode::Down => { self.selection = (self.selection + 1).min(self.items.len() - 1); @@ -80,7 +81,6 @@ impl<'a> SelectionUi<'a> { KeyCode::Enter | KeyCode::Right => return Ok(Some(self.selection)), _ => return Ok(None), }; - print!("new selection: {:?}", self.selection); self.draw(display)?; Ok(None) } diff --git a/user-apps/calculator/src/main.rs b/user-apps/calculator/src/main.rs index 9387018..0b42eb9 100644 --- a/user-apps/calculator/src/main.rs +++ b/user-apps/calculator/src/main.rs @@ -6,7 +6,7 @@ use abi::{ display::Display, get_key, keyboard::{KeyCode, KeyState}, - print, + println, }; use alloc::{format, string::String, vec, vec::Vec}; use core::panic::PanicInfo; @@ -28,7 +28,7 @@ use embedded_layout::{ #[panic_handler] fn panic(info: &PanicInfo) -> ! { - print!("user panic: {} @ {:?}", info.message(), info.location(),); + println!("user panic: {} @ {:?}", info.message(), info.location(),); loop {} } @@ -38,7 +38,7 @@ pub extern "Rust" fn _start() { } pub fn main() { - print!("Starting Calculator app"); + println!("Starting Calculator app"); let mut display = Display::take().unwrap(); let mut input = vec!['e', 'x', 'p', 'r', ':', ' ']; @@ -104,7 +104,7 @@ pub fn main() { } let event = get_key(); - if event.state != KeyState::Idle { + if event.state == KeyState::Released { match event.key { KeyCode::Char(ch) => { input.push(ch); diff --git a/user-apps/gallery/src/main.rs b/user-apps/gallery/src/main.rs index e321c97..17c5dfc 100644 --- a/user-apps/gallery/src/main.rs +++ b/user-apps/gallery/src/main.rs @@ -8,7 +8,7 @@ use abi::{ fs::{Entries, list_dir, read_file}, get_key, keyboard::{KeyCode, KeyState}, - print, + println, }; use alloc::{format, vec}; use core::panic::PanicInfo; @@ -20,7 +20,7 @@ use tinybmp::Bmp; #[panic_handler] fn panic(info: &PanicInfo) -> ! { - print!("user panic: {} @ {:?}", info.message(), info.location()); + println!("user panic: {} @ {:?}", info.message(), info.location()); loop {} } @@ -30,7 +30,7 @@ pub extern "Rust" fn _start() { } pub fn main() { - print!("Starting Gallery app"); + println!("Starting Gallery app"); let mut bmp_buf = vec![0_u8; 100_000]; let mut display = Display::take().unwrap(); @@ -49,7 +49,7 @@ pub fn main() { break; // only draw 3x3 } - print!("file: {}", file); + println!("file: {}", file); if file.extension().unwrap_or("") == "bmp" || file.extension().unwrap_or("") == "BMP" { let file_path = format!("/images/{}", file); diff --git a/user-apps/gif/Cargo.toml b/user-apps/gif/Cargo.toml index 1c5ecd8..cc45976 100644 --- a/user-apps/gif/Cargo.toml +++ b/user-apps/gif/Cargo.toml @@ -5,6 +5,6 @@ edition = "2024" [dependencies] abi = { path = "../../abi" } -embedded-graphics = "0.8.1" selection_ui = { path = "../../selection_ui" } +embedded-graphics = "0.8.1" tinygif = { git = "https://github.com/LegitCamper/tinygif" } diff --git a/user-apps/gif/src/main.rs b/user-apps/gif/src/main.rs index 77f580b..e449096 100644 --- a/user-apps/gif/src/main.rs +++ b/user-apps/gif/src/main.rs @@ -7,7 +7,7 @@ use abi::{ fs::{Entries, file_len, list_dir, read_file}, get_key, get_ms, keyboard::{KeyCode, KeyState}, - print, sleep, + println, sleep, }; use alloc::{format, vec, vec::Vec}; use core::panic::PanicInfo; @@ -23,7 +23,7 @@ use tinygif::Gif; #[panic_handler] fn panic(info: &PanicInfo) -> ! { - print!("user panic: {} @ {:?}", info.message(), info.location(),); + println!("user panic: {} @ {:?}", info.message(), info.location(),); loop {} } @@ -33,7 +33,7 @@ pub extern "Rust" fn _start() { } pub fn main() { - print!("Starting Gif app"); + println!("Starting Gif app"); let mut display = Display::take().unwrap(); let mut entries = Entries::new(); @@ -41,9 +41,10 @@ pub fn main() { let mut files = entries.entries(); files.retain(|e| e.extension().unwrap_or("") == "gif"); - let gifs = &files.iter().map(|e| e.full_name()).collect::>(); + let mut gifs = files.iter().map(|e| e.full_name()).collect::>(); + gifs.sort(); - let mut selection_ui = SelectionUi::new(&gifs); + let mut selection_ui = SelectionUi::new(&mut gifs); let selection = match selection_ui.run_selection_ui(&mut display) { Ok(maybe_sel) => maybe_sel, Err(e) => match e { @@ -66,7 +67,7 @@ pub fn main() { let size = file_len(&file_name); let mut buf = vec![0_u8; size]; let read = read_file(&file_name, 0, &mut buf); - print!("read: {}, file size: {}", read, size); + println!("read: {}, file size: {}", read, size); assert!(read == size); let gif = Gif::::from_slice(&buf).expect("Failed to parse gif"); diff --git a/user-apps/snake/src/main.rs b/user-apps/snake/src/main.rs index 01f752c..a1e078a 100644 --- a/user-apps/snake/src/main.rs +++ b/user-apps/snake/src/main.rs @@ -7,7 +7,7 @@ use abi::{ display::{Display, SCREEN_HEIGHT, SCREEN_WIDTH}, get_key, keyboard::{KeyCode, KeyState}, - print, sleep, + println, sleep, }; use core::panic::PanicInfo; use embedded_graphics::{pixelcolor::Rgb565, prelude::RgbColor}; @@ -15,7 +15,7 @@ use embedded_snake::{Direction, SnakeGame}; #[panic_handler] fn panic(info: &PanicInfo) -> ! { - print!("user panic: {} @ {:?}", info.message(), info.location(),); + println!("user panic: {} @ {:?}", info.message(), info.location(),); loop {} } @@ -27,7 +27,7 @@ pub extern "Rust" fn _start() { const CELL_SIZE: usize = 8; pub fn main() { - print!("Starting Snake app"); + println!("Starting Snake app"); let mut display = Display::take().unwrap(); let mut game = SnakeGame::<100, Rgb565, Rng>::new(