forked from M-Labs/zynq-rs
1
0
Fork 0

RegisterW/RegisterRW: required &mut self for safety

This commit is contained in:
Astro 2019-05-23 18:01:18 +02:00
parent 62ca26fa71
commit 785e726661
5 changed files with 29 additions and 29 deletions

View File

@ -3,7 +3,7 @@ use crate::regs::*;
mod regs;
pub struct Eth {
regs: &'static regs::RegisterBlock,
regs: &'static mut regs::RegisterBlock,
}
impl Eth {

View File

@ -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 })

View File

@ -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)

View File

@ -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;
}

View File

@ -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)
})