modm_data.header2svd.stmicro.tree

  1# Copyright 2022, Niklas Hauser
  2# SPDX-License-Identifier: MPL-2.0
  3
  4import re
  5import logging
  6from anytree.search import findall, find_by_attr, findall_by_attr
  7from anytree import RenderTree
  8from collections import defaultdict
  9from ...svd import *
 10
 11
 12LOGGER = logging.getLogger(__file__)
 13
 14
 15def _normalize_subtypes(memtree, peripheral, *subtypes):
 16    dmas = set(findall_by_attr(memtree, peripheral, name="type", maxlevel=2))
 17    for stype in subtypes:
 18        dmas.update(findall_by_attr(memtree, stype, name="type", maxlevel=2))
 19
 20    dmamap = defaultdict(list)
 21    key = None
 22    for pdma in list(sorted(dmas, key=lambda p: (p.address, len(p.name)))):
 23        if pdma.type == peripheral:
 24            key = pdma
 25        else:
 26            dmamap[key].append(pdma)
 27
 28    tchannels = []
 29    for dma, channels in dmamap.items():
 30        tdma = find_by_attr(memtree, peripheral, maxlevel=2)
 31        if not channels: continue
 32        tchannel = find_by_attr(memtree, channels[0].type, maxlevel=2)
 33        tchannels.append(tchannel)
 34        for channel in channels:
 35            poffset = channel.address - dma.address
 36            # print(dma.name, channel.name, offset)
 37            for treg in tchannel.children:
 38                name = treg.name + channel.name[-1]
 39                offset = treg.offset + poffset
 40                # print(name, offset)
 41                nreg = Register(name, offset=offset, width=treg.width, parent=tdma)
 42                for tbit in treg.children:
 43                    BitField(tbit.name, tbit.position, tbit.width, parent=nreg)
 44
 45        # print(RenderTree(tdma))
 46
 47    for tchannel in tchannels:
 48        tchannel.parent = None
 49    for channels in dmamap.values():
 50        for channel in channels:
 51            channel.parent = None
 52
 53    return memtree
 54
 55
 56def _normalize_duplicates(memtree, infilter, outfilter):
 57    noncommons = findall(memtree, outfilter, maxlevel=2)
 58    for common in findall(memtree, infilter, maxlevel=2):
 59        if common in noncommons:
 60            LOGGER.info(f"Removing duplicate peripheral '{common}'!")
 61            common.parent = None
 62    return memtree
 63
 64
 65def _normalize_adc_common(memtree):
 66    adc = set(findall_by_attr(memtree, "ADC_TypeDef", name="type", maxlevel=2))
 67    if len(adc) != 1: return memtree
 68    common = set(findall_by_attr(memtree, "ADC_Common_TypeDef", name="type", maxlevel=2))
 69    if len(common) != 1: return memtree
 70    adc, common = adc.pop(), common.pop()
 71
 72    tadc = find_by_attr(memtree, "ADC_TypeDef", maxlevel=2)
 73    tcommon = find_by_attr(memtree, "ADC_Common_TypeDef", maxlevel=2)
 74    offset = common.address - adc.address
 75    for treg in tcommon.children:
 76        offset = treg.offset + offset
 77        # print(treg.name, offset)
 78        nreg = Register(treg.name, offset=offset, width=treg.width, parent=tadc)
 79        for tbit in treg.children:
 80            BitField(tbit.name, tbit.position, tbit.width, parent=nreg)
 81
 82    tcommon.parent = None
 83    for common in findall_by_attr(memtree, "ADC_Common_TypeDef", name="type", maxlevel=2):
 84        common.parent = None
 85
 86    return memtree
 87
 88
 89def _normalize_i2sext(memtree):
 90    ext = findall(memtree, lambda n: "ext" not in n.name, maxlevel=2)
 91    for common in findall(memtree, lambda n: "ext" in n.name, maxlevel=2):
 92        LOGGER.info(f"Removing aliased peripheral '{common}'!")
 93        common.parent = None
 94
 95    return memtree
 96
 97
 98def _normalize_dmamux(memtree):
 99    dmamuxs = findall(memtree, lambda n: re.match(r"DMAMUX\d$", n.name), maxlevel=2)
100    for dmamux in dmamuxs:
101        dmamux.type = "DMAMUX_TypeDef"
102    if dmamuxs:
103        PeripheralType("DMAMUX_TypeDef", parent=memtree)
104        memtree = _normalize_subtypes(memtree, "DMAMUX_TypeDef",
105                        "DMAMUX_Channel_TypeDef", "DMAMUX_ChannelStatus_TypeDef",
106                        "DMAMUX_RequestGen_TypeDef", "DMAMUX_RequestGenStatus_TypeDef")
107    return memtree
108
109
110def _normalize_dfsdm(memtree):
111    channels = findall(memtree, lambda n: re.match(r"DFSDM\d_Channel0$", n.name), maxlevel=2)
112    if not channels: return memtree
113
114    PeripheralType("DFSDM_TypeDef", parent=memtree)
115    for channel in channels:
116        Peripheral(channel.name.split("_")[0], "DFSDM_TypeDef", channel.address, parent=memtree)
117    return _normalize_subtypes(memtree, "DFSDM_TypeDef", "DFSDM_Channel_TypeDef", "DFSDM_Filter_TypeDef")
118
119
120def _normalize_instances(memtree):
121    instances = findall(memtree, lambda n: isinstance(n, Peripheral), maxlevel=2)
122    cache = {}
123    for instance in instances:
124        if instance.type not in cache:
125            itype = find_by_attr(memtree, instance.type, maxlevel=2)
126            if itype is None:
127                LOGGER.error(f"Cannot find type {instance.type} for {instance.name} @{hex(instance.address)}!")
128                instance.parent = None
129                continue
130            cache[instance.type] = itype
131
132        for treg in cache[instance.type].children:
133            preg = Register(treg.name, offset=treg.offset, width=treg.width, parent=instance)
134            for tbit in treg.children:
135                BitField(tbit.name, tbit.position, tbit.width, parent=preg)
136
137    for ttype in findall(memtree, lambda n: isinstance(n, PeripheralType), maxlevel=2):
138        ttype.parent = None
139
140    return memtree
141
142
143def _normalize_order(memtree):
144    if isinstance(memtree, Device):
145        memtree.children = sorted(memtree.children, key=lambda p: p.address if isinstance(p, Peripheral) else 0)
146    elif isinstance(memtree, Peripheral):
147        memtree.children = sorted(memtree.children, key=lambda r: r.offset)
148    elif isinstance(memtree, Register):
149        memtree.children = sorted(memtree.children, key=lambda b: b.position)
150
151    for child in memtree.children:
152        _normalize_order(child)
153    return memtree
154
155
156def normalize_memory_map(memtree):
157    # print(RenderTree(memtree, maxlevel=2))
158    memtree = _normalize_subtypes(memtree, "DMA_TypeDef", "DMA_Channel_TypeDef", "DMA_Stream_TypeDef")
159    memtree = _normalize_subtypes(memtree, "MDMA_TypeDef", "MDMA_Channel_TypeDef")
160    memtree = _normalize_subtypes(memtree, "BDMA_TypeDef", "BDMA_Channel_TypeDef")
161    memtree = _normalize_subtypes(memtree, "LTDC_TypeDef", "LTDC_Layer_TypeDef")
162    memtree = _normalize_subtypes(memtree, "SAI_TypeDef", "SAI_Block_TypeDef")
163    memtree = _normalize_subtypes(memtree, "RAMECC_TypeDef", "RAMECC_MonitorTypeDef")
164
165    memtree = _normalize_dfsdm(memtree)
166    memtree = _normalize_dmamux(memtree)
167    memtree = _normalize_adc_common(memtree)
168
169    memtree = _normalize_duplicates(memtree,
170                lambda n: "_COMMON" in n.name, lambda n: "_COMMON" not in n.name)
171    memtree = _normalize_duplicates(memtree,
172                lambda n: "OPAMP" == n.name, lambda n: re.match(r"OPAMP\d$", n.name))
173
174    memtree = _normalize_instances(memtree)
175    memtree = _normalize_order(memtree)
176    return memtree
LOGGER = <Logger /opt/hostedtoolcache/Python/3.12.2/x64/lib/python3.12/site-packages/modm_data/header2svd/stmicro/tree.py (WARNING)>
def normalize_memory_map(memtree):
157def normalize_memory_map(memtree):
158    # print(RenderTree(memtree, maxlevel=2))
159    memtree = _normalize_subtypes(memtree, "DMA_TypeDef", "DMA_Channel_TypeDef", "DMA_Stream_TypeDef")
160    memtree = _normalize_subtypes(memtree, "MDMA_TypeDef", "MDMA_Channel_TypeDef")
161    memtree = _normalize_subtypes(memtree, "BDMA_TypeDef", "BDMA_Channel_TypeDef")
162    memtree = _normalize_subtypes(memtree, "LTDC_TypeDef", "LTDC_Layer_TypeDef")
163    memtree = _normalize_subtypes(memtree, "SAI_TypeDef", "SAI_Block_TypeDef")
164    memtree = _normalize_subtypes(memtree, "RAMECC_TypeDef", "RAMECC_MonitorTypeDef")
165
166    memtree = _normalize_dfsdm(memtree)
167    memtree = _normalize_dmamux(memtree)
168    memtree = _normalize_adc_common(memtree)
169
170    memtree = _normalize_duplicates(memtree,
171                lambda n: "_COMMON" in n.name, lambda n: "_COMMON" not in n.name)
172    memtree = _normalize_duplicates(memtree,
173                lambda n: "OPAMP" == n.name, lambda n: re.match(r"OPAMP\d$", n.name))
174
175    memtree = _normalize_instances(memtree)
176    memtree = _normalize_order(memtree)
177    return memtree