Skip to content

Commit a244d09

Browse files
committed
generic-p1
1 parent f8e7692 commit a244d09

File tree

3 files changed

+187
-107
lines changed

3 files changed

+187
-107
lines changed
File renamed without changes.

src/generate/generic.rs

+148-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,101 @@ 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-
bits: U,
24-
_reg: marker::PhantomData<T>,
35+
///Wrapper for registers
36+
pub struct Reg<REG>(pub(crate) REG);
37+
38+
impl<U, REG> Reg<REG>
39+
where
40+
Self: Readable,
41+
REG: Deref<Target=VolatileCell<U>>,
42+
U: Copy
43+
{
44+
///Reads the contents of the register
45+
#[inline(always)]
46+
pub fn read(&self) -> R<U, REG> {
47+
R::new((*self.0).get())
48+
}
2549
}
2650

27-
impl<U, T, FI> PartialEq<FI> for FR<U, T>
51+
impl<U, REG> Reg<REG>
2852
where
29-
U: PartialEq,
30-
FI: ToBits<U>
53+
Self: ResetValue<U> + Writable,
54+
REG: Deref<Target=VolatileCell<U>>,
55+
U: Copy,
3156
{
32-
fn eq(&self, other: &FI) -> bool {
33-
self.bits.eq(&other._bits())
57+
///Writes the reset value to the register
58+
#[inline(always)]
59+
pub fn reset(&self) {
60+
(*self.0).set(Self::reset_value())
3461
}
3562
}
63+
});
3664

