Skip to content

Commit

Permalink
Self CR fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
alloncm committed May 17, 2023
1 parent 5828112 commit b64e07a
Show file tree
Hide file tree
Showing 12 changed files with 64 additions and 93 deletions.
7 changes: 3 additions & 4 deletions baremetal/src/boot_armv7a.s
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
.section .text._start
.global _start
_start:
// TODO: add support for other CPU's other than the cortex a72 using the MIDR register
mrc p15, 0, r0, c0, c0, 5 // read MPIDR,
and r0, r0, #0b11 // on coretx a72 those bits are the CPU core id
cmp r0, #0 // check for cpu 0
Expand Down Expand Up @@ -174,13 +173,13 @@ _start:
mov r2, #0
.init_bss_loop:
cmp r0, r1
beq .start_rust
beq .finish_bss
str r2, [r0], #4 // increment r0 by 4 (dword)
b .init_bss_loop
.start_rust:
.finish_bss:
// setting up the stack
ldr sp, =__cpu0_stack_start
b _start_rust
b main

// Corrupts r4, r1 = end index
// r0 - L1 map ptr
Expand Down
25 changes: 0 additions & 25 deletions baremetal/src/drivers/ili9341/ili9341_spi.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use lib_gb::ppu::{gb_ppu::{SCREEN_WIDTH, SCREEN_HEIGHT}, gfx_device::{GfxDevice, Pixel}};

use crate::peripherals::{GpioPin, GpioManager, Mode, Timer};

use super::ili9341_spi::Ili9341Spi;
use crate::peripherals::{GpioPin, GpioManager, Mode, Timer, Spi, PERIPHERALS};

const ILI9341_SCREEN_WIDTH:usize = 320;
const ILI9341_SCREEN_HEIGHT:usize = 240;
Expand All @@ -14,7 +12,7 @@ const FRAME_BUFFER_X_OFFSET:usize = (ILI9341_SCREEN_WIDTH - TARGET_SCREEN_WIDTH)
pub const SPI_BUFFER_SIZE:usize = TARGET_SCREEN_HEIGHT * TARGET_SCREEN_WIDTH * core::mem::size_of::<u16>();

