Skip to content

Commit f0b4e55

Browse files
bors[bot]burrbull
andauthored
Merge #598
598: WriteField aliases r=Emilgardis a=burrbull Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents f99b7a5 + f0f78b3 commit f0b4e55

File tree

8 files changed

+402
-240
lines changed

8 files changed

+402
-240
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646
runs-on: ubuntu-latest
4747
strategy:
4848
matrix:
49-
rust: [stable, nightly, 1.46.0]
49+
rust: [stable, nightly, 1.51.0]
5050

5151
steps:
5252
- uses: actions/checkout@v3
@@ -94,7 +94,7 @@ jobs:
9494
options: all
9595
include:
9696
# Test MSRV
97-
- rust: 1.46.0
97+
- rust: 1.51.0
9898
vendor: Nordic
9999

100100
# Use nightly for architectures which don't support stable

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
- Use generic `FieldWriter`, `FieldReader`, `BitWriter`, `BitReader`
1011
- Disable two clippy warnings in `array_proxy.rs`
1112

1213
## [v0.23.1] - 2022-04-29

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ This project is developed and maintained by the [Tools team][team].
1313

1414
## Minimum Supported Rust Version (MSRV)
1515

16-
The **generated code** is guaranteed to compile on stable Rust 1.46.0 and up.
16+
The **generated code** is guaranteed to compile on stable Rust 1.51.0 and up.
1717

18-
If you encounter compilation errors on any stable version newer than 1.46.0, please open an issue.
18+
If you encounter compilation errors on any stable version newer than 1.51.0, please open an issue.
1919

2020
# Testing Locally
2121

ci/script.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ main() {
479479
echo 'version = "0.3.0"' >> $td/Cargo.toml
480480

481481
# Test MSP430
482-
test_svd_for_target msp430 https://raw.githubusercontent.com/pftbest/msp430g2553/v0.3.0-svd/msp430g2553.svd
482+
#test_svd_for_target msp430 https://raw.githubusercontent.com/pftbest/msp430g2553/v0.3.0-svd/msp430g2553.svd
483483
;;
484484

485485
# Community-provided RISC-V SVDs

src/generate/device.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::svd::{array::names, Device, Peripheral};
2+
use crate::util::U32Ext;
23
use proc_macro2::{Ident, Span, TokenStream};
34
use quote::{quote, ToTokens};
45

@@ -147,10 +148,15 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
147148
});
148149
}
149150

