Skip to content

Commit

Permalink
use ConstZero instead of Default
Browse files Browse the repository at this point in the history
  • Loading branch information
burrbull committed Dec 11, 2024
1 parent b6ef0b0 commit f2dfdef
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 44 deletions.
20 changes: 16 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
on:
push:
branches: master
branches: [master]
pull_request:
merge_group:

Expand Down Expand Up @@ -83,7 +83,11 @@ jobs:
- { rust: stable, vendor: Spansion, options: "--atomics" }
- { rust: stable, vendor: STMicro, options: "" }
- { rust: stable, vendor: STMicro, options: "--atomics" }
- { rust: stable, vendor: STM32-patched, options: "--strict -f enum_value::p: --max-cluster-size --atomics --atomics-feature atomics --impl-debug --impl-defmt defmt" }
- {
rust: stable,
vendor: STM32-patched,
options: "--strict -f enum_value::p: --max-cluster-size --atomics --atomics-feature atomics --impl-debug --impl-defmt defmt",
}
- { rust: stable, vendor: Toshiba, options: all }
- { rust: stable, vendor: Toshiba, options: "" }
# Test MSRV
Expand All @@ -92,8 +96,16 @@ jobs:
- { rust: nightly, vendor: MSP430, options: "--atomics" }
- { rust: nightly, vendor: MSP430, options: "" }
# Workaround for _1token0
- { rust: nightly-2024-09-25, vendor: Espressif, options: "--atomics --ident-formats-theme legacy" }
- { rust: nightly-2024-09-25, vendor: Espressif, options: "--ident-format register:::Reg" }
- {
rust: nightly-2024-09-25,
vendor: Espressif,
options: "--atomics --ident-formats-theme legacy",
}
- {
rust: nightly-2024-09-25,
vendor: Espressif,
options: "--ident-format register:::Reg",
}

steps:
- uses: actions/checkout@v4
Expand Down
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased]

- Use `ConstZero::ZERO` instead of `Default::default()` to force const

## [v0.35.0] - 2024-11-12

- Add `crate_path` setting
Expand Down Expand Up @@ -930,8 +932,7 @@ peripheral.register.write(|w| w.field().set());

- Initial version of the `svd2rust` tool

