mirror of
https://github.com/iceHtwoO/novaOS.git
synced 2026-04-16 20:22:26 +00:00
Functioning draw
This commit is contained in:
@@ -1,7 +1,11 @@
|
|||||||
|
use core::ptr::write_volatile;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
mailbox::{read_mailbox, write_mailbox},
|
mailbox::{read_mailbox, write_mailbox},
|
||||||
peripherals::uart::{print, print_u32},
|
peripherals::uart::{print, print_u32, print_u32_hex},
|
||||||
};
|
};
|
||||||
|
#[repr(align(16))]
|
||||||
|
struct Mailbox([u32; 36]);
|
||||||
|
|
||||||
const ALLOCATE_BUFFER: u32 = 0x00040001;
|
const ALLOCATE_BUFFER: u32 = 0x00040001;
|
||||||
const GET_PHYSICAL_DISPLAY_WH: u32 = 0x00040003;
|
const GET_PHYSICAL_DISPLAY_WH: u32 = 0x00040003;
|
||||||
@@ -10,79 +14,129 @@ const SET_VIRTUAL_DISPLAY_WH: u32 = 0x00048004;
|
|||||||
const SET_PIXEL_DEPTH: u32 = 0x00048005;
|
const SET_PIXEL_DEPTH: u32 = 0x00048005;
|
||||||
const SET_PIXEL_ORDER: u32 = 0x00048006;
|
const SET_PIXEL_ORDER: u32 = 0x00048006;
|
||||||
const SET_FB_OFFSET: u32 = 0x00048009;
|
const SET_FB_OFFSET: u32 = 0x00048009;
|
||||||
|
const GET_PITCH: u32 = 0x00040008;
|
||||||
|
|
||||||
pub fn init_fb() {
|
pub struct FrameBuffer {
|
||||||
let mut mailbox = [0; 32];
|
pixel_depth: u32, // Bits per pixel
|
||||||
mailbox[0] = 32 * 4;
|
pitch: u32, // Pixel per row
|
||||||
mailbox[1] = 0;
|
rows: u32, // Rows
|
||||||
|
start_addr: *mut u32,
|
||||||
|
size: u32, //Bytes
|
||||||
|
}
|
||||||
|
|
||||||
mailbox[2] = SET_PHYSICAL_DISPLAY_WH;
|
impl FrameBuffer {
|
||||||
mailbox[3] = 8;
|
pub fn new() -> Self {
|
||||||
mailbox[4] = 8;
|
let mut mailbox = Mailbox([0; 36]);
|
||||||
mailbox[5] = 1920;
|
mailbox.0[0] = 35 * 4;
|
||||||
mailbox[6] = 1200;
|
mailbox.0[1] = 0;
|
||||||
|
|
||||||
mailbox[7] = SET_VIRTUAL_DISPLAY_WH;
|
mailbox.0[2] = SET_PHYSICAL_DISPLAY_WH;
|
||||||
mailbox[8] = 8;
|
mailbox.0[3] = 8;
|
||||||
mailbox[9] = 8;
|
mailbox.0[4] = 8;
|
||||||
mailbox[10] = 1920;
|
mailbox.0[5] = 1920;
|
||||||
mailbox[11] = 1200;
|
mailbox.0[6] = 1080;
|
||||||
|
|
||||||
mailbox[12] = SET_PIXEL_DEPTH;
|
mailbox.0[7] = SET_VIRTUAL_DISPLAY_WH;
|
||||||
mailbox[13] = 4;
|
mailbox.0[8] = 8;
|
||||||
mailbox[14] = 4;
|
mailbox.0[9] = 8;
|
||||||
mailbox[15] = 32; // 32 bit per pixel
|
mailbox.0[10] = 1920;
|
||||||
|
mailbox.0[11] = 1080;
|
||||||
|
|
||||||
mailbox[16] = SET_PIXEL_ORDER;
|
mailbox.0[12] = SET_PIXEL_DEPTH;
|
||||||
mailbox[17] = 4;
|
mailbox.0[13] = 4;
|
||||||
mailbox[18] = 4;
|
mailbox.0[14] = 4;
|
||||||
mailbox[19] = 0x1; // RGB
|
mailbox.0[15] = 32; // 32 bit per pixel
|
||||||
|
|
||||||
mailbox[20] = SET_FB_OFFSET;
|
mailbox.0[16] = SET_PIXEL_ORDER;
|
||||||
mailbox[21] = 8;
|
mailbox.0[17] = 4;
|
||||||
mailbox[22] = 8;
|
mailbox.0[18] = 4;
|
||||||
mailbox[24] = 0; // X in pixels
|
mailbox.0[19] = 0x1; // RGB
|
||||||
mailbox[25] = 0; // Y in pixels
|
|
||||||
|
|
||||||
mailbox[26] = ALLOCATE_BUFFER;
|
mailbox.0[20] = SET_FB_OFFSET;
|
||||||
mailbox[27] = 8;
|
mailbox.0[21] = 8;
|
||||||
mailbox[28] = 4;
|
mailbox.0[22] = 8;
|
||||||
mailbox[29] = 4096; // Alignment
|
mailbox.0[23] = 0; // X in pixels
|
||||||
mailbox[30] = 0;
|
mailbox.0[24] = 0; // Y in pixels
|
||||||
|
|
||||||
mailbox[31] = 0; // End tag
|
mailbox.0[25] = ALLOCATE_BUFFER;
|
||||||
|
mailbox.0[26] = 8;
|
||||||
|
mailbox.0[27] = 4;
|
||||||
|
mailbox.0[28] = 4096; // Alignment
|
||||||
|
mailbox.0[29] = 0;
|
||||||
|
|
||||||
// TODO: validate responses
|
mailbox.0[30] = GET_PITCH;
|
||||||
|
mailbox.0[31] = 4;
|
||||||
|
mailbox.0[32] = 0;
|
||||||
|
mailbox.0[33] = 0;
|
||||||
|
|
||||||
let addr = core::ptr::addr_of!(mailbox[0]) as u32;
|
mailbox.0[34] = 0; // End tag
|
||||||
|
|
||||||
write_mailbox(8, addr);
|
// TODO: validate responses
|
||||||
|
|
||||||
let _ = read_mailbox(8);
|
let addr = core::ptr::addr_of!(mailbox.0[0]) as u32;
|
||||||
if mailbox[1] == 0 {
|
|
||||||
print("Failed\r\n");
|
write_mailbox(8, addr);
|
||||||
|
|
||||||
|
let _ = read_mailbox(8);
|
||||||
|
if mailbox.0[1] == 0 {
|
||||||
|
print("Failed\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
print_u32_hex(mailbox.0[28]);
|
||||||
|
print("\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],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print_u32(mailbox[29]);
|
pub fn draw_pixel(&self, x: u32, y: u32) {
|
||||||
|
let offset = x + y * self.pitch;
|
||||||
|
unsafe {
|
||||||
|
write_volatile(self.start_addr.add(offset as usize), 0x00AAFFFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mailbox[29] = (mailbox[29] & 0x00FF_FFFF) | 0x3F00_0000;
|
/*Bresenham's line algorithm */
|
||||||
|
pub fn draw_line(&self, x1: u32, y1: u32, x2: u32, y2: u32) {
|
||||||
|
if x1 == x2 {
|
||||||
|
for y in y1..=y2 {
|
||||||
|
self.draw_pixel(x1, y);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let dx = x2 as i32 - x1 as i32;
|
||||||
|
let mut dy = y2 as i32 - y1 as i32;
|
||||||
|
let mut yi = 1;
|
||||||
|
|
||||||
let mut fb: *mut u32 = mailbox[29] as *mut u32;
|
let mut d = 2 * dy - dx;
|
||||||
|
let mut y = y1 as i32;
|
||||||
|
|
||||||
fb = unsafe { fb.add(1920 * 500 + 500) };
|
if dy < 0 {
|
||||||
|
yi = -1;
|
||||||
|
dy = -dy;
|
||||||
|
}
|
||||||
|
|
||||||
for x in 0..500 {
|
for x in x1..=x2 {
|
||||||
for y in 0..10 {
|
self.draw_pixel(x, y as u32);
|
||||||
unsafe {
|
if d > 0 {
|
||||||
*fb = 0xFFFFBB00;
|
y = y + yi;
|
||||||
fb = fb.add(1);
|
d += 2 * (dy - dx);
|
||||||
};
|
} else {
|
||||||
|
d += 2 * dy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_display_resolution() {
|
pub fn print_display_resolution() {
|
||||||
let mut mailbox = [0; 8];
|
let mut mailbox: [u32; 8] = [0; 8];
|
||||||
mailbox[0] = 8 * 4;
|
mailbox[0] = 8 * 4;
|
||||||
mailbox[1] = 0;
|
mailbox[1] = 0;
|
||||||
mailbox[2] = GET_PHYSICAL_DISPLAY_WH;
|
mailbox[2] = GET_PHYSICAL_DISPLAY_WH;
|
||||||
|
|||||||
20
src/main.rs
20
src/main.rs
@@ -9,7 +9,7 @@ use core::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use nova::{
|
use nova::{
|
||||||
framebuffer::{init_fb, print_display_resolution},
|
framebuffer::{print_display_resolution, FrameBuffer},
|
||||||
irq_interrupt::enable_irq_source,
|
irq_interrupt::enable_irq_source,
|
||||||
mailbox::read_soc_temp,
|
mailbox::read_soc_temp,
|
||||||
peripherals::{
|
peripherals::{
|
||||||
@@ -94,7 +94,23 @@ pub extern "C" fn kernel_main() -> ! {
|
|||||||
set_falling_edge_detect(26, true);
|
set_falling_edge_detect(26, true);
|
||||||
|
|
||||||
print_display_resolution();
|
print_display_resolution();
|
||||||
init_fb();
|
let fb = FrameBuffer::new();
|
||||||
|
print_display_resolution();
|
||||||
|
|
||||||
|
fb.draw_line(10, 10, 1000, 10);
|
||||||
|
fb.draw_line(10, 10, 1000, 200);
|
||||||
|
fb.draw_line(10, 10, 1000, 300);
|
||||||
|
fb.draw_line(10, 10, 1000, 400);
|
||||||
|
fb.draw_line(10, 10, 1000, 500);
|
||||||
|
fb.draw_line(10, 10, 1000, 600);
|
||||||
|
fb.draw_line(10, 10, 1000, 700);
|
||||||
|
fb.draw_line(10, 10, 1000, 800);
|
||||||
|
fb.draw_line(10, 10, 1000, 900);
|
||||||
|
fb.draw_line(10, 10, 1000, 1000);
|
||||||
|
fb.draw_line(10, 10, 100, 1000);
|
||||||
|
|
||||||
|
fb.draw_line(1800, 10, 1000, 900);
|
||||||
|
fb.draw_line(1800, 500, 1000, 100);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let temp = read_soc_temp();
|
let temp = read_soc_temp();
|
||||||
|
|||||||
@@ -59,6 +59,39 @@ pub fn print_u32(mut val: u32) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
/// Initialize UART peripheral
|
||||||
pub fn uart_init() {
|
pub fn uart_init() {
|
||||||
let baud_div_times_64 = (UART_CLK * 4) / BAUD;
|
let baud_div_times_64 = (UART_CLK * 4) / BAUD;
|
||||||
|
|||||||
Reference in New Issue
Block a user