Skip to content

Comments

update tools/gen-device-svd w.r.t. recent changes to the structure of stm32-svd files#5212

Open
knieriem wants to merge 11 commits intotinygo-org:devfrom
knieriem:update-gen-device-svd
Open

update tools/gen-device-svd w.r.t. recent changes to the structure of stm32-svd files#5212
knieriem wants to merge 11 commits intotinygo-org:devfrom
knieriem:update-gen-device-svd

Conversation

@knieriem
Copy link
Contributor

@knieriem knieriem commented Feb 20, 2026

As suggested by @deadprogram, I am creating this PR with changes to gen-device-svd.

Please see the top of tinygo-org/stm32-svd#10 for a list of changes and why I think they are useful. The individual commit messages also contain specific details.

I have verified today that the tool can build device/stm32/* files from the most recent Rust-based svdtools built .svd files. that Together with these updated .svd files a few minor fixes will be necessary to some stm32 related files in TinyGo, some of them are mentioned in tinygo-org/stm32-svd#10 too.
Together with these changes, which I can provide separately, the blinky examples will build for the existing stm32 targets.

When creating the changes in May 2025 I also checked esp and nrf targets, whose device files are also generated from SVD, but will check again whether targets still work (I have a microbit and an nrf based feather board available).

Edit: 2026-02-23:

  • (Adjusted some bits of the previously added logic so that the new command option regarding aliases that I suggested would not be needed anymore).
  • Added a way to tweak devices, which I think is helpful to handle issues like CCMR*_Input/Output alternate registers that in some cases (like swan target) would result in build errors using the new data from stm32-rs.
  • Also added a way to detect missing TXE/TXFNF USART flags, which would be hard to encode into the SVDs currently.

…rals derived by name

Recent SVDs from stm32-rs, like the one for stm32u595, define derivedFrom
attributes that do not refer to a peripheral group name, but to a
peripheral name. For instance, the peripheral I2C5 may be derived from
"I2C1", not from "I2C". The previous algorithm records, in case the
group name is non-empty, only the group name in the
knownBasePeripherals map, not the name of the peripheral itself.
So in case of the base peripheral I2C1 with group name I2C: although
the peripheral gets added to the sorted list, it would be added to
knownBasePeripherals with the group name "I2C" as key, not with "I2C1".
A following peripheral, I2C5, derived from I2C1, with an empty group
name, would be recorded as known with key "I2C5", but omitted from the
sorted list, because "I2C1" is not recognized as known.
The following peripheral SEC_I2C5, derived from I2C5, with empty group
name, would be added to both the knownPeripherals map and the sorted list.
So if, later, the sorted list is examined, it would find SEC_I2C5
earlier than its base peripheral I2C5, which would be missing from
"peripheralDict", resulting in a nil pointer access.
This patch makes sure that, to stay with the example, that
"I2C1" is recorded as known too (not only the group name "I2C"),
so that "I2C5" won't be skipped anymore, preventing the program from
crashing.
…singBasePeripherals

After the first run, missingBasePeripherals may contain peripherals
with dependencies that are not guaranteed to be in proper order.

This change implements additional loop runs that try to reduce the
size of the missingBasePeripherals as far as possible.

[With recent SVDs from stm32-rs this change will not produce different
results, though (since these source files contain already properly
ordered peripherals).]
…pe dimArray

This allows encoding of dim increment and array indices to be re-used
by other elements supporting dim arrays.

This change just restructures parts of register specific code,
it does not change the output of the program.
Patched SVD files from stm32-rs recently contain many fields with
dim array parameters and names containing %s (like "CC%sIF").
This change adjusts parseBitfields so that these field elements
get resolved.
In recent patched SVD files from stm32-rs there may be two
enumeratedValues elements per SVDField, not just one.
The SVD specification allows up to two entries (they may be used
to define different enums for read and write access).

This change extends SVDField and parseBitfields so that
two enumeratedValues are processed like a single one.
…p with larger number of registers/bitfields first

In group "TIM" there may be general purpose timers like TIM16 and
advanced timers like TIM1. The advanced peripheral may contain a larger
number of registers than the general purpose ones.
TIM1 may contain CCR1..CCR4, SMCR and OR1, while TIM16 only knows
about CCR1.
Unfortunately in some SVDs, like the one for stm32g031, TIM16 is defined
before TIM1. Since register and bitfield constants are generated taking
only the first peripheral of a group into account, the resulting .go
file may lack definitions for e.g. CCR2..CCR4, SMCR, and OR1.

This change adjusts orderPeripherals so that, to stay with the example,
a peripheral like TIM1 will be moved in front of TIM16, resulting in an
output file containing the larger set of definitions.
@knieriem
Copy link
Contributor Author

Builds appear to fail because of the TXFNF / TXE issue, mentioned in tinygo-org/stm32-svd#10:

src/machine/machine_stm32wlx.go: rename TXFNF into TXE (this is an issue I may address in gen-device-svd yet; it is caused by the way alternate registers are handled)

It can be worked around like in 1c75aff, which I could cherry-pick for this PR.

Recent SVD files created by stm32-rs use "isDefault" in enumeratedValue
elements for purposes like the Div1 enum for clock prescaler registers
without specifying a specific value.
Previously, these enumeratedValues would be skipped because of the
enumEl.Value == 0 condition, and the corresponding const definitions
like "RCC_CFGR2_PPRE2_Div1 = 0x0" would be missing from the
resulting .go files, so existing code relying on these constants would
not compile anymore.
This change adds a utility type enumDefaultResolver that helps
finding an actual value that is unused by the enumeratedValues that
are defined for the field. More examples for values marked
as "isDefault", along with their resolved values:

  DAC_CR_WAVE1_Triangle => 2
  IWDG_PR_PR_DivideBy256 => 6
  DAC_CR_MAMP2_Amp4095 => 0xb
This ensures that some more constants are included in the .go files
that would otherwise be skipped (like e.g. ADC_SMPR2_SMP1_Cycles*
of some STM32 devices), which prevented compilation of some programs.

To avoid extending a lot of func argument lists, and since there
is no context.Context in use yet, this change introduces a
global derivationContext.
@deadprogram
Copy link
Member

So to clarify @knieriem the idea of this PR is that is has the changes to accommodate the newer SVD files, but still works with the existing ones.

Then in a separate PR, we would update the submodule in lib/stm32-svd to the version in your PR tinygo-org/stm32-svd#14 and also fix whatever changes break such as:

/home/ron/.gvm/pkgsets/go1.25.5/global/bin/tinygo build -size short -o test.hex -target=lgt92               examples/blinky1
# machine
/home/ron/Development/tinygo/tinygo-122/src/machine/machine_stm32_tim.go:163:19: cannot use arrtype(top - 1) (value of type uint16) as uint32 value in argument to t.Device.ARR.Set
/home/ron/Development/tinygo/tinygo-122/src/machine/machine_stm32_tim.go:310:10: cannot use &t.Device.CCR1 (value of type *volatile.Register32) as *volatile.Register16 value in return statement
/home/ron/Development/tinygo/tinygo-122/src/machine/machine_stm32_tim.go:312:10: cannot use &t.Device.CCR2 (value of type *volatile.Register32) as *volatile.Register16 value in return statement
/home/ron/Development/tinygo/tinygo-122/src/machine/machine_stm32_tim.go:314:10: cannot use &t.Device.CCR3 (value of type *volatile.Register32) as *volatile.Register16 value in return statement
/home/ron/Development/tinygo/tinygo-122/src/machine/machine_stm32_tim.go:316:10: cannot use &t.Device.CCR4 (value of type *volatile.Register32) as *volatile.Register16 value in return statement
make: *** [GNUmakefile:841: smoketest] Error 1

Is that a correct summary?

Thanks!

@knieriem
Copy link
Contributor Author

Yes, I think the summary is correct. Btw, I am preparing right now a set of three fixes with adjustments for the update of lib/stm32-svd: One covering the swan target (stm32l4r5), one covering the nucleo-l031k6 (stm32l031), and the last one for the stm32g0b1, also only minor tweaks.

May I ask which stm32 device you are compiling for when building for target lgt92? From the error messages I suppose it could be stm32l031.

@deadprogram
Copy link
Member

May I ask which stm32 device you are compiling for when building for target lgt92? From the error messages I suppose it could be stm32l031.

stm32l0x2

Please see https://github.com/tinygo-org/tinygo/blob/dev/targets/lgt92.json

@knieriem
Copy link
Contributor Author

Btw, the (actually four) commits to fix the build (also of lgt92) are now on a branch: dev...knieriem:tinygo:stm32-update-svd

@deadprogram
Copy link
Member

deadprogram commented Feb 23, 2026

@knieriem can you also please submit a separate PR using that branch? I understand that it will initially fail the CI until the other 2 PRs are in place.

Thank you so much for all your work on this!!

@knieriem
Copy link
Contributor Author

Yes, I'll submit a PR. I suppose this should also contain the lib/stm32-svd sub module update — or will this be an extra PR?

@deadprogram
Copy link
Member

deadprogram commented Feb 23, 2026

Yes, I'll submit a PR. I suppose this should also contain the lib/stm32-svd sub module update.

That seems like a good idea. Yes, please.

@knieriem
Copy link
Contributor Author

Ok, I'll do that as soon as tinygo-org/stm32-svd is updated (so that I can reference the commit from tinygo's lib/stm32-svd sub module).

@deadprogram
Copy link
Member

@knieriem please see #5219 (comment)

@deadprogram
Copy link
Member

I think this PR seems to handle the new changes coming in the SVD update form my testing, and also still works with the current files from the fact that no build has failed in this PR.

@amken3d @ysoldak or anyone else interested in stm32 have any feedback before merge?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants