diff --git a/src/framebuffer.rs b/src/framebuffer.rs index 537a927..cbafe26 100644 --- a/src/framebuffer.rs +++ b/src/framebuffer.rs @@ -4,21 +4,18 @@ mod bitmaps; use bitmaps::BASIC_LEGACY; -use crate::{ - mailbox::{read_mailbox, write_mailbox}, - peripherals::uart::{print, print_u32, print_u32_hex}, -}; +use crate::mailbox::{read_mailbox, write_mailbox}; #[repr(align(16))] struct Mailbox([u32; 36]); -const ALLOCATE_BUFFER: u32 = 0x00040001; -const GET_PHYSICAL_DISPLAY_WH: u32 = 0x00040003; -const SET_PHYSICAL_DISPLAY_WH: u32 = 0x00048003; -const SET_VIRTUAL_DISPLAY_WH: u32 = 0x00048004; -const SET_PIXEL_DEPTH: u32 = 0x00048005; -const SET_PIXEL_ORDER: u32 = 0x00048006; -const SET_FB_OFFSET: u32 = 0x00048009; -const GET_PITCH: u32 = 0x00040008; +const ALLOCATE_BUFFER: u32 = 0x0004_0001; +const GET_PHYSICAL_DISPLAY_WH: u32 = 0x0004_0003; +const SET_PHYSICAL_DISPLAY_WH: u32 = 0x0004_8003; +const SET_VIRTUAL_DISPLAY_WH: u32 = 0x0004_8004; +const SET_PIXEL_DEPTH: u32 = 0x0004_8005; +const SET_PIXEL_ORDER: u32 = 0x0004_8006; +const GET_PITCH: u32 = 0x000_40008; +const SET_FB_OFFSET: u32 = 0x0004_8009; pub struct FrameBuffer { pixel_depth: u32, // Bits per pixel @@ -89,7 +86,7 @@ impl FrameBuffer { let _ = read_mailbox(8); if mailbox.0[1] == 0 { - print("Failed\r\n"); + println!("Failed"); } mailbox.0[28] &= 0x3FFFFFFF; @@ -263,12 +260,8 @@ pub fn print_display_resolution() { let _ = read_mailbox(8); if mailbox[1] == 0 { - print("Failed\r\n"); + println!("Failed"); } - print("Width x Height: "); - print_u32(mailbox[5]); - print(" x "); - print_u32(mailbox[6]); - print("\r\n"); + println!("Width x Height: {}x{}", mailbox[5], mailbox[6]); } diff --git a/src/irq_interrupt.rs b/src/irq_interrupt.rs index b42d8ad..f17d4f6 100644 --- a/src/irq_interrupt.rs +++ b/src/irq_interrupt.rs @@ -5,10 +5,8 @@ use core::{ use crate::{ mmio_read, mmio_write, - peripherals::{ - gpio::{blink_gpio, SpecificGpio}, - uart::print, - }, + peripherals::gpio::{blink_gpio, SpecificGpio}, + print, timer::sleep_s, }; @@ -45,7 +43,7 @@ unsafe extern "C" fn irq_handler() { #[no_mangle] unsafe extern "C" fn synchronous_interrupt() { loop { - print("Sync Exception \r\n"); + println!("Sync Exception"); blink_gpio(SpecificGpio::OnboardLed as u8, 100); esr_uart_dump(); sleep_s(200); @@ -62,28 +60,28 @@ fn esr_uart_dump() { } for i in (0..32).rev() { if ((esr >> i) & 1) == 0 { - print("0"); + print!("0"); } else { - print("1"); + print!("1"); } if i % 4 == 0 && i > 0 { - print("_"); + print!("_"); } if i == 26 || i == 25 || i == 0 { - print("\n\r"); + print!("\n\r"); } } } fn handle_gpio_interrupt() { - print("Interrupt\r\n"); + println!("Interrupt"); for i in 0..=53u32 { let val = read_gpio_event_detect_status(i); if val { match i { - 26 => print("Button Pressed"), + 26 => print!("Button Pressed"), _ => {} } // Reset GPIO Interrupt handler by writing a 1 diff --git a/src/lib.rs b/src/lib.rs index 34e4c56..28a4c24 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,23 @@ use core::ptr::{read_volatile, write_volatile}; +#[macro_export] +macro_rules! print { + () => {}; + ($($arg:tt)*) => { + $crate::peripherals::uart::_print(format_args!($($arg)*)) + }; +} + +#[macro_export] +macro_rules! println { + () => {}; + ($($arg:tt)*) => { + print!($($arg)*); + print!("\r\n"); + }; +} + pub mod peripherals; pub mod configuration; diff --git a/src/mailbox.rs b/src/mailbox.rs index 63084a8..2c336a4 100644 --- a/src/mailbox.rs +++ b/src/mailbox.rs @@ -1,4 +1,4 @@ -use crate::{mmio_read, mmio_write, peripherals::uart::print}; +use crate::{mmio_read, mmio_write, print}; const MBOX_BASE: u32 = 0x3F00_0000 + 0xB880; @@ -51,7 +51,7 @@ pub fn read_soc_temp() -> u32 { let _ = read_mailbox(8); if mailbox[1] == 0 { - print("Failed\r\n"); + println!("Failed"); } let raw_temp = mailbox[6] / 1000; raw_temp diff --git a/src/main.rs b/src/main.rs index 5c364ea..a3a90b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,8 +18,9 @@ use nova::{ blink_gpio, gpio_pull_up, set_falling_edge_detect, set_gpio_function, GPIOFunction, SpecificGpio, }, - uart::{print, print_u32, uart_init}, + uart::uart_init, }, + print, println, timer::{delay_nops, sleep_us}, }; @@ -34,7 +35,7 @@ extern "C" { #[panic_handler] fn panic(_panic: &PanicInfo) -> ! { loop { - print("Panic\r\n"); + println!("Panic"); } } @@ -64,7 +65,7 @@ pub extern "C" fn main() -> ! { // Delay so clock speed can stabilize delay_nops(50000); - print("Hello World!\r\n"); + println!("Hello World!"); unsafe { asm!("mrs x0, SCTLR_EL1"); @@ -123,8 +124,7 @@ pub extern "C" fn kernel_main() -> ! { loop { let temp = read_soc_temp(); - print_u32(temp); - print("\r\n"); + println!("{} °C", temp); blink_gpio(SpecificGpio::OnboardLed as u8, 500); } @@ -163,6 +163,5 @@ fn print_current_el_str() { _ => "Unknown EL", }; - print(el_str); - print("\r\n"); + println!("{}", el_str); } diff --git a/src/peripherals/mod.rs b/src/peripherals/mod.rs index a8699a2..6cbb441 100644 --- a/src/peripherals/mod.rs +++ b/src/peripherals/mod.rs @@ -1,2 +1,3 @@ pub mod gpio; +#[macro_use] pub mod uart; diff --git a/src/peripherals/uart.rs b/src/peripherals/uart.rs index 92e76a2..556fae6 100644 --- a/src/peripherals/uart.rs +++ b/src/peripherals/uart.rs @@ -1,4 +1,7 @@ -use core::arch::asm; +use core::{ + arch::asm, + fmt::{self, Write}, +}; use crate::{mmio_read, mmio_write}; @@ -20,76 +23,28 @@ const UART0_CR_TXE: u32 = 1 << 8; const UART0_LCRH: u32 = 0x3F20_102c; const UART0_LCRH_FEN: u32 = 1 << 4; -/// Print `s` over UART -pub fn print(s: &str) { - for byte in s.bytes() { - while (mmio_read(UART0_FR) & UART0_FR_TXFF) != 0 { - unsafe { asm!("nop") } - } - mmio_write(UART0_DR, byte as u32); - } - // wait till uart is not busy anymore - while ((mmio_read(UART0_FR) >> 3) & 0b1) != 0 {} -} +pub struct Uart; -pub fn print_u32(mut val: u32) { - let mut last_valid = 0; - let mut values = [0u32; 10]; - for (i, c) in (&mut values).iter_mut().enumerate() { - if val == 0 { - break; +impl Write for Uart { + fn write_str(&mut self, s: &str) -> core::fmt::Result { + for byte in s.bytes() { + while (mmio_read(UART0_FR) & UART0_FR_TXFF) != 0 { + unsafe { asm!("nop") } + } + mmio_write(UART0_DR, byte as u32); } - - *c = val % 10; - val /= 10; - if *c != 0 { - last_valid = i; - } - } - - for (i, c) in values.iter().enumerate().rev() { - if i > last_valid { - continue; - } - let ascii_byte = b'0' + *c as u8; - let data = [ascii_byte]; - - let s = str::from_utf8(&data).unwrap(); - print(s); + // wait till uart is not busy anymore + while ((mmio_read(UART0_FR) >> 3) & 0b1) != 0 {} + Ok(()) } } -pub fn print_u32_hex(mut val: u32) { - let mut last_valid = 0; - let mut values = [0u32; 8]; - for (i, c) in (&mut values).iter_mut().enumerate() { - if val == 0 { - break; - } +pub fn _print(args: fmt::Arguments) { + let _ = Uart.write_fmt(args); +} - *c = val % 16; - val /= 16; - if *c != 0 { - last_valid = i; - } - } - - for (i, c) in values.iter().enumerate().rev() { - if i > last_valid { - continue; - } - - let ascii_byte = if *c < 10 { - b'0' + *c as u8 - } else { - b'A' - 10 + *c as u8 - }; - - let data = [ascii_byte]; - - let s = str::from_utf8(&data).unwrap(); - print(s); - } +pub fn _print_str(st: &str) { + let _ = Uart.write_str(st); } /// Initialize UART peripheral