modm_data.cubehal.dmamux_requests

  1# Copyright 2021, Christopher Durand
  2# SPDX-License-Identifier: MPL-2.0
  3
  4import re
  5from pathlib import Path
  6from ..utils import ext_path
  7
  8_CUBE_PATH = ext_path("stmicro/cubehal")
  9_DMAMUX_PATTERN = re.compile(r"^\s*#define\s+(?P<name>(LL_DMAMUX_REQ_\w+))\s+(?P<id>(0x[0-9A-Fa-f]+))U")
 10_REQUEST_PATTERN = re.compile(r"^\s*#define\s+(?P<name>(DMA_REQUEST_\w+))\s+(?P<id>([0-9]+))U")
 11
 12def read_request_map(did: "modm_data.owl.DeviceIdentifier") -> dict[str, int]:
 13    """
 14    Reads the DMA requests mapping from the Low-Level (LL) CubeHAL header files.
 15
 16    :param did: Device to query for.
 17
 18    :return: A dictionary of DMA trigger name to trigger position.
 19    """
 20    dma_header = _get_hal_dma_header_path(did.family)
 21    dmamux_header = _get_ll_dmamux_header_path(did.family)
 22    request_map = None
 23    if did.family in ["g4", "h7", "l5"]:
 24        request_map = _read_requests(dma_header)
 25    elif did.family in ["g0", "wb", "wl"]:
 26        request_map = _read_requests_from_ll_dmamux(dma_header, dmamux_header)
 27    elif did.family == "l4" and did.name[0] in ["p", "q", "r", "s"]:
 28        request_map = _read_requests_l4(did.name in ["p5", "q5"])
 29    else:
 30        raise RuntimeError("No DMAMUX request data available for {}".format(did))
 31    _fix_request_data(request_map)
 32    return request_map
 33
 34
 35def _fix_request_data(request_map):
 36    fix_requests = {}
 37    dac_pattern = re.compile(r"(?P<dac>(DAC[0-9]))_CHANNEL(?P<ch>[0-9])")
 38    for name, number in request_map.items():
 39        if name.startswith("GENERATOR"):
 40            fix_requests["DMA_" + name] = number
 41        elif name == "FMAC_READ":
 42            fix_requests["FMAC_RD"] = number
 43        elif name == "FMAC_WRITE":
 44            fix_requests["FMAC_WR"] = number
 45        elif name == "CORDIC_READ":
 46            fix_requests["CORDIC_RD"] = number
 47        elif name == "CORDIC_WRITE":
 48            fix_requests["CORDIC_WR"] = number
 49        elif name == "DCMI_PSSI":
 50            fix_requests["PSSI"] = number
 51        elif name == "TIM16_COM":
 52            fix_requests["TIM16_TRIG_COM"] = number
 53        elif name == "TIM17_COM":
 54            fix_requests["TIM17_TRIG_COM"] = number
 55        elif name == "HRTIM_MASTER":
 56            fix_requests["HRTIM1_M"] = number
 57        elif name.startswith("HRTIM_TIMER_"):
 58            fix_requests[name.replace("HRTIM_TIMER_", "HRTIM1_")] = number
 59        elif name == "SUBGHZSPI_RX":
 60            fix_requests["SUBGHZ_RX"] = number
 61        elif name == "SUBGHZSPI_TX":
 62            fix_requests["SUBGHZ_TX"] = number
 63        else:
 64            m = dac_pattern.match(name)
 65            if m:
 66                fix_requests["{}_CH{}".format(m.group("dac"), m.group("ch"))] = number
 67
 68    request_map.update(fix_requests)
 69
 70def _get_include_path(family):
 71    return _CUBE_PATH / Path("stm32{}xx/Inc".format(family))
 72
 73
 74def _get_hal_dma_header_path(family):
 75    return _get_include_path(family) / Path("stm32{}xx_hal_dma.h".format(family))
 76
 77
 78def _get_ll_dmamux_header_path(family):
 79    return _get_include_path(family) / Path("stm32{}xx_ll_dmamux.h".format(family))
 80
 81
 82# For G4, H7 and L5
 83def _read_requests(hal_dma_file):
 84    requests_map = _read_map(hal_dma_file, _REQUEST_PATTERN)
 85    out_map = {}
 86    for r in requests_map.keys():
 87        out_map[r.replace("DMA_REQUEST_", "", 1)] = int(requests_map[r])
 88    return out_map
 89
 90
 91# For G0, WB and WL
 92def _read_requests_from_ll_dmamux(hal_dma_file, ll_dmamux_file):
 93    dmamux_map = _read_map(ll_dmamux_file, _DMAMUX_PATTERN)
 94    request_pattern = re.compile("^\s*#define\s+(?P<name>(DMA_REQUEST_\w+))\s+(?P<id>(LL_DMAMUX?_REQ_\w+))\s*")
 95    requests_map = _read_map(hal_dma_file, request_pattern)
 96    out_map = {}
 97    for r in requests_map.keys():
 98        out_map[r.replace("DMA_REQUEST_", "", 1)] = int(dmamux_map[requests_map[r]], 16)
 99    return out_map