151+
let reg_sizes = util::get_register_sizes(d);
152+
150153
let generic_file = std::str::from_utf8(include_bytes!("generic.rs"))?;
151154
if config.generic_mod {
152155
let mut file = File::create(config.output_dir.join("generic.rs"))?;
153156
writeln!(file, "{}", generic_file)?;
157+
for ty in reg_sizes {
158+
writeln!(file, "impl_proxy!({});", ty.size_to_str()?)?;
159+
}
154160
if config.target == Target::Msp430 && config.nightly {
155161
let msp430_atomic_file =
156162
std::str::from_utf8(include_bytes!("generic_msp430_atomic.rs"))?;
@@ -171,6 +177,10 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
171177
}
172178
} else {
173179
let mut tokens = syn::parse_file(generic_file)?.into_token_stream();
180+
for ty in reg_sizes {
181+
let ty = Ident::new(ty.size_to_str()?, Span::call_site());
182+
tokens.extend(quote! { impl_proxy!(#ty); });
183+
}
174184
if config.target == Target::Msp430 && config.nightly {
175185
let msp430_atomic_file =
176186
std::str::from_utf8(include_bytes!("generic_msp430_atomic.rs"))?;

src/generate/generic.rs

Lines changed: 225 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -223,14 +223,13 @@ impl<REG: RegisterSpec> W<REG> {
223223
}
224224
}
225225

226-
/// Field reader.
227-
///
228-
/// Result of the `read` methods of fields.
229-
pub struct FieldReader<U> {
226+
#[doc(hidden)]
227+
pub struct FieldReaderRaw<U, T> {
230228
pub(crate) bits: U,
229+
_reg: marker::PhantomData<T>,
231230
}
232231

233-
impl<U> FieldReader<U>
232+
impl<U, FI> FieldReaderRaw<U, FI>
234233
where
235234
U: Copy,
236235
{
@@ -240,28 +239,70 @@ where
240239
pub(crate) fn new(bits: U) -> Self {
241240
Self {
242241
bits,
242+
_reg: marker::PhantomData,
243243
}
244244
}
245+
}
246+
247+
#[doc(hidden)]
248+
pub struct BitReaderRaw<T> {
249+
pub(crate) bits: bool,
250+
_reg: marker::PhantomData<T>,
251+
}
252+
253+
impl<FI> BitReaderRaw<FI> {
254+
/// Creates a new instance of the reader.
255+
#[allow(unused)]
256+
#[inline(always)]
257+
pub(crate) fn new(bits: bool) -> Self {
258+
Self {
259+
bits,
260+
_reg: marker::PhantomData,
261+
}
262+
}
263+
}
264+
265+
/// Field reader.
266+
///
267+
/// Result of the `read` methods of fields.
268+
pub type FieldReader<U, FI> = FieldReaderRaw<U, FI>;
245269

270+
/// Bit-wise field reader
271+
pub type BitReader<FI> = BitReaderRaw<FI>;
272+
273+
impl<U, FI> FieldReader<U, FI>
274+
where
275+
U: Copy,
276+
{
246277
/// Reads raw bits from field.
247278
#[inline(always)]
248279
pub fn bits(&self) -> U {
249280
self.bits
250281
}
251282
}
252283

253-
impl<U, T> PartialEq<T> for FieldReader<U>
284+
impl<U, FI> PartialEq<FI> for FieldReader<U, FI>
254285
where
255286
U: PartialEq,
256-
T: Copy + Into<U>,
287+
FI: Copy + Into<U>,
288+
{
289+
#[inline(always)]
290+
fn eq(&self, other: &FI) -> bool {
291+
self.bits.eq(&(*other).into())
292+
}
293+
}
294+
295+
impl<FI> PartialEq<FI> for BitReader<FI>
296+
where
297+
FI: Copy + Into<bool>,
257298
{
258299
#[inline(always)]
259-
fn eq(&self, other: &T) -> bool {
300+
fn eq(&self, other: &FI) -> bool {
260301
self.bits.eq(&(*other).into())
261302
}
262303
}
263304

264-
impl FieldReader<bool> {
305+
impl<FI> BitReader<FI> {
265306
/// Value of the field as raw bits.
266307
#[inline(always)]
267308
pub fn bit(&self) -> bool {
@@ -278,3 +319,178 @@ impl FieldReader<bool> {
278319
self.bit()
279320
}
280321
}
322+
323+
#[doc(hidden)]
324+
pub struct Safe;
325+
#[doc(hidden)]
326+
pub struct Unsafe;
327+
328+
#[doc(hidden)]
329+
pub struct FieldWriterRaw<'a, U, REG, N, FI, Safety, const WI: u8, const O: u8>
330+
where
331+
REG: Writable + RegisterSpec<Ux = U>,
332+
FI: Into<N>,
333+
{
334+
pub(crate) w: &'a mut REG::Writer,
335+
_field: marker::PhantomData<(N, FI, Safety)>,
336+
}
337+
338+
impl<'a, U, REG, N, FI, Safety, const WI: u8, const O: u8> FieldWriterRaw<'a, U, REG, N, FI, Safety, WI, O>
339+
where
340+
REG: Writable + RegisterSpec<Ux = U>,
341+
FI: Into<N>,
342+
{
343+
/// Creates a new instance of the writer
344+
#[allow(unused)]
345+
#[inline(always)]
346+
pub(crate) fn new(w: &'a mut REG::Writer) -> Self {
347+
Self {
348+
w,
349+
_field: marker::PhantomData,
350+
}
351+
}
352+
}
353+
354+
#[doc(hidden)]
355+
pub struct BitWriterRaw<'a, U, REG, FI, const O: u8>
356+
where
357+
REG: Writable + RegisterSpec<Ux = U>,
358+
FI: Into<bool>,
359+
{
360+
pub(crate) w: &'a mut REG::Writer,
361+
_field: marker::PhantomData<FI>,
362+
}
363+
364+
impl<'a, U, REG, FI, const O: u8> BitWriterRaw<'a, U, REG, FI, O>
365+
where
366+
REG: Writable + RegisterSpec<Ux = U>,
367+
FI: Into<bool>,
368+
{
369+
/// Creates a new instance of the writer
370+
#[allow(unused)]
371+
#[inline(always)]
372+
pub(crate) fn new(w: &'a mut REG::Writer) -> Self {
373+
Self {
374+
w,
375+
_field: marker::PhantomData,
376+
}
377+
}
378+
}
379+
380+
/// Write field Proxy with unsafe `bits`
381+
pub type FieldWriter<'a, U, REG, N, FI, const WI: u8, const O: u8> = FieldWriterRaw<'a, U, REG, N, FI, Unsafe, WI, O>;
382+
/// Write field Proxy with safe `bits`
383+
pub type FieldWriterSafe<'a, U, REG, N, FI, const WI: u8, const O: u8> = FieldWriterRaw<'a, U, REG, N, FI, Safe, WI, O>;
384+
385+
/// Bit-wise write field proxy
386+
pub type BitWriter<'a, U, REG, FI, const O: u8> = BitWriterRaw<'a, U, REG, FI, O>;
387+
388+
389+
impl<'a, U, REG, N, FI, const WI: u8, const OF: u8> FieldWriter<'a, U, REG, N, FI, WI, OF>
390+
where
391+
REG: Writable + RegisterSpec<Ux = U>,
392+
FI: Into<N>,
393+
{
394+
/// Field width
395+
pub const WIDTH: u8 = WI;
396+
/// Field offset
397+
pub const OFFSET: u8 = OF;
398+
}
399+
400+
impl<'a, U, REG, N, FI, const WI: u8, const OF: u8> FieldWriterSafe<'a, U, REG, N, FI, WI, OF>
401+
where
402+
REG: Writable + RegisterSpec<Ux = U>,
403+
FI: Into<N>,
404+
{
405+
/// Field width
406+
pub const WIDTH: u8 = WI;
407+
/// Field offset
408+
pub const OFFSET: u8 = OF;
409+
}
410+
411+
impl<'a, U, REG, FI, const OF: u8> BitWriter<'a, U, REG, FI, OF>
412+
where
413+
REG: Writable + RegisterSpec<Ux = U>,
414+
FI: Into<bool>,
415+
{
416+
/// Field width
417+
pub const WIDTH: u8 = 1;
418+
/// Field offset
419+
pub const OFFSET: u8 = OF;
420+
}
421+
422+
macro_rules! impl_proxy {
423+
($U:ty) => {
424+
impl<'a, REG, N, FI, const WI: u8, const OF: u8> FieldWriter<'a, $U, REG, N, FI, WI, OF>
425+
where
426+
REG: Writable + RegisterSpec<Ux = $U>,
427+
N: Into<$U>,
428+
FI: Into<N>,
429+
{
430+
const MASK: $U = <$U>::MAX >> (<$U>::MAX.leading_ones() as u8 - { WI });
431+
/// Writes raw bits to the field
432+
///
433+
/// # Safety
434+
///
435+
/// Passing incorrect value can cause undefined behaviour. See reference manual
436+
#[inline(always)]
437+
pub unsafe fn bits(self, value: N) -> &'a mut REG::Writer {
438+
self.w.bits =
439+
(self.w.bits & !(Self::MASK << { OF })) | ((value.into() & Self::MASK) << { OF });
440+
self.w
441+
}
442+
/// Writes `variant` to the field
443+
#[inline(always)]
444+
pub fn variant(self, variant: FI) -> &'a mut REG::Writer {
445+
unsafe { self.bits(variant.into()) }
446+
}
447+
}
448+
impl<'a, REG, N, FI, const WI: u8, const OF: u8> FieldWriterSafe<'a, $U, REG, N, FI, WI, OF>
449+
where
450+
REG: Writable + RegisterSpec<Ux = $U>,
451+
N: Into<$U>,
452+
FI: Into<N>,
453+
{
454+
const MASK: $U = <$U>::MAX >> (<$U>::MAX.leading_ones() as u8 - { WI });
455+
/// Writes raw bits to the field
456+
#[inline(always)]
457+
pub fn bits(self, value: N) -> &'a mut REG::Writer {
458+
self.w.bits =
459+
(self.w.bits & !(Self::MASK << { OF })) | ((value.into() & Self::MASK) << { OF });
460+
self.w
461+
}
462+
/// Writes `variant` to the field
463+
#[inline(always)]
464+
pub fn variant(self, variant: FI) -> &'a mut REG::Writer {
465+
self.bits(variant.into())
466+
}
467+
}
468+
impl<'a, REG, FI, const OF: u8> BitWriter<'a, $U, REG, FI, OF>
469+
where
470+
REG: Writable + RegisterSpec<Ux = $U>,
471+
FI: Into<bool>,
472+
{
473+
/// Writes bit to the field
474+
#[inline(always)]
475+
pub fn bit(self, value: bool) -> &'a mut REG::Writer {
476+
self.w.bits = (self.w.bits & !(1 << { OF })) | ((<$U>::from(value) & 1) << { OF });
477+
self.w
478+
}
479+
/// Writes `variant` to the field
480+
#[inline(always)]
481+
pub fn variant(self, variant: FI) -> &'a mut REG::Writer {
482+
self.bit(variant.into())
483+
}
484+
/// Sets the field bit
485+
#[inline(always)]
486+
pub fn set_bit(self) -> &'a mut REG::Writer {
487+
self.bit(true)
488+
}
489+
/// Clears the field bit
490+
#[inline(always)]
491+
pub fn clear_bit(self) -> &'a mut REG::Writer {
492+
self.bit(false)
493+
}
494+
}
495+
}
496+
}

0 commit comments

Comments
 (0)