forked from M-Labs/zynq-rs
uart: move logic outside regs
This commit is contained in:
parent
275f297309
commit
7872e00182
|
@ -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());
|
||||||
|
|
104
src/uart/mod.rs
104
src/uart/mod.rs
|
@ -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 {
|
||||||
|
@ -17,21 +26,92 @@ 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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
116
src/uart/regs.rs
116
src/uart/regs.rs
|
@ -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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue