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/src/framebuffer.rs b/src/framebuffer.rs new file mode 100644 index 0000000..4a85e41 --- /dev/null +++ b/src/framebuffer.rs @@ -0,0 +1,109 @@ +use crate::{ + mailbox::{read_mailbox, write_mailbox}, + peripherals::uart::{print, print_u32}, +}; + +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; + +pub fn init_fb() { + let mut mailbox = [0; 32]; + mailbox[0] = 32 * 4; + mailbox[1] = 0; + + mailbox[2] = SET_PHYSICAL_DISPLAY_WH; + mailbox[3] = 8; + mailbox[4] = 8; + mailbox[5] = 1920; + mailbox[6] = 1200; + + mailbox[7] = SET_VIRTUAL_DISPLAY_WH; + mailbox[8] = 8; + mailbox[9] = 8; + mailbox[10] = 1920; + mailbox[11] = 1200; + + mailbox[12] = SET_PIXEL_DEPTH; + mailbox[13] = 4; + mailbox[14] = 4; + mailbox[15] = 32; // 32 bit per pixel + + mailbox[16] = SET_PIXEL_ORDER; + mailbox[17] = 4; + mailbox[18] = 4; + mailbox[19] = 0x1; // RGB + + mailbox[20] = SET_FB_OFFSET; + mailbox[21] = 8; + mailbox[22] = 8; + mailbox[24] = 0; // X in pixels + mailbox[25] = 0; // Y in pixels + + mailbox[26] = ALLOCATE_BUFFER; + mailbox[27] = 8; + mailbox[28] = 4; + mailbox[29] = 4096; // Alignment + mailbox[30] = 0; + + mailbox[31] = 0; // End tag + + // TODO: validate responses + + 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_u32(mailbox[29]); + + mailbox[29] = (mailbox[29] & 0x00FF_FFFF) | 0x3F00_0000; + + let mut fb: *mut u32 = mailbox[29] as *mut u32; + + fb = unsafe { fb.add(1920 * 500 + 500) }; + + for x in 0..500 { + for y in 0..10 { + unsafe { + *fb = 0xFFFFBB00; + fb = fb.add(1); + }; + } + } +} + +pub fn print_display_resolution() { + let mut mailbox = [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/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..2f92229 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ 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 timer; 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..da47fc7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ use core::{ }; use nova::{ + framebuffer::{init_fb, print_display_resolution}, irq_interrupt::enable_irq_source, mailbox::read_soc_temp, peripherals::{ @@ -92,9 +93,13 @@ pub extern "C" fn kernel_main() -> ! { gpio_pull_up(26); set_falling_edge_detect(26, true); + print_display_resolution(); + init_fb(); + loop { let temp = read_soc_temp(); print_u32(temp); + print("\r\n"); blink_gpio(SpecificGpio::OnboardLed as u8, 500); } diff --git a/src/peripherals/uart.rs b/src/peripherals/uart.rs index 30bd345..ebe45b4 100644 --- a/src/peripherals/uart.rs +++ b/src/peripherals/uart.rs @@ -57,7 +57,6 @@ pub fn print_u32(mut val: u32) { let s = str::from_utf8(&data).unwrap(); print(s); } - print("\r\n"); } /// Initialize UART peripheral