diff --git a/src/main.rs b/src/main.rs index a495694..7d2921c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,8 +5,10 @@ use core::{arch::asm, panic::PanicInfo}; use gpio::{gpio_high, gpio_low, set_gpio_state}; +use timer::{delay_nops, sleep}; mod gpio; +mod timer; mod uart; #[panic_handler] @@ -31,20 +33,13 @@ extern "C" fn main() { } // Delay so clock speed can stabilize - unsafe { delay(50000) } + unsafe { delay_nops(50000) } uart::print("Hello World!\n"); loop { let _ = gpio_high(29); - unsafe { delay(1_000_000) } + unsafe { sleep(500_000) } // 0.5s let _ = gpio_low(29); - unsafe { delay(1_000_000) } - } -} - -unsafe fn delay(count: u32) { - for _ in 0..count { - // Prevent compiler optimizing away the loop - core::arch::asm!("nop"); + unsafe { sleep(500_000) } // 0.5s } } diff --git a/src/timer.rs b/src/timer.rs new file mode 100644 index 0000000..906907d --- /dev/null +++ b/src/timer.rs @@ -0,0 +1,18 @@ +const TIMER_CLO: u32 = 0x3F00_3004; + +fn read_clo() -> u32 { + unsafe { return core::ptr::read_volatile(TIMER_CLO as *const u32) } +} + +pub unsafe fn sleep(microseconds: u32) { + let start = read_clo(); + while read_clo() - start < microseconds { + core::arch::asm!("nop"); + } +} + +pub unsafe fn delay_nops(count: u32) { + for _ in 0..count { + core::arch::asm!("nop"); + } +} diff --git a/src/uart.rs b/src/uart.rs index 703e0c5..b834732 100644 --- a/src/uart.rs +++ b/src/uart.rs @@ -23,6 +23,8 @@ pub fn print(s: &str) { core::ptr::write_volatile(UART0_DR as *mut u32, byte as u32); } } + // wait till uart is not busy anymore + unsafe { while (core::ptr::read_volatile(UART0_FR as *const u32) >> 3) & 0b1 != 0 {} } } pub fn configure_uart() {