1
0
mirror of https://github.com/esphome/esphome.git synced 2025-04-07 03:10:27 +01:00
2024-05-07 19:40:21 +02:00

218 lines
6.2 KiB
Python

import os
from typing import Union
import esphome.codegen as cg
from esphome.core import CORE
from esphome.helpers import (
write_file_if_changed,
copy_file_if_changed,
)
from esphome.const import (
CONF_VARIANT,
CONF_BOARD,
KEY_NAME,
)
from .const import (
ZEPHYR_VARIANT_GENERIC,
ZEPHYR_VARIANT_NRF_SDK,
KEY_ZEPHYR,
KEY_PRJ_CONF,
KEY_OVERLAY,
zephyr_ns,
BOOTLOADER_MCUBOOT,
KEY_EXTRA_BUILD_FILES,
KEY_PATH,
)
AUTO_LOAD = ["preferences"]
KEY_BOARD = "board"
KEY_BOOTLOADER = "bootloader"
def zephyr_set_core_data(config):
CORE.data[KEY_ZEPHYR] = {}
CORE.data[KEY_ZEPHYR][KEY_BOARD] = config[CONF_BOARD]
CORE.data[KEY_ZEPHYR][KEY_PRJ_CONF] = {}
CORE.data[KEY_ZEPHYR][KEY_OVERLAY] = ""
CORE.data[KEY_ZEPHYR][KEY_BOOTLOADER] = config[KEY_BOOTLOADER]
CORE.data[KEY_ZEPHYR][KEY_EXTRA_BUILD_FILES] = {}
return config
PrjConfValueType = Union[bool, str, int]
def zephyr_add_prj_conf(name: str, value: PrjConfValueType):
"""Set an zephyr prj conf value."""
if not CORE.using_zephyr:
raise ValueError("Not an zephyr project")
if not name.startswith("CONFIG_"):
name = "CONFIG_" + name
if name in CORE.data[KEY_ZEPHYR][KEY_PRJ_CONF]:
old_value = CORE.data[KEY_ZEPHYR][KEY_PRJ_CONF][name]
if old_value != value:
raise ValueError(
f"{name} alread set with value {old_value}, new value {value}"
)
CORE.data[KEY_ZEPHYR][KEY_PRJ_CONF][name] = value
def zephyr_add_overlay(content):
if not CORE.using_zephyr:
raise ValueError("Not an zephyr project")
CORE.data[KEY_ZEPHYR][KEY_OVERLAY] += content
def add_extra_build_file(filename: str, path: str) -> bool:
"""Add an extra build file to the project."""
if filename not in CORE.data[KEY_ZEPHYR][KEY_EXTRA_BUILD_FILES]:
CORE.data[KEY_ZEPHYR][KEY_EXTRA_BUILD_FILES][filename] = {
KEY_NAME: filename,
KEY_PATH: path,
}
return True
return False
def add_extra_script(stage: str, filename: str, path: str):
"""Add an extra script to the project."""
key = f"{stage}:{filename}"
if add_extra_build_file(filename, path):
cg.add_platformio_option("extra_scripts", [key])
def zephyr_to_code(conf):
cg.add(zephyr_ns.setup_preferences())
cg.add_build_flag("-DUSE_ZEPHYR")
if conf[CONF_VARIANT] == ZEPHYR_VARIANT_GENERIC:
cg.add_platformio_option(
"platform_packages",
[
"platformio/framework-zephyr@^2.30500.231204",
],
)
elif conf[CONF_VARIANT] == ZEPHYR_VARIANT_NRF_SDK:
cg.add_platformio_option(
"platform_packages",
[
"platformio/framework-zephyr@https://github.com/tomaszduda23/framework-sdk-nrf",
"platformio/toolchain-gccarmnoneeabi@https://github.com/tomaszduda23/toolchain-sdk-ng",
],
)
# build is done by west so bypass board checking in platformio
cg.add_platformio_option("boards_dir", CORE.relative_build_path("boards"))
else:
raise NotImplementedError
# c++ support
zephyr_add_prj_conf("NEWLIB_LIBC", True)
zephyr_add_prj_conf("CONFIG_FPU", True)
zephyr_add_prj_conf("NEWLIB_LIBC_FLOAT_PRINTF", True)
zephyr_add_prj_conf("CPLUSPLUS", True)
zephyr_add_prj_conf("LIB_CPLUSPLUS", True)
# preferences
zephyr_add_prj_conf("SETTINGS", True)
zephyr_add_prj_conf("NVS", True)
zephyr_add_prj_conf("FLASH_MAP", True)
zephyr_add_prj_conf("CONFIG_FLASH", True)
# watchdog
zephyr_add_prj_conf("WATCHDOG", True)
zephyr_add_prj_conf("WDT_DISABLE_AT_BOOT", False)
# disable console
zephyr_add_prj_conf("UART_CONSOLE", False)
zephyr_add_prj_conf("CONSOLE", False)
# TODO debug only
zephyr_add_prj_conf("DEBUG_THREAD_INFO", True)
# zephyr_add_prj_conf("DEBUG", True)
###
zephyr_add_prj_conf("USE_SEGGER_RTT", True)
zephyr_add_prj_conf("RTT_CONSOLE", True)
zephyr_add_prj_conf("LOG", True)
zephyr_add_prj_conf("LOG_BLOCK_IN_THREAD", True)
zephyr_add_prj_conf("LOG_BUFFER_SIZE", 4096)
zephyr_add_prj_conf("SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL", True)
zephyr_add_prj_conf("USB_CDC_ACM_LOG_LEVEL_WRN", True)
add_extra_script(
"pre",
"pre_build.py",
os.path.join(os.path.dirname(__file__), "pre_build.py.script"),
)
add_extra_script(
"post",
"post_build.py",
os.path.join(os.path.dirname(__file__), "post_build.py.script"),
)
def _format_prj_conf_val(value: PrjConfValueType) -> str:
if isinstance(value, bool):
return "y" if value else "n"
if isinstance(value, int):
return str(value)
if isinstance(value, str):
return f'"{value}"'
raise ValueError
# Called by writer.py
def copy_files():
want_opts = CORE.data[KEY_ZEPHYR][KEY_PRJ_CONF]
contents = (
"\n".join(
f"{name}={_format_prj_conf_val(value)}"
for name, value in sorted(want_opts.items())
)
+ "\n"
)
write_file_if_changed(CORE.relative_build_path("zephyr/prj.conf"), contents)
write_file_if_changed(
CORE.relative_build_path("zephyr/app.overlay"),
CORE.data[KEY_ZEPHYR][KEY_OVERLAY],
)
write_file_if_changed(
CORE.relative_build_path("zephyr/child_image/mcuboot.conf"),
"""
CONFIG_MCUBOOT_SERIAL=y
CONFIG_BOOT_SERIAL_PIN_RESET=y
CONFIG_UART_CONSOLE=n
CONFIG_BOOT_SERIAL_ENTRANCE_GPIO=n
CONFIG_BOOT_SERIAL_CDC_ACM=y
CONFIG_UART_NRFX=n
CONFIG_LOG=n
CONFIG_ASSERT_VERBOSE=n
CONFIG_BOOT_BANNER=n
CONFIG_PRINTK=n
CONFIG_CBPRINTF_LIBC_SUBSTS=n
""",
)
if CORE.data[KEY_ZEPHYR][KEY_BOOTLOADER] == BOOTLOADER_MCUBOOT:
fake_board_manifest = """
{
"frameworks": [
"zephyr"
],
"name": "esphome nrf52",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104
},
"url": "https://esphome.io/",
"vendor": "esphome"
}
"""
write_file_if_changed(
CORE.relative_build_path(f"boards/{CORE.data[KEY_ZEPHYR][KEY_BOARD]}.json"),
fake_board_manifest,
)
for _, file in CORE.data[KEY_ZEPHYR][KEY_EXTRA_BUILD_FILES].items():
copy_file_if_changed(
file[KEY_PATH],
CORE.relative_build_path(file[KEY_NAME]),
)