1""" 2Utility to autogenerate generic LL HAL headers. 3 4Usage:: 5 6 python3 genllheaders.py [-p /path/to/HAL] [-o /path/to/output_dir] 7 8Copyright (c) 2020 Teslabs Engineering S.L. 9 10SPDX-License-Identifier: Apache-2.0 11""" 12 13import argparse 14import logging 15from pathlib import Path 16import re 17import shutil 18 19from jinja2 import Environment, FileSystemLoader 20 21 22logger = logging.getLogger(__name__) 23 24 25SCRIPT_DIR = Path(__file__).absolute().parent 26"""Script directory.""" 27 28README_TEMPLATE_FILE = "readme-template.j2" 29"""Readme template file.""" 30 31HEADER_TEMPLATE_FILE = "header-template.j2" 32"""Header template file.""" 33 34REPO_ROOT = SCRIPT_DIR / ".." / ".." 35"""Repository root (used for input/output default folders).""" 36 37LL_API_IGNORE = ["usb"] 38"""List of LL APIs to be ignored.""" 39 40 41def main(hal_path, output): 42 """Entry point. 43 44 Args: 45 hal_path: Zephyr CubeMX HAL path. 46 output: Output directory. 47 """ 48 49 # obtain all available LL APIs for each series 50 ll_apis = dict() 51 versions = dict() 52 for entry in sorted(hal_path.iterdir()): 53 if not entry.is_dir() or not entry.name.startswith("stm32"): 54 continue 55 56 series = entry.name 57 58 # collect version 59 with open(entry / "README") as f: 60 readme = f.read() 61 m = re.search(r"version v?([0-9\.]+)", readme) 62 if not m: 63 logger.error(f"Could not determine version for {series}") 64 continue 65 66 versions[series] = m.group(1) 67 68 # obtain series LL headers 69 series_headers = entry / "drivers" / "include" 70 for header in series_headers.iterdir(): 71 m = re.match(r"^stm32[a-z0-9]+_ll_([a-z0-9]+)\.h$", header.name) 72 if not m: 73 continue 74 75 ll_api = m.group(1) 76 77 if ll_api in LL_API_IGNORE: 78 continue 79 80 if ll_api not in ll_apis: 81 ll_apis[ll_api] = list() 82 ll_apis[ll_api].append(series) 83 84 # write header files 85 env = Environment( 86 trim_blocks=True, lstrip_blocks=True, loader=FileSystemLoader(SCRIPT_DIR) 87 ) 88 readme_template = env.get_template(README_TEMPLATE_FILE) 89 header_template = env.get_template(HEADER_TEMPLATE_FILE) 90 91 if output.exists(): 92 shutil.rmtree(output) 93 output.mkdir(parents=True) 94 95 readme_file = output / "README.rst" 96 with open(readme_file, "w") as f: 97 f.write(readme_template.render(versions=versions)) 98 99 output_headers = output / "include" 100 output_headers.mkdir() 101 102 for ll_api, all_series in ll_apis.items(): 103 header_file = output_headers / ("stm32_ll_" + ll_api + ".h") 104 with open(header_file, "w") as f: 105 f.write(header_template.render(ll_api=ll_api, all_series=all_series)) 106 107 108if __name__ == "__main__": 109 parser = argparse.ArgumentParser() 110 parser.add_argument( 111 "-p", 112 "--hal-path", 113 type=Path, 114 default=REPO_ROOT / "stm32cube", 115 help="Zephyr CubeMX HAL path", 116 ) 117 parser.add_argument( 118 "-o", 119 "--output", 120 type=Path, 121 default=REPO_ROOT / "stm32cube" / "common_ll", 122 help="Output directory", 123 ) 124 args = parser.parse_args() 125 126 main(args.hal_path, args.output) 127