Skip to content

Commit 93f1363

Browse files
committed
generic register rebase
1 parent 5ccfc14 commit 93f1363

File tree

2 files changed

+174
-110
lines changed

2 files changed

+174
-110
lines changed

src/generate/generic.rs

+142-13
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,20 @@ pub fn render() -> Result<Vec<Tokens>> {
99

1010
generic_items.push(quote! {
1111
use core::marker;
12+
use core::ops::Deref;
13+
use vcell::VolatileCell;
14+
15+
///Marker trait for readable register/field
16+
pub trait Readable {}
17+
18+
///Marker trait for writable register/field
19+
pub trait Writable {}
20+
21+
///Reset value of the register
22+
pub trait ResetValue<U> {
23+
///Reset value of the register
24+
fn reset_value() -> U;
25+
}
1226

1327
///Converting enumerated values to bits
1428
pub trait ToBits<N> {
@@ -18,23 +32,105 @@ pub fn render() -> Result<Vec<Tokens>> {
1832
});
1933

2034
generic_items.push(quote! {
21-
///Value read from the register
22-
pub struct FR<U, T> {
23-
pub(crate) bits: U,
24-
_reg: marker::PhantomData<T>,
35+
///Wrapper for registers
36+
pub struct Reg<U, REG> {
37+
register: vcell::VolatileCell<U>,
38+
_marker: marker::PhantomData<REG>,
39+
}
40+
41+
impl<U, REG> core::ops::Deref for Reg<U, REG> {
42+
type Target = vcell::VolatileCell<U>;
43+
#[inline(always)]
44+
fn deref(&self) -> &Self::Target {
45+
&self.register
46+
}
2547
}
2648

27-
impl<U, T, FI> PartialEq<FI> for FR<U, T>
49+
impl<U, REG> Reg<U, REG>
2850
where
29-
U: PartialEq,
30-
FI: ToBits<U>
51+
Self: Readable + Deref<Target=VolatileCell<U>>,
52+
U: Copy
3153
{
32-
fn eq(&self, other: &FI) -> bool {
33-
self.bits.eq(&other._bits())
54+
///Reads the contents of the register
55+
#[inline(always)]
56+
pub fn read(&self) -> R<U, Self> {
57+
R {bits: (*self).get(), _reg: marker::PhantomData}
58+
}
59+
}
60+
61+
impl<U, REG> Reg<U, REG>
62+
where
63+
Self: ResetValue<U> + Writable + Deref<Target=VolatileCell<U>>,
64+
U: Copy,
65+
{
66+
///Writes the reset value to the register
67+
#[inline(always)]
68+
pub fn reset(&self) {
69+
(*self).set(Self::reset_value())
3470
}
3571
}
72+
});
3673

37-
impl<U, T> FR<U, T>
74+
generic_items.push(quote! {
75+
impl<U, REG> Reg<U, REG>
76+
where
77+
Self: ResetValue<U> + Writable + Deref<Target=VolatileCell<U>>,
78+
U: Copy
79+
{
80+
///Writes to the register
81+
#[inline(always)]
82+
pub fn write<F>(&self, f: F)
83+
where
84+
F: FnOnce(&mut W<U, Self>) -> &mut W<U, Self>
85+
{
86+
(*self).set(f(&mut W {bits: Self::reset_value(), _reg: marker::PhantomData}).bits);
87+
}
88+
}
89+
});
90+
91+
generic_items.push(quote! {
92+
impl<U, REG> Reg<U, REG>
93+
where
94+
Self: Writable + Deref<Target=VolatileCell<U>>,
95+
U: Copy + Default
96+
{
97+
///Writes Zero to the register
98+
#[inline(always)]
99+
pub fn write_with_zero<F>(&self, f: F)
100+
where
101+
F: FnOnce(&mut W<U, Self>) -> &mut W<U, Self>
102+
{
103+
(*self).set(f(&mut W {bits: U::default(), _reg: marker::PhantomData }).bits);
104+
}
105+
}
106+
});
107+
108+
generic_items.push(quote! {
109+
impl<U, REG> Reg<U, REG>
110+
where
111+
Self: Readable + Writable + Deref<Target = VolatileCell<U>>,
112+
U: Copy,
113+
{
114+
///Modifies the contents of the register
115+
#[inline(always)]
116+
pub fn modify<F>(&self, f: F)
117+
where
118+
for<'w> F: FnOnce(&R<U, Self>, &'w mut W<U, Self>) -> &'w mut W<U, Self>
119+
{
120+
let bits = (*self).get();
121+
(*self).set(f(&R {bits, _reg: marker::PhantomData}, &mut W {bits, _reg: marker::PhantomData}).bits);
122+
}
123+
}
124+
});
125+
126+
generic_items.push(quote! {
127+
///Register/field reader
128+
pub struct R<U, T> {
129+
pub(crate) bits: U,
130+
_reg: marker::PhantomData<T>,
131+
}
132+
133+
impl<U, T> R<U, T>
38134
where
39135
U: Copy
40136
{
@@ -46,7 +142,7 @@ pub fn render() -> Result<Vec<Tokens>> {
46142
_reg: marker::PhantomData,
47143
}
48144
}
49-
///Read raw bits from field
145+
///Read raw bits from register/field
50146
#[inline(always)]
51147
pub fn bits(&self) -> U {
52148
self.bits
@@ -55,7 +151,19 @@ pub fn render() -> Result<Vec<Tokens>> {
55151
});
56152

57153
generic_items.push(quote! {
58-
impl<FI> FR<bool, FI> {
154+
impl<U, T, FI> PartialEq<FI> for R<U, T>
155+
where
156+
U: PartialEq,
157+
FI: ToBits<U>
158+
{
159+
fn eq(&self, other: &FI) -> bool {
160+
self.bits.eq(&other._bits())
161+
}
162+
}
163+
});
164+
165+
generic_items.push(quote! {
166+
impl<FI> R<bool, FI> {
59167
///Value of the field as raw bits
60168
#[inline(always)]
61169
pub fn bit(&self) -> bool {
@@ -74,6 +182,27 @@ pub fn render() -> Result<Vec<Tokens>> {
74182
}
75183
});
76184

185+
generic_items.push(quote! {
186+
///Register writer
187+
pub struct W<U, REG> {
188+
///Writable bits
189+
pub bits: U,
190+
_reg: marker::PhantomData<REG>,
191+
}
192+
});
193+
194+
generic_items.push(quote! {
195+
impl<U, REG> W<U, REG> {
196+
///Writes raw bits to the register
197+
#[inline(always)]
198+
pub fn bits(&mut self, bits: U) -> &mut Self {
199+
self.bits = bits;
200+
self
201+
}
202+
}
203+
});
204+
205+
77206
generic_items.push(quote! {
78207
///Used if enumerated values cover not the whole range
79208
#[derive(Clone,Copy,PartialEq)]
@@ -88,7 +217,7 @@ pub fn render() -> Result<Vec<Tokens>> {
88217
code.push(quote! {
89218
#[allow(unused_imports)]
90219
use generic::*;
91-
/// Common register and bit access and modify traits
220+
///Common register and bit access and modify traits
92221
pub mod generic {
93222
#(#generic_items)*
94223
}

src/generate/register.rs

+32-97
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub fn render(
1919
let access = util::access_of(register);
2020
let name = util::name_of(register);
2121
let name_pc = Ident::from(&*name.to_sanitized_upper_case());
22+
let _name_pc = Ident::from(format!("_{}", &*name.to_sanitized_upper_case()));
2223
let name_sc = Ident::from(&*name.to_sanitized_snake_case());
2324
let rsize = register
2425
.size
@@ -35,120 +36,39 @@ pub fn render(
3536
let description =
3637
util::escape_brackets(util::respace(&register.description.clone().unwrap()).as_ref());
3738

38-
let unsafety = unsafety(register.write_constraint.as_ref(), rsize);
39-
4039
let mut mod_items = vec![];
41-
let mut reg_impl_items = vec![];
4240
let mut r_impl_items = vec![];
4341
let mut w_impl_items = vec![];
4442

4543
let can_read = [Access::ReadOnly, Access::ReadWriteOnce, Access::ReadWrite].contains(&access);
4644
let can_write = access != Access::ReadOnly;
4745

48-
if access == Access::ReadWrite || access == Access::ReadWriteOnce {
49-
reg_impl_items.push(quote! {
50-
///Modifies the contents of the register
51-
#[inline(always)]
52-
pub fn modify<F>(&self, f: F)
53-
where
54-
for<'w> F: FnOnce(&R, &'w mut W) -> &'w mut W
55-
{
56-
let bits = self.register.get();
57-
self.register.set(f(&R { bits }, &mut W { bits }).bits);
58-
}
59-
});
60-
}
61-
6246
if can_read {
63-
reg_impl_items.push(quote! {
64-
///Reads the contents of the register
65-
#[inline(always)]
66-
pub fn read(&self) -> R {
67-
R { bits: self.register.get() }
68-
}
69-
});
70-
47+
let desc = format!("Reader for register {}", register.name);
7148
mod_items.push(quote! {
72-
///Value read from the register
73-
pub struct R {
74-
bits: #rty,
75-
}
76-
});
77-
78-
r_impl_items.push(quote! {
79-
///Value of the register as raw bits
80-
#[inline(always)]
81-
pub fn bits(&self) -> #rty {
82-
self.bits
83-
}
49+
#[doc = #desc]
50+
pub type R = crate::R<#rty, super::#name_pc>;
8451
});
8552
}
8653

8754
if can_write {
88-
reg_impl_items.push(quote! {
89-
///Writes to the register
90-
#[inline(always)]
91-
pub fn write<F>(&self, f: F)
92-
where
93-
F: FnOnce(&mut W) -> &mut W
94-
{
95-
self.register.set(f(&mut W { bits: Self::reset_value() }).bits);
96-
}
97-
});
98-
99-
mod_items.push(quote! {
100-
///Value to write to the register
101-
pub struct W {
102-
bits: #rty,
103-
}
104-
});
105-
10655
let rv = register
10756
.reset_value
10857
.or(defs.reset_value)
10958
.map(|v| util::hex(v as u64))
11059
.ok_or_else(|| format!("Register {} has no reset value", register.name))?;
11160

112-
reg_impl_items.push(quote! {
113-
///Reset value of the register
114-
#[inline(always)]
115-
pub const fn reset_value() -> #rty {
116-
#rv
117-
}
118-
///Writes the reset value to the register
119-
#[inline(always)]
120-
pub fn reset(&self) {
121-
self.register.set(Self::reset_value())
122-
}
123-
});
124-
125-
w_impl_items.push(quote! {
126-
///Writes raw bits to the register
127-
#[inline(always)]
128-
pub #unsafety fn bits(&mut self, bits: #rty) -> &mut Self {
129-
self.bits = bits;
130-
self
131-
}
132-
});
133-
}
134-
135-
let open = Ident::from("{");
136-
let close = Ident::from("}");
137-
138-
mod_items.push(quote! {
139-
impl super::#name_pc #open
140-
});
141-
142-
for item in reg_impl_items {
61+
let desc = format!("Writer for register {}", register.name);
14362
mod_items.push(quote! {
144-
#item
63+
#[doc = #desc]
64+
pub type W = crate::W<#rty, super::#name_pc>;
65+
impl crate::ResetValue<#rty> for super::#name_pc {
66+
#[inline(always)]
67+
fn reset_value() -> #rty { #rv }
68+
}
14569
});
14670
}
14771

148-
mod_items.push(quote! {
149-
#close
150-
});
151-
15272
if let Some(cur_fields) = register.fields.as_ref() {
15373
// filter out all reserved fields, as we should not generate code for
15474
// them
@@ -212,10 +132,25 @@ pub fn render(
212132
let mut out = vec![];
213133
out.push(quote! {
214134
#[doc = #description]
215-
pub struct #name_pc {
216-
register: vcell::VolatileCell<#rty>
217-
}
135+
pub type #name_pc = crate::Reg<#rty, #_name_pc>;
136+
137+
#[allow(missing_docs)]
138+
#[doc(hidden)]
139+
pub struct #_name_pc;
140+
});
218141

142+
if can_read {
143+
out.push(quote! {
144+
impl crate::Readable for #name_pc {}
145+
});
146+
}
147+
if can_write {
148+
out.push(quote! {
149+
impl crate::Writable for #name_pc {}
150+
});
151+
}
152+
153+
out.push(quote! {
219154
#[doc = #description]
220155
pub mod #name_sc #open
221156
});
@@ -366,7 +301,7 @@ pub fn fields(
366301

367302
mod_items.push(quote! {
368303
///Reader of the field
369-
pub type #_pc_r = crate::FR<#fty, #base_pc_r>;
304+
pub type #_pc_r = crate::R<#fty, #base_pc_r>;
370305
});
371306

372307
base_pc_r
@@ -449,7 +384,7 @@ pub fn fields(
449384

450385
mod_items.push(quote! {
451386
///Reader of the field
452-
pub type #_pc_r = crate::FR<#fty, #pc_r>;
387+
pub type #_pc_r = crate::R<#fty, #pc_r>;
453388
impl #_pc_r {
454389
#(#enum_items)*
455390
}
@@ -469,7 +404,7 @@ pub fn fields(
469404

470405
mod_items.push(quote! {
471406
///Reader of the field
472-
pub type #_pc_r = crate::FR<#fty, #fty>;
407+
pub type #_pc_r = crate::R<#fty, #fty>;
473408
})
474409

475410
}

0 commit comments

Comments
 (0)