[Unreleased]: https://github.com/rust-embedded/svd2rust/compare/v0.35.0...HEAD
[v0.35.0]: https://github.com/rust-embedded/svd2rust/compare/v0.34.0...v0.35.0
[Unreleased]: https://github.com/rust-embedded/svd2rust/compare/v0.34.0...HEAD
[v0.34.0]: https://github.com/rust-embedded/svd2rust/compare/v0.33.5...v0.34.0
[v0.33.5]: https://github.com/rust-embedded/svd2rust/compare/v0.33.4...v0.33.5
[v0.33.4]: https://github.com/rust-embedded/svd2rust/compare/v0.33.3...v0.33.4
Expand Down
1 change: 1 addition & 0 deletions ci/script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ main() {
echo 'cortex-m = "0.7.7"' >> $td/Cargo.toml
echo 'cortex-m-rt = "0.7.3"' >> $td/Cargo.toml
echo 'vcell = "0.1.3"' >> $td/Cargo.toml
echo 'num-traits = { version = "0.2.19", default-features = false }' >> $td/Cargo.toml
if [[ "$options" == *"--atomics"* ]]; then
echo 'portable-atomic = { version = "1.4", default-features = false }' >> $td/Cargo.toml
fi
Expand Down
6 changes: 5 additions & 1 deletion ci/svd2rust-regress/src/svd_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ use std::{
path::Path,
};

const CRATES_ALL: &[&str] = &["critical-section = \"1.0\"", "vcell = \"0.1.2\""];
const CRATES_ALL: &[&str] = &[
"critical-section = \"1.0\"",
"vcell = \"0.1.2\"",
"num-traits = { version = \"0.2.19\", default-features = false }",
];
const CRATES_MSP430: &[&str] = &["msp430 = \"0.4.0\"", "msp430-rt = \"0.4.0\""];
const CRATES_ATOMICS: &[&str] =
&["portable-atomic = { version = \"0.3.16\", default-features = false }"];
Expand Down
49 changes: 25 additions & 24 deletions src/generate/generic.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use core::marker;
use num_traits::{ConstOne, ConstZero};

/// Raw register type (`u8`, `u16`, `u32`, ...)
pub trait RawReg:
Copy
+ Default
+ ConstOne
+ ConstZero
+ From<bool>
+ core::ops::BitOr<Output = Self>
+ core::ops::BitAnd<Output = Self>
Expand All @@ -14,8 +16,6 @@ pub trait RawReg:
{
/// Mask for bits of width `WI`
fn mask<const WI: u8>() -> Self;
/// Mask for bits of width 1
fn one() -> Self;
}

macro_rules! raw_reg {
Expand All @@ -25,10 +25,6 @@ macro_rules! raw_reg {
fn mask<const WI: u8>() -> Self {
$mask::<WI>()
}
#[inline(always)]
fn one() -> Self {
1
}
}
const fn $mask<const WI: u8>() -> $U {
<$U>::MAX >> ($size - WI)
Expand Down Expand Up @@ -74,10 +70,10 @@ pub trait Writable: RegisterSpec {
type Safety;

/// Specifies the register bits that are not changed if you pass `1` and are changed if you pass `0`
const ZERO_TO_MODIFY_FIELDS_BITMAP: Self::Ux;
const ZERO_TO_MODIFY_FIELDS_BITMAP: Self::Ux = Self::Ux::ZERO;

/// Specifies the register bits that are not changed if you pass `0` and are changed if you pass `1`
const ONE_TO_MODIFY_FIELDS_BITMAP: Self::Ux;
const ONE_TO_MODIFY_FIELDS_BITMAP: Self::Ux = Self::Ux::ZERO;
}

/// Reset value of the register.
Expand All @@ -86,7 +82,7 @@ pub trait Writable: RegisterSpec {
/// register by using the `reset` method.
pub trait Resettable: RegisterSpec {
/// Reset value of the register.
const RESET_VALUE: Self::Ux;
const RESET_VALUE: Self::Ux = Self::Ux::ZERO;

/// Reset value of the register.
#[inline(always)]
Expand Down Expand Up @@ -247,7 +243,10 @@ impl<REG: Writable> W<REG> {
self
}
}
impl<REG> W<REG> where REG: Writable<Safety = Safe> {
impl<REG> W<REG>
where
REG: Writable<Safety = Safe>,
{
/// Writes raw bits to the register.
#[inline(always)]
pub fn set(&mut self, bits: REG::Ux) -> &mut Self {
Expand Down Expand Up @@ -335,7 +334,8 @@ pub struct RangeFrom<const MIN: u64>;
pub struct RangeTo<const MAX: u64>;

/// Write field Proxy
pub type FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe> = raw::FieldWriter<'a, REG, WI, FI, Safety>;
pub type FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe> =
raw::FieldWriter<'a, REG, WI, FI, Safety>;

impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
where
Expand Down Expand Up @@ -390,7 +390,8 @@ where
}
}

impl<'a, REG, const WI: u8, FI, const MIN: u64, const MAX: u64> FieldWriter<'a, REG, WI, FI, Range<MIN, MAX>>
impl<'a, REG, const WI: u8, FI, const MIN: u64, const MAX: u64>
FieldWriter<'a, REG, WI, FI, Range<MIN, MAX>>
where
REG: Writable + RegisterSpec,
FI: FieldSpec,
Expand Down Expand Up @@ -478,7 +479,7 @@ macro_rules! bit_proxy {
pub const fn width(&self) -> u8 {
Self::WIDTH
}

/// Field offset
#[inline(always)]
pub const fn offset(&self) -> u8 {
Expand All @@ -488,8 +489,8 @@ macro_rules! bit_proxy {
/// Writes bit to the field
#[inline(always)]
pub fn bit(self, value: bool) -> &'a mut W<REG> {
self.w.bits &= !(REG::Ux::one() << self.o);
self.w.bits |= (REG::Ux::from(value) & REG::Ux::one()) << self.o;
self.w.bits &= !(REG::Ux::ONE << self.o);
self.w.bits |= (REG::Ux::from(value) & REG::Ux::ONE) << self.o;
self.w
}
/// Writes `variant` to the field
Expand Down Expand Up @@ -517,13 +518,13 @@ where
/// Sets the field bit
#[inline(always)]
pub fn set_bit(self) -> &'a mut W<REG> {
self.w.bits |= REG::Ux::one() << self.o;
self.w.bits |= REG::Ux::ONE << self.o;
self.w
}
/// Clears the field bit
#[inline(always)]
pub fn clear_bit(self) -> &'a mut W<REG> {
self.w.bits &= !(REG::Ux::one() << self.o);
self.w.bits &= !(REG::Ux::ONE << self.o);
self.w
}
}
Expand All @@ -536,7 +537,7 @@ where
/// Sets the field bit
#[inline(always)]
pub fn set_bit(self) -> &'a mut W<REG> {
self.w.bits |= REG::Ux::one() << self.o;
self.w.bits |= REG::Ux::ONE << self.o;
self.w
}
}
Expand All @@ -549,7 +550,7 @@ where
/// Clears the field bit
#[inline(always)]
pub fn clear_bit(self) -> &'a mut W<REG> {
self.w.bits &= !(REG::Ux::one() << self.o);
self.w.bits &= !(REG::Ux::ONE << self.o);
self.w
}
}
Expand All @@ -562,7 +563,7 @@ where
///Clears the field bit by passing one
#[inline(always)]
pub fn clear_bit_by_one(self) -> &'a mut W<REG> {
self.w.bits |= REG::Ux::one() << self.o;
self.w.bits |= REG::Ux::ONE << self.o;
self.w
}
}
Expand All @@ -575,7 +576,7 @@ where
///Sets the field bit by passing zero
#[inline(always)]
pub fn set_bit_by_zero(self) -> &'a mut W<REG> {
self.w.bits &= !(REG::Ux::one() << self.o);
self.w.bits &= !(REG::Ux::ONE << self.o);
self.w
}
}
Expand All @@ -588,7 +589,7 @@ where
///Toggle the field bit by passing one
#[inline(always)]
pub fn toggle_bit(self) -> &'a mut W<REG> {
self.w.bits |= REG::Ux::one() << self.o;
self.w.bits |= REG::Ux::ONE << self.o;
self.w
}
}
Expand All @@ -601,7 +602,7 @@ where
///Toggle the field bit by passing zero
#[inline(always)]
pub fn toggle_bit(self) -> &'a mut W<REG> {
self.w.bits &= !(REG::Ux::one() << self.o);
self.w.bits &= !(REG::Ux::ONE << self.o);
self.w
}
}
8 changes: 4 additions & 4 deletions src/generate/generic_atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ mod atomic {

impl<REG: Readable + Writable> Reg<REG>
where
REG::Ux: AtomicOperations
REG::Ux: AtomicOperations,
{
/// Set high every bit in the register that was set in the write proxy. Leave other bits
/// untouched. The write is done in a single atomic instruction.
Expand All @@ -53,7 +53,7 @@ mod atomic {
F: FnOnce(&mut W<REG>) -> &mut W<REG>,
{
let bits = f(&mut W {
bits: Default::default(),
bits: REG::Ux::ZERO,
_reg: marker::PhantomData,
})
.bits;
Expand All @@ -72,7 +72,7 @@ mod atomic {
F: FnOnce(&mut W<REG>) -> &mut W<REG>,
{
let bits = f(&mut W {
bits: !REG::Ux::default(),
bits: !REG::Ux::ZERO,
_reg: marker::PhantomData,
})
.bits;
Expand All @@ -91,7 +91,7 @@ mod atomic {
F: FnOnce(&mut W<REG>) -> &mut W<REG>,
{
let bits = f(&mut W {
bits: Default::default(),
bits: REG::Ux::ZERO,
_reg: marker::PhantomData,
})
.bits;
Expand Down
4 changes: 2 additions & 2 deletions src/generate/generic_reg_vcell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ impl<REG: Writable> Reg<REG> {
F: FnOnce(&mut W<REG>) -> &mut W<REG>,
{
let value = f(&mut W {
bits: REG::Ux::default(),
bits: REG::Ux::ZERO,
_reg: marker::PhantomData,
})
.bits;
Expand All @@ -169,7 +169,7 @@ impl<REG: Writable> Reg<REG> {
F: FnOnce(&mut W<REG>) -> T,
{
let mut writer = W {
bits: REG::Ux::default(),
bits: REG::Ux::ZERO,
_reg: marker::PhantomData,
};

Expand Down
21 changes: 14 additions & 7 deletions src/generate/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,24 +413,31 @@ pub fn render_register_mod(

let doc = format!("`write(|w| ..)` method takes [`{mod_ty}::W`](W) writer structure",);

let zero_to_modify_fields_bitmap = util::hex(zero_to_modify_fields_bitmap);
let one_to_modify_fields_bitmap = util::hex(one_to_modify_fields_bitmap);
let zero_to_modify_fields_bitmap = util::hex_nonzero(zero_to_modify_fields_bitmap)
.map(|bm| quote!(const ZERO_TO_MODIFY_FIELDS_BITMAP: #rty = #bm;));
let one_to_modify_fields_bitmap = util::hex_nonzero(one_to_modify_fields_bitmap)
.map(|bm| quote!(const ONE_TO_MODIFY_FIELDS_BITMAP: #rty = #bm;));

mod_items.extend(quote! {
#[doc = #doc]
impl crate::Writable for #regspec_ty {
type Safety = crate::#safe_ty;
const ZERO_TO_MODIFY_FIELDS_BITMAP: #rty = #zero_to_modify_fields_bitmap;
const ONE_TO_MODIFY_FIELDS_BITMAP: #rty = #one_to_modify_fields_bitmap;
#zero_to_modify_fields_bitmap
#one_to_modify_fields_bitmap
}
});
}
if let Some(rv) = properties.reset_value.map(util::hex) {
let doc = format!("`reset()` method sets {} to value {rv}", register.name);
if let Some(rv) = properties.reset_value.map(util::hex_nonzero) {
let doc = if let Some(rv) = &rv {
format!("`reset()` method sets {} to value {rv}", register.name)
} else {
format!("`reset()` method sets {} to value 0", register.name)
};
let rv = rv.map(|rv| quote!(const RESET_VALUE: #rty = #rv;));
mod_items.extend(quote! {
#[doc = #doc]
impl crate::Resettable for #regspec_ty {
const RESET_VALUE: #rty = #rv;
#rv
}
});
}
Expand Down
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
//! - [`cortex-m`](https://crates.io/crates/cortex-m) >=v0.7.6
//! - [`cortex-m-rt`](https://crates.io/crates/cortex-m-rt) >=v0.6.13
//! - [`vcell`](https://crates.io/crates/vcell) >=v0.1.2
//! - [`num-traits`](https://crates.io/crates/const-default) >=v0.2.18
//!
//! Furthermore, the "device" feature of `cortex-m-rt` must be enabled when the `rt` feature
//! is enabled. The `Cargo.toml` of the device crate will look like this:
Expand Down Expand Up @@ -126,6 +127,7 @@
//! - [`msp430`](https://crates.io/crates/msp430) v0.4.x
//! - [`msp430-rt`](https://crates.io/crates/msp430-rt) v0.4.x
//! - [`vcell`](https://crates.io/crates/vcell) v0.1.x
//! - [`num-traits`](https://crates.io/crates/const-default) v0.2.x
//!
//! The "device" feature of `msp430-rt` must be enabled when the `rt` feature is
//! enabled. The `Cargo.toml` of the device crate will look like this:
Expand All @@ -136,6 +138,7 @@
//! msp430 = "0.4.0"
//! msp430-rt = { version = "0.4.0", optional = true }
//! vcell = "0.1.0"
//! num-traits = { version = "0.2.19", default-features = false }
//!
//! [features]
//! rt = ["msp430-rt/device"]
Expand All @@ -153,6 +156,7 @@
//! - [`riscv-peripheral`](https://crates.io/crates/riscv-peripheral) v0.2.x (if target is RISC-V and has standard peripherals)
//! - [`riscv-rt`](https://crates.io/crates/riscv-rt) v0.13.x (if target is RISC-V)
//! - [`vcell`](https://crates.io/crates/vcell) v0.1.x
//! - [`num-traits`](https://crates.io/crates/const-default) v0.2.x
//!
//! The `*-rt` dependencies must be optional only enabled when the `rt` feature is enabled.
//! If target is RISC-V and supports vectored mode, you must include a feature `v-trap` to activate `riscv-rt/v-trap`.
Expand All @@ -165,6 +169,7 @@
//! riscv-peripheral = "0.2.0"
//! riscv-rt = { version = "0.13.0", optional = true }
//! vcell = "0.1.0"
//! num-traits = { version = "0.2.19", default-features = false }
//!
//! [features]
//! rt = ["riscv-rt"]
Expand Down
Loading

0 comments on commit f2dfdef

Please sign in to comment.