rahix / atdf2svd Goto Github PK
View Code? Open in Web Editor NEWConverter from Atmel's atdf format to CMSIS SVD
License: GNU General Public License v3.0
Converter from Atmel's atdf format to CMSIS SVD
License: GNU General Public License v3.0
New AVR MCUs contain a list containing all interrupts, similar to the following (attiny412.atdf
):
<interrupts>
<interrupt index="1" module-instance="CRCSCAN" name="NMI"/>
<interrupt index="2" module-instance="BOD" name="VLM"/>
<interrupt index="3" module-instance="PORTA" name="PORT"/>
<interrupt index="6" module-instance="RTC" name="CNT"/>
<interrupt index="7" module-instance="RTC" name="PIT"/>
<interrupt index="8" module-instance="TCA0" name="LUNF"/>
<interrupt index="8" module-instance="TCA0" name="OVF"/>
<interrupt index="9" module-instance="TCA0" name="HUNF"/>
<interrupt index="10" module-instance="TCA0" name="CMP0"/>
<interrupt index="10" module-instance="TCA0" name="LCMP0"/>
<interrupt index="11" module-instance="TCA0" name="CMP1"/>
<interrupt index="11" module-instance="TCA0" name="LCMP1"/>
<interrupt index="12" module-instance="TCA0" name="CMP2"/>
<interrupt index="12" module-instance="TCA0" name="LCMP2"/>
<interrupt index="13" module-instance="TCB0" name="INT"/>
<interrupt index="14" module-instance="TCD0" name="OVF"/>
<interrupt index="15" module-instance="TCD0" name="TRIG"/>
<interrupt index="16" module-instance="AC0" name="AC"/>
<interrupt index="17" module-instance="ADC0" name="RESRDY"/>
<interrupt index="18" module-instance="ADC0" name="WCOMP"/>
<interrupt index="19" module-instance="TWI0" name="TWIS"/>
<interrupt index="20" module-instance="TWI0" name="TWIM"/>
<interrupt index="21" module-instance="SPI0" name="INT"/>
<interrupt index="22" module-instance="USART0" name="RXC"/>
<interrupt index="23" module-instance="USART0" name="DRE"/>
<interrupt index="24" module-instance="USART0" name="TXC"/>
<interrupt index="25" module-instance="NVMCTRL" name="EE"/>
</interrupts>
Some of those interrupt vectors, have multiple meanings depending on the configurations.
An example of this is the TCA0
peripheral, where the two modes "Normal Mode" and "Split Mode" exist - both using the same interrupt vector, both with different meanings on it:
Long overdue but as this project never got high priority from me, I never got around to it. I think it would be quite nice to not only do the usual build, formatting, etc. but to also add some regression tests to ensure we don't break existing users. Right now I'm doing this manually which is quite error prone and doesn't cover everything.
https://crates.io/crates/insta seems like a nice crate for such kinds of tests.
As visible in CI from #38, there seem to be quite substantial changes between xmltree 0.8 and 0.10. We need to check how this is best integrated into our parsing code.
I don't think this has high priority but it would be good to do at some point anyway...
Right now, the interrupt list specified in the atdf
file is completely ignored. atdf2svd
definitely needs a way to add them to the svd file, but unfortunately, this is not quite trivial: The atdf does not associate interrupts with peripherals like svd does ... I am currently in favor of just adding all interrupts to the CPU peripheral unconditionally, as svd2rust
does not care about this association anyway ...
When I run atdf2svd for the attiny412, the following warnings appear:
Warning: Unhandled register node: "<register-group name-in-module=\"TCA_SINGLE\" offset=\"0\" name=\"SINGLE\" union-tag-value=\"0\" ...>"
Warning: Unhandled register node: "<register-group union-tag-value=\"1\" name-in-module=\"TCA_SPLIT\" name=\"SPLIT\" offset=\"0\" ...>"
Warning: Merging interrupt TCA0_LUNF and TCA0_OVF to TCA0_LUNF_OVF
Warning: Merging interrupt TCA0_LCMP0 and TCA0_CMP0 to TCA0_LCMP0_CMP0
Warning: Merging interrupt TCA0_CMP1 and TCA0_LCMP1 to TCA0_CMP1_LCMP1
Warning: Merging interrupt TCA0_CMP2 and TCA0_LCMP2 to TCA0_CMP2_LCMP2
Warning: No registers found for peripheral "TCA0"
These are omitting the ones regarding no field description. The svd file generated doesn't have the TCA0 peripheral as a result.
I suspect this is due to the split mode of the peripheral resulting in register blocks that overlap in the atdf (one for the single mode and one for the split mode) that the program doesn't know how to handle.
Adding support for this would be great!
From Rahix/avr-device#26
@jwagen: There is also an issue that module list contain the caption attribute of that module, but the instances of that module does not contain the caption attribute. Currently atdf2svd expects it to be on the instance.
@Rahix: Would adding a fall-back for the other tag fix this, or is a more elaborate distinction needed?
@jwagen: Yes a fall-back does seem to be sufficient. So I don't think something more elaborate is necessary at least for now.
From Rahix/avr-device#26
The current patch only works for old AVR devices, with 3 registers per port. Newer devices have more registers which need to be supported as well:
Okay, I'd say the best way to deal with this is a whitelist approach. So the patch should only touch registers named
- For 'old' scheme (
n
is port letter)
DDRn
PORTn
PINn
- For 'new' scheme
DIR
,DIRSET
,DIRCLR
,DIRTGL
OUT
,OUTSET
,OUTCLR
,OUTTGL
IN
INTFLAGS
Register access is specified by an rw attribute on the register element, not by the ocd-rw attribute.
If rw is missing, it is to be interpreted as "RW".
ocd-rw is used to indicate destructive accesses to a register, and thus lock a debugger out from doing destructive reads and writes to a register.
We should verify that output from atdf2svd
is valid in regards to the SVD schema: https://www.keil.com/pack/doc/CMSIS/SVD/html/schema_1_2_gr.html
According to CMSIS-SVD docs:
addressBlock:| Specify an address range uniquely mapped to this peripheral. A peripheral must have at least one
address block, but can allocate multiple distinct address ranges. If a peripheral is derived from another peripheral, the
addressBlock is not mandatory.
It seems that generated SVDs are generally missing this element. This breaks e.g. PlatformIO Debugger.
Seems that atdf2svd
still sometimes generates empty description tags. I suspect this happends when a description is present in the ATDF but is empty.
We should not emit a description in this case which can be archieved by setting the description
attributes in the relevant types to None
.
While trying to add support for the atmega328pb in avr-device I ran across a problem with parsing the atdf file for the device.
The parser paniced at https://github.com/Rahix/atdf2svd/blob/master/src/svd/peripheral.rs#L7 and after some investigation I found out that the PTC peripheral was missing a base address.
After reading about PTC here, https://github.com/jgilbert20/Libre_PTC my guess is that PTC is so secret to Atmel that they don't even include the base address for the device.
One solution would be to just skip those peripherals and log an warning, or the the PTC could be special cased and just skipped. Would be happy to create a patch, just need to know what you think is the best way to solve it.
In newer versions of svd2rust
it has become a hard error when an enumerated value does not fit into the field it is meant for. This has lead to a lot of additional patches being necessary in avr-device
: Rahix/avr-device#64
I suggest that atdf2svd
should just not emit any enumerated values which are beyond the field-size and drop them with a warning. This would mean we at least don't have to patch every single one of these cases right away.
In code this means that here
Lines 29 to 35 in a3385d1
we need to filter the values by their validity for the current field.
New AVR MCUs contain a list containing all interrupts, similar to the following (attiny412.atdf
):
<interrupts>
<interrupt index="1" module-instance="CRCSCAN" name="NMI"/>
<interrupt index="2" module-instance="BOD" name="VLM"/>
<interrupt index="3" module-instance="PORTA" name="PORT"/>
<interrupt index="6" module-instance="RTC" name="CNT"/>
<interrupt index="7" module-instance="RTC" name="PIT"/>
<interrupt index="8" module-instance="TCA0" name="LUNF"/>
<interrupt index="8" module-instance="TCA0" name="OVF"/>
<interrupt index="9" module-instance="TCA0" name="HUNF"/>
<interrupt index="10" module-instance="TCA0" name="CMP0"/>
<interrupt index="10" module-instance="TCA0" name="LCMP0"/>
<interrupt index="11" module-instance="TCA0" name="CMP1"/>
<interrupt index="11" module-instance="TCA0" name="LCMP1"/>
<interrupt index="12" module-instance="TCA0" name="CMP2"/>
<interrupt index="12" module-instance="TCA0" name="LCMP2"/>
<interrupt index="13" module-instance="TCB0" name="INT"/>
<interrupt index="14" module-instance="TCD0" name="OVF"/>
<interrupt index="15" module-instance="TCD0" name="TRIG"/>
<interrupt index="16" module-instance="AC0" name="AC"/>
<interrupt index="17" module-instance="ADC0" name="RESRDY"/>
<interrupt index="18" module-instance="ADC0" name="WCOMP"/>
<interrupt index="19" module-instance="TWI0" name="TWIS"/>
<interrupt index="20" module-instance="TWI0" name="TWIM"/>
<interrupt index="21" module-instance="SPI0" name="INT"/>
<interrupt index="22" module-instance="USART0" name="RXC"/>
<interrupt index="23" module-instance="USART0" name="DRE"/>
<interrupt index="24" module-instance="USART0" name="TXC"/>
<interrupt index="25" module-instance="NVMCTRL" name="EE"/>
</interrupts>
The module-instance
is neglected at the moment, leading to a bad naming of the addresses, e.g. CMP0
- without informations on the peripheral:
<interrupt>
<name>NMI</name>
<value>1</value>
<description><TBD></description>
</interrupt>
<interrupt>
<name>VLM</name>
<value>2</value>
<description><TBD></description>
</interrupt>
<interrupt>
<name>PORT</name>
<value>3</value>
<description><TBD></description>
</interrupt>
...
Example: ATxmega128A1
Some ATDF files contain nested <register-group />
elements, for example:
<register-group caption="DMA Controller" name="DMA" size="80">
<register caption="Control" name="CTRL" offset="0x00" size="1">
...
</register>
...
<register-group caption="DMA Channel 0" name="CH0" offset="0x10" name-in-module="DMA_CH"/>
<register-group caption="DMA Channel 1" name="CH1" offset="0x20" name-in-module="DMA_CH"/>
<register-group caption="DMA Channel 2" name="CH2" offset="0x30" name-in-module="DMA_CH"/>
<register-group caption="DMA Channel 3" name="CH3" offset="0x40" name-in-module="DMA_CH"/>
</register-group>
These register groups are defined right next to this one, in the same <module>
:
<register-group caption="DMA Channel" name="DMA_CH" size="16">
<register caption="Channel Control" name="CTRLA" offset="0x00" size="1">
...
</register>
</register-group>
The parser needs to expand those sub-register groups into registers in the peripheral, probably by appending the names. E.g. the above example would create a CH0_CTRLA
register.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.