100
101
102# For L4+
103def _read_requests_l4(read_for_p5_q5):
104    out_map = {}
105    p5_q5_if = "#if defined (STM32L4P5xx) || defined (STM32L4Q5xx)"
106    if_pattern = re.compile(r"^\s*#\s*if\s+")
107    else_pattern = re.compile(r"^\s*#\s*else")
108    endif_pattern = re.compile(r"^\s*#\s*endif")
109    in_p5_q5_section = False
110    ignore = False
111    with open(_get_hal_dma_header_path("l4"), "r") as header_file:
112        if_counter = 0
113        for line in header_file.readlines():
114            if p5_q5_if in line:
115                in_p5_q5_section = True
116                ignore = not read_for_p5_q5
117            elif in_p5_q5_section:
118                if if_pattern.match(line):
119                    if_counter += 1
120                elif endif_pattern.match(line):
121                    if if_counter == 0:
122                        in_p5_q5_section = False
123                        ignore = False
124                    else:
125                        if_counter -= 1
126                elif else_pattern.match(line) and if_counter == 0:
127                    ignore = read_for_p5_q5
128            if not ignore:
129                m = _REQUEST_PATTERN.match(line)
130                if m:
131                    name = m.group("name").replace("DMA_REQUEST_", "", 1)
132                    if name in out_map:
133                        raise RuntimeError("Duplicate entry {}".format(name))
134                    out_map[name] = int(m.group("id"))
135    return out_map
136
137
138def _read_map(filename, pattern):
139    out_map = {}
140    with open(filename, "r") as header_file:
141        for line in header_file.readlines():
142            m = pattern.match(line)
143            if m:
144                name = m.group("name")
145                if name in out_map:
146                    raise RuntimeError("Duplicate entry {}".format(name))
147                out_map[name] = m.group("id")
148    return out_map
def read_request_map(did: modm_data.owl.identifier.DeviceIdentifier) -> dict[str, int]:
13def read_request_map(did: "modm_data.owl.DeviceIdentifier") -> dict[str, int]:
14    """
15    Reads the DMA requests mapping from the Low-Level (LL) CubeHAL header files.
16
17    :param did: Device to query for.
18
19    :return: A dictionary of DMA trigger name to trigger position.
20    """
21    dma_header = _get_hal_dma_header_path(did.family)
22    dmamux_header = _get_ll_dmamux_header_path(did.family)
23    request_map = None
24    if did.family in ["g4", "h7", "l5"]:
25        request_map = _read_requests(dma_header)
26    elif did.family in ["g0", "wb", "wl"]:
27        request_map = _read_requests_from_ll_dmamux(dma_header, dmamux_header)
28    elif did.family == "l4" and did.name[0] in ["p", "q", "r", "s"]:
29        request_map = _read_requests_l4(did.name in ["p5", "q5"])
30    else:
31        raise RuntimeError("No DMAMUX request data available for {}".format(did))
32    _fix_request_data(request_map)
33    return request_map

Reads the DMA requests mapping from the Low-Level (LL) CubeHAL header files.

Parameters
  • did: Device to query for.
Returns

A dictionary of DMA trigger name to trigger position.