rust-embedded / rust-embedded/svd2rust

Odd (and incorrect) code generation from SVD

Open
#966 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
857
Forks
164
PR merge metrics
No merged PRs in 30d

Description

I was in the process of updating a project that I am working on to new SVD's and when I generated the PAC I got some strange code. This first block is and excerpt from the relevant part of the SVD. The full thing can be found here:

<field>
    <name>CTS_ASSERT</name>
    <description>CTS assert level</description>
    <bitOffset>7</bitOffset>
    <bitWidth>1</bitWidth>
    <enumeratedValues>
        <name>ASSERT_LEVEL</name>
        <enumeratedValue>
            <name>HIGH</name>
            <description>Assert high</description>
            <value>0</value>
        </enumeratedValue>
        <enumeratedValue>
            <name>LOW</name>
            <description>Assert low</description>
            <value>1</value>
        </enumeratedValue>
    </enumeratedValues>
</field>
<field>
    <name>RTS_ASSERT</name>
    <description>RTS assert level</description>
    <bitOffset>6</bitOffset>
    <bitWidth>1</bitWidth>
    <enumeratedValues derivedFrom="UART1.CNTL.CTS_ASSERT.ASSERT_LEVEL"></enumeratedValues>
</field>

Generated code is as follows:

#[doc = "RTS assert level"]
pub use AssertLevel;
#[doc = "Field `RTS_ASSERT` reader - RTS assert level"]
pub use CtsAssertR as RtsAssertR;
#[doc = "Field `RTS_ASSERT` writer - RTS assert level"]
pub use CtsAssertW as RtsAssertW;
#[doc = "CTS assert level\n\nValue on reset: 0"]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum AssertLevel {
    #[doc = "0: Assert high"]
    High = 0,
    #[doc = "1: Assert low"]
    Low = 1,
}
impl From<AssertLevel> for bool {
    #[inline(always)]
    fn from(variant: AssertLevel) -> Self {
        variant as u8 != 0
    }
}
#[doc = "Field `CTS_ASSERT` reader - CTS assert level"]
pub type CtsAssertR = crate::BitReader<AssertLevel>;
impl CtsAssertR {
    #[doc = "Get enumerated values variant"]
    #[inline(always)]
    pub const fn variant(&self) -> AssertLevel {
        match self.bits {
            false => AssertLevel::High,
            true => AssertLevel::Low,
        }
    }
    #[doc = "Assert high"]
    #[inline(always)]
    pub fn is_high(&self) -> bool {
        *self == AssertLevel::High
    }
    #[doc = "Assert low"]
    #[inline(always)]
    pub fn is_low(&self) -> bool {
        *self == AssertLevel::Low
    }
}
#[doc = "Field `CTS_ASSERT` writer - CTS assert level"]
pub type CtsAssertW<'a, REG> = crate::BitWriter<'a, REG, AssertLevel>;
impl<'a, REG> CtsAssertW<'a, REG>
where
    REG: crate::Writable + crate::RegisterSpec,
{
    #[doc = "Assert high"]
    #[inline(always)]
    pub fn high(self) -> &'a mut crate::W<REG> {
        self.variant(AssertLevel::High)
    }
    #[doc = "Assert low"]
    #[inline(always)]
    pub fn low(self) -> &'a mut crate::W<REG> {
        self.variant(AssertLevel::Low)
    }
}

The error here is that for some reason a pub use AssertLevel; was generated just before pub enum AssertLevel {...}. I am using svd2rust version 0.37.1 and rust version 1.92.0. I am running Ubuntu 24.04.

As to what the actual issue here is I'm not sure. However it is unlikely to be the SVD because that specific file has been the same for years.

Let me know if anymore information is needed.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the report with svd2rust 0.37.1 using the linked bcm_aux.svd.jinja SVD excerpt, then inspect the generated PAC around the CTS_ASSERT and RTS_ASSERT fields. Trace handling of the derivedFrom enumeratedValues and verify that generation no longer emits a duplicate pub use AssertLevel; before the enum while preserving the expected reader and writer APIs.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
embedded-iot, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.