Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ STM32Cube, as an external library, is not supposed to be modified.
In practice, it might be required to patch it.
When updating a STM32Cube package to a new version, please have a look
to the patch list in dedicated README file, to make sure you don't overwrite
some earlier modifications of the package.
some earlier modifications of the package. Furthermore, make sure to run the
``genllheaders.py`` script in order to make sure generic LL API headers are
up-to-date.
In case of doubt, contact Zephyr code owner for stm32cube.


Expand All @@ -53,11 +55,12 @@ and ``stm32yyxx.h`` should be included in ``soc.h``

#include <stm32f1xx.h>

Additionally, in order to use STM32Cube LL, include ``stm32yyxx_ll_foo.h`` in ``soc.h``.
Additionally, in order to use STM32Cube LL, you should include the provided
generic LL headers ``stm32_ll_foo.h`` directly in the file using the LL API:

.. code-block:: c

#include <stm32f1xx_ll_usart.h>
#include <stm32_ll_usart.h>

Drivers and applications that need functions from the STM32Cube HAL/LL C-files
will need to add the appropriate select entries in their Kconfig files.
Expand Down Expand Up @@ -103,7 +106,7 @@ Additionally, you need to add the following includes:
.. code-block:: c

#include <soc.h>
#include <stm32YYxx_ll_bar.h>
#include <stm32_ll_bar.h>

.dtsi files
***********
Expand Down
128 changes: 128 additions & 0 deletions scripts/genllheaders/genllheaders.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
"""
Utility to autogenerate generic LL HAL headers.

Usage::

python3 genllheaders.py [-p /path/to/HAL] [-o /path/to/output_dir]

Copyright (c) 2020 Teslabs Engineering S.L.

SPDX-License-Identifier: Apache-2.0
"""

import argparse
import logging
from pathlib import Path
import re
import shutil

from jinja2 import Environment, FileSystemLoader


logger = logging.getLogger(__name__)


SCRIPT_DIR = Path(__file__).absolute().parent
"""Script directory."""

README_TEMPLATE_FILE = "readme-template.j2"
"""Readme template file."""

HEADER_TEMPLATE_FILE = "header-template.j2"
"""Header template file."""

REPO_ROOT = SCRIPT_DIR / ".." / ".."
"""Repository root (used for input/output default folders)."""

LL_API_IGNORE = [
"usb"
]
"""List of LL APIs to be ignored."""


def main(hal_path, output):
"""Entry point.

Args:
hal_path: Zephyr CubeMX HAL path.
output: Output directory.
"""

# obtain all available LL APIs for each series
ll_apis = dict()
versions = dict()
for entry in sorted(hal_path.iterdir()):
if not entry.is_dir() or not entry.name.startswith("stm32"):
continue

series = entry.name

# collect version
with open(entry / "README") as f:
readme = f.read()
m = re.search(r"version v?([0-9\.]+)", readme)
if not m:
logger.error(f"Could not determine version for {series}")
continue

versions[series] = m.group(1)

# obtain series LL headers
series_headers = entry / "drivers" / "include"
for header in series_headers.iterdir():
m = re.match(r"stm32[a-z0-9]+_ll_([a-z0-9]+)\.h", header.name)
if not m:
continue

ll_api = m.group(1)

if ll_api in LL_API_IGNORE:
continue

if ll_api not in ll_apis:
ll_apis[ll_api] = list()
ll_apis[ll_api].append(series)

# write header files
env = Environment(
trim_blocks=True, lstrip_blocks=True, loader=FileSystemLoader(SCRIPT_DIR)
)
readme_template = env.get_template(README_TEMPLATE_FILE)
header_template = env.get_template(HEADER_TEMPLATE_FILE)

if output.exists():
shutil.rmtree(output)
output.mkdir(parents=True)

readme_file = output / "README.rst"
with open(readme_file, "w") as f:
f.write(readme_template.render(versions=versions))

output_headers = output / "include"
output_headers.mkdir()

for ll_api, all_series in ll_apis.items():
header_file = output_headers / ("stm32_ll_" + ll_api + ".h")
with open(header_file, "w") as f:
f.write(header_template.render(ll_api=ll_api, all_series=all_series))


if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
"-p",
"--hal-path",
type=Path,
default=REPO_ROOT / "stm32cube",
help="Zephyr CubeMX HAL path",
)
parser.add_argument(
"-o",
"--output",
type=Path,
default=REPO_ROOT / "stm32cube" / "common_ll",
help="Output directory",
)
args = parser.parse_args()

main(args.hal_path, args.output)
14 changes: 14 additions & 0 deletions scripts/genllheaders/header-template.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* NOTE: Autogenerated file using genllheaders.py
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <autoconf.h>

{% for series in all_series %}
#{{ "if" if loop.index == 1 else "elif"}} defined(CONFIG_SOC_SERIES_{{ series[:-1] | upper }})
#include <{{ series }}_ll_{{ ll_api }}.h>
{% endfor %}
#endif
{{ newline }}
16 changes: 16 additions & 0 deletions scripts/genllheaders/readme-template.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
STM32CubeMX Generic LL Headers
##############################

This folder contains generic STM32CubeMX LL API headers that include the right
LL API header based on the active series being used in a Zephyr application.

The current headers have been generated using the versions found in the table
below.

=============== ===============
Series CubeMX version
=============== ===============
{% for series, version in versions.items() %}
{{ "%-15s" | format(series) }} {{ version }}
{% endfor %}
=============== ===============
20 changes: 20 additions & 0 deletions scripts/tests/genllheaders/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from pathlib import Path
import sys

import pytest


_SCRIPT_DIR = Path(__file__).absolute().parent
sys.path.insert(0, str(_SCRIPT_DIR / ".." / ".." / "genllheaders"))


@pytest.fixture()
def data():
"""Pytest fixture to load test data files"""
return _SCRIPT_DIR / "data"


@pytest.fixture()
def hal_path(data):
"""Pytest fixture to load test HAL files"""
return data / "stm32cube"
15 changes: 15 additions & 0 deletions scripts/tests/genllheaders/data/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
STM32CubeMX Generic LL Headers
##############################

This folder contains generic STM32CubeMX LL API headers that include the right
LL API header based on the active series being used in a Zephyr application.

The current headers have been generated using the versions found in the table
below.

=============== ===============
Series CubeMX version
=============== ===============
stm32f0xx 1.0.0
stm32f1xx 2.0.0
=============== ===============
13 changes: 13 additions & 0 deletions scripts/tests/genllheaders/data/stm32_ll_tim.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* NOTE: Autogenerated file using genllheaders.py
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <autoconf.h>

#if defined(CONFIG_SOC_SERIES_STM32F0X)
#include <stm32f0xx_ll_tim.h>
#elif defined(CONFIG_SOC_SERIES_STM32F1X)
#include <stm32f1xx_ll_tim.h>
#endif
11 changes: 11 additions & 0 deletions scripts/tests/genllheaders/data/stm32_ll_usart.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* NOTE: Autogenerated file using genllheaders.py
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <autoconf.h>

#if defined(CONFIG_SOC_SERIES_STM32F1X)
#include <stm32f1xx_ll_usart.h>
#endif
1 change: 1 addition & 0 deletions scripts/tests/genllheaders/data/stm32cube/no_family.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This file should be skipped by genllheaders.py script
5 changes: 5 additions & 0 deletions scripts/tests/genllheaders/data/stm32cube/stm32f0xx/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
STM32CubeF0
###########

Status:
version v1.0.0
5 changes: 5 additions & 0 deletions scripts/tests/genllheaders/data/stm32cube/stm32f1xx/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
STM32CubeF1
###########

Status:
version 2.0.0
39 changes: 39 additions & 0 deletions scripts/tests/genllheaders/test_genllheaders.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from genllheaders import main


def test_main(data, hal_path, tmp_path):
"""Test that common LL headers are generated correctly."""

main(hal_path, tmp_path)

# check README file
ref_readme_file = data / "README.rst"
gen_readme_file = tmp_path / "README.rst"

assert gen_readme_file.exists()

