From 719837d753de27c5e25364a086ae52e2abe9e566 Mon Sep 17 00:00:00 2001 From: Histausse Date: Thu, 17 Nov 2022 20:24:06 +0100 Subject: [PATCH] Implement UART write for raspi 3 --- src/bsp/rpi3/uart.rs | 36 ++++++++++++++++++++++++++++++------ src/main.rs | 8 ++++---- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/bsp/rpi3/uart.rs b/src/bsp/rpi3/uart.rs index 7c80b52..153a3de 100644 --- a/src/bsp/rpi3/uart.rs +++ b/src/bsp/rpi3/uart.rs @@ -29,7 +29,7 @@ impl<'a> UartInner<'a> { self.flush(); - // Stop UART + // Stop UART, see doc of CR register for the config process (P 185, doc BCM2835) self.memory_map.cr_uarten.read_and_write(0); // Flush the FIFOs @@ -54,7 +54,8 @@ impl<'a> UartInner<'a> { self.memory_map.lcrh.write_without_read(lcrh_val); let cr_val = self.memory_map.cr_txe.read_and_write_to_u32(1, 0); - // TODO: let cr_val = self.memory_map.cr_rxe.read_and_write_to_u32(1, 0); to enable read + let cr_val = self.memory_map.cr_rxe.read_and_write_to_u32(1, cr_val); + // Again, see doc of CR register for the config process (P 185, doc BCM2835) self.memory_map.cr.write_without_read(cr_val); // Start the UART @@ -67,11 +68,16 @@ impl<'a> UartInner<'a> { self.memory_map.fr_busy.read() != 0 } - /// Test if the the TX FIFO is full. + /// Test if the TX FIFO is full. fn is_tx_full(&self) -> bool { self.memory_map.fr_txff.read() != 0 } + /// Test if the RX FIFO is empty + fn is_rx_empty(&self) -> bool { + self.memory_map.fr_rxfe.read() != 0 + } + /// Write a character to the Uart fn write_char(&self, c: char) { if !self.initialized { @@ -85,12 +91,28 @@ impl<'a> UartInner<'a> { self.memory_map.dr_data.write_without_read(c as u32); } - /// Flush the uart + /// Read a character from the UART. + /// Blocking. + fn blocking_read_char(&self) -> char { + while self.is_rx_empty() { + unsafe { asm!("nop") }; + } + self.memory_map.dr_data.read() as u8 as char + } + + /// Flush the output of the uart fn flush(&self) { while self.is_busy() { unsafe { asm!("nop") }; } } + + /// Flush the input of the uart + fn flush_input(&self) { + while !self.is_rx_empty() { + let _ = self.memory_map.dr_data.read() as u8 as char; + } + } } // Allow the use of uart for fmt::Write::write_fmt. @@ -122,10 +144,12 @@ impl Write for Uart<'_> { impl Read for Uart<'_> { fn read_char(&self) -> char { - todo!() + self.inner.lock(|uart| uart.blocking_read_char()) } - fn flush_input(&self) {} + fn flush_input(&self) { + self.inner.lock(|uart| uart.flush_input()) + } } impl<'a> Uart<'a> { diff --git a/src/main.rs b/src/main.rs index 2322a23..3e6c6b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,9 +27,9 @@ use core::arch::global_asm; use core::arch::asm; // TODO: handle this with features -use crate::bsp::qemu::console::console; -//#[cfg(not(test))] -//use crate::bsp::rpi3::uart::console; +//use crate::bsp::qemu::console::console; +#[cfg(not(test))] +use crate::bsp::rpi3::uart::console; #[cfg(not(test))] use crate::bsp::rpi3::gpio; @@ -66,7 +66,7 @@ pub unsafe fn _start_rust() -> ! { match gpio::set_pin_output_state(20, gpio::PinOutputState::Low) { _ => (), } - //bsp::rpi3::uart::init(); + bsp::rpi3::uart::init(); println!("Hello there"); let mut buffer = ['X'; 200];