peripheral_register/
lib.rs1#![no_std]
2use core::convert::{From, Into};
3use core::marker::PhantomData;
4use core::slice::from_raw_parts_mut;
5
6pub struct RegisterValue(usize);
7
8impl From<u8> for RegisterValue {
9 fn from(value: u8) -> RegisterValue {
10 RegisterValue(value as usize)
11 }
12}
13
14impl From<u16> for RegisterValue {
15 fn from(value: u16) -> RegisterValue {
16 RegisterValue(value as usize)
17 }
18}
19
20impl From<u32> for RegisterValue {
21 fn from(value: u32) -> RegisterValue {
22 RegisterValue(value as usize)
23 }
24}
25
26impl From<RegisterValue> for u8 {
27 fn from(value: RegisterValue) -> u8 {
28 value.0 as u8
29 }
30}
31
32impl From<RegisterValue> for u16 {
33 fn from(value: RegisterValue) -> u16 {
34 value.0 as u16
35 }
36}
37
38impl From<RegisterValue> for u32 {
39 fn from(value: RegisterValue) -> u32 {
40 value.0 as u32
41 }
42}
43
44pub trait Field {
45 fn get_offset_length(&self) -> (usize, usize);
46
47 fn of(&self, value: usize) -> usize {
48 let (offset, length) = self.get_offset_length();
49 (value & ((1 << length) - 1)) << offset
50 }
51}
52
53pub enum NoField {}
54
55impl Field for NoField {
56 fn get_offset_length(&self) -> (usize, usize) {
57 return (0, 0);
58 }
59}
60
61pub enum Bits {
62 Of(usize, usize),
63}
64
65impl Field for Bits {
66 fn get_offset_length(&self) -> (usize, usize) {
67 match self {
68 Bits::Of(offset, length) => (*offset, *length),
69 }
70 }
71}
72
73#[derive(Copy, Clone, Debug)]
74pub struct Register<T, U: Field = NoField> {
75 pub value: T,
76 u: PhantomData<U>,
77}
78
79impl<T, U: Field> From<T> for Register<T, U> {
80 fn from(value: T) -> Register<T, U> {
81 Register {
82 value,
83 u: PhantomData,
84 }
85 }
86}
87
88impl<'a, T, U: Field> Into<&'a mut [T]> for Register<T, U> {
89 fn into(mut self) -> &'a mut [T] {
90 unsafe { from_raw_parts_mut(&mut self.value, 1) }
91 }
92}
93
94impl<T, U> Register<T, U>
95where
96 T: Into<RegisterValue> + From<RegisterValue> + Copy + Default,
97 U: Field,
98{
99 pub fn new(value: T) -> Self {
100 Self {
101 value: value,
102 u: PhantomData,
103 }
104 }
105
106 pub fn of(u: U, value: T) -> Self {
107 let mut v = Self {
108 value: Default::default(),
109 u: PhantomData,
110 };
111 v.set(u, value);
112 v
113 }
114
115 pub fn get(&self, u: U) -> T {
116 let (offset, length) = u.get_offset_length();
117 let mask = ((1 << length) - 1) << offset;
118 RegisterValue((self.value.into().0 >> offset) & mask).into()
119 }
120
121 pub fn is_set(&self, u: U) -> bool {
122 self.get(u).into().0 > 0
123 }
124
125 pub fn set(&mut self, u: U, value: T) {
126 let (offset, length) = u.get_offset_length();
127 let mask = ((1 << length) - 1) << offset;
128 let to_set = self.value.into().0 & !mask;
129 let usize_value = value.into().0;
130 self.value = RegisterValue(to_set | (usize_value << offset) & mask).into();
131 }
132
133 pub fn reset(&mut self, u: U) {
134 let (offset, length) = u.get_offset_length();
135 let mask = ((1 << length) - 1) << offset;
136 let to_set = self.value.into().0 & !mask;
137 self.value = RegisterValue(to_set).into();
138 }
139}
140
141#[macro_export]
142macro_rules! register_fields {
143 (
144 $(
145 $(#[$outer:meta])*
146 enum $name:ident {
147 $($field:ident = $offset:tt : $len:tt,)*
148 }
149 )*
150 ) => {
151 $(
152 $(#[$outer])*
153 #[repr(usize)]
154 #[derive(Copy, Clone)]
155 enum $name {
156 $($field = $offset << 8 | $len,)*
157 }
158
159 impl Field for $name {
160 fn get_offset_length(&self) -> (usize, usize) {
161 (*self as usize >> 8, *self as usize & 0xFF)
162 }
163 }
164 )*
165 };
166 (
167 $(
168 $(#[$outer:meta])*
169 pub enum $name:ident {
170 $($field:ident = $offset:tt : $len:tt,)*
171 }
172 )*
173 ) => {
174 $(
175 $(#[$outer])*
176 #[repr(usize)]
177 #[derive(Copy, Clone)]
178 pub enum $name {
179 $($field = $offset << 8 | $len,)*
180 }
181
182 impl Field for $name {
183 fn get_offset_length(&self) -> (usize, usize) {
184 (*self as usize >> 8, *self as usize & 0xFF)
185 }
186 }
187 )*
188 }
189}