#[repr(u8)]
pub enum Ili9341Commands{
enum Ili9341Command{
SoftwareReset = 0x01,
SleepOut = 0x11,
GammaSet = 0x26,
Expand Down Expand Up @@ -42,7 +40,7 @@ pub enum Ili9341Commands{
}

struct Ili9341Contoller{
spi:Ili9341Spi,
spi:Spi,
timer: Timer,
led_pin: GpioPin,
reset_pin: GpioPin
Expand All @@ -57,7 +55,7 @@ impl Ili9341Contoller{

let reset_pin = gpio.take_pin(reset_pin_bcm, Mode::Output);
let led_pin = gpio.take_pin(led_pin_bcm, Mode::Output);
let spi = Ili9341Spi::new();
let spi = unsafe{PERIPHERALS.take_spi0()};

let mut controller = Ili9341Contoller { spi, led_pin, reset_pin, timer};

Expand All @@ -81,37 +79,37 @@ impl Ili9341Contoller{
// fbcp-ili9341 inspired implementation:
/*---------------------------------------------------------------------------------------------------------------------- */
// Reset the screen
controller.spi.write(Ili9341Commands::SoftwareReset,&[]);
controller.spi.write(Ili9341Command::SoftwareReset as u8,&[]);
controller.sleep_ms(5);
controller.spi.write(Ili9341Commands::DisplayOff,&[]);
controller.spi.write(Ili9341Command::DisplayOff as u8,&[]);

// Some power stuff, probably uneccessary but just for sure
controller.spi.write(Ili9341Commands::PowerControlA, &[0x39, 0x2C, 0x0, 0x34, 0x2]);
controller.spi.write(Ili9341Commands::PowerControlB, &[0x0, 0xC1, 0x30]);
controller.spi.write(Ili9341Commands::DriverTimingControlA, &[0x85, 0x0, 0x78]);
controller.spi.write(Ili9341Commands::DriverTimingControlB, &[0x0, 0x0]);
controller.spi.write(Ili9341Commands::PowerOnSequenceControl, &[0x64, 0x3, 0x12, 0x81]);
controller.spi.write(Ili9341Commands::PowerControl1, &[0x23]);
controller.spi.write(Ili9341Commands::PowerControl2,&[0x10]);
controller.spi.write(Ili9341Commands::VcomControl1, &[0xE3, 0x28]);
controller.spi.write(Ili9341Commands::VcomControl2, &[0x86]);
controller.spi.write(Ili9341Command::PowerControlA as u8, &[0x39, 0x2C, 0x0, 0x34, 0x2]);
controller.spi.write(Ili9341Command::PowerControlB as u8, &[0x0, 0xC1, 0x30]);
controller.spi.write(Ili9341Command::DriverTimingControlA as u8, &[0x85, 0x0, 0x78]);
controller.spi.write(Ili9341Command::DriverTimingControlB as u8, &[0x0, 0x0]);
controller.spi.write(Ili9341Command::PowerOnSequenceControl as u8, &[0x64, 0x3, 0x12, 0x81]);
controller.spi.write(Ili9341Command::PowerControl1 as u8, &[0x23]);
controller.spi.write(Ili9341Command::PowerControl2 as u8,&[0x10]);
controller.spi.write(Ili9341Command::VcomControl1 as u8, &[0xE3, 0x28]);
controller.spi.write(Ili9341Command::VcomControl2 as u8, &[0x86]);

// Configuring the screen
controller.spi.write(Ili9341Commands::MemoryAccessControl, &[0x28]); // This command tlit the screen 90 degree and set pixel to BGR order
controller.spi.write(Ili9341Commands::PixelFormatSet, &[0x55]); // set pixel format to 16 bit per pixel;
controller.spi.write(Ili9341Commands::FrameRateControl, &[0x0, 0x10 /*According to the docs this is 119 hrz, setting this option in order to avoid screen tearing on rpi zero2 */]);
controller.spi.write(Ili9341Commands::DisplayFunctionControl, &[0x8, 0x82, 0x27]);
controller.spi.write(Ili9341Command::MemoryAccessControl as u8, &[0x28]); // This command tlit the screen 90 degree and set pixel to BGR order
controller.spi.write(Ili9341Command::PixelFormatSet as u8, &[0x55]); // set pixel format to 16 bit per pixel;
controller.spi.write(Ili9341Command::FrameRateControl as u8, &[0x0, 0x10 /*According to the docs this is 119 hrz, setting this option in order to avoid screen tearing on rpi zero2 */]);
controller.spi.write(Ili9341Command::DisplayFunctionControl as u8, &[0x8, 0x82, 0x27]);

// Gamma values - pretty sure its redundant
controller.spi.write(Ili9341Commands::Enable3G, &[0x2]);
controller.spi.write(Ili9341Commands::GammaSet, &[0x1]);
controller.spi.write(Ili9341Commands::PossitiveGammaCorrection,&[0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00]);
controller.spi.write(Ili9341Commands::NegativeGammaCorrection, &[0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F]);
controller.spi.write(Ili9341Command::Enable3G as u8, &[0x2]);
controller.spi.write(Ili9341Command::GammaSet as u8, &[0x1]);
controller.spi.write(Ili9341Command::PossitiveGammaCorrection as u8,&[0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00]);
controller.spi.write(Ili9341Command::NegativeGammaCorrection as u8, &[0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F]);

// Turn screen on
controller.spi.write(Ili9341Commands::SleepOut,&[]);
controller.spi.write(Ili9341Command::SleepOut as u8,&[]);
controller.sleep_ms(120);
controller.spi.write(Ili9341Commands::DisplayOn,&[]);
controller.spi.write(Ili9341Command::DisplayOn as u8,&[]);
/*---------------------------------------------------------------------------------------------------------------------- */
//End of fbcp-ili9341 inpired implementation

Expand All @@ -121,10 +119,10 @@ impl Ili9341Contoller{
controller.led_pin.set_high();

// Clear screen
controller.spi.write(Ili9341Commands::ColumnAddressSet, &[0,0,((ILI9341_SCREEN_WIDTH -1) >> 8) as u8, ((ILI9341_SCREEN_WIDTH -1) & 0xFF) as u8]);
controller.spi.write(Ili9341Commands::PageAddressSet, &[0,0,((ILI9341_SCREEN_HEIGHT -1) >> 8) as u8, ((ILI9341_SCREEN_HEIGHT -1) & 0xFF) as u8]);
controller.spi.write(Ili9341Command::ColumnAddressSet as u8, &[0,0,((ILI9341_SCREEN_WIDTH -1) >> 8) as u8, ((ILI9341_SCREEN_WIDTH -1) & 0xFF) as u8]);
controller.spi.write(Ili9341Command::PageAddressSet as u8, &[0,0,((ILI9341_SCREEN_HEIGHT -1) >> 8) as u8, ((ILI9341_SCREEN_HEIGHT -1) & 0xFF) as u8]);
// using write and not write buffer since this is not the correct size
controller.spi.write(Ili9341Commands::MemoryWrite, &Self::CLEAN_BUFFER);
controller.spi.write(Ili9341Command::MemoryWrite as u8, &Self::CLEAN_BUFFER);

// need to sleep before changing the clock after transferring pixels to the lcd
controller.sleep_ms(120);
Expand All @@ -142,30 +140,30 @@ impl Ili9341Contoller{
unsafe{image_inter::scale_bilinear::<SCREEN_WIDTH, SCREEN_HEIGHT, TARGET_SCREEN_WIDTH, TARGET_SCREEN_HEIGHT>(buffer.as_ptr(), scaled_buffer.as_mut_ptr())};

let end_x_index = TARGET_SCREEN_WIDTH + FRAME_BUFFER_X_OFFSET - 1;
self.spi.write(Ili9341Commands::ColumnAddressSet, &[
self.spi.write(Ili9341Command::ColumnAddressSet as u8, &[
(FRAME_BUFFER_X_OFFSET >> 8) as u8,
(FRAME_BUFFER_X_OFFSET & 0xFF) as u8,
(end_x_index >> 8) as u8,
(end_x_index & 0xFF) as u8
]);
self.spi.write(Ili9341Commands::PageAddressSet, &[
self.spi.write(Ili9341Command::PageAddressSet as u8, &[
0x0, 0x0,
((TARGET_SCREEN_HEIGHT - 1) >> 8) as u8,
((TARGET_SCREEN_HEIGHT - 1) & 0xFF) as u8
]);

self.spi.write_buffer(Ili9341Commands::MemoryWrite, &scaled_buffer);
self.spi.write_dma(Ili9341Command::MemoryWrite as u8, &scaled_buffer);
}

fn sleep_ms(&mut self, milliseconds_to_sleep:u64){
let target_wait_time = core::time::Duration::from_millis(milliseconds_to_sleep);
self.timer.sleep(target_wait_time);
self.timer.wait(target_wait_time);
}
}

impl Drop for Ili9341Contoller{
fn drop(&mut self) {
self.spi.write(Ili9341Commands::DisplayOff, &[]);
self.spi.write(Ili9341Command::DisplayOff as u8, &[]);
self.led_pin.set_low();
self.reset_pin.set_high();
self.sleep_ms(1);
Expand Down
7 changes: 2 additions & 5 deletions baremetal/src/drivers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
mod gpio_joypad;
mod ili9341{
pub mod ili9341_gfx_device;
pub mod ili9341_spi;
}
mod ili9341_gfx_device;

pub use gpio_joypad::*;
pub use ili9341::ili9341_gfx_device::*;
pub use ili9341_gfx_device::*;
5 changes: 4 additions & 1 deletion baremetal/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ const ROM:&'static [u8] = include_bytes!("../../Dependencies/TetrisDX.gbc");
const RESET_PIN_BCM:u8 = 13;
const LED_PIN_BCM:u8 = 25;

// This function is no regular main.
// It will not return and will be jumped to from the _start proc in the boot code
// it is unmangled and exposed as a "C" function in order for the _start proc to call it
#[no_mangle]
pub extern "C" fn _start_rust()->!{
pub extern "C" fn main()->!{
unsafe{PERIPHERALS.set_core_clock()};
logging::UartLogger::init(log::LevelFilter::Debug);
log::info!("Initialized logger");
Expand Down
2 changes: 1 addition & 1 deletion baremetal/src/peripherals/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ impl Timer{
return Duration::from_micros(diff);
}

pub fn sleep(&mut self, duration:Duration){
pub fn wait(&mut self, duration:Duration){
let mut counter = core::time::Duration::ZERO;
let _ = self.tick(); // reset the timer ticking and disard the result
while counter < duration{
Expand Down
13 changes: 7 additions & 6 deletions baremetal/src/peripherals/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,28 @@ pub(super) fn memory_barrier(){
core::sync::atomic::fence(core::sync::atomic::Ordering::SeqCst);
}

pub(super) enum Peripheral<T>{
pub enum Peripheral<T>{
Uninit,
Init(T),
Taken
}

impl<T> Peripheral<T>{
pub(super) fn get<F:FnOnce()->T>(&mut self, init:F)->&mut T{
pub(super) fn get(&mut self, init_callback: impl FnOnce()->T)->&mut T{
if let Self::Uninit = self {
*self = Self::Init(init());
*self = Self::Init(init_callback());
}
return match self{
Self::Init(t) => t,
_ => core::panic!("Peripheral is unavaliable, its either been taken or uninitialized"),
Self::Taken => core::panic!("Peripheral is unavaliable, its been taken "),
Self::Uninit => core::unreachable!("At this point the peripheral must be initialized"),
};
}

pub(super) fn take<F:FnOnce()->T>(&mut self, init:F)->T{
pub(super) fn take(&mut self, init_callback: impl FnOnce()->T)->T{
let s = core::mem::replace(self, Self::Taken);
return match s{
Self::Uninit => init(),
Self::Uninit => init_callback(),
Self::Init(t) => t,
Self::Taken => core::panic!("Peripheral is unavaliable, its been taken"),
};
Expand Down
4 changes: 2 additions & 2 deletions baremetal/src/syncronization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ impl<TData> Mutex<TData>{
Mutex { data:UnsafeCell::new(data), lock:AtomicBool::new(false) }
}

pub fn lock<'a, TReturn>(&'a self, f: impl FnOnce(&'a mut TData)->TReturn)->TReturn{
pub fn lock<'a, TReturn>(&'a self, callback: impl FnOnce(&'a mut TData)->TReturn)->TReturn{
// block untill given access to lock the mutex
while self.lock.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst).is_ok(){}
let data = unsafe{&mut *self.data.get()};
let res = f(data);
let res = callback(data);
// free the mutex
self.lock.store(false, Ordering::SeqCst);

Expand Down
3 changes: 1 addition & 2 deletions image_inter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ pub unsafe fn scale_nearest<const INPUT_WIDTH:usize,const INPUT_HEIGHT:usize, co
let scale_y = OUTPUT_HEIGHT as f32 / INPUT_HEIGHT as f32;
for y in 0..OUTPUT_HEIGHT{
for x in 0..OUTPUT_WIDTH{
// This does not compile on no_std
// maybe round like this -> (x + 0.5) as int
let proj_x = round_f32(x as f32 / scale_x) as usize;
let proj_y = round_f32(y as f32 / scale_y) as usize;
let pixel = *input_buffer.add((proj_y * INPUT_WIDTH) + proj_x);
Expand All @@ -78,6 +76,7 @@ pub unsafe fn scale_nearest<const INPUT_WIDTH:usize,const INPUT_HEIGHT:usize, co
}

#[inline]
// round is not present in core so implementing it myself
fn round_f32(mut f:f32)->u32{
f += 0.5;
return f as u32;
Expand Down
2 changes: 1 addition & 1 deletion lib_gb/src/machine/mbc_initializer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{mmu::carts::*, utils::global_static_alloctor::{static_alloc, static_alloc_array}};
use crate::{mmu::carts::*, utils::global_static_alloctor::*};
use super::Mode;

const CARTRIDGE_TYPE_ADDRESS:usize = 0x147;
Expand Down
2 changes: 1 addition & 1 deletion lib_gb/src/utils/global_static_alloctor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::static_allocator::{StaticAllocator, Layout};

const STATIC_MEMORY_SIZE:usize = 0x100_0000;
static mut MEMORY:[u8;STATIC_MEMORY_SIZE] = [0;STATIC_MEMORY_SIZE];
static mut ALLOCATOR:StaticAllocator = unsafe{StaticAllocator::new(MEMORY.as_mut_ptr(), MEMORY.len())};
static mut ALLOCATOR:StaticAllocator = unsafe{StaticAllocator::new(&mut MEMORY)};

pub fn static_alloc<T>(t:T)->&'static mut T{
let layout = Layout::from_type::<T>();
Expand Down
19 changes: 9 additions & 10 deletions lib_gb/src/utils/static_allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,22 @@ impl Layout{
}

pub struct StaticAllocator{
buffer_ptr:*mut u8,
buffer_size: usize,
allocation_offset:usize
buffer:&'static [u8],
allocation_size:usize
}

impl StaticAllocator{
pub const unsafe fn new(buffer:*mut u8, buffer_size:usize)->Self{
Self{ buffer_ptr: buffer, buffer_size, allocation_offset: 0 }
pub const fn new(buffer:&'static [u8])->Self{
Self{ buffer, allocation_size: 0 }
}

pub unsafe fn alloc(&mut self, layout: Layout) -> NonNull<u8> {
let allocation_address = self.buffer_ptr.add(self.allocation_offset) as usize;
let allocation_address = self.buffer.as_ptr().add(self.allocation_size) as usize;
let aligned_address = Self::align_address(allocation_address, layout.align);
self.allocation_offset += layout.size + (aligned_address - allocation_address);
self.allocation_size += layout.size + (aligned_address - allocation_address);

if self.allocation_offset > self.buffer_size{
core::panic!("Allocation failed, allocator is out of static memory, pool size: {}, allocation req: {}", self.buffer_size, layout.size);
if self.allocation_size > self.buffer.len(){
core::panic!("Allocation failed, allocator is out of static memory, pool size: {}, allocation req: {}", self.buffer.len(), layout.size);
}
return NonNull::new_unchecked(aligned_address as *mut u8);
}
Expand All @@ -61,7 +60,7 @@ mod tests{
fn test_alloc_alignment(){
unsafe{
static mut BUFFER:[u8;100] = [0;100];
let mut allocator = StaticAllocator::new(BUFFER.as_mut_ptr(), 100);
let mut allocator = StaticAllocator::new(&mut BUFFER);
let aligns = 5;
for a in 1..aligns{
let align = 1 << a;
Expand Down

0 comments on commit b64e07a

Please sign in to comment.