From 3ee47a9c1b0787e567d7af0f661cf02b8b5d5aed Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 6 Aug 2020 23:28:45 +0200 Subject: 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. --- tools/gen-device-svd/gen-device-svd.go | 80 ++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 18 deletions(-) (limited to 'tools') 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{ -- cgit v1.2.3