1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
use core::marker::PhantomData; #[derive(Copy, Clone)] pub struct RW; #[derive(Copy, Clone)] pub struct R; #[derive(Copy, Clone)] pub struct W; mod sealed; pub trait Access: sealed::Access + Copy {} impl Access for R {} impl Access for W {} impl Access for RW {} pub trait Read: Access {} impl Read for RW {} impl Read for R {} pub trait Write: Access {} impl Write for RW {} impl Write for W {} #[derive(Copy, Clone)] pub struct Reg<T: Copy, A: Access> { ptr: *mut u8, phantom: PhantomData<*mut (T, A)>, } unsafe impl<T: Copy, A: Access> Send for Reg<T, A> {} unsafe impl<T: Copy, A: Access> Sync for Reg<T, A> {} impl<T: Copy, A: Access> Reg<T, A> { pub fn from_ptr(ptr: *mut u8) -> Self { Self { ptr, phantom: PhantomData, } } pub fn ptr(&self) -> *mut T { self.ptr as _ } } impl<T: Copy, A: Read> Reg<T, A> { pub unsafe fn read(&self) -> T { (self.ptr as *mut T).read_volatile() } } impl<T: Copy, A: Write> Reg<T, A> { pub unsafe fn write_value(&self, val: T) { (self.ptr as *mut T).write_volatile(val) } } impl<T: Default + Copy, A: Write> Reg<T, A> { pub unsafe fn write<R>(&self, f: impl FnOnce(&mut T) -> R) -> R { let mut val = Default::default(); let res = f(&mut val); self.write_value(val); res } } impl<T: Copy, A: Read + Write> Reg<T, A> { pub unsafe fn modify<R>(&self, f: impl FnOnce(&mut T) -> R) -> R { let mut val = self.read(); let res = f(&mut val); self.write_value(val); res } }