Wait until serial tx buffer is empty
This commit is contained in:
parent
b02c34fd1d
commit
07136397d0
@ -9,6 +9,8 @@ use num_derive::FromPrimitive;
|
|||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
use x86_64::instructions::port::Port;
|
use x86_64::instructions::port::Port;
|
||||||
|
|
||||||
|
use crate::arch::asm::nop;
|
||||||
|
|
||||||
/// Represents an x86 port-mapped serial port.
|
/// Represents an x86 port-mapped serial port.
|
||||||
pub struct SerialPort {
|
pub struct SerialPort {
|
||||||
base_port: Port<u8>,
|
base_port: Port<u8>,
|
||||||
@ -21,6 +23,7 @@ pub struct SerialPort {
|
|||||||
scratch: Port<u8>,
|
scratch: Port<u8>,
|
||||||
fifo_register: u8,
|
fifo_register: u8,
|
||||||
pub crlf: Crlf,
|
pub crlf: Crlf,
|
||||||
|
pub wait_tx_clear: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
@ -123,7 +126,6 @@ pub enum ModemStatus {
|
|||||||
DataCarrierDetect = 0b10000000,
|
DataCarrierDetect = 0b10000000,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Ensure we don't clobber the tx buffer and prevent some data from getting printed
|
|
||||||
impl SerialPort {
|
impl SerialPort {
|
||||||
pub fn log_write(&mut self, msg: &str) {
|
pub fn log_write(&mut self, msg: &str) {
|
||||||
if self.crlf == Crlf::Crlf {
|
if self.crlf == Crlf::Crlf {
|
||||||
@ -140,10 +142,18 @@ impl SerialPort {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get whether the transmit buffer is empty.
|
||||||
pub fn is_transmit_empty(&mut self) -> bool {
|
pub fn is_transmit_empty(&mut self) -> bool {
|
||||||
self.get_interrupt_state() != InterruptState::TransmitterEmpty
|
self.get_line_status().contains(LineStatus::TransmitterEmpty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn block_until_transmit_empty(&mut self) {
|
||||||
|
while !self.is_transmit_empty() {
|
||||||
|
nop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write a message with a newline appended to the serial port.
|
||||||
pub fn log_writeln(&mut self, msg: &str) {
|
pub fn log_writeln(&mut self, msg: &str) {
|
||||||
self.log_write(msg);
|
self.log_write(msg);
|
||||||
self.log_write("\n");
|
self.log_write("\n");
|
||||||
@ -162,6 +172,7 @@ impl SerialPort {
|
|||||||
scratch: Port::new(port_addr + 7),
|
scratch: Port::new(port_addr + 7),
|
||||||
fifo_register: 0,
|
fifo_register: 0,
|
||||||
crlf: Crlf::Crlf,
|
crlf: Crlf::Crlf,
|
||||||
|
wait_tx_clear: true,
|
||||||
};
|
};
|
||||||
// ensure this is false
|
// ensure this is false
|
||||||
port.set_dlab(false);
|
port.set_dlab(false);
|
||||||
@ -190,6 +201,10 @@ impl SerialPort {
|
|||||||
}
|
}
|
||||||
/// Write a single character to the TX buffer.
|
/// Write a single character to the TX buffer.
|
||||||
pub fn write_char(&mut self, c: char) {
|
pub fn write_char(&mut self, c: char) {
|
||||||
|
// Wait for the TX Buffer to be empty
|
||||||
|
if self.wait_tx_clear {
|
||||||
|
self.block_until_transmit_empty();
|
||||||
|
}
|
||||||
unsafe { self.base_port.write(c as u8) };
|
unsafe { self.base_port.write(c as u8) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user