forked from M-Labs/zynq-rs
refactor regs macros for RO/WO/RW access
This commit is contained in:
parent
1e540a1175
commit
ca9b10dce8
89
src/regs.rs
89
src/regs.rs
|
@ -1,24 +1,37 @@
|
||||||
//! Interface to peripheral registers akin to the code that svd2rust
|
//! Interface to peripheral registers akin to the code that svd2rust
|
||||||
//! generates.
|
//! generates.
|
||||||
|
#![allow(unused)]
|
||||||
|
|
||||||
use volatile_register::{RO, WO, RW};
|
use volatile_register::{RO, WO, RW};
|
||||||
use bit_field::BitField;
|
use bit_field::BitField;
|
||||||
|
|
||||||
pub trait Register {
|
/// A readable register
|
||||||
|
pub trait RegisterR {
|
||||||
|
/// Type-safe reader for the register value
|
||||||
type R;
|
type R;
|
||||||
type W;
|
|
||||||
|
|
||||||
fn read(&self) -> Self::R;
|
fn read(&self) -> Self::R;
|
||||||
|
}
|
||||||
|
/// A writable register
|
||||||
|
pub trait RegisterW {
|
||||||
|
/// Type-safe writer to the register value
|
||||||
|
type W;
|
||||||
|
|
||||||
|
fn zeroed() -> Self::W;
|
||||||
fn write(&self, w: Self::W);
|
fn write(&self, w: Self::W);
|
||||||
fn modify<F: FnOnce(Self::R, Self::W) -> Self::W>(&self, f: F);
|
}
|
||||||
|
/// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! register {
|
macro_rules! register_common {
|
||||||
($mod_name: ident, $struct_name: ident, $inner: ty) => (
|
($mod_name: ident, $struct_name: ident, $access: ty, $inner: ty) => (
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct $struct_name {
|
pub struct $struct_name {
|
||||||
inner: RW<$inner>,
|
inner: $access,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod $mod_name {
|
pub mod $mod_name {
|
||||||
|
@ -29,28 +42,46 @@ macro_rules! register {
|
||||||
pub inner: $inner,
|
pub inner: $inner,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
);
|
||||||
impl $struct_name {
|
}
|
||||||
pub fn zeroed() -> $mod_name::Write {
|
#[doc(hidden)]
|
||||||
$mod_name::Write { inner: 0 }
|
#[macro_export]
|
||||||
}
|
macro_rules! register_r {
|
||||||
}
|
($mod_name: ident, $struct_name: ident) => (
|
||||||
|
impl crate::regs::RegisterR for $struct_name {
|
||||||
impl crate::regs::Register for $struct_name {
|
|
||||||
type R = $mod_name::Read;
|
type R = $mod_name::Read;
|
||||||
type W = $mod_name::Write;
|
|
||||||
|
|
||||||
fn read(&self) -> Self::R {
|
fn read(&self) -> Self::R {
|
||||||
let inner = self.inner.read();
|
let inner = self.inner.read();
|
||||||
$mod_name::Read { inner }
|
$mod_name::Read { inner }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! register_w {
|
||||||
|
($mod_name: ident, $struct_name: ident) => (
|
||||||
|
impl crate::regs::RegisterW for $struct_name {
|
||||||
|
type W = $mod_name::Write;
|
||||||
|
|
||||||
|
fn zeroed() -> $mod_name::Write {
|
||||||
|
$mod_name::Write { inner: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
fn write(&self, w: Self::W) {
|
fn write(&self, w: Self::W) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.inner.write(w.inner);
|
self.inner.write(w.inner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[macro_export]
|
||||||
|
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>(&self, f: F) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.inner.modify(|inner| {
|
self.inner.modify(|inner| {
|
||||||
|
@ -63,6 +94,31 @@ macro_rules! register {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Main macro for register definition
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! register {
|
||||||
|
// Define read-only register
|
||||||
|
($mod_name: ident, $struct_name: ident, RO, $inner: ty) => (
|
||||||
|
crate::register_common!($mod_name, $struct_name, volatile_register::RO<$inner>, $inner);
|
||||||
|
crate::register_r!($mod_name, $struct_name);
|
||||||
|
);
|
||||||
|
|
||||||
|
// Define write-only register
|
||||||
|
($mod_name: ident, $struct_name: ident, WO, $inner: ty) => (
|
||||||
|
crate::register_common!($mod_name, $struct_name, volatile_register::WO<$inner>, $inner);
|
||||||
|
crate::register_w!($mod_name, $struct_name);
|
||||||
|
);
|
||||||
|
|
||||||
|
// Define read-write register
|
||||||
|
($mod_name: ident, $struct_name: ident, RW, $inner: ty) => (
|
||||||
|
crate::register_common!($mod_name, $struct_name, volatile_register::RW<$inner>, $inner);
|
||||||
|
crate::register_r!($mod_name, $struct_name);
|
||||||
|
crate::register_w!($mod_name, $struct_name);
|
||||||
|
crate::register_rw!($mod_name, $struct_name);
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Define a 1-bit field of a register
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! register_bit {
|
macro_rules! register_bit {
|
||||||
($mod_name: ident, $name: ident, $bit: expr) => (
|
($mod_name: ident, $name: ident, $bit: expr) => (
|
||||||
|
@ -85,6 +141,7 @@ macro_rules! register_bit {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Define a multi-bit field of a register
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! register_bits {
|
macro_rules! register_bits {
|
||||||
($mod_name: ident, $name: ident, $type: ty, $bit_begin: expr, $bit_end: expr) => (
|
($mod_name: ident, $name: ident, $type: ty, $bit_begin: expr, $bit_end: expr) => (
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use volatile_register::{RO, WO, RW};
|
#[allow(unused)]
|
||||||
|
|
||||||
use crate::{register, register_bit, register_bits, regs::Register};
|
use crate::{register, register_bit, register_bits, regs::RegisterRW};
|
||||||
|
|
||||||
pub enum PllSource {
|
pub enum PllSource {
|
||||||
IoPll = 0b00,
|
IoPll = 0b00,
|
||||||
|
@ -8,7 +8,7 @@ pub enum PllSource {
|
||||||
DdrPll = 0b11,
|
DdrPll = 0b11,
|
||||||
}
|
}
|
||||||
|
|
||||||
register!(uart_clk_ctrl, UartClkCtrl, u32);
|
register!(uart_clk_ctrl, UartClkCtrl, RW, u32);
|
||||||
register_bit!(uart_clk_ctrl, clkact0, 0);
|
register_bit!(uart_clk_ctrl, clkact0, 0);
|
||||||
register_bit!(uart_clk_ctrl, clkact1, 1);
|
register_bit!(uart_clk_ctrl, clkact1, 1);
|
||||||
register_bits!(uart_clk_ctrl, divisor, u8, 8, 13);
|
register_bits!(uart_clk_ctrl, divisor, u8, 8, 13);
|
||||||
|
@ -32,7 +32,7 @@ impl UartClkCtrl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
register!(uart_rst_ctrl, UartRstCtrl, u32);
|
register!(uart_rst_ctrl, UartRstCtrl, RW, u32);
|
||||||
register_bit!(uart_rst_ctrl, uart0_ref_rst, 3);
|
register_bit!(uart_rst_ctrl, uart0_ref_rst, 3);
|
||||||
register_bit!(uart_rst_ctrl, uart1_ref_rst, 2);
|
register_bit!(uart_rst_ctrl, uart1_ref_rst, 2);
|
||||||
register_bit!(uart_rst_ctrl, uart0_cpu1x_rst, 1);
|
register_bit!(uart_rst_ctrl, uart0_cpu1x_rst, 1);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(unused)]
|
||||||
|
|
||||||
mod regs;
|
mod regs;
|
||||||
pub use regs::RegisterBlock;
|
pub use regs::RegisterBlock;
|
||||||
|
|
||||||
|
@ -25,10 +27,8 @@ impl Uart {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_byte(&self, v: u8) {
|
pub fn write_byte(&self, v: u8) {
|
||||||
unsafe {
|
|
||||||
while self.regs.tx_fifo_full() {}
|
while self.regs.tx_fifo_full() {}
|
||||||
|
|
||||||
self.regs.write_byte(v);
|
self.regs.write_byte(v);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use volatile_register::{RO, WO, RW};
|
use volatile_register::{RO, WO, RW};
|
||||||
use bit_field::BitField;
|
|
||||||
|
|
||||||
use crate::{register, register_bit, register_bits, regs::Register};
|
use crate::{register, register_bit, register_bits, regs::*};
|
||||||
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum ParityMode {
|
pub enum ParityMode {
|
||||||
|
@ -33,7 +32,7 @@ pub struct RegisterBlock {
|
||||||
tx_fifo_trigger_level: RW<u32>,
|
tx_fifo_trigger_level: RW<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
register!(control, Control, u32);
|
register!(control, Control, RW, u32);
|
||||||
register_bit!(control, rxrst, 0);
|
register_bit!(control, rxrst, 0);
|
||||||
register_bit!(control, txrst, 1);
|
register_bit!(control, txrst, 1);
|
||||||
register_bit!(control, rxen, 2);
|
register_bit!(control, rxen, 2);
|
||||||
|
@ -41,19 +40,19 @@ register_bit!(control, rxdis, 3);
|
||||||
register_bit!(control, txen, 4);
|
register_bit!(control, txen, 4);
|
||||||
register_bit!(control, txdis, 5);
|
register_bit!(control, txdis, 5);
|
||||||
|
|
||||||
register!(mode, Mode, u32);
|
register!(mode, Mode, RW, u32);
|
||||||
register_bits!(mode, par, u8, 3, 5);
|
register_bits!(mode, par, u8, 3, 5);
|
||||||
|
|
||||||
register!(baud_rate_gen, BaudRateGen, u32);
|
register!(baud_rate_gen, BaudRateGen, RW, u32);
|
||||||
register_bits!(baud_rate_gen, cd, u16, 0, 15);
|
register_bits!(baud_rate_gen, cd, u16, 0, 15);
|
||||||
|
|
||||||
register!(channel_sts, ChannelSts, u32);
|
register!(channel_sts, ChannelSts, RO, u32);
|
||||||
register_bit!(channel_sts, txfull, 4);
|
register_bit!(channel_sts, txfull, 4);
|
||||||
|
|
||||||
register!(tx_rx_fifo, TxRxFifo, u32);
|
register!(tx_rx_fifo, TxRxFifo, RW, u32);
|
||||||
register_bits!(tx_rx_fifo, data, u32, 0, 31);
|
register_bits!(tx_rx_fifo, data, u32, 0, 31);
|
||||||
|
|
||||||
register!(baud_rate_div, BaudRateDiv, u32);
|
register!(baud_rate_div, BaudRateDiv, RW, u32);
|
||||||
register_bits!(baud_rate_div, bdiv, u8, 0, 7);
|
register_bits!(baud_rate_div, bdiv, u8, 0, 7);
|
||||||
|
|
||||||
impl RegisterBlock {
|
impl RegisterBlock {
|
||||||
|
|
Loading…
Reference in New Issue