|
|
|
@ -38,14 +38,10 @@ impl Uart {
|
|
|
|
|
self.flush();
|
|
|
|
|
|
|
|
|
|
// Stop UART
|
|
|
|
|
let mut cr_val = unsafe { read_volatile(TMP_UARTEN.get_address() as *mut u32) };
|
|
|
|
|
cr_val &= !TMP_UARTEN.get_mask();
|
|
|
|
|
unsafe { write_volatile(TMP_UARTEN.get_address() as *mut u32, cr_val); }
|
|
|
|
|
TMP_UARTEN.read_and_write(0);
|
|
|
|
|
|
|
|
|
|
// Flush the FIFOs
|
|
|
|
|
let mut lcrh_val = unsafe { read_volatile(TMP_FEN.get_address() as *mut u32) };
|
|
|
|
|
lcrh_val &= !TMP_FEN.get_mask();
|
|
|
|
|
unsafe { write_volatile(TMP_FEN.get_address() as *mut u32, lcrh_val); }
|
|
|
|
|
TMP_FEN.read_and_write(0);
|
|
|
|
|
|
|
|
|
|
// Clear all interrupt
|
|
|
|
|
unsafe { write_volatile(ICR as *mut u32, 0); }
|
|
|
|
@ -56,37 +52,33 @@ impl Uart {
|
|
|
|
|
// divbaud = freq/16/baudrate = 48_000_000 / 16 / 115_200 = 26.041666666666668
|
|
|
|
|
// => IBRD = 26
|
|
|
|
|
// => FBRD = round(0.041666666666668 * 64) = 3 // TODO: why 64?
|
|
|
|
|
unsafe { write_volatile(TMP_IBRD.get_address() as *mut u32, 26 & TMP_IBRD.get_mask()); }
|
|
|
|
|
unsafe { write_volatile(TMP_FBRD.get_address() as *mut u32, 3 & TMP_FBRD.get_mask()); }
|
|
|
|
|
TMP_IBRD.write_without_read(26);
|
|
|
|
|
TMP_FBRD.write_without_read(3);
|
|
|
|
|
|
|
|
|
|
lcrh_val = 0;
|
|
|
|
|
// Set word len to 8
|
|
|
|
|
lcrh_val |= 0b11 << TMP_WLEN.get_offset();
|
|
|
|
|
let lcrh_val = TMP_WLEN.read_and_write_to_u32(0b11, 0);
|
|
|
|
|
// Reenable the FIFOs
|
|
|
|
|
lcrh_val |= TMP_FEN.get_mask();
|
|
|
|
|
let lcrh_val = TMP_FEN.read_and_write_to_u32(1, lcrh_val);
|
|
|
|
|
unsafe { write_volatile(LCRH as *mut u32, lcrh_val); }
|
|
|
|
|
|
|
|
|
|
let mut cr_val = 0;
|
|
|
|
|
cr_val |= TMP_TXE.get_mask(); // enable TX
|
|
|
|
|
unsafe { write_volatile(TMP_TXE.get_address() as *mut u32, cr_val); }
|
|
|
|
|
let cr_val = TMP_TXE.read_and_write_to_u32(1, 0);
|
|
|
|
|
// TODO: let cr_val = TMP_RXE.read_and_write_to_u32(1, 0); to enable read
|
|
|
|
|
unsafe { write_volatile(CR.get_address() as *mut u32, cr_val); }
|
|
|
|
|
|
|
|
|
|
// Start the UART
|
|
|
|
|
cr_val |= TMP_UARTEN.get_mask();
|
|
|
|
|
unsafe { write_volatile(TMP_UARTEN.get_address() as *mut u32, cr_val); }
|
|
|
|
|
|
|
|
|
|
self.initialized = true;
|
|
|
|
|
TMP_UARTEN.read_and_write(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Test if the UART is busy.
|
|
|
|
|
fn is_busy(&self) -> bool {
|
|
|
|
|
let fr_val = unsafe { read_volatile(TMP_BUSY.get_address() as *mut u32) };
|
|
|
|
|
(fr_val & TMP_BUSY.get_mask()) != 0
|
|
|
|
|
TMP_BUSY.read() != 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Test if the the TX FIFO is full.
|
|
|
|
|
fn is_tx_full(&self) -> bool {
|
|
|
|
|
let fr_val = unsafe { read_volatile(TMP_TXFF.get_address() as *mut u32) };
|
|
|
|
|
(fr_val & TMP_TXFF.get_mask()) != 0
|
|
|
|
|
TMP_TXFF.read() != 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -114,7 +106,7 @@ impl Write for Uart {
|
|
|
|
|
let _ = gpio::set_pin_output_state(20, gpio::PinOutputState::High);
|
|
|
|
|
unsafe { asm!("nop") };
|
|
|
|
|
}
|
|
|
|
|
unsafe { write_volatile(TMP_DATA.get_address() as *mut u32, c as u32) };
|
|
|
|
|
TMP_DATA.write_without_read(c as u32);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn write_fmt(&self, args: fmt::Arguments) -> fmt::Result {
|
|
|
|
|