diff --git a/src/main.rs b/src/main.rs index 6cc161d6..6f9055f8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,8 +50,11 @@ unsafe fn boot_core0() -> ! { } fn main() { - let mut uart = Uart::uart0(); + let mut uart = Uart::uart1(); writeln!(uart, "Hello World\r").unwrap(); + for i in 0.. { + writeln!(uart, "i={}\r", i).unwrap(); + } let eth = eth::Eth::gem0(); loop { diff --git a/src/slcr.rs b/src/slcr.rs index d53dfad0..697dc6fc 100644 --- a/src/slcr.rs +++ b/src/slcr.rs @@ -75,6 +75,17 @@ impl UartClkCtrl { .clkact0(true) }) } + + pub fn enable_uart1(&self) { + self.modify(|_, w| { + // a. Clock divisor, slcr.UART_CLK_CTRL[DIVISOR] = 0x14. + // b. Select the IO PLL, slcr.UART_CLK_CTRL[SRCSEL] = 0. + // c. Enable the UART 1 Reference clock, slcr.UART_CLK_CTRL [CLKACT1] = 1. + w.divisor(0x14) + .srcsel(PllSource::IoPll as u8) + .clkact1(true) + }) + } } register!(uart_rst_ctrl, UartRstCtrl, RW, u32); diff --git a/src/uart/mod.rs b/src/uart/mod.rs index c66a334a..806d882a 100644 --- a/src/uart/mod.rs +++ b/src/uart/mod.rs @@ -1,6 +1,7 @@ #![allow(unused)] use core::fmt; +use volatile_register::RW; use crate::regs::*; @@ -19,16 +20,28 @@ pub struct Uart { } impl Uart { - pub fn uart0() -> Self { - let uart_rst_ctrl = super::slcr::UartRstCtrl::new(); - uart_rst_ctrl.reset_uart0(); - // TODO: Route UART 0 RxD/TxD Signals to MIO Pins + pub fn uart1() -> Self { + super::slcr::with_slcr(|| { + let uart_rst_ctrl = super::slcr::UartRstCtrl::new(); + uart_rst_ctrl.reset_uart1(); - let uart_clk_ctrl = super::slcr::UartClkCtrl::new(); - uart_clk_ctrl.enable_uart0(); + // Route UART 1 RxD/TxD Signals to MIO Pins + unsafe { + // TX pin + let mio_pin_48 = &*(0xF80007C0 as *const RW); + mio_pin_48.write(0x0000_12E0); + // RX pin + let mio_pin_49 = &*(0xF80007C4 as *const RW); + mio_pin_49.write(0x0000_12E1); + } + let aper_clk_ctrl = super::slcr::AperClkCtrl::new(); + aper_clk_ctrl.enable_uart1(); + let uart_clk_ctrl = super::slcr::UartClkCtrl::new(); + uart_clk_ctrl.enable_uart1(); + }); let self_ = Uart { - regs: regs::RegisterBlock::uart0(), + regs: regs::RegisterBlock::uart1(), }; self_.configure(); self_ @@ -54,20 +67,25 @@ impl Uart { self.regs.mode.write( regs::Mode::zeroed() .par(parity_mode as u8) + .chmode(regs::ChannelMode::AutomaticEcho as u8) ); // Configure the Baud Rate self.disable_rx(); self.disable_tx(); - // 9,600 baud - self.regs.baud_rate_gen.write(regs::BaudRateGen::zeroed().cd(651)); - self.regs.baud_rate_divider.write(regs::BaudRateDiv::zeroed().bdiv(7)); + // 115,200 baud + self.regs.baud_rate_gen.write(regs::BaudRateGen::zeroed().cd(0x28B)); + self.regs.baud_rate_divider.write(regs::BaudRateDiv::zeroed().bdiv(0xF)); + // Enable controller self.reset_rx(); self.reset_tx(); self.enable_rx(); self.enable_tx(); + + self.set_rx_timeout(false); + self.set_break(false, true); } fn disable_rx(&self) { @@ -110,6 +128,20 @@ impl Uart { }) } + fn set_break(&self, startbrk: bool, stopbrk: bool) { + self.regs.control.modify(|_, w| { + w.sttbrk(startbrk) + .stpbrk(stopbrk) + }) + } + + // 0 disables + fn set_rx_timeout(&self, enable: bool) { + self.regs.control.modify(|_, w| { + w.rstto(enable) + }) + } + pub fn tx_fifo_full(&self) -> bool { self.regs.channel_sts.read().txfull() } diff --git a/src/uart/regs.rs b/src/uart/regs.rs index e842cd60..7cd01749 100644 --- a/src/uart/regs.rs +++ b/src/uart/regs.rs @@ -2,6 +2,13 @@ use volatile_register::{RO, WO, RW}; use crate::{register, register_bit, register_bits, register_at, regs::*}; +pub enum ChannelMode { + Normal = 0b00, + AutomaticEcho = 0b01, + LocalLoopback = 0b10, + RemoteLoopback = 0b11, +} + #[repr(C)] pub struct RegisterBlock { pub control: Control, @@ -33,8 +40,13 @@ register_bit!(control, rxen, 2); register_bit!(control, rxdis, 3); register_bit!(control, txen, 4); register_bit!(control, txdis, 5); +register_bit!(control, rstto, 6); +register_bit!(control, sttbrk, 7); +register_bit!(control, stpbrk, 8); register!(mode, Mode, RW, u32); +/// Channel mode: Defines the mode of operation of the UART. +register_bits!(mode, chmode, u8, 8, 9); register_bits!(mode, par, u8, 3, 5); register!(baud_rate_gen, BaudRateGen, RW, u32);