37-
impl<U, T> FR<U, T>
65+
generic_items.push(quote! {
66+
impl<U, REG> Reg<REG>
67+
where
68+
Self: ResetValue<U> + Writable,
69+
REG: Deref<Target=VolatileCell<U>>,
70+
U: Copy
71+
{
72+
///Writes to the register
73+
#[inline(always)]
74+
pub fn write<F>(&self, f: F)
75+
where
76+
F: FnOnce(&mut W<U, REG>) -> &mut W<U, REG>
77+
{
78+
79+
(*self.0).set(f(&mut W::new(Self::reset_value())).bits);
80+
}
81+
}
82+
});
83+
84+
generic_items.push(quote! {
85+
impl<U, REG> Reg<REG>
86+
where
87+
Self: Writable,
88+
REG: Deref<Target=VolatileCell<U>>,
89+
U: Copy + Default
90+
{
91+
///Writes Zero to the register
92+
#[inline(always)]
93+
pub fn write_with_zero<F>(&self, f: F)
94+
where
95+
F: FnOnce(&mut W<U, REG>) -> &mut W<U, REG>
96+
{
97+
98+
(*self.0).set(f(&mut W::new(U::default())).bits);
99+
}
100+
}
101+
});
102+
103+
generic_items.push(quote! {
104+
impl<U, REG> Reg<REG>
105+
where
106+
Self: Readable + Writable,
107+
REG: Deref<Target = VolatileCell<U>>,
108+
U: Copy,
109+
{
110+
///Modifies the contents of the register
111+
#[inline(always)]
112+
pub fn modify<F>(&self, f: F)
113+
where
114+
for<'w> F: FnOnce(&R<U, REG>, &'w mut W<U, REG>) -> &'w mut W<U, REG>
115+
{
116+
let bits = (*self.0).get();
117+
(*self.0).set(f(&R::new(bits), &mut W::new(bits)).bits);
118+
}
119+
}
120+
});
121+
122+
generic_items.push(quote! {
123+
///Register/field reader
124+
pub struct R<U, T> {
125+
bits: U,
126+
_reg: marker::PhantomData<T>,
127+
}
128+
129+
impl<U, T> R<U, T>
38130
where
39131
U: Copy
40132
{
@@ -46,7 +138,7 @@ pub fn render() -> Result<Vec<Tokens>> {
46138
_reg: marker::PhantomData,
47139
}
48140
}
49-
///Read raw bits from field
141+
///Read raw bits from register/field
50142
#[inline(always)]
51143
pub fn bits(&self) -> U {
52144
self.bits
@@ -55,7 +147,19 @@ pub fn render() -> Result<Vec<Tokens>> {
55147
});
56148

57149
generic_items.push(quote! {
58-
impl<FI> FR<bool, FI> {
150+
impl<U, T, FI> PartialEq<FI> for R<U, T>
151+
where
152+
U: PartialEq,
153+
FI: ToBits<U>
154+
{
155+
fn eq(&self, other: &FI) -> bool {
156+
self.bits.eq(&other._bits())
157+
}
158+
}
159+
});
160+
161+
generic_items.push(quote! {
162+
impl<FI> R<bool, FI> {
59163
///Value of the field as raw bits
60164
#[inline(always)]
61165
pub fn bit(&self) -> bool {
@@ -74,10 +178,41 @@ pub fn render() -> Result<Vec<Tokens>> {
74178
}
75179
});
76180

181+
generic_items.push(quote! {
182+
///Register writer
183+
pub struct W<U, REG> {
184+
///Writable bits
185+
pub bits: U,
186+
_reg: marker::PhantomData<REG>,
187+
}
188+
189+
impl<U, REG> W<U, REG> {
190+
///Create new instance of reader
191+
#[inline(always)]
192+
pub(crate) fn new(bits: U) -> Self {
193+
Self {
194+
bits,
195+
_reg: marker::PhantomData,
196+
}
197+
}
198+
}
199+
});
200+
201+
generic_items.push(quote! {
202+
impl<U, REG> W<U, REG> {
203+
///Writes raw bits to the register
204+
#[inline(always)]
205+
pub fn bits(&mut self, bits: U) -> &mut Self {
206+
self.bits = bits;
207+
self
208+
}
209+
}
210+
});
211+
77212
code.push(quote! {
78213
#[allow(unused_imports)]
79214
use generic::*;
80-
/// Common register and bit access and modify traits
215+
///Common register and bit access and modify traits
81216
pub mod generic {
82217
#(#generic_items)*
83218
}

src/generate/register.rs

+39-94
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,9 +132,34 @@ pub fn render(
212132
let mut out = vec![];
213133
out.push(quote! {
214134
#[doc = #description]
215-
pub struct #name_pc {
135+
pub type #name_pc = crate::Reg<#_name_pc>;
136+
137+
#[allow(missing_docs)]
138+
#[doc(hidden)]
139+
pub struct #_name_pc {
216140
register: vcell::VolatileCell<#rty>
217141
}
142+
});
143+
144+
if can_read {
145+
out.push(quote! {
146+
impl crate::Readable for #name_pc {}
147+
});
148+
}
149+
if can_write {
150+
out.push(quote! {
151+
impl crate::Writable for #name_pc {}
152+
});
153+
}
154+
155+
out.push(quote! {
156+
impl core::ops::Deref for #_name_pc {
157+
type Target = vcell::VolatileCell<#rty>;
158+
#[inline(always)]
159+
fn deref(&self) -> &Self::Target {
160+
&self.register
161+
}
162+
}
218163

219164
#[doc = #description]
220165
pub mod #name_sc #open
@@ -469,7 +414,7 @@ pub fn fields(
469414

470415
mod_items.push(quote! {
471416
///Reader of the field
472-
pub type #_pc_r = crate::FR<#fty, #pc_r>;
417+
pub type #_pc_r = crate::R<#fty, #pc_r>;
473418
impl #_pc_r {
474419
#(#enum_items)*
475420
}
@@ -489,7 +434,7 @@ pub fn fields(
489434

490435
mod_items.push(quote! {
491436
///Reader of the field
492-
pub type #_pc_r = crate::FR<#fty, #fty>;
437+
pub type #_pc_r = crate::R<#fty, #fty>;
493438
})
494439

495440
}

0 commit comments

Comments
 (0)