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;
|
mod regs;
|
||||||
|
|
||||||
pub struct Eth {
|
pub struct Eth {
|
||||||
regs: &'static regs::RegisterBlock,
|
regs: &'static mut regs::RegisterBlock,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eth {
|
impl Eth {
|
||||||
|
|
|
@ -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 })
|
||||||
|
|
22
src/slcr.rs
22
src/slcr.rs
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue