diff options
author | Ayke van Laethem <[email protected]> | 2020-08-06 23:28:45 +0200 |
---|---|---|
committer | Ron Evans <[email protected]> | 2020-08-31 09:02:23 +0200 |
commit | 3ee47a9c1b0787e567d7af0f661cf02b8b5d5aed (patch) | |
tree | a8447560da0c9059b5e163d1668b52996e9c4da6 /tools | |
parent | da7db81087d8326c887391b58794d3bea1cae6bc (diff) | |
download | tinygo-3ee47a9c1b0787e567d7af0f661cf02b8b5d5aed.tar.gz tinygo-3ee47a9c1b0787e567d7af0f661cf02b8b5d5aed.zip |
esp: add support for the Espressif ESP32 chip
This is only very minimal support. More support (such as tinygo flash,
or peripheral access) should be added in later commits, to keep this one
focused.
Importantly, this commit changes the LLVM repo from llvm/llvm-project to
tinygo-org/llvm-project. This provides a little bit of versioning in
case something changes in the Espressif fork. If we want to upgrade to
LLVM 11 it's easy to switch back to llvm/llvm-project until Espressif
has updated their fork.
Diffstat (limited to 'tools')
-rwxr-xr-x | tools/gen-device-svd/gen-device-svd.go | 80 |
1 files changed, 62 insertions, 18 deletions
diff --git a/tools/gen-device-svd/gen-device-svd.go b/tools/gen-device-svd/gen-device-svd.go index 2e417b3ea..d6e1ca686 100755 --- a/tools/gen-device-svd/gen-device-svd.go +++ b/tools/gen-device-svd/gen-device-svd.go @@ -19,23 +19,25 @@ var validName = regexp.MustCompile("^[a-zA-Z0-9_]+$") var enumBitSpecifier = regexp.MustCompile("^#[x01]+$") type SVDFile struct { - XMLName xml.Name `xml:"device"` - Name string `xml:"name"` - Description string `xml:"description"` - LicenseText string `xml:"licenseText"` - Peripherals []struct { - Name string `xml:"name"` - Description string `xml:"description"` - BaseAddress string `xml:"baseAddress"` - GroupName string `xml:"groupName"` - DerivedFrom string `xml:"derivedFrom,attr"` - Interrupts []struct { - Name string `xml:"name"` - Index int `xml:"value"` - } `xml:"interrupt"` - Registers []*SVDRegister `xml:"registers>register"` - Clusters []*SVDCluster `xml:"registers>cluster"` - } `xml:"peripherals>peripheral"` + XMLName xml.Name `xml:"device"` + Name string `xml:"name"` + Description string `xml:"description"` + LicenseText string `xml:"licenseText"` + Peripherals []SVDPeripheral `xml:"peripherals>peripheral"` +} + +type SVDPeripheral struct { + Name string `xml:"name"` + Description string `xml:"description"` + BaseAddress string `xml:"baseAddress"` + GroupName string `xml:"groupName"` + DerivedFrom string `xml:"derivedFrom,attr"` + Interrupts []struct { + Name string `xml:"name"` + Index int `xml:"value"` + } `xml:"interrupt"` + Registers []*SVDRegister `xml:"registers>register"` + Clusters []*SVDCluster `xml:"registers>cluster"` } type SVDRegister struct { @@ -139,6 +141,11 @@ func cleanName(text string) string { } text = string(result) } + if len(text) != 0 && (text[0] >= '0' && text[0] <= '9') { + // Identifiers may not start with a number. + // Add an underscore instead. + text = "_" + text + } return text } @@ -163,7 +170,12 @@ func readSVD(path, sourceURL string) (*Device, error) { interrupts := make(map[string]*interrupt) var peripheralsList []*peripheral - for _, periphEl := range device.Peripherals { + // Some SVD files have peripheral elements derived from a peripheral that + // comes later in the file. To make sure this works, sort the peripherals if + // needed. + orderedPeripherals := orderPeripherals(device.Peripherals) + + for _, periphEl := range orderedPeripherals { description := formatText(periphEl.Description) baseAddress, err := strconv.ParseUint(periphEl.BaseAddress, 0, 32) if err != nil { @@ -172,6 +184,9 @@ func readSVD(path, sourceURL string) (*Device, error) { // Some group names (for example the STM32H7A3x) have an invalid // group name. Replace invalid characters with "_". groupName := cleanName(periphEl.GroupName) + if groupName == "" { + groupName = cleanName(periphEl.Name) + } for _, interrupt := range periphEl.Interrupts { addInterrupt(interrupts, interrupt.Name, interrupt.Name, interrupt.Index, description) @@ -396,6 +411,34 @@ func readSVD(path, sourceURL string) (*Device, error) { }, nil } +// orderPeripherals sorts the peripherals so that derived peripherals come after +// base peripherals. This is necessary for some SVD files. +func orderPeripherals(input []SVDPeripheral) []*SVDPeripheral { + var sortedPeripherals []*SVDPeripheral + var missingBasePeripherals []*SVDPeripheral + knownBasePeripherals := map[string]struct{}{} + for i := range input { + p := &input[i] + groupName := p.GroupName + if groupName == "" { + groupName = p.Name + } + knownBasePeripherals[groupName] = struct{}{} + if p.DerivedFrom != "" { + if _, ok := knownBasePeripherals[p.DerivedFrom]; !ok { + missingBasePeripherals = append(missingBasePeripherals, p) + continue + } + } + sortedPeripherals = append(sortedPeripherals, p) + } + + // Let's hope all base peripherals are now included. + sortedPeripherals = append(sortedPeripherals, missingBasePeripherals...) + + return sortedPeripherals +} + func addInterrupt(interrupts map[string]*interrupt, name, interruptName string, index int, description string) { if _, ok := interrupts[name]; ok { if interrupts[name].Value != index { @@ -654,6 +697,7 @@ func parseRegister(groupName string, regEl *SVDRegister, baseAddress uint64, bit if !unicode.IsUpper(rune(regName[0])) && !unicode.IsDigit(rune(regName[0])) { regName = strings.ToUpper(regName) } + regName = cleanName(regName) bitfields := parseBitfields(groupName, regName, regEl.Fields, bitfieldPrefix) return []*PeripheralField{&PeripheralField{ |