modm_data.svd.stmicro.device

 1# Copyright 2022, Niklas Hauser
 2# SPDX-License-Identifier: MPL-2.0
 3
 4import re
 5import json
 6from pathlib import Path
 7from collections import defaultdict
 8
 9from ...utils import root_path, cache_path
10from ...owl.stmicro import did_from_string
11from ...owl import DeviceIdentifier
12from ...cubemx import cubemx_device_list
13
14
15_SVD_FILES = None
16_SVD_MAP_FILE = cache_path("svd_files.json")
17
18
19def svd_file_devices() -> dict[Path, list[DeviceIdentifier]]:
20    global _SVD_FILES, _SVD_MAP_FILE
21    if _SVD_FILES is None:
22        if not _SVD_MAP_FILE.exists():
23            rm_files, hd_files, cm_files = {}, {}, {}
24            for file in cache_path("stmicro-svd/").glob("*.svd"):
25                match = re.search(r"<description>(.*?)</description>", file.read_text())
26                devices = [did_from_string(n) for n in match.group(1).split(",")]
27                if file.stem.startswith("rm_"):
28                    rm_files[file] = devices
29                else:
30                    hd_files[file] = devices
31
32            files = list(root_path("ext/cmsis/svd/data/STMicro/").glob("*.svd"))
33            def _sortkey(file):
34                name = re.sub(r"x+$", "", file.stem)
35                return (-len(name),
36                        name.count("x"),
37                        name.index("x") if "x" in name else 0,
38                        name)
39            files.sort(key=_sortkey)
40
41            def _match(file, devices):
42                pattern = re.sub(r"x+$", "", file.stem)
43                pattern = pattern.replace("x", ".").replace("_CM", ".*?@m")
44                pattern = pattern.replace("...A", ".....A")
45                return [d for d in devices if re.match(pattern, d.string, flags=re.IGNORECASE)]
46
47            mdevices = set(cubemx_device_list())
48            for file in files:
49                devices = _match(file, mdevices)
50                mdevices -= set(devices)
51                cm_files[file] = devices
52
53            filefmt = {"cm": {str(p):[str(d) for d in v] for p,v in cm_files.items()},
54                       "hd": {str(p):[str(d) for d in v] for p,v in hd_files.items()},
55                       "rm": {str(p):[str(d) for d in v] for p,v in rm_files.items()}}
56            with _SVD_MAP_FILE.open('w', encoding='utf-8') as fh:
57                json.dump(filefmt, fh, indent=4)
58        else:
59            with _SVD_MAP_FILE.open('r', encoding='utf-8') as fh:
60                cache = json.load(fh)
61            rm_files = {Path(p):[did_from_string(d) for d in v] for p,v in cache["rm"].items()}
62            hd_files = {Path(p):[did_from_string(d) for d in v] for p,v in cache["hd"].items()}
63            cm_files = {Path(p):[did_from_string(d) for d in v] for p,v in cache["cm"].items()}
64
65        _SVD_FILES = (hd_files, cm_files, rm_files)
66
67    return _SVD_FILES
68
69
70def svd_device_files() -> dict[DeviceIdentifier, list[Path]]:
71    device_files = defaultdict(dict)
72
73    def _remap(files, key):
74        for file, devices in files.items():
75            for device in devices:
76                device_files[device][key] = file
77
78    hd_files, cm_files, rm_files = svd_file_devices()
79    _remap(hd_files, "hd")
80    _remap(cm_files, "cm")
81    _remap(rm_files, "rm")
82    return device_files
def svd_file_devices() -> dict[pathlib.Path, list[modm_data.owl.identifier.DeviceIdentifier]]:
20def svd_file_devices() -> dict[Path, list[DeviceIdentifier]]:
21    global _SVD_FILES, _SVD_MAP_FILE
22    if _SVD_FILES is None:
23        if not _SVD_MAP_FILE.exists():
24            rm_files, hd_files, cm_files = {}, {}, {}
25            for file in cache_path("stmicro-svd/").glob("*.svd"):
26                match = re.search(r"<description>(.*?)</description>", file.read_text())
27                devices = [did_from_string(n) for n in match.group(1).split(",")]
28                if file.stem.startswith("rm_"):
29                    rm_files[file] = devices
30                else:
31                    hd_files[file] = devices
32
33            files = list(root_path("ext/cmsis/svd/data/STMicro/").glob("*.svd"))
34            def _sortkey(file):
35                name = re.sub(r"x+$", "", file.stem)
36                return (-len(name),
37                        name.count("x"),
38                        name.index("x") if "x" in name else 0,
39                        name)
40            files.sort(key=_sortkey)
41
42            def _match(file, devices):
43                pattern = re.sub(r"x+$", "", file.stem)
44                pattern = pattern.replace("x", ".").replace("_CM", ".*?@m")
45                pattern = pattern.replace("...A", ".....A")
46                return [d for d in devices if re.match(pattern, d.string, flags=re.IGNORECASE)]
47
48            mdevices = set(cubemx_device_list())
49            for file in files:
50                devices = _match(file, mdevices)
51                mdevices -= set(devices)
52                cm_files[file] = devices
53
54            filefmt = {"cm": {str(p):[str(d) for d in v] for p,v in cm_files.items()},
55                       "hd": {str(p):[str(d) for d in v] for p,v in hd_files.items()},
56                       "rm": {str(p):[str(d) for d in v] for p,v in rm_files.items()}}
57            with _SVD_MAP_FILE.open('w', encoding='utf-8') as fh:
58                json.dump(filefmt, fh, indent=4)
59        else:
60            with _SVD_MAP_FILE.open('r', encoding='utf-8') as fh:
61                cache = json.load(fh)
62            rm_files = {Path(p):[did_from_string(d) for d in v] for p,v in cache["rm"].items()}
63            hd_files = {Path(p):[did_from_string(d) for d in v] for p,v in cache["hd"].items()}
64            cm_files = {Path(p):[did_from_string(d) for d in v] for p,v in cache["cm"].items()}
65
66        _SVD_FILES = (hd_files, cm_files, rm_files)
67
68    return _SVD_FILES
def svd_device_files() -> dict[modm_data.owl.identifier.DeviceIdentifier, list[pathlib.Path]]:
71def svd_device_files() -> dict[DeviceIdentifier, list[Path]]:
72    device_files = defaultdict(dict)
73
74    def _remap(files, key):
75        for file, devices in files.items():
76            for device in devices:
77                device_files[device][key] = file
78
79    hd_files, cm_files, rm_files = svd_file_devices()
80    _remap(hd_files, "hd")
81    _remap(cm_files, "cm")
82    _remap(rm_files, "rm")
83    return device_files