1
0
Fork 0

uart: move logic outside regs

This commit is contained in:
Astro 2019-05-07 17:46:37 +02:00
parent 275f297309
commit 7872e00182
3 changed files with 114 additions and 114 deletions

View File

@ -123,7 +123,7 @@ macro_rules! register {
macro_rules! register_bit { macro_rules! register_bit {
($mod_name: ident, $name: ident, $bit: expr) => ( ($mod_name: ident, $name: ident, $bit: expr) => (
impl $mod_name::Read { impl $mod_name::Read {
fn $name(&self) -> bool { pub fn $name(&self) -> bool {
use bit_field::BitField; use bit_field::BitField;
self.inner.get_bit($bit) self.inner.get_bit($bit)
@ -131,7 +131,7 @@ macro_rules! register_bit {
} }
impl $mod_name::Write { impl $mod_name::Write {
fn $name(mut self, value: bool) -> Self { pub fn $name(mut self, value: bool) -> Self {
use bit_field::BitField; use bit_field::BitField;
self.inner.set_bit($bit, value); self.inner.set_bit($bit, value);
@ -146,7 +146,7 @@ macro_rules! register_bit {
macro_rules! register_bits { macro_rules! register_bits {
($mod_name: ident, $name: ident, $type: ty, $bit_begin: expr, $bit_end: expr) => ( ($mod_name: ident, $name: ident, $type: ty, $bit_begin: expr, $bit_end: expr) => (
impl $mod_name::Read { impl $mod_name::Read {
fn $name(&self) -> $type { pub fn $name(&self) -> $type {
use bit_field::BitField; use bit_field::BitField;
self.inner.get_bits($bit_begin..=$bit_end) as $type self.inner.get_bits($bit_begin..=$bit_end) as $type
@ -154,7 +154,7 @@ macro_rules! register_bits {
} }
impl $mod_name::Write { impl $mod_name::Write {
fn $name(mut self, value: $type) -> Self { pub fn $name(mut self, value: $type) -> Self {
use bit_field::BitField; use bit_field::BitField;
self.inner.set_bits($bit_begin..=$bit_end, value.into()); self.inner.set_bits($bit_begin..=$bit_end, value.into());

View File

@ -2,11 +2,20 @@
use core::fmt; use core::fmt;
use crate::regs::*;
mod regs; mod regs;
pub use regs::RegisterBlock;
#[repr(u8)]
pub enum ParityMode {
EvenParity = 0b000,
OddParity = 0b001,
ForceTo0 = 0b010,
ForceTo1 = 0b011,
}
pub struct Uart { pub struct Uart {
regs: &'static mut RegisterBlock, regs: &'static mut regs::RegisterBlock,
} }
impl Uart { impl Uart {
@ -18,20 +27,91 @@ impl Uart {
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_uart0();
Uart { let self_ = Uart {
regs: RegisterBlock::uart0(), regs: regs::RegisterBlock::uart0(),
}.init() };
self_.configure();
self_
} }
fn init(self) -> Self { pub fn write_byte(&self, value: u8) {
self.regs.configure(); while self.tx_fifo_full() {}
self
self.regs.tx_rx_fifo.write(
regs::TxRxFifo::zeroed()
.data(value.into())
);
} }
pub fn write_byte(&self, v: u8) { pub fn configure(&self) {
while self.regs.tx_fifo_full() {} // 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)
);
self.regs.write_byte(v); // 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)
})
}
pub fn tx_fifo_full(&self) -> bool {
self.regs.channel_sts.read().txfull()
} }
} }

View File

@ -2,34 +2,26 @@ use volatile_register::{RO, WO, RW};
use crate::{register, register_bit, register_bits, regs::*}; use crate::{register, register_bit, register_bits, regs::*};
#[repr(u8)]
pub enum ParityMode {
EvenParity = 0b000,
OddParity = 0b001,
ForceTo0 = 0b010,
ForceTo1 = 0b011,
}
#[repr(C)] #[repr(C)]
pub struct RegisterBlock { pub struct RegisterBlock {
control: Control, pub control: Control,
mode: Mode, pub mode: Mode,
intrpt_en: RW<u32>, pub intrpt_en: RW<u32>,
intrpt_dis: RW<u32>, pub intrpt_dis: RW<u32>,
intrpt_mask: RO<u32>, pub intrpt_mask: RO<u32>,
chnl_int_sts: WO<u32>, pub chnl_int_sts: WO<u32>,
baud_rate_gen: BaudRateGen, pub baud_rate_gen: BaudRateGen,
rcvr_timeout: RW<u32>, pub rcvr_timeout: RW<u32>,
rcvr_fifo_trigger_level: RW<u32>, pub rcvr_fifo_trigger_level: RW<u32>,
modem_ctrl: RW<u32>, pub modem_ctrl: RW<u32>,
modem_sts: RW<u32>, pub modem_sts: RW<u32>,
channel_sts: ChannelSts, pub channel_sts: ChannelSts,
tx_rx_fifo: TxRxFifo, pub tx_rx_fifo: TxRxFifo,
baud_rate_divider: BaudRateDiv, pub baud_rate_divider: BaudRateDiv,
flow_delay: RW<u32>, pub flow_delay: RW<u32>,
reserved0: RO<u32>, pub unused0: RO<u32>,
reserved1: RO<u32>, pub unused1: RO<u32>,
tx_fifo_trigger_level: RW<u32>, pub tx_fifo_trigger_level: RW<u32>,
} }
register!(control, Control, RW, u32); register!(control, Control, RW, u32);
@ -66,76 +58,4 @@ impl RegisterBlock {
pub fn uart1() -> &'static mut Self { pub fn uart1() -> &'static mut Self {
unsafe { &mut *Self::UART1 } unsafe { &mut *Self::UART1 }
} }
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.mode.write(Mode::zeroed().par(parity_mode as u8));
// Configure the Baud Rate
self.disable_rx();
self.disable_tx();
// 9,600 baud
self.baud_rate_gen.write(BaudRateGen::zeroed().cd(651));
self.baud_rate_divider.write(BaudRateDiv::zeroed().bdiv(7));
self.reset_rx();
self.reset_tx();
self.enable_rx();
self.enable_tx();
}
pub fn write_byte(&self, value: u8) {
self.tx_rx_fifo.write(TxRxFifo::zeroed().data(value.into()));
}
fn disable_rx(&self) {
self.control.modify(|_, w| {
w.rxen(false)
.rxdis(true)
})
}
fn disable_tx(&self) {
self.control.modify(|_, w| {
w.txen(false)
.txdis(true)
})
}
fn enable_rx(&self) {
self.control.modify(|_, w| {
w.rxen(true)
.rxdis(false)
})
}
fn enable_tx(&self) {
self.control.modify(|_, w| {
w.txen(true)
.txdis(false)
})
}
fn reset_rx(&self) {
self.control.modify(|_, w| {
w.rxrst(true)
})
}
fn reset_tx(&self) {
self.control.modify(|_, w| {
w.txrst(true)
})
}
pub fn tx_fifo_full(&self) -> bool {
self.channel_sts.read().txfull()
}
} }