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
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.