diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 4fc74df..ee92f12 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -21,7 +21,7 @@ jobs: - name: Run format check run: cargo fmt --check - name: Run lint - run: cargo clippy + run: cargo clippy -- -D warnings build: runs-on: ubuntu-latest diff --git a/Cargo.lock b/Cargo.lock index 8c89787..e68673b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + [[package]] name = "nova" version = "0.1.0" +dependencies = [ + "libm", +] diff --git a/Cargo.toml b/Cargo.toml index c8de713..8de0a0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,6 @@ opt-level = 0 [profile.release] panic = "abort" + +[dependencies] +libm = "0.2.15" diff --git a/README.md b/README.md index 372bebc..325091c 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ NovaOS is a expository project where I build a kernel from scratch for a Raspber - UART ✓ - GPIOs ✓ - GPIO Interrupts ✓ -- Frame Buffer +- Communicate with peripherals via mailboxes ✓ +- Frame Buffer ✓ - MMU - Basic Terminal over UART diff --git a/src/framebuffer.rs b/src/framebuffer.rs new file mode 100644 index 0000000..537a927 --- /dev/null +++ b/src/framebuffer.rs @@ -0,0 +1,274 @@ +use core::ptr::write_volatile; + +mod bitmaps; + +use bitmaps::BASIC_LEGACY; + +use crate::{ + mailbox::{read_mailbox, write_mailbox}, + peripherals::uart::{print, print_u32, print_u32_hex}, +}; +#[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; + +pub struct FrameBuffer { + pixel_depth: u32, // Bits per pixel + pitch: u32, // Pixel per row + rows: u32, // Rows + start_addr: *mut u32, + size: u32, //Bytes +} + +pub const RED: u32 = 0x00FF0000; +pub const GREEN: u32 = 0x0000FF00; +pub const BLUE: u32 = 0x000000FF; +pub const ORANGE: u32 = 0x00FFA500; +pub const YELLOW: u32 = 0x00FFFF00; + +impl FrameBuffer { + pub fn new() -> Self { + let mut mailbox = Mailbox([0; 36]); + mailbox.0[0] = 35 * 4; + mailbox.0[1] = 0; + + mailbox.0[2] = SET_PHYSICAL_DISPLAY_WH; + mailbox.0[3] = 8; + mailbox.0[4] = 8; + mailbox.0[5] = 1920; + mailbox.0[6] = 1080; + + mailbox.0[7] = SET_VIRTUAL_DISPLAY_WH; + mailbox.0[8] = 8; + mailbox.0[9] = 8; + mailbox.0[10] = 1920; + mailbox.0[11] = 1080; + + mailbox.0[12] = SET_PIXEL_DEPTH; + mailbox.0[13] = 4; + mailbox.0[14] = 4; + mailbox.0[15] = 32; // 32 bit per pixel + + mailbox.0[16] = SET_PIXEL_ORDER; + mailbox.0[17] = 4; + mailbox.0[18] = 4; + mailbox.0[19] = 0x0; // RGB + + mailbox.0[20] = SET_FB_OFFSET; + mailbox.0[21] = 8; + mailbox.0[22] = 8; + mailbox.0[23] = 0; // X in pixels + mailbox.0[24] = 0; // Y in pixels + + mailbox.0[25] = ALLOCATE_BUFFER; + mailbox.0[26] = 8; + mailbox.0[27] = 4; + mailbox.0[28] = 4096; // Alignment + mailbox.0[29] = 0; + + mailbox.0[30] = GET_PITCH; + mailbox.0[31] = 4; + mailbox.0[32] = 0; + mailbox.0[33] = 0; + + mailbox.0[34] = 0; // End tag + + // TODO: validate responses + + let addr = core::ptr::addr_of!(mailbox.0[0]) as u32; + + write_mailbox(8, addr); + + let _ = read_mailbox(8); + if mailbox.0[1] == 0 { + print("Failed\r\n"); + } + + mailbox.0[28] &= 0x3FFFFFFF; + + Self { + pixel_depth: mailbox.0[15], + pitch: mailbox.0[33] / (mailbox.0[15] / 8), + rows: mailbox.0[29] / mailbox.0[33], + start_addr: mailbox.0[28] as *mut u32, + size: mailbox.0[29], + } + } + + pub fn draw_pixel(&self, x: u32, y: u32, color: u32) { + let offset = x + y * self.pitch; + unsafe { + write_volatile(self.start_addr.add(offset as usize), color); + } + } + + /*Bresenham's line algorithm + TODO: check if its possible to optimize y1==y2 case (ARM neon?) + */ + pub fn draw_line(&self, x1: u32, y1: u32, x2: u32, y2: u32, color: u32) { + if x1 == x2 { + for y in y1..=y2 { + self.draw_pixel(x1, y, color); + } + return; + } + + if (y2 as i32 - y1 as i32).abs() < (x2 as i32 - x1 as i32).abs() { + if x1 > x2 { + self.plot_line_low(x2, y2, x1, y1, color); + } else { + self.plot_line_low(x1, y1, x2, y2, color); + } + } else { + if y1 > y2 { + self.plot_line_high(x2, y2, x1, y1, color); + } else { + self.plot_line_high(x1, y1, x2, y2, color); + } + } + } + + pub fn draw_square(&self, x1: u32, y1: u32, x2: u32, y2: u32, color: u32) { + self.draw_line(x1, y1, x2, y1, color); + self.draw_line(x1, y2, x2, y2, color); + self.draw_line(x1, y1, x1, y2, color); + self.draw_line(x2, y1, x2, y2, color); + } + + pub fn draw_square_fill(&self, x1: u32, y1: u32, x2: u32, y2: u32, color: u32) { + let mut y_start = y1; + let mut y_end = y2; + + if y2 < y1 { + y_start = y2; + y_end = y1; + } + + for y in y_start..=y_end { + self.draw_line(x1, y, x2, y, color); + } + } + + fn plot_line_low(&self, x1: u32, y1: u32, x2: u32, y2: u32, color: u32) { + let dx = x2 as i32 - x1 as i32; + let mut dy = y2 as i32 - y1 as i32; + let mut yi = 1; + + let mut d = 2 * dy - dx; + let mut y = y1 as i32; + + if dy < 0 { + yi = -1; + dy = -dy; + } + + for x in x1..=x2 { + self.draw_pixel(x, y as u32, color); + if d > 0 { + y += yi; + d += 2 * (dy - dx); + } else { + d += 2 * dy; + } + } + } + fn plot_line_high(&self, x1: u32, y1: u32, x2: u32, y2: u32, color: u32) { + let mut dx = x2 as i32 - x1 as i32; + let dy = y2 as i32 - y1 as i32; + let mut xi: i32 = 1; + + let mut d = 2 * dy - dx; + let mut x = x1 as i32; + + if dx < 0 { + xi = -1; + dx = -dx; + } + + for y in y1..=y2 { + self.draw_pixel(x as u32, y, color); + if d > 0 { + x += xi; + d += 2 * (dx - dy); + } else { + d += 2 * dx; + } + } + } + + //TODO: Scale in pixels + pub fn draw_string(&self, string: &str, x: u32, mut y: u32, scale: u32, color: u32) { + let mut offset = 0; + for c in string.bytes() { + match c { + b'\n' => { + y += 8 * scale; + offset = 0; + } + _ => { + self.draw_ascii(x + (offset as u32 * 8 * scale), y, c as usize, scale, color); + offset += 1 + } + } + } + } + + fn draw_ascii(&self, x: u32, y: u32, char: usize, scale: u32, color: u32) { + for (y_offset, row) in (&BASIC_LEGACY[char]).iter().enumerate() { + for bit in 0..8 { + match row & (1 << bit) { + 0 => {} + _ => self.draw_square_fill( + x + (bit * scale), + y + (y_offset as u32 * scale), + x + ((bit + 1) * scale), + y + ((y_offset + 1) as u32 * scale), + color, + ), + } + } + } + } + + pub fn draw_function(&self, f: fn(u32) -> f64, x_offset: i32, y_offset: i32, color: u32) { + for x in 0..self.pitch as i32 { + let y = f(x as u32); + self.draw_pixel((x + x_offset) as u32, (y + y_offset as f64) as u32, color); + } + } +} + +pub fn print_display_resolution() { + let mut mailbox: [u32; 8] = [0; 8]; + mailbox[0] = 8 * 4; + mailbox[1] = 0; + mailbox[2] = GET_PHYSICAL_DISPLAY_WH; + mailbox[3] = 8; + mailbox[4] = 0; + mailbox[5] = 0; + mailbox[6] = 0; + mailbox[7] = 0; + + let addr = core::ptr::addr_of!(mailbox[0]) as u32; + + write_mailbox(8, addr); + + let _ = read_mailbox(8); + if mailbox[1] == 0 { + print("Failed\r\n"); + } + + print("Width x Height: "); + print_u32(mailbox[5]); + print(" x "); + print_u32(mailbox[6]); + print("\r\n"); +} diff --git a/src/framebuffer/bitmaps.rs b/src/framebuffer/bitmaps.rs new file mode 100644 index 0000000..813c59f --- /dev/null +++ b/src/framebuffer/bitmaps.rs @@ -0,0 +1,132 @@ +pub const NOTHING_TO_DISPLAY: [u8; 8] = [0x00; 8]; + +pub const BASIC_LEGACY: [[u8; 8]; 128] = [ + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + NOTHING_TO_DISPLAY, + [0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00], + [0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + [0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00], + [0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00], + [0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00], + [0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00], + [0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00], + [0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00], + [0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00], + [0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00], + [0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06], + [0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00], + [0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00], + [0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00], + [0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00], + [0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00], + [0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00], + [0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00], + [0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00], + [0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00], + [0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00], + [0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00], + [0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00], + [0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00], + [0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06], + [0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00], + [0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00], + [0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00], + [0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00], + [0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00], + [0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00], + [0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00], + [0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00], + [0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00], + [0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00], + [0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00], + [0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00], + [0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00], + [0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00], + [0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00], + [0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00], + [0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00], + [0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00], + [0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00], + [0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00], + [0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00], + [0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00], + [0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00], + [0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00], + [0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00], + [0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00], + [0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00], + [0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00], + [0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00], + [0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00], + [0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00], + [0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00], + [0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00], + [0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00], + [0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF], + [0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00], + [0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00], + [0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00], + [0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00], + [0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00], + [0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00], + [0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F], + [0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00], + [0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00], + [0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E], + [0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00], + [0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00], + [0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00], + [0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00], + [0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00], + [0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F], + [0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78], + [0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00], + [0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00], + [0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00], + [0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00], + [0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00], + [0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00], + [0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00], + [0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F], + [0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00], + [0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00], + [0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00], + [0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00], + [0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + NOTHING_TO_DISPLAY, +]; diff --git a/src/irq_interrupt.rs b/src/irq_interrupt.rs index 8e03285..b42d8ad 100644 --- a/src/irq_interrupt.rs +++ b/src/irq_interrupt.rs @@ -9,7 +9,7 @@ use crate::{ gpio::{blink_gpio, SpecificGpio}, uart::print, }, - timer::{sleep_ms, sleep_s}, + timer::sleep_s, }; const INTERRUPT_BASE: u32 = 0x3F00_B000; diff --git a/src/lib.rs b/src/lib.rs index 61a00be..34e4c56 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,8 +5,10 @@ use core::ptr::{read_volatile, write_volatile}; pub mod peripherals; pub mod configuration; +pub mod framebuffer; pub mod irq_interrupt; pub mod mailbox; +pub mod math; pub mod timer; pub fn mmio_read(address: u32) -> u32 { diff --git a/src/mailbox.rs b/src/mailbox.rs index 3f94599..63084a8 100644 --- a/src/mailbox.rs +++ b/src/mailbox.rs @@ -34,7 +34,7 @@ pub fn write_mailbox(channel: u32, data: u32) { } pub fn read_soc_temp() -> u32 { - let mut mailbox = [0; 36]; + let mut mailbox = [0; 8]; mailbox[0] = 8 * 4; // Total size in bytes mailbox[1] = 0; // Request mailbox[2] = 0x00030006; // Tag diff --git a/src/main.rs b/src/main.rs index 81c3b16..5c364ea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,8 +9,10 @@ use core::{ }; use nova::{ + framebuffer::{print_display_resolution, FrameBuffer, BLUE, GREEN, ORANGE, RED, YELLOW}, irq_interrupt::enable_irq_source, mailbox::read_soc_temp, + math::polar_to_cartesian, peripherals::{ gpio::{ blink_gpio, gpio_pull_up, set_falling_edge_detect, set_gpio_function, GPIOFunction, @@ -92,14 +94,46 @@ pub extern "C" fn kernel_main() -> ! { gpio_pull_up(26); set_falling_edge_detect(26, true); + print_display_resolution(); + let fb = FrameBuffer::new(); + print_display_resolution(); + + for a in 0..360 { + let (x, y) = polar_to_cartesian(100.0, a as f32); + fb.draw_line( + 150, + 150, + (150.0 + x) as u32, + (150.0 + y) as u32, + a * (0x00FFFFFF / 360), + ); + } + + fb.draw_square(500, 500, 600, 700, RED); + fb.draw_square_fill(800, 800, 900, 900, GREEN); + fb.draw_square_fill(1000, 800, 1200, 700, BLUE); + fb.draw_square_fill(900, 100, 800, 150, RED | BLUE); + fb.draw_string("Hello World! :D\nTest next Line", 500, 5, 3, BLUE); + + fb.draw_function(cos, 100, 101, RED); + fb.draw_function(cos, 100, 102, ORANGE); + fb.draw_function(cos, 100, 103, YELLOW); + fb.draw_function(cos, 100, 104, GREEN); + fb.draw_function(cos, 100, 105, BLUE); + loop { let temp = read_soc_temp(); print_u32(temp); + print("\r\n"); blink_gpio(SpecificGpio::OnboardLed as u8, 500); } } +fn cos(x: u32) -> f64 { + libm::cos(x as f64 * 0.1) * 20.0 +} + pub fn get_current_el() -> u64 { let el: u64; unsafe { diff --git a/src/math.rs b/src/math.rs new file mode 100644 index 0000000..4597857 --- /dev/null +++ b/src/math.rs @@ -0,0 +1,5 @@ +pub fn polar_to_cartesian(r: f32, theta_rad: f32) -> (f32, f32) { + let x = r * libm::cosf(theta_rad); + let y = r * libm::sinf(theta_rad); + (x, y) +} diff --git a/src/peripherals/uart.rs b/src/peripherals/uart.rs index 30bd345..92e76a2 100644 --- a/src/peripherals/uart.rs +++ b/src/peripherals/uart.rs @@ -57,7 +57,39 @@ pub fn print_u32(mut val: u32) { let s = str::from_utf8(&data).unwrap(); print(s); } - print("\r\n"); +} + +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; + } + + *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); + } } /// Initialize UART peripheral diff --git a/tools/start_simulator.sh b/tools/start_simulator.sh index f313b93..0955560 100755 --- a/tools/start_simulator.sh +++ b/tools/start_simulator.sh @@ -8,5 +8,4 @@ qemu-system-aarch64 \ -cpu cortex-a53 \ -serial stdio \ -sd ../sd.img \ - -display none \ -kernel ../target/aarch64-unknown-none/release/kernel8.img