2019-05-07 06:32:45 +08:00
|
|
|
#![allow(unused)]
|
|
|
|
|
2019-05-07 22:45:31 +08:00
|
|
|
use core::fmt;
|
|
|
|
|
2019-05-07 23:46:37 +08:00
|
|
|
use crate::regs::*;
|
|
|
|
|
2019-05-05 20:56:23 +08:00
|
|
|
mod regs;
|
2019-05-07 23:46:37 +08:00
|
|
|
|
|
|
|
#[repr(u8)]
|
|
|
|
pub enum ParityMode {
|
|
|
|
EvenParity = 0b000,
|
|
|
|
OddParity = 0b001,
|
|
|
|
ForceTo0 = 0b010,
|
|
|
|
ForceTo1 = 0b011,
|
|
|
|
}
|
2019-05-05 20:56:23 +08:00
|
|
|
|
|
|
|
pub struct Uart {
|
2019-05-07 23:46:37 +08:00
|
|
|
regs: &'static mut regs::RegisterBlock,
|
2019-05-05 20:56:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
let uart_clk_ctrl = super::slcr::UartClkCtrl::new();
|
|
|
|
uart_clk_ctrl.enable_uart0();
|
2019-05-07 23:46:37 +08:00
|
|
|
|
|
|
|
let self_ = Uart {
|
|
|
|
regs: regs::RegisterBlock::uart0(),
|
|
|
|
};
|
|
|
|
self_.configure();
|
|
|
|
self_
|
2019-05-05 20:56:23 +08:00
|
|
|
}
|
|
|
|
|
2019-05-07 23:46:37 +08:00
|
|
|
pub fn write_byte(&self, value: u8) {
|
|
|
|
while self.tx_fifo_full() {}
|
|
|
|
|
|
|
|
self.regs.tx_rx_fifo.write(
|
|
|
|
regs::TxRxFifo::zeroed()
|
|
|
|
.data(value.into())
|
|
|
|
);
|
2019-05-05 20:56:23 +08:00
|
|
|
}
|
|
|
|
|
2019-05-07 23:46:37 +08:00
|
|
|
pub fn configure(&self) {
|
|
|
|
// Confiugre UART character frame
|
|
|
|
// * Disable clock-divider
|
|
|
|
// * 8-bit
|
|
|
|
// * 1 stop bit
|
|
|
|
// * Normal channel mode
|
|
|
|
// * no parity
|
|
|
|
let parity_mode = ParityMode::ForceTo0;
|
|
|
|
self.regs.mode.write(
|
|
|
|
regs::Mode::zeroed()
|
|
|
|
.par(parity_mode 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));
|
|
|
|
|
|
|
|
self.reset_rx();
|
|
|
|
self.reset_tx();
|
|
|
|
self.enable_rx();
|
|
|
|
self.enable_tx();
|
|
|
|
}
|
|
|
|
|
|
|
|
fn disable_rx(&self) {
|
|
|
|
self.regs.control.modify(|_, w| {
|
|
|
|
w.rxen(false)
|
|
|
|
.rxdis(true)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
fn disable_tx(&self) {
|
|
|
|
self.regs.control.modify(|_, w| {
|
|
|
|
w.txen(false)
|
|
|
|
.txdis(true)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
fn enable_rx(&self) {
|
|
|
|
self.regs.control.modify(|_, w| {
|
|
|
|
w.rxen(true)
|
|
|
|
.rxdis(false)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
fn enable_tx(&self) {
|
|
|
|
self.regs.control.modify(|_, w| {
|
|
|
|
w.txen(true)
|
|
|
|
.txdis(false)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
fn reset_rx(&self) {
|
|
|
|
self.regs.control.modify(|_, w| {
|
|
|
|
w.rxrst(true)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
fn reset_tx(&self) {
|
|
|
|
self.regs.control.modify(|_, w| {
|
|
|
|
w.txrst(true)
|
|
|
|
})
|
|
|
|
}
|
2019-05-05 20:56:23 +08:00
|
|
|
|
2019-05-07 23:46:37 +08:00
|
|
|
pub fn tx_fifo_full(&self) -> bool {
|
|
|
|
self.regs.channel_sts.read().txfull()
|
2019-05-05 20:56:23 +08:00
|
|
|
}
|
|
|
|
}
|
2019-05-07 22:45:31 +08:00
|
|
|
|
|
|
|
impl fmt::Write for Uart {
|
|
|
|
fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
|
|
|
|
for b in s.bytes() {
|
|
|
|
self.write_byte(b);
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|