Skip to content

Commit 0aa62db

Browse files
committed
raw_read_write
1 parent 5b01c9c commit 0aa62db

File tree

7 files changed

+584
-247
lines changed

7 files changed

+584
-247
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
77

88
## [Unreleased]
99

10+
- Add `raw-access` options
1011
- Refactor `Accessor`
1112

1213
## [v0.33.3] - 2024-05-10

src/generate/device.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,12 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
6363

6464
out.extend(quote! {
6565
use core::ops::Deref;
66-
use core::marker::PhantomData;
6766
});
67+
if !config.raw_access {
68+
out.extend(quote! {
69+
use core::marker::PhantomData;
70+
});
71+
}
6872

6973
// Retaining the previous assumption
7074
let mut fpu_present = true;
@@ -140,6 +144,11 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
140144
}
141145

142146
let generic_file = include_str!("generic.rs");
147+
let generic_reg_file = if config.raw_access {
148+
include_str!("generic_reg_raw.rs")
149+
} else {
150+
include_str!("generic_reg_vcell.rs")
151+
};
143152
let generic_atomic_file = include_str!("generic_atomic.rs");
144153
if config.generic_mod {
145154
let mut file = File::create(
@@ -150,6 +159,7 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
150159
.join("generic.rs"),
151160
)?;
152161
writeln!(file, "{generic_file}")?;
162+
writeln!(file, "{generic_reg_file}")?;
153163
if config.atomics {
154164
if let Some(atomics_feature) = config.atomics_feature.as_ref() {
155165
writeln!(file, "#[cfg(feature = \"{atomics_feature}\")]")?;
@@ -167,6 +177,7 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
167177
}
168178
} else {
169179
let mut tokens = syn::parse_file(generic_file)?.into_token_stream();
180+
syn::parse_file(generic_reg_file)?.to_tokens(&mut tokens);
170181
if config.atomics {
171182
if let Some(atomics_feature) = config.atomics_feature.as_ref() {
172183
quote!(#[cfg(feature = #atomics_feature)]).to_tokens(&mut tokens);
@@ -246,9 +257,7 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
246257
#feature_attribute
247258
pub #p_singleton: #p_ty,
248259
});
249-
exprs.extend(
250-
quote!(#feature_attribute #p_singleton: #p_ty { _marker: PhantomData },),
251-
);
260+
exprs.extend(quote!(#feature_attribute #p_singleton: unsafe { #p_ty::steal() },));
252261
}
253262
Peripheral::Array(p, dim_element) => {
254263
for p_name in names(p, dim_element) {
@@ -264,7 +273,7 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
264273
pub #p_singleton: #p_ty,
265274
});
266275
exprs.extend(
267-
quote!(#feature_attribute #p_singleton: #p_ty { _marker: PhantomData },),
276+
quote!(#feature_attribute #p_singleton: unsafe { #p_ty::steal() },),
268277
);
269278
}
270279
}

src/generate/generic.rs

-172
Original file line numberDiff line numberDiff line change
@@ -95,178 +95,6 @@ pub trait Resettable: RegisterSpec {
9595
}
9696
}
9797

98-
/// This structure provides volatile access to registers.
99-
#[repr(transparent)]
100-
pub struct Reg<REG: RegisterSpec> {
101-
register: vcell::VolatileCell<REG::Ux>,
102-
_marker: marker::PhantomData<REG>,
103-
}
104-
105-
unsafe impl<REG: RegisterSpec> Send for Reg<REG> where REG::Ux: Send {}
106-
107-
impl<REG: RegisterSpec> Reg<REG> {
108-
/// Returns the underlying memory address of register.
109-
///
110-
/// ```ignore
111-
/// let reg_ptr = periph.reg.as_ptr();
112-
/// ```
113-
#[inline(always)]
114-
pub fn as_ptr(&self) -> *mut REG::Ux {
115-
self.register.as_ptr()
116-
}
117-
}
118-
119-
impl<REG: Readable> Reg<REG> {
120-
/// Reads the contents of a `Readable` register.
121-
///
122-
/// You can read the raw contents of a register by using `bits`:
123-
/// ```ignore
124-
/// let bits = periph.reg.read().bits();
125-
/// ```
126-
/// or get the content of a particular field of a register:
127-
/// ```ignore
128-
/// let reader = periph.reg.read();
129-
/// let bits = reader.field1().bits();
130-
/// let flag = reader.field2().bit_is_set();
131-
/// ```
132-
#[inline(always)]
133-
pub fn read(&self) -> R<REG> {
134-
R {
135-
bits: self.register.get(),
136-
_reg: marker::PhantomData,
137-
}
138-
}
139-
}
140-
141-
impl<REG: Resettable + Writable> Reg<REG> {
142-
/// Writes the reset value to `Writable` register.
143-
///
144-
/// Resets the register to its initial state.
145-
#[inline(always)]
146-
pub fn reset(&self) {
147-
self.register.set(REG::RESET_VALUE)
148-
}
149-
150-
/// Writes bits to a `Writable` register.
151-
///
152-
/// You can write raw bits into a register:
153-
/// ```ignore
154-
/// periph.reg.write(|w| unsafe { w.bits(rawbits) });
155-
/// ```
156-
/// or write only the fields you need:
157-
/// ```ignore
158-
/// periph.reg.write(|w| w
159-
/// .field1().bits(newfield1bits)
160-
/// .field2().set_bit()
161-
/// .field3().variant(VARIANT)
162-
/// );
163-
/// ```
164-
/// or an alternative way of saying the same:
165-
/// ```ignore
166-
/// periph.reg.write(|w| {
167-
/// w.field1().bits(newfield1bits);
168-
/// w.field2().set_bit();
169-
/// w.field3().variant(VARIANT)
170-
/// });
171-
/// ```
172-
/// In the latter case, other fields will be set to their reset value.
173-
#[inline(always)]
174-
pub fn write<F>(&self, f: F)
175-
where
176-
F: FnOnce(&mut W<REG>) -> &mut W<REG>,
177-
{
178-
self.register.set(
179-
f(&mut W {
180-
bits: REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
181-
| REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
182-
_reg: marker::PhantomData,
183-
})
184-
.bits,
185-
);
186-
}
187-
}
188-
189-
impl<REG: Writable> Reg<REG> {
190-
/// Writes 0 to a `Writable` register.
191-
///
192-
/// Similar to `write`, but unused bits will contain 0.
193-
///
194-
/// # Safety
195-
///
196-
/// Unsafe to use with registers which don't allow to write 0.
197-
#[inline(always)]
198-
pub unsafe fn write_with_zero<F>(&self, f: F)
199-
where
200-
F: FnOnce(&mut W<REG>) -> &mut W<REG>,
201-
{
202-
self.register.set(
203-
f(&mut W {
204-
bits: REG::Ux::default(),
205-
_reg: marker::PhantomData,
206-
})
207-
.bits,
208-
);
209-
}
210-
}
211-
212-
impl<REG: Readable + Writable> Reg<REG> {
213-
/// Modifies the contents of the register by reading and then writing it.
214-
///
215-
/// E.g. to do a read-modify-write sequence to change parts of a register:
216-
/// ```ignore
217-
/// periph.reg.modify(|r, w| unsafe { w.bits(
218-
/// r.bits() | 3
219-
/// ) });
220-
/// ```
221-
/// or
222-
/// ```ignore
223-
/// periph.reg.modify(|_, w| w
224-
/// .field1().bits(newfield1bits)
225-
/// .field2().set_bit()
226-
/// .field3().variant(VARIANT)
227-
/// );
228-
/// ```
229-
/// or an alternative way of saying the same:
230-
/// ```ignore
231-
/// periph.reg.modify(|_, w| {
232-
/// w.field1().bits(newfield1bits);
233-
/// w.field2().set_bit();
234-
/// w.field3().variant(VARIANT)
235-
/// });
236-
/// ```
237-
/// Other fields will have the value they had before the call to `modify`.
238-
#[inline(always)]
239-
pub fn modify<F>(&self, f: F)
240-
where
241-
for<'w> F: FnOnce(&R<REG>, &'w mut W<REG>) -> &'w mut W<REG>,
242-
{
243-
let bits = self.register.get();
244-
self.register.set(
245-
f(
246-
&R {
247-
bits,
248-
_reg: marker::PhantomData,
249-
},
250-
&mut W {
251-
bits: bits & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
252-
| REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
253-
_reg: marker::PhantomData,
254-
},
255-
)
256-
.bits,
257-
);
258-
}
259-
}
260-
261-
impl<REG: Readable> core::fmt::Debug for crate::generic::Reg<REG>
262-
where
263-
R<REG>: core::fmt::Debug
264-
{
265-
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
266-
core::fmt::Debug::fmt(&self.read(), f)
267-
}
268-
}
269-
27098
#[doc(hidden)]
27199
pub mod raw {
272100
use super::{marker, BitM, FieldSpec, RegisterSpec, Unsafe, Writable};

0 commit comments

Comments
 (0)