RegisterW/RegisterRW: required &mut self for safety

smoltcp
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; mod regs;
pub struct Eth { pub struct Eth {
regs: &'static regs::RegisterBlock, regs: &'static mut regs::RegisterBlock,
} }
impl Eth { impl Eth {

View File

@ -18,11 +18,11 @@ pub trait RegisterW {
type W; type W;
fn zeroed() -> Self::W; fn zeroed() -> Self::W;
fn write(&self, w: Self::W); fn write(&mut self, w: Self::W);
} }
/// A modifiable register /// A modifiable register
pub trait RegisterRW: RegisterR + RegisterW { 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)] #[doc(hidden)]
@ -69,7 +69,7 @@ macro_rules! register_w {
$mod_name::Write { inner: 0 } $mod_name::Write { inner: 0 }
} }
fn write(&self, w: Self::W) { fn write(&mut self, w: Self::W) {
unsafe { unsafe {
self.inner.write(w.inner); self.inner.write(w.inner);
} }
@ -82,7 +82,7 @@ macro_rules! register_w {
macro_rules! register_rw { macro_rules! register_rw {
($mod_name: ident, $struct_name: ident) => ( ($mod_name: ident, $struct_name: ident) => (
impl crate::regs::RegisterRW for $struct_name { 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 { unsafe {
self.inner.modify(|inner| { self.inner.modify(|inner| {
f($mod_name::Read { inner }, $mod_name::Write { inner }) f($mod_name::Read { inner }, $mod_name::Write { inner })

View File

@ -197,10 +197,10 @@ pub struct RegisterBlock {
register_at!(RegisterBlock, 0xF8000000, new); register_at!(RegisterBlock, 0xF8000000, new);
impl RegisterBlock { impl RegisterBlock {
pub fn unlocked<F: FnMut(&Self) -> R, R>(mut f: F) -> R { pub fn unlocked<F: FnMut(&mut Self) -> R, R>(mut f: F) -> R {
let self_ = Self::new(); let mut self_ = Self::new();
self_.slcr_unlock.unlock(); self_.slcr_unlock.unlock();
let r = f(&self_); let r = f(&mut self_);
self_.slcr_lock.lock(); self_.slcr_lock.lock();
r r
} }
@ -209,7 +209,7 @@ impl RegisterBlock {
register!(slcr_lock, SlcrLock, WO, u32); register!(slcr_lock, SlcrLock, WO, u32);
register_bits!(slcr_lock, lock_key, u16, 0, 15); register_bits!(slcr_lock, lock_key, u16, 0, 15);
impl SlcrLock { impl SlcrLock {
pub fn lock(&self) { pub fn lock(&mut self) {
self.write( self.write(
Self::zeroed() Self::zeroed()
.lock_key(0x767B) .lock_key(0x767B)
@ -220,7 +220,7 @@ impl SlcrLock {
register!(slcr_unlock, SlcrUnlock, WO, u32); register!(slcr_unlock, SlcrUnlock, WO, u32);
register_bits!(slcr_unlock, unlock_key, u16, 0, 15); register_bits!(slcr_unlock, unlock_key, u16, 0, 15);
impl SlcrUnlock { impl SlcrUnlock {
pub fn unlock(&self) { pub fn unlock(&mut self) {
self.write( self.write(
Self::zeroed() Self::zeroed()
.unlock_key(0xDF0D) .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, uart1_cpu_1xclkact, 21);
register_bit!(aper_clk_ctrl, uart0_cpu_1xclkact, 20); register_bit!(aper_clk_ctrl, uart0_cpu_1xclkact, 20);
impl AperClkCtrl { impl AperClkCtrl {
pub fn enable_uart0(&self) { pub fn enable_uart0(&mut self) {
self.modify(|_, w| w.uart0_cpu_1xclkact(true)); 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)); 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_bits!(uart_clk_ctrl, srcsel, u8, 4, 5);
register_at!(UartClkCtrl, 0xF8000154, new); register_at!(UartClkCtrl, 0xF8000154, new);
impl UartClkCtrl { impl UartClkCtrl {
pub fn enable_uart0(&self) { pub fn enable_uart0(&mut self) {
self.modify(|_, w| { self.modify(|_, w| {
// a. Clock divisor, slcr.UART_CLK_CTRL[DIVISOR] = 0x14. // a. Clock divisor, slcr.UART_CLK_CTRL[DIVISOR] = 0x14.
// b. Select the IO PLL, slcr.UART_CLK_CTRL[SRCSEL] = 0. // 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| { self.modify(|_, w| {
// a. Clock divisor, slcr.UART_CLK_CTRL[DIVISOR] = 0x14. // a. Clock divisor, slcr.UART_CLK_CTRL[DIVISOR] = 0x14.
// b. Select the IO PLL, slcr.UART_CLK_CTRL[SRCSEL] = 0. // 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_bit!(uart_rst_ctrl, uart1_cpu1x_rst, 0);
register_at!(UartRstCtrl, 0xF8000228, new); register_at!(UartRstCtrl, 0xF8000228, new);
impl UartRstCtrl { impl UartRstCtrl {
pub fn reset_uart0(&self) { pub fn reset_uart0(&mut self) {
self.modify(|_, w| self.modify(|_, w|
w.uart0_ref_rst(true) w.uart0_ref_rst(true)
.uart0_cpu1x_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| self.modify(|_, w|
w.uart1_ref_rst(true) w.uart1_ref_rst(true)
.uart1_cpu1x_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 /// 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() { if regs.mode.read().clks() {
clk /= 8; clk /= 8;
} }

View File

@ -42,14 +42,14 @@ impl Uart {
slcr.aper_clk_ctrl.enable_uart1(); slcr.aper_clk_ctrl.enable_uart1();
slcr.uart_clk_ctrl.enable_uart1(); slcr.uart_clk_ctrl.enable_uart1();
}); });
let self_ = Uart { let mut self_ = Uart {
regs: regs::RegisterBlock::uart1(), regs: regs::RegisterBlock::uart1(),
}; };
self_.configure(baudrate); self_.configure(baudrate);
self_ self_
} }
pub fn write_byte(&self, value: u8) { pub fn write_byte(&mut self, value: u8) {
while self.tx_fifo_full() {} while self.tx_fifo_full() {}
self.regs.tx_rx_fifo.write( 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 // Configure UART character frame
// * Disable clock-divider // * Disable clock-divider
// * 8-bit // * 8-bit
@ -76,7 +76,7 @@ impl Uart {
self.disable_rx(); self.disable_rx();
self.disable_tx(); 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 // Enable controller
self.reset_rx(); self.reset_rx();
@ -89,41 +89,41 @@ impl Uart {
self.set_break(false, true); self.set_break(false, true);
} }
fn disable_rx(&self) { fn disable_rx(&mut self) {
self.regs.control.modify(|_, w| { self.regs.control.modify(|_, w| {
w.rxen(false) w.rxen(false)
.rxdis(true) .rxdis(true)
}) })
} }
fn disable_tx(&self) { fn disable_tx(&mut self) {
self.regs.control.modify(|_, w| { self.regs.control.modify(|_, w| {
w.txen(false) w.txen(false)
.txdis(true) .txdis(true)
}) })
} }
fn enable_rx(&self) { fn enable_rx(&mut self) {
self.regs.control.modify(|_, w| { self.regs.control.modify(|_, w| {
w.rxen(true) w.rxen(true)
.rxdis(false) .rxdis(false)
}) })
} }
fn enable_tx(&self) { fn enable_tx(&mut self) {
self.regs.control.modify(|_, w| { self.regs.control.modify(|_, w| {
w.txen(true) w.txen(true)
.txdis(false) .txdis(false)
}) })
} }
fn reset_rx(&self) { fn reset_rx(&mut self) {
self.regs.control.modify(|_, w| { self.regs.control.modify(|_, w| {
w.rxrst(true) w.rxrst(true)
}) })
} }
fn reset_tx(&self) { fn reset_tx(&mut self) {
self.regs.control.modify(|_, w| { self.regs.control.modify(|_, w| {
w.txrst(true) 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| { self.regs.control.modify(|_, w| {
w.sttbrk(startbrk) w.sttbrk(startbrk)
.stpbrk(stopbrk) .stpbrk(stopbrk)
@ -146,7 +146,7 @@ impl Uart {
} }
// 0 disables // 0 disables
fn set_rx_timeout(&self, enable: bool) { fn set_rx_timeout(&mut self, enable: bool) {
self.regs.control.modify(|_, w| { self.regs.control.modify(|_, w| {
w.rstto(enable) w.rstto(enable)
}) })