lib: replae usize
with Register
This ensures we can't write to random values in memory. Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
02bb380848
commit
30a9171031
36
src/lib.rs
36
src/lib.rs
@ -1,4 +1,15 @@
|
||||
use std::convert::TryInto;
|
||||
pub struct Register {
|
||||
/// Offset of this register within this CSR
|
||||
offset: usize,
|
||||
}
|
||||
|
||||
impl Register {
|
||||
pub const fn new(offset: usize) -> Register {
|
||||
Register { offset }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Field {
|
||||
/// A bitmask we use to AND to the value, unshifted.
|
||||
/// E.g. for a width of `3` bits, this mask would be 0b111.
|
||||
@ -66,22 +77,26 @@ where
|
||||
pub fn new(base: *mut T) -> Self {
|
||||
CSR { base }
|
||||
}
|
||||
pub fn r(&mut self, reg: usize, field: Field) -> T {
|
||||
pub fn r(&mut self, reg: Register, field: Field) -> T {
|
||||
let usize_base: *mut usize = unsafe { core::mem::transmute(&self.base) };
|
||||
((unsafe { usize_base.add(reg).read_volatile() } >> field.offset) & field.mask)
|
||||
((unsafe { usize_base.add(reg.offset).read_volatile() } >> field.offset) & field.mask)
|
||||
.try_into()
|
||||
.unwrap_or_default()
|
||||
}
|
||||
pub fn rw(&mut self, reg: usize, field: Field, value: T) {
|
||||
pub fn rw(&mut self, reg: Register, field: Field, value: T) {
|
||||
let usize_base: *mut usize = unsafe { core::mem::transmute(&self.base) };
|
||||
let value_as_usize: usize = value.try_into().unwrap_or_default() << field.offset;
|
||||
let previous = unsafe { usize_base.add(reg).read_volatile() } & ! field.mask;
|
||||
unsafe { usize_base.add(reg).write_volatile(previous | value_as_usize)};
|
||||
let previous = unsafe { usize_base.add(reg.offset).read_volatile() } & !field.mask;
|
||||
unsafe {
|
||||
usize_base
|
||||
.add(reg.offset)
|
||||
.write_volatile(previous | value_as_usize)
|
||||
};
|
||||
}
|
||||
pub fn ow(&mut self, reg: usize, field: Field, value: T) {
|
||||
pub fn ow(&mut self, reg: Register, field: Field, value: T) {
|
||||
let usize_base: *mut usize = unsafe { core::mem::transmute(&self.base) };
|
||||
let value_as_usize: usize = value.try_into().unwrap_or_default() << field.offset;
|
||||
unsafe { usize_base.add(reg).write_volatile(value_as_usize)};
|
||||
unsafe { usize_base.add(reg.offset).write_volatile(value_as_usize) };
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,14 +104,15 @@ where
|
||||
mod tests {
|
||||
pub mod pac {
|
||||
pub mod audio {
|
||||
pub const RX_CTL: usize = 0x0c;
|
||||
pub const RX_CTL: crate::Register = crate::Register::new(0x0c);
|
||||
pub const RX_CTL_ENABLE: crate::Field = crate::Field::new(1, 0);
|
||||
pub const RX_CTL_RESET: crate::Field = crate::Field::new(1, 1);
|
||||
}
|
||||
pub mod uart {
|
||||
pub const RXTX: usize = 0x00;
|
||||
pub const RXTX: crate::Register = crate::Register::new(0x00);
|
||||
pub const RXTX_RXTX: crate::Field = crate::Field::new(8, 0);
|
||||
pub const TXFULL: usize = 0x04;
|
||||
|
||||
pub const TXFULL: crate::Register = crate::Register::new(0x04);
|
||||
pub const TXFULL_TXFULL: crate::Field = crate::Field::new(1, 0);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user