with open(ref_readme_file) as ref, open(gen_readme_file) as gen:
assert ref.read() == gen.read()

# check tim file
ref_tim_file = data / "stm32_ll_tim.h"
gen_tim_file = tmp_path / "include" / "stm32_ll_tim.h"

assert gen_tim_file.exists()

with open(ref_tim_file) as ref, open(gen_tim_file) as gen:
assert ref.read() == gen.read()

# check usart file
ref_usart_file = data / "stm32_ll_usart.h"
gen_usart_file = tmp_path / "include" / "stm32_ll_usart.h"

assert gen_usart_file.exists()

with open(ref_usart_file) as ref, open(gen_usart_file) as gen:
assert ref.read() == gen.read()

# check usb file is not created (ignore list)
gen_usb_file = tmp_path / "include" / "stm32_ll_usb.h"

assert not gen_usb_file.exists()
2 changes: 2 additions & 0 deletions stm32cube/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,5 @@ foreach(stm_soc ${stm_socs})
add_subdirectory(${stm_soc}x)
endif()
endforeach()

zephyr_include_directories(common_ll/include)
28 changes: 28 additions & 0 deletions stm32cube/common_ll/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
STM32CubeMX Generic LL Headers
##############################

This folder contains generic STM32CubeMX LL API headers that include the right
LL API header based on the active series being used in a Zephyr application.

The current headers have been generated using the versions found in the table
below.

=============== ===============
Series CubeMX version
=============== ===============
stm32f0xx 1.11.1
stm32f1xx 1.8.2
stm32f2xx 1.9.1
stm32f3xx 1.11.1
stm32f4xx 1.25.1
stm32f7xx 1.16.0
stm32g0xx 1.3.0
stm32g4xx 1.3.0
stm32h7xx 1.8.0
stm32l0xx 1.11.3
stm32l1xx 1.9.0
stm32l4xx 1.16.0
stm32l5xx 1.3.1
stm32mp1xx 1.2.0
stm32wbxx 1.9.0
=============== ===============
39 changes: 39 additions & 0 deletions stm32cube/common_ll/include/stm32_ll_adc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* NOTE: Autogenerated file using genllheaders.py
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <autoconf.h>

#if defined(CONFIG_SOC_SERIES_STM32F0X)
#include <stm32f0xx_ll_adc.h>
#elif defined(CONFIG_SOC_SERIES_STM32F1X)
#include <stm32f1xx_ll_adc.h>
#elif defined(CONFIG_SOC_SERIES_STM32F2X)
#include <stm32f2xx_ll_adc.h>
#elif defined(CONFIG_SOC_SERIES_STM32F3X)
#include <stm32f3xx_ll_adc.h>
#elif defined(CONFIG_SOC_SERIES_STM32F4X)
#include <stm32f4xx_ll_adc.h>
#elif defined(CONFIG_SOC_SERIES_STM32F7X)
#include <stm32f7xx_ll_adc.h>
#elif defined(CONFIG_SOC_SERIES_STM32G0X)
#include <stm32g0xx_ll_adc.h>
#elif defined(CONFIG_SOC_SERIES_STM32G4X)
#include <stm32g4xx_ll_adc.h>
#elif defined(CONFIG_SOC_SERIES_STM32H7X)
#include <stm32h7xx_ll_adc.h>
#elif defined(CONFIG_SOC_SERIES_STM32L0X)
#include <stm32l0xx_ll_adc.h>
#elif defined(CONFIG_SOC_SERIES_STM32L1X)
#include <stm32l1xx_ll_adc.h>
#elif defined(CONFIG_SOC_SERIES_STM32L4X)
#include <stm32l4xx_ll_adc.h>
#elif defined(CONFIG_SOC_SERIES_STM32L5X)
#include <stm32l5xx_ll_adc.h>
#elif defined(CONFIG_SOC_SERIES_STM32MP1X)
#include <stm32mp1xx_ll_adc.h>
#elif defined(CONFIG_SOC_SERIES_STM32WBX)
#include <stm32wbxx_ll_adc.h>
#endif
Loading