use uart1 with more configuration

This commit is contained in:
Astro 2019-05-21 01:30:54 +02:00
parent 5d02fe5c95
commit 47ec0116a9
4 changed files with 69 additions and 11 deletions

View File

@ -50,8 +50,11 @@ unsafe fn boot_core0() -> ! {
} }
fn main() { fn main() {
let mut uart = Uart::uart0(); let mut uart = Uart::uart1();
writeln!(uart, "Hello World\r").unwrap(); writeln!(uart, "Hello World\r").unwrap();
for i in 0.. {
writeln!(uart, "i={}\r", i).unwrap();
}
let eth = eth::Eth::gem0(); let eth = eth::Eth::gem0();
loop { loop {

View File

@ -75,6 +75,17 @@ impl UartClkCtrl {
.clkact0(true) .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); register!(uart_rst_ctrl, UartRstCtrl, RW, u32);

View File

@ -1,6 +1,7 @@
#![allow(unused)] #![allow(unused)]
use core::fmt; use core::fmt;
use volatile_register::RW;
use crate::regs::*; use crate::regs::*;
@ -19,16 +20,28 @@ pub struct Uart {
} }
impl Uart { impl Uart {
pub fn uart0() -> Self { pub fn uart1() -> Self {
super::slcr::with_slcr(|| {
let uart_rst_ctrl = super::slcr::UartRstCtrl::new(); let uart_rst_ctrl = super::slcr::UartRstCtrl::new();
uart_rst_ctrl.reset_uart0(); uart_rst_ctrl.reset_uart1();
// TODO: Route UART 0 RxD/TxD Signals to MIO Pins
// Route UART 1 RxD/TxD Signals to MIO Pins
unsafe {
// TX pin
let mio_pin_48 = &*(0xF80007C0 as *const RW<u32>);
mio_pin_48.write(0x0000_12E0);
// RX pin
let mio_pin_49 = &*(0xF80007C4 as *const RW<u32>);
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(); let uart_clk_ctrl = super::slcr::UartClkCtrl::new();
uart_clk_ctrl.enable_uart0(); uart_clk_ctrl.enable_uart1();
});
let self_ = Uart { let self_ = Uart {
regs: regs::RegisterBlock::uart0(), regs: regs::RegisterBlock::uart1(),
}; };
self_.configure(); self_.configure();
self_ self_
@ -54,20 +67,25 @@ impl Uart {
self.regs.mode.write( self.regs.mode.write(
regs::Mode::zeroed() regs::Mode::zeroed()
.par(parity_mode as u8) .par(parity_mode as u8)
.chmode(regs::ChannelMode::AutomaticEcho as u8)
); );
// Configure the Baud Rate // Configure the Baud Rate
self.disable_rx(); self.disable_rx();
self.disable_tx(); self.disable_tx();
// 9,600 baud // 115,200 baud
self.regs.baud_rate_gen.write(regs::BaudRateGen::zeroed().cd(651)); self.regs.baud_rate_gen.write(regs::BaudRateGen::zeroed().cd(0x28B));
self.regs.baud_rate_divider.write(regs::BaudRateDiv::zeroed().bdiv(7)); self.regs.baud_rate_divider.write(regs::BaudRateDiv::zeroed().bdiv(0xF));
// Enable controller
self.reset_rx(); self.reset_rx();
self.reset_tx(); self.reset_tx();
self.enable_rx(); self.enable_rx();
self.enable_tx(); self.enable_tx();
self.set_rx_timeout(false);
self.set_break(false, true);
} }
fn disable_rx(&self) { 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 { pub fn tx_fifo_full(&self) -> bool {
self.regs.channel_sts.read().txfull() self.regs.channel_sts.read().txfull()
} }

View File

@ -2,6 +2,13 @@ use volatile_register::{RO, WO, RW};
use crate::{register, register_bit, register_bits, register_at, regs::*}; use crate::{register, register_bit, register_bits, register_at, regs::*};
pub enum ChannelMode {
Normal = 0b00,
AutomaticEcho = 0b01,
LocalLoopback = 0b10,
RemoteLoopback = 0b11,
}
#[repr(C)] #[repr(C)]
pub struct RegisterBlock { pub struct RegisterBlock {
pub control: Control, pub control: Control,
@ -33,8 +40,13 @@ register_bit!(control, rxen, 2);
register_bit!(control, rxdis, 3); register_bit!(control, rxdis, 3);
register_bit!(control, txen, 4); register_bit!(control, txen, 4);
register_bit!(control, txdis, 5); 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); 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_bits!(mode, par, u8, 3, 5);
register!(baud_rate_gen, BaudRateGen, RW, u32); register!(baud_rate_gen, BaudRateGen, RW, u32);