diff --git a/svd-encoder/src/config.rs b/svd-encoder/src/config.rs index 0292d17d..2c24ae23 100644 --- a/svd-encoder/src/config.rs +++ b/svd-encoder/src/config.rs @@ -130,7 +130,7 @@ where NumberFormat::UpperHex => format!("{:#X}", value), NumberFormat::UpperHex8 => format!("{:#010X}", value), NumberFormat::UpperHex16 => { - if value.into() > std::u32::MAX as u64 { + if value.into() > u32::MAX as u64 { format!("{:#018X}", value) } else { format!("{:#010X}", value) @@ -139,7 +139,7 @@ where NumberFormat::LowerHex => format!("{:#x}", value), NumberFormat::LowerHex8 => format!("{:#010x}", value), NumberFormat::LowerHex16 => { - if value.into() > std::u32::MAX as u64 { + if value.into() > u32::MAX as u64 { format!("{:#018x}", value) } else { format!("{:#010x}", value) diff --git a/svd-rs/CHANGELOG.md b/svd-rs/CHANGELOG.md index c8af63fd..c1931b9f 100644 --- a/svd-rs/CHANGELOG.md +++ b/svd-rs/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +- use `hex` format for address when serialize - Revert the `riscv` elements, as well as the `unstable-riscv` feature. ## [v0.14.9] - 2024-08-20 @@ -143,4 +144,3 @@ Previous versions in common [changelog](../CHANGELOG.md). [v0.11.2]: https://github.com/rust-embedded/svd/compare/svd-rs-v0.11.1...svd-rs-v0.11.2 [v0.11.1]: https://github.com/rust-embedded/svd/compare/v0.11.0...svd-rs-v0.11.1 [v0.11.0]: https://github.com/rust-embedded/svd/compare/v0.10.2...v0.11.0 - diff --git a/svd-rs/src/addressblock.rs b/svd-rs/src/addressblock.rs index 6e5d5def..930d8624 100644 --- a/svd-rs/src/addressblock.rs +++ b/svd-rs/src/addressblock.rs @@ -6,8 +6,10 @@ use super::{BuildError, Protection, SvdError, ValidateLevel}; #[non_exhaustive] pub struct AddressBlock { /// Specifies the start address of an address block relative to the peripheral [`baseAddress`](crate::Peripheral::base_address). + #[cfg_attr(feature = "serde", serde(serialize_with = "crate::as_hex"))] pub offset: u32, /// Specifies the number of [`addressUnitBits`](crate::Device::address_unit_bits) being covered by this address block. + #[cfg_attr(feature = "serde", serde(serialize_with = "crate::as_hex"))] pub size: u32, /// Usage of the address block. pub usage: AddressBlockUsage, diff --git a/svd-rs/src/cluster.rs b/svd-rs/src/cluster.rs index f9c15ab0..d9a4aef5 100644 --- a/svd-rs/src/cluster.rs +++ b/svd-rs/src/cluster.rs @@ -55,6 +55,7 @@ pub struct ClusterInfo { pub header_struct_name: Option, /// Cluster address relative to the `baseAddress` of the peripheral + #[cfg_attr(feature = "serde", serde(serialize_with = "crate::as_hex"))] pub address_offset: u32, /// Default properties for all registers diff --git a/svd-rs/src/lib.rs b/svd-rs/src/lib.rs index fe895426..80e4f814 100644 --- a/svd-rs/src/lib.rs +++ b/svd-rs/src/lib.rs @@ -95,22 +95,17 @@ pub mod datatype; pub use self::datatype::DataType; /// Level of validation -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] pub enum ValidateLevel { /// No validation. Disabled, /// Weak validation. + #[default] Weak, /// Strict validation. Strict, } -impl Default for ValidateLevel { - fn default() -> Self { - ValidateLevel::Weak - } -} - impl ValidateLevel { /// Returns true if validation is disabled. pub fn is_disabled(self) -> bool { @@ -281,3 +276,79 @@ where T::description(*self) } } + +#[cfg(feature = "serde")] +struct Hex(T); + +#[cfg(feature = "serde")] +impl serde::Serialize for Hex { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let n = self.0; + let (h4, h3, h2, h1) = ( + (n >> 48) & 0xffff, + (n >> 32) & 0xffff, + (n >> 16) & 0xffff, + n & 0xffff, + ); + let f = if h4 != 0 { + format!("0x{h4:04x}{h3:04x}{h2:04x}{h1:04x}") + } else if h3 != 0 { + format!("0x{h3:04x}{h2:04x}{h1:04x}") + } else if h2 != 0 { + format!("0x{h2:04x}{h1:04x}") + } else if h1 & 0xff00 != 0 { + format!("0x{h1:04x}") + } else if h1 != 0 { + format!("0x{:02x}", h1 & 0xff) + } else { + "0".to_string() + }; + serializer.serialize_str(&f) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for Hex { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let n = self.0; + let (h2, h1) = ((n >> 16) & 0xffff, n & 0xffff); + let f = if h2 != 0 { + format!("0x{h2:04x}{h1:04x}") + } else if h1 & 0xff00 != 0 { + format!("0x{h1:04x}") + } else if h1 != 0 { + format!("0x{:02x}", h1 & 0xff) + } else { + "0".to_string() + }; + serializer.serialize_str(&f) + } +} + +#[cfg(feature = "serde")] +fn as_hex(n: &T, s: S) -> Result +where + S: serde::Serializer, + T: Copy, + Hex: serde::Serialize, +{ + use serde::Serialize; + Hex(*n).serialize(s) +} + +#[cfg(feature = "serde")] +fn as_opt_hex(n: &Option, s: S) -> Result +where + S: serde::Serializer, + T: Copy, + Hex: serde::Serialize, +{ + use serde::Serialize; + (*n).map(Hex).serialize(s) +} diff --git a/svd-rs/src/peripheral.rs b/svd-rs/src/peripheral.rs index 1e4a0a72..9827315a 100644 --- a/svd-rs/src/peripheral.rs +++ b/svd-rs/src/peripheral.rs @@ -89,6 +89,7 @@ pub struct PeripheralInfo { pub header_struct_name: Option, /// Lowest address reserved or used by the peripheral + #[cfg_attr(feature = "serde", serde(serialize_with = "crate::as_hex"))] pub base_address: u64, /// Default properties for all registers diff --git a/svd-rs/src/register.rs b/svd-rs/src/register.rs index 0afdf32c..99ab32e3 100644 --- a/svd-rs/src/register.rs +++ b/svd-rs/src/register.rs @@ -60,6 +60,7 @@ pub struct RegisterInfo { pub alternate_register: Option, /// Define the address offset relative to the enclosing element + #[cfg_attr(feature = "serde", serde(serialize_with = "crate::as_hex"))] pub address_offset: u32, /// Specifies register size, access permission and reset value diff --git a/svd-rs/src/registerproperties.rs b/svd-rs/src/registerproperties.rs index 3f119c18..39b426e0 100644 --- a/svd-rs/src/registerproperties.rs +++ b/svd-rs/src/registerproperties.rs @@ -26,7 +26,11 @@ pub struct RegisterProperties { /// Bit-width of register #[cfg_attr( feature = "serde", - serde(default, skip_serializing_if = "Option::is_none") + serde( + default, + skip_serializing_if = "Option::is_none", + serialize_with = "crate::as_opt_hex" + ) )] pub size: Option, @@ -47,14 +51,22 @@ pub struct RegisterProperties { /// Register value at RESET #[cfg_attr( feature = "serde", - serde(default, skip_serializing_if = "Option::is_none") + serde( + default, + skip_serializing_if = "Option::is_none", + serialize_with = "crate::as_opt_hex" + ) )] pub reset_value: Option, /// Define which register bits have a defined reset value #[cfg_attr( feature = "serde", - serde(default, skip_serializing_if = "Option::is_none") + serde( + default, + skip_serializing_if = "Option::is_none", + serialize_with = "crate::as_opt_hex" + ) )] pub reset_mask: Option, } @@ -133,7 +145,7 @@ pub(crate) fn check_reset_value( mask: Option, lvl: ValidateLevel, ) -> Result<(), Error> { - const MAX_BITS: u32 = core::u64::MAX.count_ones(); + const MAX_BITS: u32 = u64::MAX.count_ones(); if let (Some(size), Some(value)) = (size, value) { if MAX_BITS - value.leading_zeros() > size {