Miscellaneous cleanup
This commit is contained in:
parent
2b27d10aa4
commit
22df2dbb99
@ -6,11 +6,9 @@ use crate::pac::{uart0::RegisterBlock, UART0, UART1};
|
|||||||
|
|
||||||
const UART_FIFO_SIZE: u16 = 128;
|
const UART_FIFO_SIZE: u16 = 128;
|
||||||
|
|
||||||
/// UART-specific errors
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {}
|
pub enum Error {}
|
||||||
|
|
||||||
/// UART peripheral (UART)
|
|
||||||
pub struct Serial<T> {
|
pub struct Serial<T> {
|
||||||
uart: T,
|
uart: T,
|
||||||
}
|
}
|
||||||
@ -26,13 +24,10 @@ impl<T: Instance> Serial<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait Instance {
|
pub trait Instance {
|
||||||
/// Return registerblock of uart instance as if it were UART0
|
fn register_block(&self) -> &RegisterBlock;
|
||||||
fn as_uart0(&self) -> &RegisterBlock;
|
|
||||||
|
|
||||||
/// Clear and disable all tx-related interrupts
|
|
||||||
fn disable_tx_interrupts(&mut self) {
|
fn disable_tx_interrupts(&mut self) {
|
||||||
// Disable UART TX interrupts
|
self.register_block().int_clr.write(|w| {
|
||||||
self.as_uart0().int_clr.write(|w| {
|
|
||||||
w.txfifo_empty_int_clr()
|
w.txfifo_empty_int_clr()
|
||||||
.set_bit()
|
.set_bit()
|
||||||
.tx_brk_done_int_clr()
|
.tx_brk_done_int_clr()
|
||||||
@ -43,7 +38,7 @@ pub trait Instance {
|
|||||||
.set_bit()
|
.set_bit()
|
||||||
});
|
});
|
||||||
|
|
||||||
self.as_uart0().int_ena.write(|w| {
|
self.register_block().int_ena.write(|w| {
|
||||||
w.txfifo_empty_int_ena()
|
w.txfifo_empty_int_ena()
|
||||||
.clear_bit()
|
.clear_bit()
|
||||||
.tx_brk_done_int_ena()
|
.tx_brk_done_int_ena()
|
||||||
@ -55,10 +50,8 @@ pub trait Instance {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear and disable all rx-related interrupts
|
|
||||||
fn disable_rx_interrupts(&mut self) {
|
fn disable_rx_interrupts(&mut self) {
|
||||||
// Disable UART RX interrupts
|
self.register_block().int_clr.write(|w| {
|
||||||
self.as_uart0().int_clr.write(|w| {
|
|
||||||
w.rxfifo_full_int_clr()
|
w.rxfifo_full_int_clr()
|
||||||
.set_bit()
|
.set_bit()
|
||||||
.rxfifo_ovf_int_clr()
|
.rxfifo_ovf_int_clr()
|
||||||
@ -67,7 +60,7 @@ pub trait Instance {
|
|||||||
.set_bit()
|
.set_bit()
|
||||||
});
|
});
|
||||||
|
|
||||||
self.as_uart0().int_ena.write(|w| {
|
self.register_block().int_ena.write(|w| {
|
||||||
w.rxfifo_full_int_ena()
|
w.rxfifo_full_int_ena()
|
||||||
.clear_bit()
|
.clear_bit()
|
||||||
.rxfifo_ovf_int_ena()
|
.rxfifo_ovf_int_ena()
|
||||||
@ -77,63 +70,66 @@ pub trait Instance {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the number of occupied entries in the tx fifo buffer
|
|
||||||
fn get_tx_fifo_count(&mut self) -> u16 {
|
fn get_tx_fifo_count(&mut self) -> u16 {
|
||||||
self.as_uart0().status.read().txfifo_cnt().bits().into()
|
self.register_block()
|
||||||
|
.status
|
||||||
|
.read()
|
||||||
|
.txfifo_cnt()
|
||||||
|
.bits()
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the number of occupied entries in the rx fifo buffer
|
|
||||||
fn get_rx_fifo_count(&mut self) -> u16 {
|
fn get_rx_fifo_count(&mut self) -> u16 {
|
||||||
self.as_uart0().status.read().rxfifo_cnt().bits().into()
|
self.register_block()
|
||||||
|
.status
|
||||||
|
.read()
|
||||||
|
.rxfifo_cnt()
|
||||||
|
.bits()
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the UART TX statemachine is is idle
|
|
||||||
fn is_tx_idle(&mut self) -> bool {
|
fn is_tx_idle(&mut self) -> bool {
|
||||||
#[cfg(feature = "32")]
|
#[cfg(feature = "32")]
|
||||||
let ret = self.as_uart0().status.read().st_utx_out().bits() == 0x0u8;
|
let idle = self.register_block().status.read().st_utx_out().bits() == 0x0u8;
|
||||||
#[cfg(not(feature = "32"))]
|
#[cfg(not(feature = "32"))]
|
||||||
let ret = self.as_uart0().fsm_status.read().st_utx_out().bits() == 0x0u8;
|
let idle = self.register_block().fsm_status.read().st_utx_out().bits() == 0x0u8;
|
||||||
|
|
||||||
ret
|
idle
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the UART RX statemachine is is idle
|
|
||||||
fn is_rx_idle(&mut self) -> bool {
|
fn is_rx_idle(&mut self) -> bool {
|
||||||
#[cfg(feature = "32")]
|
#[cfg(feature = "32")]
|
||||||
let ret = self.as_uart0().status.read().st_urx_out().bits() == 0x0u8;
|
let idle = self.register_block().status.read().st_urx_out().bits() == 0x0u8;
|
||||||
#[cfg(not(feature = "32"))]
|
#[cfg(not(feature = "32"))]
|
||||||
let ret = self.as_uart0().fsm_status.read().st_urx_out().bits() == 0x0u8;
|
let idle = self.register_block().fsm_status.read().st_urx_out().bits() == 0x0u8;
|
||||||
|
|
||||||
ret
|
idle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write half of a serial interface
|
|
||||||
impl<T: Instance> Write<u8> for Serial<T> {
|
impl<T: Instance> Write<u8> for Serial<T> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
/// Writes a single word to the serial interface
|
|
||||||
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
|
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
|
||||||
if self.uart.get_tx_fifo_count() >= UART_FIFO_SIZE {
|
if self.uart.get_tx_fifo_count() < UART_FIFO_SIZE {
|
||||||
Err(nb::Error::WouldBlock)
|
|
||||||
} else {
|
|
||||||
#[cfg(feature = "32")]
|
#[cfg(feature = "32")]
|
||||||
self.uart
|
self.uart
|
||||||
.as_uart0()
|
.register_block()
|
||||||
.fifo()
|
.fifo()
|
||||||
.write(|w| unsafe { w.rxfifo_rd_byte().bits(word) });
|
.write(|w| unsafe { w.rxfifo_rd_byte().bits(word) });
|
||||||
|
|
||||||
#[cfg(not(feature = "32"))]
|
#[cfg(not(feature = "32"))]
|
||||||
self.uart
|
self.uart
|
||||||
.as_uart0()
|
.register_block()
|
||||||
.fifo
|
.fifo
|
||||||
.write(|w| unsafe { w.rxfifo_rd_byte().bits(word) });
|
.write(|w| unsafe { w.rxfifo_rd_byte().bits(word) });
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(nb::Error::WouldBlock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensures that none of the previously written words are still buffered
|
|
||||||
fn flush(&mut self) -> nb::Result<(), Self::Error> {
|
fn flush(&mut self) -> nb::Result<(), Self::Error> {
|
||||||
if self.uart.is_tx_idle() {
|
if self.uart.is_tx_idle() {
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -143,17 +139,28 @@ impl<T: Instance> Write<u8> for Serial<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write half of a serial interface
|
|
||||||
impl<T: Instance> Read<u8> for Serial<T> {
|
impl<T: Instance> Read<u8> for Serial<T> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
/// Reads a single word from the serial interface
|
|
||||||
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
||||||
if self.uart.get_rx_fifo_count() > 0 {
|
if self.uart.get_rx_fifo_count() > 0 {
|
||||||
#[cfg(feature = "32")]
|
#[cfg(feature = "32")]
|
||||||
let value = self.uart.as_uart0().fifo().read().rxfifo_rd_byte().bits();
|
let value = self
|
||||||
|
.uart
|
||||||
|
.register_block()
|
||||||
|
.fifo()
|
||||||
|
.read()
|
||||||
|
.rxfifo_rd_byte()
|
||||||
|
.bits();
|
||||||
|
|
||||||
#[cfg(not(feature = "32"))]
|
#[cfg(not(feature = "32"))]
|
||||||
let value = self.uart.as_uart0().fifo.read().rxfifo_rd_byte().bits();
|
let value = self
|
||||||
|
.uart
|
||||||
|
.register_block()
|
||||||
|
.fifo
|
||||||
|
.read()
|
||||||
|
.rxfifo_rd_byte()
|
||||||
|
.bits();
|
||||||
|
|
||||||
Ok(value)
|
Ok(value)
|
||||||
} else {
|
} else {
|
||||||
@ -171,27 +178,24 @@ impl<T: Instance> core::fmt::Write for Serial<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specific instance implementation for the UART0 peripheral
|
|
||||||
impl Instance for UART0 {
|
impl Instance for UART0 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn as_uart0(&self) -> &RegisterBlock {
|
fn register_block(&self) -> &RegisterBlock {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specific instance implementation for the UART1 peripheral
|
|
||||||
impl Instance for UART1 {
|
impl Instance for UART1 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn as_uart0(&self) -> &RegisterBlock {
|
fn register_block(&self) -> &RegisterBlock {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "32", feature = "32s3"))]
|
#[cfg(any(feature = "32", feature = "32s3"))]
|
||||||
/// Specific instance implementation for the UART2 peripheral
|
|
||||||
impl Instance for UART2 {
|
impl Instance for UART2 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn as_uart0(&self) -> &RegisterBlock {
|
fn register_block(&self) -> &RegisterBlock {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,13 +11,8 @@ pub struct Timer<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Report that the timer is active and certain management
|
|
||||||
/// operations cannot be performed safely
|
|
||||||
TimerActive,
|
TimerActive,
|
||||||
/// Report that the timer is inactive and thus not
|
|
||||||
/// ever reaching any potentially configured alarm value
|
|
||||||
TimerInactive,
|
TimerInactive,
|
||||||
/// Report that the alarm functionality is disabled
|
|
||||||
AlarmInactive,
|
AlarmInactive,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,48 +26,56 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait Instance {
|
pub trait Instance {
|
||||||
fn as_timg0(&self) -> &RegisterBlock;
|
fn register_block(&self) -> &RegisterBlock;
|
||||||
|
|
||||||
fn reset_counter(&mut self) {
|
fn reset_counter(&mut self) {
|
||||||
let reg_block = self.as_timg0();
|
let reg_block = self.register_block();
|
||||||
|
|
||||||
reg_block
|
reg_block
|
||||||
.t0loadlo
|
.t0loadlo
|
||||||
.write(|w| unsafe { w.t0_load_lo().bits(0) });
|
.write(|w| unsafe { w.t0_load_lo().bits(0) });
|
||||||
|
|
||||||
reg_block
|
reg_block
|
||||||
.t0loadhi
|
.t0loadhi
|
||||||
.write(|w| unsafe { w.t0_load_hi().bits(0) });
|
.write(|w| unsafe { w.t0_load_hi().bits(0) });
|
||||||
|
|
||||||
reg_block.t0load.write(|w| unsafe { w.t0_load().bits(1) });
|
reg_block.t0load.write(|w| unsafe { w.t0_load().bits(1) });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_counter_active(&mut self, state: bool) {
|
fn set_counter_active(&mut self, state: bool) {
|
||||||
self.as_timg0().t0config.modify(|_, w| w.t0_en().bit(state));
|
self.register_block()
|
||||||
|
.t0config
|
||||||
|
.modify(|_, w| w.t0_en().bit(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_counter_active(&mut self) -> bool {
|
fn is_counter_active(&mut self) -> bool {
|
||||||
self.as_timg0().t0config.read().t0_en().bit_is_set()
|
self.register_block().t0config.read().t0_en().bit_is_set()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_counter_decrementing(&mut self, decrementing: bool) {
|
fn set_counter_decrementing(&mut self, decrementing: bool) {
|
||||||
self.as_timg0()
|
self.register_block()
|
||||||
.t0config
|
.t0config
|
||||||
.modify(|_, w| w.t0_increase().bit(!decrementing));
|
.modify(|_, w| w.t0_increase().bit(!decrementing));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_auto_reload(&mut self, auto_reload: bool) {
|
fn set_auto_reload(&mut self, auto_reload: bool) {
|
||||||
self.as_timg0()
|
self.register_block()
|
||||||
.t0config
|
.t0config
|
||||||
.modify(|_, w| w.t0_autoreload().bit(auto_reload));
|
.modify(|_, w| w.t0_autoreload().bit(auto_reload));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_alarm_active(&mut self, state: bool) {
|
fn set_alarm_active(&mut self, state: bool) {
|
||||||
self.as_timg0()
|
self.register_block()
|
||||||
.t0config
|
.t0config
|
||||||
.modify(|_, w| w.t0_alarm_en().bit(state));
|
.modify(|_, w| w.t0_alarm_en().bit(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_alarm_active(&mut self) -> bool {
|
fn is_alarm_active(&mut self) -> bool {
|
||||||
self.as_timg0().t0config.read().t0_alarm_en().bit_is_set()
|
self.register_block()
|
||||||
|
.t0config
|
||||||
|
.read()
|
||||||
|
.t0_alarm_en()
|
||||||
|
.bit_is_set()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_alarm_value(&mut self, value: u64) {
|
fn load_alarm_value(&mut self, value: u64) {
|
||||||
@ -80,23 +83,26 @@ pub trait Instance {
|
|||||||
let high = (value >> 32) as u32;
|
let high = (value >> 32) as u32;
|
||||||
let low = (value & 0xFFFF_FFFF) as u32;
|
let low = (value & 0xFFFF_FFFF) as u32;
|
||||||
|
|
||||||
let reg_block = self.as_timg0();
|
let reg_block = self.register_block();
|
||||||
|
|
||||||
reg_block
|
reg_block
|
||||||
.t0alarmlo
|
.t0alarmlo
|
||||||
.write(|w| unsafe { w.t0_alarm_lo().bits(low) });
|
.write(|w| unsafe { w.t0_alarm_lo().bits(low) });
|
||||||
|
|
||||||
reg_block
|
reg_block
|
||||||
.t0alarmhi
|
.t0alarmhi
|
||||||
.write(|w| unsafe { w.t0_alarm_hi().bits(high) });
|
.write(|w| unsafe { w.t0_alarm_hi().bits(high) });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_wdt_enabled(&mut self, enabled: bool) {
|
fn set_wdt_enabled(&mut self, enabled: bool) {
|
||||||
let reg_block = self.as_timg0();
|
let reg_block = self.register_block();
|
||||||
|
|
||||||
reg_block
|
reg_block
|
||||||
.wdtwprotect
|
.wdtwprotect
|
||||||
.write(|w| unsafe { w.wdt_wkey().bits(0u32) });
|
.write(|w| unsafe { w.wdt_wkey().bits(0u32) });
|
||||||
|
|
||||||
reg_block.wdtconfig0.write(|w| w.wdt_en().bit(enabled));
|
reg_block.wdtconfig0.write(|w| w.wdt_en().bit(enabled));
|
||||||
|
|
||||||
reg_block
|
reg_block
|
||||||
.wdtwprotect
|
.wdtwprotect
|
||||||
.write(|w| unsafe { w.wdt_wkey().bits(0x50D8_3AA1u32) });
|
.write(|w| unsafe { w.wdt_wkey().bits(0x50D8_3AA1u32) });
|
||||||
@ -130,31 +136,19 @@ where
|
|||||||
panic!("Called wait on an inactive timer!");
|
panic!("Called wait on an inactive timer!");
|
||||||
}
|
}
|
||||||
|
|
||||||
let int_raw_is_clear = self
|
let reg_block = self.timg.register_block();
|
||||||
.timg
|
|
||||||
.as_timg0()
|
|
||||||
.int_raw_timers
|
|
||||||
.read()
|
|
||||||
.t0_int_raw()
|
|
||||||
.bit_is_clear();
|
|
||||||
|
|
||||||
if int_raw_is_clear {
|
|
||||||
Err(nb::Error::WouldBlock)
|
|
||||||
} else {
|
|
||||||
self.timg
|
|
||||||
.as_timg0()
|
|
||||||
.int_clr_timers
|
|
||||||
.write(|w| w.t0_int_clr().set_bit());
|
|
||||||
|
|
||||||
|
if reg_block.int_raw_timers.read().t0_int_raw().bit_is_set() {
|
||||||
|
reg_block.int_clr_timers.write(|w| w.t0_int_clr().set_bit());
|
||||||
self.timg.set_alarm_active(true);
|
self.timg.set_alarm_active(true);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(nb::Error::WouldBlock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Periodic for Timer<T> where T: Instance {}
|
|
||||||
|
|
||||||
impl<T> Cancel for Timer<T>
|
impl<T> Cancel for Timer<T>
|
||||||
where
|
where
|
||||||
T: Instance,
|
T: Instance,
|
||||||
@ -174,6 +168,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Periodic for Timer<T> where T: Instance {}
|
||||||
|
|
||||||
impl<T> WatchdogDisable for Timer<T>
|
impl<T> WatchdogDisable for Timer<T>
|
||||||
where
|
where
|
||||||
T: Instance,
|
T: Instance,
|
||||||
@ -185,14 +181,14 @@ where
|
|||||||
|
|
||||||
impl Instance for TIMG0 {
|
impl Instance for TIMG0 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn as_timg0(&self) -> &RegisterBlock {
|
fn register_block(&self) -> &RegisterBlock {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Instance for TIMG1 {
|
impl Instance for TIMG1 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn as_timg0(&self) -> &RegisterBlock {
|
fn register_block(&self) -> &RegisterBlock {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
enum_discrim_align_threshold = 15
|
||||||
group_imports = "StdExternalCrate"
|
group_imports = "StdExternalCrate"
|
||||||
imports_granularity = "Crate"
|
imports_granularity = "Crate"
|
||||||
imports_layout = "HorizontalVertical"
|
imports_layout = "HorizontalVertical"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user