forked from M-Labs/zynq-rs
RegisterW/RegisterRW: required &mut self for safety
This commit is contained in:
parent
62ca26fa71
commit
785e726661
|
@ -3,7 +3,7 @@ use crate::regs::*;
|
|||
mod regs;
|
||||
|
||||
pub struct Eth {
|
||||
regs: &'static regs::RegisterBlock,
|
||||
regs: &'static mut regs::RegisterBlock,
|
||||
}
|
||||
|
||||
impl Eth {
|
||||
|
|
|
@ -18,11 +18,11 @@ pub trait RegisterW {
|
|||
type W;
|
||||
|
||||
fn zeroed() -> Self::W;
|
||||
fn write(&self, w: Self::W);
|
||||
fn write(&mut self, w: Self::W);
|
||||
}
|
||||
/// A modifiable register
|
||||
pub trait RegisterRW: RegisterR + RegisterW {
|
||||
fn modify<F: FnOnce(<Self as RegisterR>::R, <Self as RegisterW>::W) -> <Self as RegisterW>::W>(&self, f: F);
|
||||
fn modify<F: FnOnce(<Self as RegisterR>::R, <Self as RegisterW>::W) -> <Self as RegisterW>::W>(&mut self, f: F);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
@ -69,7 +69,7 @@ macro_rules! register_w {
|
|||
$mod_name::Write { inner: 0 }
|
||||
}
|
||||
|
||||
fn write(&self, w: Self::W) {
|
||||
fn write(&mut self, w: Self::W) {
|
||||
unsafe {
|
||||
self.inner.write(w.inner);
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ macro_rules! register_w {
|
|||
macro_rules! register_rw {
|
||||
($mod_name: ident, $struct_name: ident) => (
|
||||
impl crate::regs::RegisterRW for $struct_name {
|
||||
fn modify<F: FnOnce(Self::R, Self::W) -> Self::W>(&self, f: F) {
|
||||
fn modify<F: FnOnce(Self::R, Self::W) -> Self::W>(&mut self, f: F) {
|
||||
unsafe {
|
||||
self.inner.modify(|inner| {
|
||||
f($mod_name::Read { inner }, $mod_name::Write { inner })
|
||||
|
|
22
src/slcr.rs
22
src/slcr.rs
|
@ -197,10 +197,10 @@ pub struct RegisterBlock {
|
|||
register_at!(RegisterBlock, 0xF8000000, new);
|
||||
|
||||
impl RegisterBlock {
|
||||
pub fn unlocked<F: FnMut(&Self) -> R, R>(mut f: F) -> R {
|
||||
let self_ = Self::new();
|
||||
pub fn unlocked<F: FnMut(&mut Self) -> R, R>(mut f: F) -> R {
|
||||
let mut self_ = Self::new();
|
||||
self_.slcr_unlock.unlock();
|
||||
let r = f(&self_);
|
||||
let r = f(&mut self_);
|
||||
self_.slcr_lock.lock();
|
||||
r
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ impl RegisterBlock {
|
|||
register!(slcr_lock, SlcrLock, WO, u32);
|
||||
register_bits!(slcr_lock, lock_key, u16, 0, 15);
|
||||
impl SlcrLock {
|
||||
pub fn lock(&self) {
|
||||
pub fn lock(&mut self) {
|
||||
self.write(
|
||||
Self::zeroed()
|
||||
.lock_key(0x767B)
|
||||
|
@ -220,7 +220,7 @@ impl SlcrLock {
|
|||
register!(slcr_unlock, SlcrUnlock, WO, u32);
|
||||
register_bits!(slcr_unlock, unlock_key, u16, 0, 15);
|
||||
impl SlcrUnlock {
|
||||
pub fn unlock(&self) {
|
||||
pub fn unlock(&mut self) {
|
||||
self.write(
|
||||
Self::zeroed()
|
||||
.unlock_key(0xDF0D)
|
||||
|
@ -232,11 +232,11 @@ register!(aper_clk_ctrl, AperClkCtrl, RW, u32);
|
|||
register_bit!(aper_clk_ctrl, uart1_cpu_1xclkact, 21);
|
||||
register_bit!(aper_clk_ctrl, uart0_cpu_1xclkact, 20);
|
||||
impl AperClkCtrl {
|
||||
pub fn enable_uart0(&self) {
|
||||
pub fn enable_uart0(&mut self) {
|
||||
self.modify(|_, w| w.uart0_cpu_1xclkact(true));
|
||||
}
|
||||
|
||||
pub fn enable_uart1(&self) {
|
||||
pub fn enable_uart1(&mut self) {
|
||||
self.modify(|_, w| w.uart1_cpu_1xclkact(true));
|
||||
}
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ register_bits!(uart_clk_ctrl, divisor, u8, 8, 13);
|
|||
register_bits!(uart_clk_ctrl, srcsel, u8, 4, 5);
|
||||
register_at!(UartClkCtrl, 0xF8000154, new);
|
||||
impl UartClkCtrl {
|
||||
pub fn enable_uart0(&self) {
|
||||
pub fn enable_uart0(&mut self) {
|
||||
self.modify(|_, w| {
|
||||
// a. Clock divisor, slcr.UART_CLK_CTRL[DIVISOR] = 0x14.
|
||||
// b. Select the IO PLL, slcr.UART_CLK_CTRL[SRCSEL] = 0.
|
||||
|
@ -260,7 +260,7 @@ impl UartClkCtrl {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn enable_uart1(&self) {
|
||||
pub fn enable_uart1(&mut self) {
|
||||
self.modify(|_, w| {
|
||||
// a. Clock divisor, slcr.UART_CLK_CTRL[DIVISOR] = 0x14.
|
||||
// b. Select the IO PLL, slcr.UART_CLK_CTRL[SRCSEL] = 0.
|
||||
|
@ -279,7 +279,7 @@ register_bit!(uart_rst_ctrl, uart0_cpu1x_rst, 1);
|
|||
register_bit!(uart_rst_ctrl, uart1_cpu1x_rst, 0);
|
||||
register_at!(UartRstCtrl, 0xF8000228, new);
|
||||
impl UartRstCtrl {
|
||||
pub fn reset_uart0(&self) {
|
||||
pub fn reset_uart0(&mut self) {
|
||||
self.modify(|_, w|
|
||||
w.uart0_ref_rst(true)
|
||||
.uart0_cpu1x_rst(true)
|
||||
|
@ -290,7 +290,7 @@ impl UartRstCtrl {
|
|||
);
|
||||
}
|
||||
|
||||
pub fn reset_uart1(&self) {
|
||||
pub fn reset_uart1(&mut self) {
|
||||
self.modify(|_, w|
|
||||
w.uart1_ref_rst(true)
|
||||
.uart1_cpu1x_rst(true)
|
||||
|
|
|
@ -10,7 +10,7 @@ fn div_round_closest(q: u32, d: u32) -> u32 {
|
|||
}
|
||||
|
||||
/// Algorithm as in the Linux 5.1 driver
|
||||
pub fn configure(regs: &RegisterBlock, mut clk: u32, baud: u32) {
|
||||
pub fn configure(regs: &mut RegisterBlock, mut clk: u32, baud: u32) {
|
||||
if regs.mode.read().clks() {
|
||||
clk /= 8;
|
||||
}
|
||||
|
|
|
@ -42,14 +42,14 @@ impl Uart {
|
|||
slcr.aper_clk_ctrl.enable_uart1();
|
||||
slcr.uart_clk_ctrl.enable_uart1();
|
||||
});
|
||||
let self_ = Uart {
|
||||
let mut self_ = Uart {
|
||||
regs: regs::RegisterBlock::uart1(),
|
||||
};
|
||||
self_.configure(baudrate);
|
||||
self_
|
||||
}
|
||||
|
||||
pub fn write_byte(&self, value: u8) {
|
||||
pub fn write_byte(&mut self, value: u8) {
|
||||
while self.tx_fifo_full() {}
|
||||
|
||||
self.regs.tx_rx_fifo.write(
|
||||
|
@ -58,7 +58,7 @@ impl Uart {
|
|||
);
|
||||
}
|
||||
|
||||
pub fn configure(&self, baudrate: u32) {
|
||||
pub fn configure(&mut self, baudrate: u32) {
|
||||
// Configure UART character frame
|
||||
// * Disable clock-divider
|
||||
// * 8-bit
|
||||
|
@ -76,7 +76,7 @@ impl Uart {
|
|||
self.disable_rx();
|
||||
self.disable_tx();
|
||||
|
||||
baud_rate_gen::configure(&self.regs, UART_REF_CLK, baudrate);
|
||||
baud_rate_gen::configure(self.regs, UART_REF_CLK, baudrate);
|
||||
|
||||
// Enable controller
|
||||
self.reset_rx();
|
||||
|
@ -89,41 +89,41 @@ impl Uart {
|
|||
self.set_break(false, true);
|
||||
}
|
||||
|
||||
fn disable_rx(&self) {
|
||||
fn disable_rx(&mut self) {
|
||||
self.regs.control.modify(|_, w| {
|
||||
w.rxen(false)
|
||||
.rxdis(true)
|
||||
})
|
||||
}
|
||||
|
||||
fn disable_tx(&self) {
|
||||
fn disable_tx(&mut self) {
|
||||
self.regs.control.modify(|_, w| {
|
||||
w.txen(false)
|
||||
.txdis(true)
|
||||
})
|
||||
}
|
||||
|
||||
fn enable_rx(&self) {
|
||||
fn enable_rx(&mut self) {
|
||||
self.regs.control.modify(|_, w| {
|
||||
w.rxen(true)
|
||||
.rxdis(false)
|
||||
})
|
||||
}
|
||||
|
||||
fn enable_tx(&self) {
|
||||
fn enable_tx(&mut self) {
|
||||
self.regs.control.modify(|_, w| {
|
||||
w.txen(true)
|
||||
.txdis(false)
|
||||
})
|
||||
}
|
||||
|
||||
fn reset_rx(&self) {
|
||||
fn reset_rx(&mut self) {
|
||||
self.regs.control.modify(|_, w| {
|
||||
w.rxrst(true)
|
||||
})
|
||||
}
|
||||
|
||||
fn reset_tx(&self) {
|
||||
fn reset_tx(&mut self) {
|
||||
self.regs.control.modify(|_, w| {
|
||||
w.txrst(true)
|
||||
})
|
||||
|
@ -138,7 +138,7 @@ impl Uart {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_break(&self, startbrk: bool, stopbrk: bool) {
|
||||
fn set_break(&mut self, startbrk: bool, stopbrk: bool) {
|
||||
self.regs.control.modify(|_, w| {
|
||||
w.sttbrk(startbrk)
|
||||
.stpbrk(stopbrk)
|
||||
|
@ -146,7 +146,7 @@ impl Uart {
|
|||
}
|
||||
|
||||
// 0 disables
|
||||
fn set_rx_timeout(&self, enable: bool) {
|
||||
fn set_rx_timeout(&mut self, enable: bool) {
|
||||
self.regs.control.modify(|_, w| {
|
||||
w.rstto(enable)
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue