From f17d21bff43f9b5d8aebfab1d703541d3be7fad0 Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Wed, 28 Feb 2024 21:25:19 +0300 Subject: [PATCH] add Datatype --- svd-encoder/src/datatype.rs | 11 +++++ svd-encoder/src/lib.rs | 1 + svd-encoder/src/register.rs | 4 ++ svd-parser/src/datatype.rs | 14 ++++++ svd-parser/src/device.rs | 4 +- svd-parser/src/lib.rs | 3 ++ svd-parser/src/register.rs | 3 +- svd-rs/CHANGELOG.md | 2 + svd-rs/src/datatype.rs | 88 +++++++++++++++++++++++++++++++++++++ svd-rs/src/lib.rs | 4 ++ svd-rs/src/register.rs | 21 ++++++++- 11 files changed, 150 insertions(+), 5 deletions(-) create mode 100644 svd-encoder/src/datatype.rs create mode 100644 svd-parser/src/datatype.rs create mode 100644 svd-rs/src/datatype.rs diff --git a/svd-encoder/src/datatype.rs b/svd-encoder/src/datatype.rs new file mode 100644 index 00000000..db550b46 --- /dev/null +++ b/svd-encoder/src/datatype.rs @@ -0,0 +1,11 @@ +use super::{Config, Element, Encode, EncodeError, XMLNode}; + +impl Encode for crate::svd::DataType { + type Error = EncodeError; + + fn encode_with_config(&self, _config: &Config) -> Result { + let mut elem = Element::new("dataType"); + elem.children.push(XMLNode::Text(self.as_str().to_string())); + Ok(elem) + } +} diff --git a/svd-encoder/src/lib.rs b/svd-encoder/src/lib.rs index b6acf937..7f531426 100644 --- a/svd-encoder/src/lib.rs +++ b/svd-encoder/src/lib.rs @@ -88,6 +88,7 @@ mod bitrange; mod cluster; mod config; mod cpu; +mod datatype; mod device; mod dimelement; mod endian; diff --git a/svd-encoder/src/register.rs b/svd-encoder/src/register.rs index 21bf8fe7..b4b4aa84 100644 --- a/svd-encoder/src/register.rs +++ b/svd-encoder/src/register.rs @@ -63,6 +63,10 @@ impl Encode for RegisterInfo { elem.children .extend(self.properties.encode_with_config(config)?); + if let Some(v) = &self.datatype { + elem.children.push(v.encode_node_with_config(config)?); + } + if let Some(v) = &self.modified_write_values { elem.children.push(v.encode_node_with_config(config)?); } diff --git a/svd-parser/src/datatype.rs b/svd-parser/src/datatype.rs new file mode 100644 index 00000000..1701c3f1 --- /dev/null +++ b/svd-parser/src/datatype.rs @@ -0,0 +1,14 @@ +use super::*; +use crate::svd::DataType; + +impl Parse for DataType { + type Object = Self; + type Error = SVDErrorAt; + type Config = Config; + + fn parse(tree: &Node, _config: &Self::Config) -> Result { + let text = tree.get_text()?; + + Self::parse_str(text).ok_or_else(|| SVDError::InvalidDatatype(text.into()).at(tree.id())) + } +} diff --git a/svd-parser/src/device.rs b/svd-parser/src/device.rs index 2897f578..32ec8d07 100644 --- a/svd-parser/src/device.rs +++ b/svd-parser/src/device.rs @@ -1,7 +1,5 @@ use super::*; -use crate::svd::{ - cpu::Cpu, peripheral::Peripheral, registerproperties::RegisterProperties, Device, -}; +use crate::svd::{cpu::Cpu, peripheral::Peripheral, registerproperties::RegisterProperties}; /// Parses a SVD file impl Parse for Device { diff --git a/svd-parser/src/lib.rs b/svd-parser/src/lib.rs index dbd92a04..b3d22c6d 100644 --- a/svd-parser/src/lib.rs +++ b/svd-parser/src/lib.rs @@ -196,6 +196,7 @@ mod addressblock; mod bitrange; mod cluster; mod cpu; +mod datatype; mod device; mod dimelement; mod endian; @@ -247,6 +248,8 @@ pub enum SVDError { NotExpectedTag(String), #[error("Invalid RegisterCluster (expected register or cluster), found {0}")] InvalidRegisterCluster(String), + #[error("Invalid datatype variant, found {0}")] + InvalidDatatype(String), #[error("Invalid modifiedWriteValues variant, found {0}")] InvalidModifiedWriteValues(String), #[error("Invalid readAction variant, found {0}")] diff --git a/svd-parser/src/register.rs b/svd-parser/src/register.rs index ef5340a2..fa3b8920 100644 --- a/svd-parser/src/register.rs +++ b/svd-parser/src/register.rs @@ -1,6 +1,6 @@ use super::*; use crate::svd::{ - Field, ModifiedWriteValues, ReadAction, Register, RegisterInfo, RegisterProperties, + DataType, Field, ModifiedWriteValues, ReadAction, Register, RegisterInfo, RegisterProperties, WriteConstraint, }; @@ -28,6 +28,7 @@ impl Parse for RegisterInfo { .alternate_register(tree.get_child_text_opt("alternateRegister")?) .address_offset(tree.get_child_u32("addressOffset")?) .properties(RegisterProperties::parse(tree, config)?) + .datatype(optional::("dataType", tree, config)?) .modified_write_values(optional::( "modifiedWriteValues", tree, diff --git a/svd-rs/CHANGELOG.md b/svd-rs/CHANGELOG.md index 741a8b3d..fc66bfc0 100644 --- a/svd-rs/CHANGELOG.md +++ b/svd-rs/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +- Add `DataType` + ## [v0.14.8] - 2024-02-13 - add `maybe_array` constructors diff --git a/svd-rs/src/datatype.rs b/svd-rs/src/datatype.rs new file mode 100644 index 00000000..3e97258c --- /dev/null +++ b/svd-rs/src/datatype.rs @@ -0,0 +1,88 @@ +/// Register data type +#[cfg_attr( + feature = "serde", + derive(serde::Deserialize, serde::Serialize), + serde(rename_all = "snake_case") +)] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum DataType { + /// unsigned byte + U8, + /// unsigned half word + U16, + /// unsigned word + U32, + /// unsigned double word + U64, + /// signed byte + I8, + /// signed half word + I16, + /// signed world + I32, + /// signed double word + I64, + /// pointer to unsigned byte + U8Ptr, + /// pointer to unsigned half word + U16Ptr, + /// pointer to unsigned word + U32Ptr, + /// pointer to unsigned double word + U64Ptr, + /// pointer to signed byte + I8Ptr, + /// pointer to signed half word + I16Ptr, + /// pointer to signed world + I32Ptr, + /// pointer to signed double word + I64Ptr, +} + +impl DataType { + /// Parse a string into an [`DataType`] value, returning [`Option::None`] if the string is not valid. + pub fn parse_str(s: &str) -> Option { + match s { + "uint8_t" => Some(Self::U8), + "uint16_t" => Some(Self::U16), + "uint32_t" => Some(Self::U32), + "uint64_t" => Some(Self::U64), + "int8_t" => Some(Self::I8), + "int16_t" => Some(Self::I16), + "int32_t" => Some(Self::I32), + "int64_t" => Some(Self::I64), + "uint8_t *" => Some(Self::U8Ptr), + "uint16_t *" => Some(Self::U16Ptr), + "uint32_t *" => Some(Self::U32Ptr), + "uint64_t *" => Some(Self::U64Ptr), + "int8_t *" => Some(Self::I8Ptr), + "int16_t *" => Some(Self::I16Ptr), + "int32_t *" => Some(Self::I32Ptr), + "int64_t *" => Some(Self::I64Ptr), + _ => None, + } + } + + /// Convert this [`DataType`] into a static string. + pub const fn as_str(self) -> &'static str { + match self { + Self::U8 => "uint8_t", + Self::U16 => "uint16_t", + Self::U32 => "uint32_t", + Self::U64 => "uint64_t", + Self::I8 => "int8_t", + Self::I16 => "int16_t", + Self::I32 => "int32_t", + Self::I64 => "int64_t", + Self::U8Ptr => "uint8_t *", + Self::U16Ptr => "uint16_t *", + Self::U32Ptr => "uint32_t *", + Self::U64Ptr => "uint64_t *", + Self::I8Ptr => "int8_t *", + Self::I16Ptr => "int16_t *", + Self::I32Ptr => "int32_t *", + Self::I64Ptr => "int64_t *", + } + } +} diff --git a/svd-rs/src/lib.rs b/svd-rs/src/lib.rs index 7ce8d04f..fe895426 100644 --- a/svd-rs/src/lib.rs +++ b/svd-rs/src/lib.rs @@ -90,6 +90,10 @@ pub use self::readaction::ReadAction; pub mod protection; pub use self::protection::Protection; +/// DataType objects +pub mod datatype; +pub use self::datatype::DataType; + /// Level of validation #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum ValidateLevel { diff --git a/svd-rs/src/register.rs b/svd-rs/src/register.rs index c35f11ed..0afdf32c 100644 --- a/svd-rs/src/register.rs +++ b/svd-rs/src/register.rs @@ -1,6 +1,6 @@ use super::{ array::{descriptions, names}, - Access, BuildError, Description, DimElement, EmptyToNone, Field, MaybeArray, + Access, BuildError, DataType, Description, DimElement, EmptyToNone, Field, MaybeArray, ModifiedWriteValues, Name, ReadAction, RegisterProperties, SvdError, ValidateLevel, WriteConstraint, }; @@ -66,6 +66,13 @@ pub struct RegisterInfo { #[cfg_attr(feature = "serde", serde(flatten))] pub properties: RegisterProperties, + /// Register data type + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Option::is_none") + )] + pub datatype: Option, + /// Specifies the write side effects #[cfg_attr( feature = "serde", @@ -143,6 +150,7 @@ pub struct RegisterInfoBuilder { alternate_register: Option, address_offset: Option, properties: RegisterProperties, + datatype: Option, modified_write_values: Option, write_constraint: Option, read_action: Option, @@ -160,6 +168,7 @@ impl From for RegisterInfoBuilder { alternate_register: r.alternate_register, address_offset: Some(r.address_offset), properties: r.properties, + datatype: r.datatype, modified_write_values: r.modified_write_values, write_constraint: r.write_constraint, read_action: r.read_action, @@ -205,6 +214,11 @@ impl RegisterInfoBuilder { self.properties = value; self } + /// Set the datatype of the register. + pub fn datatype(mut self, value: Option) -> Self { + self.datatype = value; + self + } /// Set the size of the register. pub fn size(mut self, value: Option) -> Self { self.properties.size = value; @@ -264,6 +278,7 @@ impl RegisterInfoBuilder { .address_offset .ok_or_else(|| BuildError::Uninitialized("address_offset".to_string()))?, properties: self.properties.build(lvl)?, + datatype: self.datatype, modified_write_values: self.modified_write_values, write_constraint: self.write_constraint, read_action: self.read_action, @@ -324,10 +339,14 @@ impl RegisterInfo { self.derived_from = builder.derived_from; self.fields = None; self.properties = RegisterProperties::default(); + self.datatype = None; self.modified_write_values = None; self.write_constraint = None; } else { self.properties.modify_from(builder.properties, lvl)?; + if builder.datatype.is_some() { + self.datatype = builder.datatype; + } if builder.modified_write_values.is_some() { self.modified_write_values = builder.modified_write_values; }