diff --git a/src/regs.rs b/src/regs.rs index f1c2292..4363a47 100644 --- a/src/regs.rs +++ b/src/regs.rs @@ -123,7 +123,7 @@ macro_rules! register { macro_rules! register_bit { ($mod_name: ident, $name: ident, $bit: expr) => ( impl $mod_name::Read { - fn $name(&self) -> bool { + pub fn $name(&self) -> bool { use bit_field::BitField; self.inner.get_bit($bit) @@ -131,7 +131,7 @@ macro_rules! register_bit { } impl $mod_name::Write { - fn $name(mut self, value: bool) -> Self { + pub fn $name(mut self, value: bool) -> Self { use bit_field::BitField; self.inner.set_bit($bit, value); @@ -146,7 +146,7 @@ macro_rules! register_bit { macro_rules! register_bits { ($mod_name: ident, $name: ident, $type: ty, $bit_begin: expr, $bit_end: expr) => ( impl $mod_name::Read { - fn $name(&self) -> $type { + pub fn $name(&self) -> $type { use bit_field::BitField; self.inner.get_bits($bit_begin..=$bit_end) as $type @@ -154,7 +154,7 @@ macro_rules! register_bits { } impl $mod_name::Write { - fn $name(mut self, value: $type) -> Self { + pub fn $name(mut self, value: $type) -> Self { use bit_field::BitField; self.inner.set_bits($bit_begin..=$bit_end, value.into()); diff --git a/src/uart/mod.rs b/src/uart/mod.rs index ec87469..c66a334 100644 --- a/src/uart/mod.rs +++ b/src/uart/mod.rs @@ -2,11 +2,20 @@ use core::fmt; +use crate::regs::*; + mod regs; -pub use regs::RegisterBlock; + +#[repr(u8)] +pub enum ParityMode { + EvenParity = 0b000, + OddParity = 0b001, + ForceTo0 = 0b010, + ForceTo1 = 0b011, +} pub struct Uart { - regs: &'static mut RegisterBlock, + regs: &'static mut regs::RegisterBlock, } impl Uart { @@ -17,21 +26,92 @@ impl Uart { let uart_clk_ctrl = super::slcr::UartClkCtrl::new(); uart_clk_ctrl.enable_uart0(); - - Uart { - regs: RegisterBlock::uart0(), - }.init() + + let self_ = Uart { + regs: regs::RegisterBlock::uart0(), + }; + self_.configure(); + self_ } - fn init(self) -> Self { - self.regs.configure(); - self + pub fn write_byte(&self, value: u8) { + while self.tx_fifo_full() {} + + self.regs.tx_rx_fifo.write( + regs::TxRxFifo::zeroed() + .data(value.into()) + ); } - pub fn write_byte(&self, v: u8) { - while self.regs.tx_fifo_full() {} + 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) + ); - 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() } } diff --git a/src/uart/regs.rs b/src/uart/regs.rs index ffda358..e4c92b7 100644 --- a/src/uart/regs.rs +++ b/src/uart/regs.rs @@ -2,34 +2,26 @@ use volatile_register::{RO, WO, RW}; use crate::{register, register_bit, register_bits, regs::*}; -#[repr(u8)] -pub enum ParityMode { - EvenParity = 0b000, - OddParity = 0b001, - ForceTo0 = 0b010, - ForceTo1 = 0b011, -} - #[repr(C)] pub struct RegisterBlock { - control: Control, - mode: Mode, - intrpt_en: RW, - intrpt_dis: RW, - intrpt_mask: RO, - chnl_int_sts: WO, - baud_rate_gen: BaudRateGen, - rcvr_timeout: RW, - rcvr_fifo_trigger_level: RW, - modem_ctrl: RW, - modem_sts: RW, - channel_sts: ChannelSts, - tx_rx_fifo: TxRxFifo, - baud_rate_divider: BaudRateDiv, - flow_delay: RW, - reserved0: RO, - reserved1: RO, - tx_fifo_trigger_level: RW, + pub control: Control, + pub mode: Mode, + pub intrpt_en: RW, + pub intrpt_dis: RW, + pub intrpt_mask: RO, + pub chnl_int_sts: WO, + pub baud_rate_gen: BaudRateGen, + pub rcvr_timeout: RW, + pub rcvr_fifo_trigger_level: RW, + pub modem_ctrl: RW, + pub modem_sts: RW, + pub channel_sts: ChannelSts, + pub tx_rx_fifo: TxRxFifo, + pub baud_rate_divider: BaudRateDiv, + pub flow_delay: RW, + pub unused0: RO, + pub unused1: RO, + pub tx_fifo_trigger_level: RW, } register!(control, Control, RW, u32); @@ -66,76 +58,4 @@ impl RegisterBlock { pub fn uart1() -> &'static mut Self { 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() - } }