From 49fb053af24291a3deced7cc58dbf11904727a34 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Tue, 5 Aug 2025 14:05:29 -0300 Subject: [PATCH 01/14] west.yml: hal_espressif: Update for ESP32-H2 support Update HAL for ESP32-H2 support. Signed-off-by: Raffael Rostagno --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 2a7ae1a9b2fce..2a01cfcbe9f99 100644 --- a/west.yml +++ b/west.yml @@ -169,7 +169,7 @@ manifest: groups: - hal - name: hal_espressif - revision: 883b9e84c86bab3ffef8572330cdaad8c1b289bc + revision: pull/472/head path: modules/hal/espressif west-commands: west/west-commands.yml groups: From f2bf3056c68beabbe8b7c339e920e019675f776c Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Tue, 29 Jul 2025 14:21:12 -0300 Subject: [PATCH 02/14] soc: esp32h2: Add initial support Add initial support files for ESP32-H2 SoC. Signed-off-by: Raffael Rostagno --- .../espressif/esp32h2/esp32h2_common.dtsi | 211 +++++ .../espressif/esp32h2/esp32h2_mini_h2.dtsi | 12 + .../espressif/esp32h2/esp32h2_mini_h4.dtsi | 12 + .../esp32h2/esp32h2_wroom_02c_h2.dtsi | 12 + .../esp32h2/esp32h2_wroom_02c_h4.dtsi | 12 + soc/espressif/common/Kconfig.defconfig | 7 +- soc/espressif/common/Kconfig.esptool | 4 + soc/espressif/common/Kconfig.flash | 2 +- soc/espressif/esp32h2/CMakeLists.txt | 12 + soc/espressif/esp32h2/Kconfig | 16 + soc/espressif/esp32h2/Kconfig.defconfig | 18 + soc/espressif/esp32h2/Kconfig.soc | 38 + soc/espressif/esp32h2/default.ld | 870 ++++++++++++++++++ soc/espressif/esp32h2/hw_init.c | 98 ++ soc/espressif/esp32h2/mcuboot.ld | 275 ++++++ soc/espressif/esp32h2/memory.h | 69 ++ soc/espressif/esp32h2/pinctrl_soc.h | 76 ++ soc/espressif/esp32h2/soc.c | 57 ++ soc/espressif/esp32h2/soc.h | 61 ++ soc/espressif/esp32h2/soc_irq.S | 15 + soc/espressif/esp32h2/vectors.S | 35 + soc/espressif/soc.yml | 3 + 22 files changed, 1911 insertions(+), 4 deletions(-) create mode 100644 dts/riscv/espressif/esp32h2/esp32h2_common.dtsi create mode 100644 dts/riscv/espressif/esp32h2/esp32h2_mini_h2.dtsi create mode 100644 dts/riscv/espressif/esp32h2/esp32h2_mini_h4.dtsi create mode 100644 dts/riscv/espressif/esp32h2/esp32h2_wroom_02c_h2.dtsi create mode 100644 dts/riscv/espressif/esp32h2/esp32h2_wroom_02c_h4.dtsi create mode 100644 soc/espressif/esp32h2/CMakeLists.txt create mode 100644 soc/espressif/esp32h2/Kconfig create mode 100644 soc/espressif/esp32h2/Kconfig.defconfig create mode 100644 soc/espressif/esp32h2/Kconfig.soc create mode 100644 soc/espressif/esp32h2/default.ld create mode 100644 soc/espressif/esp32h2/hw_init.c create mode 100644 soc/espressif/esp32h2/mcuboot.ld create mode 100644 soc/espressif/esp32h2/memory.h create mode 100644 soc/espressif/esp32h2/pinctrl_soc.h create mode 100644 soc/espressif/esp32h2/soc.c create mode 100644 soc/espressif/esp32h2/soc.h create mode 100644 soc/espressif/esp32h2/soc_irq.S create mode 100644 soc/espressif/esp32h2/vectors.S diff --git a/dts/riscv/espressif/esp32h2/esp32h2_common.dtsi b/dts/riscv/espressif/esp32h2/esp32h2_common.dtsi new file mode 100644 index 0000000000000..0b9f8f96dd140 --- /dev/null +++ b/dts/riscv/espressif/esp32h2/esp32h2_common.dtsi @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + + aliases { + die-temp0 = &coretemp; + }; + + chosen { + zephyr,entropy = &trng0; + zephyr,flash-controller = &flash; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "espressif,riscv"; + riscv,isa = "rv32imac_zicsr"; + reg = <0>; + clock-source = ; + clock-frequency = ; + xtal-freq = ; + }; + }; + + pinctrl: pin-controller { + compatible = "espressif,esp32-pinctrl"; + status = "okay"; + }; + + clock: clock { + compatible = "espressif,esp32-clock"; + fast-clk-src = ; + slow-clk-src = ; + #clock-cells = <1>; + status = "okay"; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges; + + sramhp: memory@40800000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x40800000 DT_SIZE_K(320)>; + zephyr,memory-region = "SRAMHP"; + }; + + sramlp: memory@50000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x50000000 DT_SIZE_K(4)>; + zephyr,memory-region = "SRAMLP"; + }; + + intc: interrupt-controller@60010000 { + compatible = "espressif,esp32-intc"; + #address-cells = <0>; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x60010000 DT_SIZE_K(4)>; + status = "okay"; + }; + + systimer0: systimer@6000b000 { + compatible = "espressif,esp32-systimer"; + reg = <0x6000B000 DT_SIZE_K(4)>; + interrupts = ; + interrupt-parent = <&intc>; + status = "okay"; + }; + + timer0: counter@60009000 { + compatible = "espressif,esp32-timer"; + reg = <0x60009000 DT_SIZE_K(4)>; + clocks = <&clock ESP32_TIMG0_MODULE>; + group = <0>; + index = <0>; + interrupts = ; + interrupt-parent = <&intc>; + status = "disabled"; + + counter { + compatible = "espressif,esp32-counter"; + status = "disabled"; + }; + }; + + timer1: counter@6000a000 { + compatible = "espressif,esp32-timer"; + reg = <0x6000A000 DT_SIZE_K(4)>; + clocks = <&clock ESP32_TIMG1_MODULE>; + group = <1>; + index = <0>; + interrupts = ; + interrupt-parent = <&intc>; + status = "disabled"; + + counter { + compatible = "espressif,esp32-counter"; + status = "disabled"; + }; + }; + + rtc_timer: rtc_timer@600b0c00 { + compatible = "espressif,esp32-rtc_timer"; + reg = <0x600B0C00 DT_SIZE_K(1)>; + clocks = <&clock ESP32_MODULE_MAX>; + interrupts = ; + interrupt-parent = <&intc>; + status = "disabled"; + }; + + trng0: trng@600b2808 { + compatible = "espressif,esp32-trng"; + reg = <0x600B2808 0x4>; + clocks = <&clock ESP32_RNG_MODULE>; + status = "disabled"; + }; + + wdt0: watchdog@60009048 { + compatible = "espressif,esp32-watchdog"; + reg = <0x60009048 0x20>; + interrupts = ; + interrupt-parent = <&intc>; + clocks = <&clock ESP32_TIMG0_MODULE>; + status = "disabled"; + }; + + wdt1: watchdog@6000a048 { + compatible = "espressif,esp32-watchdog"; + reg = <0x6000A048 0x20>; + interrupts = ; + interrupt-parent = <&intc>; + clocks = <&clock ESP32_TIMG1_MODULE>; + status = "disabled"; + }; + + flash: flash-controller@60002000 { + compatible = "espressif,esp32-flash-controller"; + reg = <0x60002000 0x1000>; + + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@0 { + compatible = "soc-nv-flash"; + erase-block-size = <4096>; + write-block-size = <4>; + /* Flash size is specified in SOC/SIP dtsi */ + }; + }; + + coretemp: coretemp@6000e058 { + compatible = "espressif,esp32-temp"; + friendly-name = "coretemp"; + reg = <0x6000E058 0x4>; + status = "disabled"; + }; + + gpio0: gpio@60091000 { + compatible = "espressif,esp32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x60091000 DT_SIZE_K(4)>; + interrupts = ; + interrupt-parent = <&intc>; + ngpios = <32>; + gpio-reserved-ranges = + <6 2>, /* GPIO6–7 */ + <15 7>, /* GPIO15–21 */ + <28 4>; /* GPIO28–31 */ + }; + + uart0: uart@60000000 { + compatible = "espressif,esp32-uart"; + reg = <0x60000000 DT_SIZE_K(4)>; + status = "disabled"; + interrupts = ; + interrupt-parent = <&intc>; + clocks = <&clock ESP32_UART0_MODULE>; + }; + + uart1: uart@60001000 { + compatible = "espressif,esp32-uart"; + reg = <0x60001000 DT_SIZE_K(4)>; + status = "disabled"; + interrupts = ; + interrupt-parent = <&intc>; + clocks = <&clock ESP32_UART1_MODULE>; + }; + }; +}; diff --git a/dts/riscv/espressif/esp32h2/esp32h2_mini_h2.dtsi b/dts/riscv/espressif/esp32h2/esp32h2_mini_h2.dtsi new file mode 100644 index 0000000000000..e67b0e6475ad4 --- /dev/null +++ b/dts/riscv/espressif/esp32h2/esp32h2_mini_h2.dtsi @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + #include "esp32h2_common.dtsi" + +/* 2MB flash */ +&flash0 { + reg = <0x0 DT_SIZE_M(2)>; +}; diff --git a/dts/riscv/espressif/esp32h2/esp32h2_mini_h4.dtsi b/dts/riscv/espressif/esp32h2/esp32h2_mini_h4.dtsi new file mode 100644 index 0000000000000..e4de9fd312f97 --- /dev/null +++ b/dts/riscv/espressif/esp32h2/esp32h2_mini_h4.dtsi @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + #include "esp32h2_common.dtsi" + +/* 4MB flash */ +&flash0 { + reg = <0x0 DT_SIZE_M(4)>; +}; diff --git a/dts/riscv/espressif/esp32h2/esp32h2_wroom_02c_h2.dtsi b/dts/riscv/espressif/esp32h2/esp32h2_wroom_02c_h2.dtsi new file mode 100644 index 0000000000000..e67b0e6475ad4 --- /dev/null +++ b/dts/riscv/espressif/esp32h2/esp32h2_wroom_02c_h2.dtsi @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + #include "esp32h2_common.dtsi" + +/* 2MB flash */ +&flash0 { + reg = <0x0 DT_SIZE_M(2)>; +}; diff --git a/dts/riscv/espressif/esp32h2/esp32h2_wroom_02c_h4.dtsi b/dts/riscv/espressif/esp32h2/esp32h2_wroom_02c_h4.dtsi new file mode 100644 index 0000000000000..e4de9fd312f97 --- /dev/null +++ b/dts/riscv/espressif/esp32h2/esp32h2_wroom_02c_h4.dtsi @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + #include "esp32h2_common.dtsi" + +/* 4MB flash */ +&flash0 { + reg = <0x0 DT_SIZE_M(4)>; +}; diff --git a/soc/espressif/common/Kconfig.defconfig b/soc/espressif/common/Kconfig.defconfig index 23924f8612133..337895ded15d7 100644 --- a/soc/espressif/common/Kconfig.defconfig +++ b/soc/espressif/common/Kconfig.defconfig @@ -1,7 +1,7 @@ -# Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. +# Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_ESP32C2 || SOC_SERIES_ESP32C3 || SOC_SERIES_ESP32C6 +if SOC_SERIES_ESP32C2 || SOC_SERIES_ESP32C3 || SOC_SERIES_ESP32C6 || SOC_SERIES_ESP32H2 config GEN_ISR_TABLES default y if !SOC_ESP32C6_LPCORE @@ -30,6 +30,7 @@ config XTAL_FREQ_HZ config SYS_CLOCK_HW_CYCLES_PER_SEC default 10400000 if XTAL_FREQ_HZ = 26000000 + default 16000000 if XTAL_FREQ_HZ = 32000000 default 16000000 if XTAL_FREQ_HZ = 40000000 config SYS_CLOCK_TICKS_PER_SEC @@ -51,7 +52,7 @@ config ROM_START_OFFSET endif # BOOTLOADER_MCUBOOT -endif # SOC_SERIES_ESP32C2 || SOC_SERIES_ESP32C3 || SOC_SERIES_ESP32C6 +endif # SOC_SERIES_ESP32C2 || SOC_SERIES_ESP32C3 || SOC_SERIES_ESP32C6 || SOC_SERIES_ESP32H2 if SOC_SERIES_ESP32 || SOC_SERIES_ESP32S2 || SOC_SERIES_ESP32S3 diff --git a/soc/espressif/common/Kconfig.esptool b/soc/espressif/common/Kconfig.esptool index b484437197156..09c880e4cd318 100644 --- a/soc/espressif/common/Kconfig.esptool +++ b/soc/espressif/common/Kconfig.esptool @@ -81,6 +81,7 @@ config ESPTOOLPY_FLASHMODE choice ESPTOOLPY_FLASHFREQ prompt "Flash SPI speed" default ESPTOOLPY_FLASHFREQ_40M if SOC_SERIES_ESP32 + default ESPTOOLPY_FLASHFREQ_48M if SOC_SERIES_ESP32H2 default ESPTOOLPY_FLASHFREQ_60M if SOC_SERIES_ESP32C2 default ESPTOOLPY_FLASHFREQ_80M if ESPTOOLPY_FLASHFREQ_80M_DEFAULT @@ -102,6 +103,8 @@ config ESPTOOLPY_FLASHFREQ_80M bool "80 MHz" config ESPTOOLPY_FLASHFREQ_60M bool "60 MHz" +config ESPTOOLPY_FLASHFREQ_48M + bool "48 MHz" config ESPTOOLPY_FLASHFREQ_40M bool "40 MHz" config ESPTOOLPY_FLASHFREQ_26M @@ -125,6 +128,7 @@ config ESPTOOLPY_FLASHFREQ default '80m' if ESPTOOLPY_FLASHFREQ_120M default '80m' if ESPTOOLPY_FLASHFREQ_80M default '60m' if ESPTOOLPY_FLASHFREQ_60M + default '48m' if ESPTOOLPY_FLASHFREQ_48M default '40m' if ESPTOOLPY_FLASHFREQ_40M default '26m' if ESPTOOLPY_FLASHFREQ_26M default '20m' if ESPTOOLPY_FLASHFREQ_20M diff --git a/soc/espressif/common/Kconfig.flash b/soc/espressif/common/Kconfig.flash index 84f565f85aa91..d0da7284b18c5 100644 --- a/soc/espressif/common/Kconfig.flash +++ b/soc/espressif/common/Kconfig.flash @@ -94,7 +94,7 @@ config BOOTLOADER_FLASH_XMC_SUPPORT choice BOOTLOADER_VDDSDIO_BOOST bool "VDDSDIO LDO voltage" default BOOTLOADER_VDDSDIO_BOOST_1_9V - depends on !SOC_SERIES_ESP32C2 && !SOC_SERIES_ESP32C3 && !SOC_SERIES_ESP32C6 + depends on !SOC_SERIES_ESP32C2 && !SOC_SERIES_ESP32C3 && !SOC_SERIES_ESP32C6 && !SOC_SERIES_ESP32H2 help If this option is enabled, and VDDSDIO LDO is set to 1.8V (using eFuse or MTDI bootstrapping pin), bootloader will change LDO settings to diff --git a/soc/espressif/esp32h2/CMakeLists.txt b/soc/espressif/esp32h2/CMakeLists.txt new file mode 100644 index 0000000000000..0248ccef51e47 --- /dev/null +++ b/soc/espressif/esp32h2/CMakeLists.txt @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources( + vectors.S + soc_irq.S + soc.c + ../common/loader.c + ) + +zephyr_include_directories(.) + +zephyr_sources_ifndef(CONFIG_BOOTLOADER_MCUBOOT hw_init.c) diff --git a/soc/espressif/esp32h2/Kconfig b/soc/espressif/esp32h2/Kconfig new file mode 100644 index 0000000000000..e5974e87a7923 --- /dev/null +++ b/soc/espressif/esp32h2/Kconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_ESP32H2 + select RISCV + select RISCV_SOC_HAS_GP_RELATIVE_ADDRESSING + select DYNAMIC_INTERRUPTS + select CLOCK_CONTROL + select PINCTRL + select RISCV_ISA_RV32I + select RISCV_ISA_EXT_A + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_C + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI + select HAS_ESPRESSIF_HAL diff --git a/soc/espressif/esp32h2/Kconfig.defconfig b/soc/espressif/esp32h2/Kconfig.defconfig new file mode 100644 index 0000000000000..558dff5b6df9c --- /dev/null +++ b/soc/espressif/esp32h2/Kconfig.defconfig @@ -0,0 +1,18 @@ +# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_ESP32H2 + +config NUM_IRQS + default 32 + +config FLASH_SIZE + default $(dt_node_reg_size_int,/soc/flash-controller@60002000/flash@0,0) + +config FLASH_BASE_ADDRESS + default $(dt_node_reg_addr_hex,/soc/flash-controller@60002000/flash@0) + +config MAIN_STACK_SIZE + default 2048 + +endif # SOC_SERIES_ESP32H2 diff --git a/soc/espressif/esp32h2/Kconfig.soc b/soc/espressif/esp32h2/Kconfig.soc new file mode 100644 index 0000000000000..c1f76ae06833d --- /dev/null +++ b/soc/espressif/esp32h2/Kconfig.soc @@ -0,0 +1,38 @@ +# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_ESP32H2 + bool + select SOC_FAMILY_ESPRESSIF_ESP32 + +config SOC_ESP32_H2_MINI_H2 + bool + select SOC_ESP32H2 + +config SOC_ESP32_H2_MINI_H4 + bool + select SOC_ESP32H2 + +config SOC_ESP32_H2_WROOM_02C_H2 + bool + select SOC_ESP32H2 + +config SOC_ESP32_H2_WROOM_02C_H4 + bool + select SOC_ESP32H2 + +config SOC_ESP32H2 + bool + select SOC_SERIES_ESP32H2 + +config SOC_SERIES + default "esp32h2" if SOC_SERIES_ESP32H2 + +config SOC + default "esp32h2" if SOC_ESP32H2 + +config SOC_PART_NUMBER + default "ESP32_H2_MINI_1_H2S" if SOC_ESP32_H2_MINI_H2 + default "ESP32_H2_MINI_1_H4S" if SOC_ESP32_H2_MINI_H4 + default "ESP32_H2_WROOM_02C_H2S" if SOC_ESP32_H2_WROOM_02C_H2 + default "ESP32_H2_WROOM_02C_H4S" if SOC_ESP32_H2_WROOM_02C_H4 diff --git a/soc/espressif/esp32h2/default.ld b/soc/espressif/esp32h2/default.ld new file mode 100644 index 0000000000000..c933a43425801 --- /dev/null +++ b/soc/espressif/esp32h2/default.ld @@ -0,0 +1,870 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "memory.h" + +/* The "user_sram_end" represents the 2nd stage bootloader + * "iram_loader_seg" start address (that should not be overlapped). + * If no bootloader is used, we can extend it to gain more user ram. + */ +#ifdef CONFIG_ESP_SIMPLE_BOOT +user_sram_end = DRAM_BUFFERS_START; +#else +user_sram_end = BOOTLOADER_IRAM_LOADER_SEG_START; +#endif + +/* User available memory segments */ +user_sram_org = HPSRAM_START; +user_sram_size = (user_sram_end - user_sram_org); + +/* Aliases */ +#define FLASH_CODE_REGION irom0_0_seg +#define RODATA_REGION drom0_0_seg +#define RAMABLE_REGION sram0_0_seg +#define ROMABLE_REGION FLASH + +#undef GROUP_DATA_LINK_IN +#define GROUP_DATA_LINK_IN(vregion, lregion) > vregion AT > lregion + +#undef GROUP_NOLOAD_LINK_IN +#define GROUP_NOLOAD_LINK_IN(vregion, lregion) > vregion + +/* Flash segments (rodata and text) should be mapped in the virtual address spaces. + * Executing directly from LMA is not possible. */ +#undef GROUP_ROM_LINK_IN +#define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion + +/* Make sure new sections have consistent alignment between input and output sections */ +#undef SECTION_DATA_PROLOGUE +#define SECTION_DATA_PROLOGUE(name, options, align) name options : ALIGN_WITH_INPUT + +#undef SECTION_PROLOGUE +#define SECTION_PROLOGUE SECTION_DATA_PROLOGUE + +/* Global symbols required for espressif hal build */ +MEMORY +{ +#ifdef CONFIG_BOOTLOADER_MCUBOOT + mcuboot_hdr (R): org = 0x0, len = 0x20 + metadata (R): org = 0x20, len = 0x60 + FLASH (R): org = 0x80, len = FLASH_SIZE - 0x80 +#else + /* Make safety margin in the FLASH memory size so the + * (esp_img_header + (n*esp_seg_headers)) would fit */ + FLASH (R): org = 0x0, len = FLASH_SIZE - 0x100 +#endif + + sram0_0_seg(RW): org = user_sram_org, len = user_sram_size + + irom0_0_seg(RX): org = IROM_SEG_ORG, len = IROM_SEG_LEN + drom0_0_seg(R): org = DROM_SEG_ORG, len = DROM_SEG_LEN + + lp_ram_seg(RW): org = LPSRAM_IRAM_START, + len = 0x4000 - CONFIG_RESERVE_RTC_MEM + + /* We reduced the size of lp_ram_seg by CONFIG_RESERVE_RTC_MEM value. + It reserves the amount of LP memory that we use for this memory segment. + This segment is intended for keeping: + - (lower addr) rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files). + - (higher addr) bootloader rtc data (s_bootloader_retain_mem, when a Kconfig option is on). + The aim of this is to keep data that will not be moved around and have a fixed address. + */ +#if (CONFIG_RESERVE_RTC_MEM > 0) + lp_reserved_seg(RW) : org = LPSRAM_IRAM_START + 0x4000 - CONFIG_RESERVE_RTC_MEM, + len = CONFIG_RESERVE_RTC_MEM +#endif + +#ifdef CONFIG_GEN_ISR_TABLES + IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000 +#endif +} + +/* The lines below define location alias for .rtc.data section + * H2 has no distinguished LP(RTC) fast and slow memory sections, + * instead, there is a unified LP_RAM section + * Thus, the following region segments are + * not configurable like on other targets + */ +REGION_ALIAS("rtc_iram_seg", lp_ram_seg ); +REGION_ALIAS("rtc_data_seg", rtc_iram_seg ); +REGION_ALIAS("rtc_slow_seg", rtc_iram_seg ); +REGION_ALIAS("rtc_data_location", rtc_iram_seg ); + +/* Default entry point: */ +ENTRY(CONFIG_KERNEL_ENTRY) + +/* Heap size calculations */ +_heap_sentry = DRAM_RESERVED_START; +_libc_heap_size = _heap_sentry - _end; + +SECTIONS +{ +#ifdef CONFIG_BOOTLOADER_MCUBOOT + /* Reserve space for MCUboot header in the binary */ + .mcuboot_header : + { + QUAD(0x0) + QUAD(0x0) + QUAD(0x0) + QUAD(0x0) + } > mcuboot_hdr + .metadata : + { + /* 0. Magic byte for load header */ + LONG(0xace637d3) + + /* 1. Application entry point address */ + KEEP(*(.entry_addr)) + + /* IRAM metadata: + * 2. Destination address (VMA) for IRAM region + * 3. Flash offset (LMA) for start of IRAM region + * 4. Size of IRAM region + */ + LONG(ADDR(.iram0.text)) + LONG(LOADADDR(.iram0.text)) + LONG(LOADADDR(.iram0.data) - LOADADDR(.iram0.text)) + + /* DRAM metadata: + * 5. Destination address (VMA) for DRAM region + * 6. Flash offset (LMA) for start of DRAM region + * 7. Size of DRAM region + */ + LONG(ADDR(.dram0.data)) + LONG(LOADADDR(.dram0.data)) + LONG(LOADADDR(.dram0.end) - LOADADDR(.dram0.data)) + + /* LP_IRAM metadata: + * 8. Destination address (VMA) for LP_IRAM region + * 9. Flash offset (LMA) for start of LP_IRAM region + * 10. Size of LP_IRAM region + */ + LONG(ADDR(.rtc.text)) + LONG(LOADADDR(.rtc.text)) + LONG(SIZEOF(.rtc.text)) + + /* LP_DATA metadata: + * 11. Destination address (VMA) for LP_DRAM region + * 12. Flash offset (LMA) for start of LP_DRAM region + * 13. Size of LP_DRAM region + */ + LONG(ADDR(.rtc.data)) + LONG(LOADADDR(.rtc.data)) + LONG(SIZEOF(.rtc.data)) + + /* IROM metadata: + * 14. Destination address (VMA) for IROM region + * 15. Flash offset (LMA) for start of IROM region + * 16. Size of IROM region + */ + LONG(ADDR(.flash.text)) + LONG(LOADADDR(.flash.text)) + LONG(SIZEOF(.flash.text)) + + /* DROM metadata: + * 17. Destination address (VMA) for DROM region + * 18. Flash offset (LMA) for start of DROM region + * 19. Size of DROM region + */ + LONG(ADDR(.flash.rodata)) + LONG(LOADADDR(.flash.rodata)) + LONG(LOADADDR(.flash.rodata_end) - LOADADDR(.flash.rodata)) + } > metadata +#endif /* CONFIG_BOOTLOADER_MCUBOOT */ + + #include + +#ifdef CONFIG_LLEXT + #include +#endif + + /* --- START OF RTC --- */ + .rtc.text : + { + . = ALIGN(4); + _rtc_fast_start = ABSOLUTE(.); + _rtc_text_start = ABSOLUTE(.); + *(.rtc.entry.text) + *(.rtc.literal .rtc.literal.* .rtc.text .rtc.text.*) + . = ALIGN(4); + _rtc_text_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION) + + /* This section located in RTC FAST Memory area. + * It holds data marked with RTC_FAST_ATTR attribute. + * See the file "esp_attr.h" for more information. + */ + .rtc.force_fast : + { + . = ALIGN(4); + _rtc_force_fast_start = ABSOLUTE(.); + + *(.rtc.force_fast .rtc.force_fast.*) + . = ALIGN(4); + _rtc_force_fast_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION) + + /* RTC data section holds data marked with + * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. + */ + .rtc.data : + { + _rtc_data_start = ABSOLUTE(.); + *(.rtc.data .rtc.data.*) + *(.rtc.rodata .rtc.rodata.*) + _rtc_data_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION) + + .rtc.bss (NOLOAD) : + { + _rtc_bss_start = ABSOLUTE(.); + *(.rtc.bss .rtc.bss.*) + _rtc_bss_end = ABSOLUTE(.); + } GROUP_LINK_IN(lp_ram_seg) + + /* This section holds data that should not be initialized at power up + * and will be retained during deep sleep. + * User data marked with RTC_NOINIT_ATTR will be placed + * into this section. See the file "esp_attr.h" for more information. + */ + .rtc_noinit (NOLOAD) : + { + . = ALIGN(4); + _rtc_noinit_start = ABSOLUTE(.); + *(.rtc_noinit .rtc_noinit.*) + . = ALIGN(4) ; + _rtc_noinit_end = ABSOLUTE(.); + } GROUP_LINK_IN(lp_ram_seg) + + /* This section located in RTC SLOW Memory area. + * It holds data marked with RTC_SLOW_ATTR attribute. + * See the file "esp_attr.h" for more information. + */ + .rtc.force_slow : + { + . = ALIGN(4); + _rtc_force_slow_start = ABSOLUTE(.); + *(.rtc.force_slow .rtc.force_slow.*) + . = ALIGN(4); + _rtc_force_slow_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION) + + /** + * This section holds RTC data that should have fixed addresses. + * The data are not initialized at power-up and are retained during deep sleep. + */ +#if (CONFIG_RESERVE_RTC_MEM > 0) + .rtc_reserved (NOLOAD) : + { + . = ALIGN(4); + _rtc_reserved_start = ABSOLUTE(.); + *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) + _rtc_reserved_end = ABSOLUTE(.); + } GROUP_LINK_IN(lp_reserved_seg) +#endif + + /* Get size of rtc slow data based on rtc_data_location alias */ + _rtc_slow_length = (_rtc_force_slow_end - _rtc_data_start); + _rtc_fast_length = (_rtc_force_fast_end - _rtc_fast_start); + + ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), "RTC_SLOW segment data does not fit.") + ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), "RTC_FAST segment data does not fit.") + + /* --- END OF RTC --- */ + + /* --- START OF IRAM --- */ + + .iram0.text : ALIGN(4) + { + /* Vectors go to IRAM */ + _iram_start = ABSOLUTE(.); + _init_start = ABSOLUTE(.); + + KEEP(*(.exception_vectors.text)); + . = ALIGN(256); + + _invalid_pc_placeholder = ABSOLUTE(.); + + KEEP(*(.exception.entry*)); /* contains _isr_wrapper */ + *(.exception.other*) + . = ALIGN(4); + + *(.entry.text) + *(.init.literal) + *(.init) + . = ALIGN(4); + + _init_end = ABSOLUTE(.); + _iram_text_start = ABSOLUTE(.); + + *(.iram1 .iram1.*) + *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) + *libzephyr.a:panic.*(.literal .text .literal.* .text.*) + *libzephyr.a:loader.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:soc_flash_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:console_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:soc_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:hw_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:soc_random.*(.literal .text .literal.* .text.*) + + *libarch__riscv__core.a:(.literal .text .literal.* .text.*) + *libkernel.a:(.literal .text .literal.* .text.*) + *libgcc.a:lib2funcs.*(.literal .text .literal.* .text.*) + *libdrivers__flash.a:flash_esp32.*(.literal .text .literal.* .text.*) + *libzephyr.a:log_noos.*(.literal .text .literal.* .text.*) + *libdrivers__timer.a:esp32h2_sys_timer.*(.literal .text .literal.* .text.*) + *libzephyr.a:log_core.*(.literal .text .literal.* .text.*) + *libzephyr.a:cbprintf_complete.*(.literal .text .literal.* .text.*) + *libzephyr.a:printk.*(.literal.printk .literal.vprintk .literal.char_out .text.printk .text.vprintk .text.char_out) + *libzephyr.a:log_msg.*(.literal .text .literal.* .text.*) + *libzephyr.a:log_list.*(.literal .text .literal.* .text.*) + *libdrivers__console.a:uart_console.*(.literal.console_out .text.console_out) + *libzephyr.a:log_output.*(.literal .text .literal.* .text.*) + *libzephyr.a:log_backend_uart.*(.literal .text .literal.* .text.*) + *libzephyr.a:rtc_*.*(.literal .text .literal.* .text.*) + *libzephyr.a:periph_ctrl.*(.literal .text .literal.* .text.*) + *libzephyr.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) + *libgcov.a:(.literal .text .literal.* .text.*) + *libphy.a:( .phyiram .phyiram.*) + *librtc.a:(.literal .text .literal.* .text.*) + + /* [mapping:hal] */ + *libzephyr.a:efuse_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:spi_flash_hal_iram.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_encrypt_hal_iram.*(.literal .text .literal.* .text.*) + *libzephyr.a:cache_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:ledc_hal_iram.*(.literal .text .literal.* .text.*) + *libzephyr.a:i2c_hal_iram.*(.literal .text .literal.* .text.*) + *libzephyr.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) + *libzephyr.a:systimer_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:spi_flash_hal_gpspi.*(.literal .literal.* .text .text.*) + *libzephyr.a:modem_clock_hal.*(.literal .literal.* .text .text.*) + *libzephyr.a:modem_clock.*(.literal .literal.* .text .text.*) + + /* [mapping:soc] */ + *libzephyr.a:lldesc.*(.literal .literal.* .text .text.*) + + /* [mapping:log] */ + *(.literal.esp_log_write .text.esp_log_write) + *(.literal.esp_log_timestamp .text.esp_log_timestamp) + *(.literal.esp_log_early_timestamp .text.esp_log_early_timestamp) + *(.literal.esp_log_impl_lock .text.esp_log_impl_lock) + *(.literal.esp_log_impl_lock_timeout .text.esp_log_impl_lock_timeout) + *(.literal.esp_log_impl_unlock .text.esp_log_impl_unlock) + + /* [mapping:spi_flash] */ + *libzephyr.a:spi_flash_chip_boya.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_gd.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_generic.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_issi.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_mxic.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_mxic_opi.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_th.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_winbond.*(.literal .literal.* .text .text.*) + *libzephyr.a:memspi_host_driver.*(.literal .literal.* .text .text.*) + *libzephyr.a:flash_brownout_hook.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_wrap.*(.literal .literal.* .text .text.*) + *libzephyr.a:flash_ops.*(.literal .literal.* .text .text.*) + + /* [mapping:esp_system] */ + *libzephyr.a:reset_reason.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_err.*(.literal .literal.* .text .text.*) + *(.literal.esp_system_abort .text.esp_system_abort) + + /* [mapping:esp_hw_support] */ + *(.literal.esp_cpu_stall .text.esp_cpu_stall) + *(.literal.esp_cpu_unstall .text.esp_cpu_unstall) + *(.literal.esp_cpu_reset .text.esp_cpu_reset) + *(.literal.esp_cpu_wait_for_intr .text.esp_cpu_wait_for_intr) + *(.literal.esp_cpu_compare_and_set .text.esp_cpu_compare_and_set) + *(.literal.esp_gpio_reserve_pins .text.esp_gpio_reserve_pins) + *(.literal.esp_gpio_is_pin_reserved .text.esp_gpio_is_pin_reserved) + *(.literal.rtc_vddsdio_get_config .text.rtc_vddsdio_get_config) + *(.literal.rtc_vddsdio_set_config .text.rtc_vddsdio_set_config) + *libzephyr.a:esp_memory_utils.*(.literal .literal.* .text .text.*) + *libzephyr.a:pmu_init.*(.literal .literal.* .text .text.*) + *libzephyr.a:pmu_param.*(.literal .literal.* .text .text.*) + *libzephyr.a:pmu_sleep.*(.literal .literal.* .text .text.*) + *libzephyr.a:rtc_clk.*(.literal .literal.* .text .text.*) + *libzephyr.a:rtc_clk_init.*(.literal .literal.* .text .text.*) + *libzephyr.a:rtc_time.*(.literal .literal.* .text .text.*) + *libzephyr.a:rtc_sleep.*(.literal .literal.* .text .text.*) + *libzephyr.a:systimer.*(.literal .literal.* .text .text.*) + *(.literal.sar_periph_ctrl_power_enable .text.sar_periph_ctrl_power_enable) + + /* [mapping:soc_pm] */ + *(.literal.GPIO_HOLD_MASK .text.GPIO_HOLD_MASK) + + /* [mapping:esp_rom] */ + *libzephyr.a:esp_rom_crc.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_sys.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_uart.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_spiflash.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_efuse.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_systimer.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_wdt.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_regi2c_esp32h2.*(.literal .literal.* .text .text.*) + + /* [mapping:esp_mm] */ + *libzephyr.a:esp_cache.*(.literal .literal.* .text .text.*) + *libzephyr.a:cache_utils.*(.literal .text .literal.* .text.*) + + . = ALIGN(4) + 16; + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + +#ifdef CONFIG_ESP_SIMPLE_BOOT + .loader.text : + { + . = ALIGN(4); + _loader_text_start = ABSOLUTE(.); + *libzephyr.a:bootloader_clock_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_wdt.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_flash.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_panic.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_random.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_efuse.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_utility.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_sha.*(.literal .text .literal.* .text.*) + + *libzephyr.a:esp_image_format.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_ops.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_encrypt.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_partitions.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_qio_mode.*(.literal .text .literal.* .text.*) + *libzephyr.a:spi_flash_hal.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_hal_common.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_flash_api.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_flash_spi_init.*(.literal .text .literal.* .text.*) + + *libzephyr.a:esp_efuse_table.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_efuse_fields.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_efuse_api.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_efuse_utility.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_efuse_api_key_esp32xx.*(.literal .text .literal.* .text.*) + *libzephyr.a:secure_boot.*(.literal .text .literal.* .text.*) + *libzephyr.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) + *libzephyr.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) + + *libzephyr.a:cpu_region_protect.*(.literal .text .literal.* .text.*) + + /* TODO: optimise */ + *libzephyr.a:esp_gpio_reserve.*(.literal .text .literal.* .text.*) + + . = ALIGN(4) + 16; + _loader_text_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) +#endif /* CONFIG_ESP_SIMPLE_BOOT */ + + .iram0.text_end (NOLOAD) : + { + /* H2 memprot requires 512 B alignment for split lines */ + . = ALIGN(16); + _iram_text_end = ABSOLUTE(.); + } GROUP_LINK_IN(RAMABLE_REGION) + + .iram0.data : + { + . = ALIGN(16); + *(.iram.data) + *(.iram.data*) + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + + .iram0.bss (NOLOAD) : + { + . = ALIGN(16); + *(.iram.bss) + *(.iram.bss*) + + . = ALIGN(16); + _iram_end = ABSOLUTE(.); + . = ALIGN(16) + 16; + } GROUP_LINK_IN(RAMABLE_REGION) + + /* --- END OF IRAM --- */ + + /* --- START OF DRAM --- */ + + .dram0.data : + { + . = ALIGN(4); + _data_start = ABSOLUTE(.); + __data_start = ABSOLUTE(.); + + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.data1) + +#ifdef CONFIG_RISCV_GP + . = ALIGN(8); + __global_pointer$ = . + 0x800; +#endif /* CONFIG_RISCV_GP */ + + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + + /* All dependent functions should be placed in DRAM to avoid issue + * when flash cache is disabled */ + *libkernel.a:fatal.*(.rodata .rodata.* .srodata .srodata.*) + *libkernel.a:init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:cbprintf_complete*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:log_core.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:log_backend_uart.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:log_output.*(.rodata .rodata.* .srodata .srodata.*) + *libdrivers__flash.a:flash_esp32.*(.rodata .rodata.* .srodata .srodata.*) + *libdrivers__serial.a:uart_esp32.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:periph_ctrl.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:loader.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:flash_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:soc_flash_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:console_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:soc_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:hw_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:soc_random.*(.rodata .rodata.* .srodata .srodata.*) + + *libzephyr.a:cache_utils.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:hal] */ + *libzephyr.a:efuse_hal.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:mmu_hal.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_hal_iram.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_encrypt_hal_iram.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:cache_hal.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:ledc_hal_iram.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:i2c_hal_iram.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:wdt_hal_iram.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:systimer_hal.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_hal_gpspi.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:modem_clock_hal.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:modem_clock.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:soc] */ + *libzephyr.a:lldesc.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:log] */ + *(.rodata.esp_log_write) + *(.rodata.esp_log_timestamp) + *(.rodata.esp_log_early_timestamp) + *(.rodata.esp_log_impl_lock) + *(.rodata.esp_log_impl_lock_timeout) + *(.rodata.esp_log_impl_unlock) + + /* [mapping:spi_flash] */ + *libzephyr.a:spi_flash_chip_boya.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_gd.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_generic.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_issi.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_mxic.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_mxic_opi.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_th.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_winbond.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:memspi_host_driver.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:flash_brownout_hook.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_wrap.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:flash_ops.*(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*) + *libzephyr.a:flash_qio_mode.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:esp_mm] */ + *libzephyr.a:esp_cache.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:esp_hw_support] */ + *(.rodata.esp_cpu_stall) + *(.rodata.esp_cpu_unstall) + *(.rodata.esp_cpu_reset) + *(.rodata.esp_cpu_wait_for_intr) + *(.rodata.esp_cpu_compare_and_set) + *(.rodata.esp_gpio_reserve_pins) + *(.rodata.esp_gpio_is_pin_reserved) + *(.rodata.rtc_vddsdio_get_config) + *(.rodata.rtc_vddsdio_set_config) + *libzephyr.a:esp_memory_utils.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:rtc_clk.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:rtc_clk_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:systimer.*(.rodata .rodata.* .srodata .srodata.*) + *(.rodata.sar_periph_ctrl_power_enable) + *libzephyr.a:pmu_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:pmu_param.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:esp_system] */ + *libzephyr.a:reset_reason.*(.rodata .rodata.*) + *libzephyr.a:esp_err.*(.rodata .rodata.*) + *(.rodata.esp_system_abort) + + /* [mapping:esp_rom] */ + *libzephyr.a:esp_rom_crc.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_sys.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_uart.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_spiflash.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_efuse.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_systimer.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_regi2c_esp32h2.*(.rodata .rodata.* .srodata .srodata.*) + + *libphy.a:(.rodata .rodata.* .srodata .srodata.*) + + . = ALIGN(4); + #include + . = ALIGN(4); + + KEEP(*(.jcr)) + *(.dram1 .dram1.*) + . = ALIGN(4); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + +#ifdef CONFIG_ESP_SIMPLE_BOOT + /* Secondary loader sections */ + .loader.data : + { + . = ALIGN(4); + _loader_data_start = ABSOLUTE(.); + *libzephyr.a:bootloader_clock_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:bootloader_wdt.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:bootloader_flash.*(.srodata .srodata.* .rodata .rodata.*) + *libzephyr.a:bootloader_clock_loader.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:bootloader_common_loader.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:bootloader_panic.*(.rodata .rodata.* .srodata .srodata.*) + + *libzephyr.a:cpu_region_protect.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:clk.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_clk.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:flash_mmap.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:flash_ops.*(.rodata .rodata.* .srodata .srodata.*) + + *libzephyr.a:esp_gpio_reserve.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_hal.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_hal_common.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_flash_api.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_flash_spi_init.*(.rodata .rodata.* .srodata .srodata.*) + + . = ALIGN(16); + _loader_data_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) +#endif /* CONFIG_ESP_SIMPLE_BOOT */ + + #include + #include + #include + #include + + /* logging sections should be placed in RAM area to avoid flash cache disabled issues */ + #pragma push_macro("GROUP_ROM_LINK_IN") + #undef GROUP_ROM_LINK_IN + #define GROUP_ROM_LINK_IN GROUP_DATA_LINK_IN + #include + #pragma pop_macro("GROUP_ROM_LINK_IN") + + .dram0.end : + { + . = ALIGN(4); + _data_end = ABSOLUTE(.); + __data_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + + .dram0.noinit (NOLOAD): + { + . = ALIGN(4); + *(.noinit) + *(.noinit.*) + . = ALIGN(4); + } GROUP_LINK_IN(RAMABLE_REGION) + + /* Shared RAM */ + .dram0.bss (NOLOAD) : + { + . = ALIGN (8); + __bss_start = ABSOLUTE(.); + _bss_start = ABSOLUTE(.); + + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.share.mem) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (16); + __bss_end = ABSOLUTE(.); + _bss_end = ABSOLUTE(.); + } GROUP_LINK_IN(RAMABLE_REGION) + + /* Provide total SRAM usage, including IRAM and DRAM */ + _image_ram_start = _iram_start; + #include + + ASSERT(((_end - ORIGIN(sram0_0_seg)) <= LENGTH(sram0_0_seg)), "SRAM code/data does not fit.") + + /* --- END OF DRAM --- */ + + /* --- START OF .flash.text --- */ + + .flash.align_text (NOLOAD): + { + /* Subsequent segment lma align */ + . = ALIGN(CACHE_ALIGN); + } GROUP_LINK_IN(ROMABLE_REGION) + + /* Symbols used during the application memory mapping */ + _image_irom_start = LOADADDR(.flash.text); + _image_irom_size = SIZEOF(.flash.text); + _image_irom_vaddr = ADDR(.flash.text); + + .flash.text : ALIGN(0x10) + { + _stext = .; + _instruction_reserved_start = ABSOLUTE(.); + _text_start = ABSOLUTE(.); + _instruction_reserved_start = ABSOLUTE(.); + __text_region_start = ABSOLUTE(.); + __rom_region_start = ABSOLUTE(.); + + *(.literal .text .literal.* .text.*) + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ + + *(.fini.literal) + *(.fini) + + *(.gnu.version) + + /** CPU will try to prefetch up to 16 bytes of + * of instructions. This means that any configuration (e.g. MMU, PMS) must allow + * safe access to up to 16 bytes after the last real instruction, add + * dummy bytes to ensure this + */ + . += 16; + + _instruction_reserved_end = ABSOLUTE(.); + _text_end = ABSOLUTE(.); + _instruction_reserved_end = ABSOLUTE(.); + __text_region_end = ABSOLUTE(.); + __rom_region_end = ABSOLUTE(.); + _etext = .; + + } GROUP_DATA_LINK_IN(FLASH_CODE_REGION, ROMABLE_REGION) + + /* --- END OF .flash.text --- */ + + /* --- START OF .rodata --- */ + + /* Align next section to 64k to allow mapping */ + .flash.align_rom (NOLOAD) : + { + . = ALIGN(CACHE_ALIGN); + } GROUP_LINK_IN(ROMABLE_REGION) + + /* Symbols used during the application memory mapping */ + _image_drom_start = LOADADDR(.flash.rodata); + _image_drom_size = _image_rodata_end - _image_rodata_start; + _image_drom_vaddr = ADDR(.flash.rodata); + + .flash.rodata : ALIGN(0x10) + { + _rodata_reserved_start = ABSOLUTE(.); + _image_rodata_start = ABSOLUTE(.); + _rodata_start = ABSOLUTE(.); + + *(.rodata_desc .rodata_desc.*) + *(.rodata_custom_desc .rodata_custom_desc.*) + + __rodata_region_start = ABSOLUTE(.); + + . = ALIGN(4); + #include + + *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); + *(.xt_except_table) + *(.gcc_except_table .gcc_except_table.*) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + . = (. + 3) & ~ 3; + __eh_frame = ABSOLUTE(.); + KEEP(*(.eh_frame)) + . = (. + 7) & ~ 3; + + /* C++ exception handlers table: */ + __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + __rodata_region_end = .; + _rodata_end = ABSOLUTE(.); + /* Literals are also RO data. */ + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + . = ALIGN(4); + *(.srodata) + *(.srodata.*) + *(.rodata) + *(.rodata.*) + *(.rodata_wlog) + *(.rodata_wlog*) + . = ALIGN(4); + } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + /* Create an explicit section at the end of all the data that shall be mapped into drom. + * This is used to calculate the size of the _image_drom_size variable */ + .flash.rodata_end : ALIGN(0x10) + { + . = ALIGN(4); + _rodata_reserved_end = ABSOLUTE(.); + _image_rodata_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) + + /* --- END OF .rodata --- */ + +#ifdef CONFIG_GEN_ISR_TABLES + #include +#endif + + #include + /DISCARD/ : { *(.note.GNU-stack) } + + SECTION_PROLOGUE(.riscv.attributes, 0,) + { + KEEP(*(.riscv.attributes)) + KEEP(*(.gnu.attributes)) + } +} diff --git a/soc/espressif/esp32h2/hw_init.c b/soc/espressif/esp32h2/hw_init.c new file mode 100644 index 0000000000000..3eaf036e68e77 --- /dev/null +++ b/soc/espressif/esp32h2/hw_init.c @@ -0,0 +1,98 @@ +/* + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "hw_init.h" +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +const static char *TAG = "hw_init"; + +int hardware_init(void) +{ + int err = 0; + + soc_hw_init(); + + ana_reset_config(); + super_wdt_auto_feed(); + + /* By default, these access path filters are enable and allow the + * access to masters only if they are in TEE mode. Since all masters + * except HP CPU boots in REE mode, default setting of these filters + * will deny the access to all masters except HP CPU. + * So, at boot disabling these filters. They will enable as per the + * use case by TEE initialization code. + */ + REG_WRITE(LP_APM_FUNC_CTRL_REG, 0); + REG_WRITE(LP_APM0_FUNC_CTRL_REG, 0); + REG_WRITE(HP_APM_FUNC_CTRL_REG, 0); + +#ifdef CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE + esp_cpu_configure_region_protection(); +#endif + + bootloader_clock_configure(); + +#ifdef CONFIG_ESP_CONSOLE + /* initialize console, from now on, we can log */ + esp_console_init(); + print_banner(); +#endif /* CONFIG_ESP_CONSOLE */ + + cache_hal_init(); + mmu_hal_init(); + + flash_update_id(); + + err = bootloader_flash_xmc_startup(); + if (err != 0) { + ESP_EARLY_LOGE(TAG, "failed when running XMC startup flow, reboot!"); + return err; + } + + err = read_bootloader_header(); + if (err != 0) { + return err; + } + + err = check_bootloader_validity(); + if (err != 0) { + return err; + } + + err = init_spi_flash(); + if (err != 0) { + return err; + } + + check_wdt_reset(); + config_wdt(); + + soc_random_enable(); + + return 0; +} diff --git a/soc/espressif/esp32h2/mcuboot.ld b/soc/espressif/esp32h2/mcuboot.ld new file mode 100644 index 0000000000000..4856d6d3dac60 --- /dev/null +++ b/soc/espressif/esp32h2/mcuboot.ld @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include "memory.h" + +/* Disable all romable LMA */ +#undef GROUP_DATA_LINK_IN +#define GROUP_DATA_LINK_IN(vregion, lregion) > vregion + +#define RAMABLE_REGION dram_seg +#define RODATA_REGION dram_seg +#define ROMABLE_REGION dram_seg + +/* Global symbols required for espressif hal build */ +MEMORY +{ + iram_seg (RX) : org = BOOTLOADER_IRAM_SEG_START, + len = BOOTLOADER_IRAM_SEG_LEN + iram_loader_seg (RX) : org = BOOTLOADER_IRAM_LOADER_SEG_START, + len = BOOTLOADER_IRAM_LOADER_SEG_LEN + dram_seg (RW) : org = BOOTLOADER_DRAM_SEG_START, + len = BOOTLOADER_DRAM_SEG_LEN + +#ifdef CONFIG_GEN_ISR_TABLES + IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000 +#endif +} + +/* Default entry point: */ +ENTRY(CONFIG_KERNEL_ENTRY) + +SECTIONS +{ + .iram0.loader_text : + { + . = ALIGN (16); + _loader_text_start = ABSOLUTE(.); + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + + *libapp.a:flash_map_extended.*(.literal .text .literal.* .text.*) + *libzephyr.a:cbprintf_nano.*(.literal .text .literal.* .text.*) + *libzephyr.a:cpu.*(.literal .text .literal.* .text.*) + *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_map.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_rom_spiflash.*(.literal .text .literal.* .text.*) + *libkernel.a:device.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_loader.*(.literal .text .literal.* .text.*) + + *(.literal.esp_intr_disable .literal.esp_intr_disable.* .text.esp_intr_disable .text.esp_intr_disable.*) + *(.literal.default_intr_handler .text.default_intr_handler .iram1.*.default_intr_handler) + *(.literal.esp_log_timestamp .text.esp_log_timestamp) + *(.literal.esp_log_early_timestamp .text.esp_log_early_timestamp) + *(.literal.esp_system_abort .text.esp_system_abort) + + *(.fini.literal) + *(.fini) + *(.gnu.version) + _loader_text_end = ABSOLUTE(.); + _iram_end = ABSOLUTE(.); + } > iram_loader_seg + + .iram0.text : + { + /* Vectors go to IRAM */ + _iram_start = ABSOLUTE(.); + _init_start = ABSOLUTE(.); + __text_region_start = ABSOLUTE(.); + + KEEP(*(.exception_vectors.text)); + . = ALIGN(256); + + _invalid_pc_placeholder = ABSOLUTE(.); + + _iram_text_start = ABSOLUTE(.); + + KEEP(*(.exception.entry*)); /* contains _isr_wrapper */ + *(.exception.other*) + . = ALIGN(4); + + *(.entry.text) + *(.init.literal) + *(.init) + . = ALIGN(4); + *(.iram1 .iram1.*) + *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) + + /* H2 memprot requires 512 B alignment for split lines */ + . = ALIGN (16); + _init_end = ABSOLUTE(.); + . = ALIGN(16); + *(.iram.data) + *(.iram.data*) + . = ALIGN(16); + *(.iram.bss) + *(.iram.bss*) + + . = ALIGN(16); + + *(.literal .text .literal.* .text.*) + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.fini.literal) + *(.fini) + *(.gnu.version) + + /* CPU will try to prefetch up to 16 bytes of + * of instructions. This means that any configuration (e.g. MMU, PMS) must allow + * safe access to up to 16 bytes after the last real instruction, add + * dummy bytes to ensure this + */ + . += 16; + + _text_end = ABSOLUTE(.); + __text_region_end = ABSOLUTE(.); + _etext = .; + + /* Similar to _iram_start, this symbol goes here so it is + * resolved by addr2line in preference to the first symbol in + * the flash.text segment. + */ + _flash_cache_start = ABSOLUTE(0); + } > iram_seg + + .dram0.data : + { + . = ALIGN(4); + __data_start = ABSOLUTE(.); + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.data1) +#ifdef CONFIG_RISCV_GP + __global_pointer$ = . + 0x800; +#endif /* CONFIG_RISCV_GP */ + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + *libzephyr.a:mmu_hal.*(.rodata .rodata.*) + *libzephyr.a:rtc_clk.*(.rodata .rodata.*) + KEEP(*(.jcr)) + *(.dram1 .dram1.*) + . = ALIGN(4); + + #include + . = ALIGN(4); + + *(.rodata_desc .rodata_desc.*) + *(.rodata_custom_desc .rodata_custom_desc.*) + + . = ALIGN(4); + #include + . = ALIGN(4); + + *(.rodata) + *(.rodata.*) + *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); + *(.xt_except_table) + *(.gcc_except_table .gcc_except_table.*) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + . = (. + 3) & ~ 3; + __eh_frame = ABSOLUTE(.); + KEEP(*(.eh_frame)) + . = (. + 7) & ~ 3; + + /* C++ exception handlers table: */ + __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + __rodata_region_end = .; + _rodata_end = ABSOLUTE(.); + /* Literals are also RO data. */ + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + . = ALIGN(4); + _thread_local_start = ABSOLUTE(.); + *(.tdata) + *(.tdata.*) + *(.tbss) + *(.tbss.*) + *(.srodata) + *(.srodata.*) + *(.rodata) + *(.rodata.*) + *(.rodata_wlog) + *(.rodata_wlog*) + _thread_local_end = ABSOLUTE(.); + /* _rodata_reserved_end = ABSOLUTE(.); */ + . = ALIGN(4); + } > dram_seg + + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + + #include + + .noinit (NOLOAD): + { + . = ALIGN(4); + *(.noinit) + *(.noinit.*) + . = ALIGN(4); + } > dram_seg + + /* Shared RAM */ + .bss (NOLOAD): + { + . = ALIGN (8); + _bss_start = ABSOLUTE(.); + __bss_start = ABSOLUTE(.); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.share.mem) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + __bss_end = ABSOLUTE(.); + _bss_end = ABSOLUTE(.); + } > dram_seg + + /* linker rel sections*/ + #include + +#ifdef CONFIG_GEN_ISR_TABLES + #include +#endif + +#include + /DISCARD/ : { *(.note.GNU-stack) } + + SECTION_PROLOGUE(.riscv.attributes, 0,) + { + KEEP(*(.riscv.attributes)) + KEEP(*(.gnu.attributes)) + } +} diff --git a/soc/espressif/esp32h2/memory.h b/soc/espressif/esp32h2/memory.h new file mode 100644 index 0000000000000..9e2978d30f2cd --- /dev/null +++ b/soc/espressif/esp32h2/memory.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +/* LP-SRAM (4kB) memory */ +#define LPSRAM_IRAM_START DT_REG_ADDR(DT_NODELABEL(sramlp)) +#define LPSRAM_SIZE DT_REG_SIZE(DT_NODELABEL(sramlp)) + +/* HP-SRAM (320kB) memory */ +#define HPSRAM_START DT_REG_ADDR(DT_NODELABEL(sramhp)) +#define HPSRAM_SIZE DT_REG_SIZE(DT_NODELABEL(sramhp)) +#define HPSRAM_DRAM_START HPSRAM_START +#define HPSRAM_IRAM_START HPSRAM_START +/* ICache size is fixed to 16KB on ESP32-H2 */ +#define ICACHE_SIZE 0x4000 + +/** Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + * + * ESP32-H2 ROM static data usage is as follows: + * - 0x4083ba78 - 0x4084d380: Shared buffers, used in UART/USB/SPI download mode only + * - 0x4084d380 - 0x4084f380: PRO CPU stack, can be reclaimed as heap after RTOS startup + * - 0x4084f380 - 0x4084fee0: ROM .bss and .data (reclaimable) + * - 0x4084fee0 - 0x40850000: ROM .bss and .data (cannot be freed) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x4084d380). + */ + +#define DRAM_BUFFERS_START 0x4083ba78 +#define DRAM_BUFFERS_END 0x4084d380 +#define DRAM_STACK_START DRAM_BUFFERS_END +#define DRAM_ROM_BSS_DATA_START 0x4084f380 + +/* Set the limit for the application runtime dynamic allocations */ +#define DRAM_RESERVED_START DRAM_BUFFERS_END + +/* For safety margin between bootloader data section and startup stacks */ +#define BOOTLOADER_STACK_OVERHEAD 0x0 +/* These lengths can be adjusted, if necessary: FIXME: optimize ram usage */ +#define BOOTLOADER_DRAM_SEG_LEN 0x5000 +#define BOOTLOADER_IRAM_LOADER_SEG_LEN 0x7000 +#define BOOTLOADER_IRAM_SEG_LEN 0x2000 + +/* Base address used for calculating memory layout + * counted from Dbus backwards and back to the Ibus + */ +#define BOOTLOADER_USER_SRAM_END (DRAM_BUFFERS_START - BOOTLOADER_STACK_OVERHEAD) + +/* Start of the lower region is determined by region size and the end of the higher region */ +#define BOOTLOADER_IRAM_LOADER_SEG_START (BOOTLOADER_USER_SRAM_END - BOOTLOADER_IRAM_LOADER_SEG_LEN) +#define BOOTLOADER_IRAM_SEG_START (BOOTLOADER_IRAM_LOADER_SEG_START - BOOTLOADER_IRAM_SEG_LEN) +#define BOOTLOADER_DRAM_SEG_START (BOOTLOADER_IRAM_SEG_START - BOOTLOADER_DRAM_SEG_LEN) + +/* Flash */ +#ifdef CONFIG_FLASH_SIZE +#define FLASH_SIZE CONFIG_FLASH_SIZE +#else +#define FLASH_SIZE 0x400000 +#endif + +/* Cached memory */ +#define CACHE_ALIGN CONFIG_MMU_PAGE_SIZE +#define IROM_SEG_ORG 0x42000000 +#define IROM_SEG_LEN FLASH_SIZE +#define DROM_SEG_ORG 0x42800000 +#define DROM_SEG_LEN FLASH_SIZE diff --git a/soc/espressif/esp32h2/pinctrl_soc.h b/soc/espressif/esp32h2/pinctrl_soc.h new file mode 100644 index 0000000000000..ac1bfba5b4b92 --- /dev/null +++ b/soc/espressif/esp32h2/pinctrl_soc.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * ESP32H2 SoC specific helpers for pinctrl driver + */ + +#ifndef ZEPHYR_SOC_RISCV_ESP32H2_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_RISCV_ESP32H2_PINCTRL_SOC_H_ + +#include +#include + +#include + +/** @cond INTERNAL_HIDDEN */ + +/** Type for ESP32 pin. */ +typedef struct pinctrl_soc_pin { + /** Pinmux settings (pin, direction and signal). */ + uint32_t pinmux; + /** Pincfg settings (bias). */ + uint32_t pincfg; +} pinctrl_soc_pin_t; + +/** + * @brief Utility macro to initialize pinmux field in #pinctrl_pin_t. + * + * @param node_id Node identifier. + */ +#define Z_PINCTRL_ESP32_PINMUX_INIT(node_id, prop, idx) DT_PROP_BY_IDX(node_id, prop, idx) + +/** + * @brief Utility macro to initialize pincfg field in #pinctrl_pin_t. + * + * @param node_id Node identifier. + */ +#define Z_PINCTRL_ESP32_PINCFG_INIT(node_id) \ + (((ESP32_NO_PULL * DT_PROP(node_id, bias_disable)) << ESP32_PIN_BIAS_SHIFT) | \ + ((ESP32_PULL_UP * DT_PROP(node_id, bias_pull_up)) << ESP32_PIN_BIAS_SHIFT) | \ + ((ESP32_PULL_DOWN * DT_PROP(node_id, bias_pull_down)) << ESP32_PIN_BIAS_SHIFT) | \ + ((ESP32_PUSH_PULL * DT_PROP(node_id, drive_push_pull)) << ESP32_PIN_DRV_SHIFT) | \ + ((ESP32_OPEN_DRAIN * DT_PROP(node_id, drive_open_drain)) << ESP32_PIN_DRV_SHIFT) | \ + ((ESP32_PIN_OUT_HIGH * DT_PROP(node_id, output_high)) << ESP32_PIN_OUT_SHIFT) | \ + ((ESP32_PIN_OUT_LOW * DT_PROP(node_id, output_low)) << ESP32_PIN_OUT_SHIFT) | \ + ((ESP32_PIN_OUT_EN * DT_PROP(node_id, output_enable)) << ESP32_PIN_EN_DIR_SHIFT) | \ + ((ESP32_PIN_IN_EN * DT_PROP(node_id, input_enable)) << ESP32_PIN_EN_DIR_SHIFT)) + +/** + * @brief Utility macro to initialize each pin. + * + * @param node_id Node identifier. + * @param prop Property name. + * @param idx Property entry index. + */ +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + {.pinmux = Z_PINCTRL_ESP32_PINMUX_INIT(node_id, prop, idx), \ + .pincfg = Z_PINCTRL_ESP32_PINCFG_INIT(node_id)}, + +/** + * @brief Utility macro to initialize state pins contained in a given property. + * + * @param node_id Node identifier. + * @param prop Property name describing state pins. + */ +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, pinmux, \ + Z_PINCTRL_STATE_PIN_INIT)} + +/** @endcond */ + +#endif /* ZEPHYR_SOC_RISCV_ESP32H2_PINCTRL_SOC_H_ */ diff --git a/soc/espressif/esp32h2/soc.c b/soc/espressif/esp32h2/soc.c new file mode 100644 index 0000000000000..47d417a2c21f5 --- /dev/null +++ b/soc/espressif/esp32h2/soc.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void esp_reset_reason_init(void); + +void IRAM_ATTR __esp_platform_app_start(void) +{ + esp_reset_reason_init(); + + esp_timer_early_init(); + + esp_flash_config(); + + esp_efuse_init_virtual(); + + /* Start Zephyr */ + z_cstart(); + + CODE_UNREACHABLE; +} + +void IRAM_ATTR __esp_platform_mcuboot_start(void) +{ + /* Start Zephyr */ + z_cstart(); + + CODE_UNREACHABLE; +} + +/* Boot-time static default printk handler, possibly to be overridden later. */ +int IRAM_ATTR arch_printk_char_out(int c) +{ + if (c == '\n') { + esp_rom_uart_tx_one_char('\r'); + } + esp_rom_uart_tx_one_char(c); + return 0; +} + +void sys_arch_reboot(int type) +{ + esp_restart(); +} diff --git a/soc/espressif/esp32h2/soc.h b/soc/espressif/esp32h2/soc.h new file mode 100644 index 0000000000000..b7590d4c7d0e0 --- /dev/null +++ b/soc/espressif/esp32h2/soc.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __SOC_H__ +#define __SOC_H__ + +#ifndef _ASMLANGUAGE +#include +#include +#include +#include +#include +#include +#endif + +/* ECALL Exception numbers */ +#define SOC_MCAUSE_ECALL_EXP 11 /* Machine ECALL instruction */ +#define SOC_MCAUSE_USER_ECALL_EXP 8 /* User ECALL instruction */ + +/* Interrupt Mask */ +#define SOC_MCAUSE_IRQ_MASK (1 << 31) +/* Exception code Mask */ +#define SOC_MCAUSE_EXP_MASK 0x7FFFFFFF + +#ifndef _ASMLANGUAGE + +void __esp_platform_mcuboot_start(void); +void __esp_platform_app_start(void); + +static inline uint32_t esp_core_id(void) +{ + return 0; +} + +extern void esp_reset_reason_init(void); +extern void esp_rom_route_intr_matrix(int cpu_no, uint32_t model_num, uint32_t intr_num); +extern void esp_rom_intr_matrix_set(int cpu_no, uint32_t model_num, uint32_t intr_num); +extern void esp_rom_uart_attach(void); +extern void esp_rom_uart_tx_wait_idle(uint8_t uart_no); +extern int esp_rom_uart_tx_one_char(uint8_t chr); +extern int esp_rom_gpio_matrix_in(uint32_t gpio, uint32_t signal_index, bool inverted); +extern int esp_rom_gpio_matrix_out(uint32_t gpio, uint32_t signal_index, bool out_inverted, + bool out_enabled_inverted); +extern void esp_rom_ets_set_user_start(uint32_t start); +extern void esprv_intc_int_set_threshold(int priority_threshold); +uint32_t soc_intr_get_next_source(void); +extern void esp_rom_Cache_Resume_ICache(uint32_t autoload); +extern int esp_rom_Cache_Invalidate_Addr(uint32_t addr, uint32_t size); +extern uint32_t esp_rom_Cache_Suspend_ICache(void); +extern void esp_rom_Cache_Invalidate_ICache_All(void); +extern int esp_rom_Cache_Dbus_MMU_Set(uint32_t ext_ram, uint32_t vaddr, uint32_t paddr, + uint32_t psize, uint32_t num, uint32_t fixed); +extern int esp_rom_Cache_Ibus_MMU_Set(uint32_t ext_ram, uint32_t vaddr, uint32_t paddr, + uint32_t psize, uint32_t num, uint32_t fixed); + +#endif /* _ASMLANGUAGE */ + +#endif /* __SOC_H__ */ diff --git a/soc/espressif/esp32h2/soc_irq.S b/soc/espressif/esp32h2/soc_irq.S new file mode 100644 index 0000000000000..90c016792fd31 --- /dev/null +++ b/soc/espressif/esp32h2/soc_irq.S @@ -0,0 +1,15 @@ +/* Copyright 2025 Espressif Systems (Shanghai) PTE LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* Exports */ +GTEXT(__soc_handle_irq) + +SECTION_FUNC(exception.other, __soc_handle_irq) + + /* int status clearing is done at ISR */ + ret diff --git a/soc/espressif/esp32h2/vectors.S b/soc/espressif/esp32h2/vectors.S new file mode 100644 index 0000000000000..1e1910ea602d2 --- /dev/null +++ b/soc/espressif/esp32h2/vectors.S @@ -0,0 +1,35 @@ +/* Copyright 2025 Espressif Systems (Shanghai) PTE LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc.h" +#include "soc/interrupt_reg.h" +#include "riscv/rvruntime-frames.h" +#include "soc/soc_caps.h" +#include + +/* Imports */ +GTEXT(_isr_wrapper) + + /* This is the vector table. MTVEC points here. + * + * Use 4-byte intructions here. 1 instruction = 1 entry of the table. + * The CPU jumps to MTVEC (i.e. the first entry) in case of an exception, + * and (MTVEC & 0xfffffffc) + (mcause & 0x7fffffff) * 4, in case of an interrupt. + * + * Note: for our CPU, we need to place this on a 256-byte boundary, as CPU + * only uses the 24 MSBs of the MTVEC, i.e. (MTVEC & 0xffffff00). + */ + + .global _vector_table + .section .exception_vectors.text + .balign 0x100 + .type _vector_table, @function + +_vector_table: + .option push + .option norvc + .rept (32) + j _isr_wrapper /* 32 identical entries, all pointing to the interrupt handler */ + .endr diff --git a/soc/espressif/soc.yml b/soc/espressif/soc.yml index cd20df8a60b1c..a883b3b792810 100644 --- a/soc/espressif/soc.yml +++ b/soc/espressif/soc.yml @@ -28,3 +28,6 @@ family: cpuclusters: - name: hpcore - name: lpcore + - name: esp32h2 + socs: + - name: esp32h2 From d2fc47331840e1cfa249b9c61b03bf220812bdcd Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Tue, 29 Jul 2025 17:31:14 -0300 Subject: [PATCH 03/14] drivers: clock_control: esp32h2: Add support Add clocl control support for ESP32-H2. Signed-off-by: Raffael Rostagno --- drivers/clock_control/clock_control_esp32.c | 85 ++++++++++++++---- .../clock_control/esp32_clock_control.h | 4 +- .../zephyr/dt-bindings/clock/esp32h2_clock.h | 89 +++++++++++++++++++ 3 files changed, 159 insertions(+), 19 deletions(-) create mode 100644 include/zephyr/dt-bindings/clock/esp32h2_clock.h diff --git a/drivers/clock_control/clock_control_esp32.c b/drivers/clock_control/clock_control_esp32.c index 48a72c9967e77..beb7b794c9743 100644 --- a/drivers/clock_control/clock_control_esp32.c +++ b/drivers/clock_control/clock_control_esp32.c @@ -49,6 +49,18 @@ #include #include #include +#elif defined(CONFIG_SOC_SERIES_ESP32H2) +#define DT_CPU_COMPAT espressif_riscv +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #endif #include @@ -85,10 +97,13 @@ static bool reset_reason_is_cpu_reset(void) return false; } -#if defined(CONFIG_SOC_SERIES_ESP32C6) +#if defined(CONFIG_SOC_SERIES_ESP32C6) || defined(CONFIG_SOC_SERIES_ESP32H2) static void esp32_clock_perip_init(void) { soc_rtc_slow_clk_src_t rtc_slow_clk_src = rtc_clk_slow_src_get(); + soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0); + +#if defined(CONFIG_SOC_SERIES_ESP32C6) modem_clock_lpclk_src_t modem_lpclk_src = (modem_clock_lpclk_src_t)((rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_RC_SLOW @@ -101,19 +116,36 @@ static void esp32_clock_perip_init(void) : MODEM_CLOCK_LPCLK_SRC_RC_SLOW); modem_clock_select_lp_clock_source(PERIPH_WIFI_MODULE, modem_lpclk_src, 0); - - soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0); +#elif defined(CONFIG_SOC_SERIES_ESP32H2) + esp_sleep_pd_domain_t pu_domain = + (esp_sleep_pd_domain_t)((rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) + ? ESP_PD_DOMAIN_XTAL32K + : (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) + ? ESP_PD_DOMAIN_RC32K + : ESP_PD_DOMAIN_MAX); + esp_sleep_pd_config(pu_domain, ESP_PD_OPTION_ON); +#endif if ((rst_reason != RESET_REASON_CPU0_MWDT0) && (rst_reason != RESET_REASON_CPU0_MWDT1) && (rst_reason != RESET_REASON_CPU0_SW) && (rst_reason != RESET_REASON_CPU0_RTC_WDT)) { +#if CONFIG_ESP_CONSOLE_UART_NUM != 0 + periph_ll_disable_clk_set_rst(PERIPH_UART0_MODULE); +#endif +#if CONFIG_ESP_CONSOLE_UART_NUM != 1 periph_ll_disable_clk_set_rst(PERIPH_UART1_MODULE); +#endif periph_ll_disable_clk_set_rst(PERIPH_I2C0_MODULE); +#if defined(CONFIG_SOC_SERIES_ESP32H2) + periph_ll_disable_clk_set_rst(PERIPH_I2C1_MODULE); +#endif periph_ll_disable_clk_set_rst(PERIPH_RMT_MODULE); periph_ll_disable_clk_set_rst(PERIPH_LEDC_MODULE); periph_ll_disable_clk_set_rst(PERIPH_TIMG1_MODULE); periph_ll_disable_clk_set_rst(PERIPH_TWAI0_MODULE); +#if defined(CONFIG_SOC_SERIES_ESP32C6) periph_ll_disable_clk_set_rst(PERIPH_TWAI1_MODULE); +#endif periph_ll_disable_clk_set_rst(PERIPH_I2S1_MODULE); periph_ll_disable_clk_set_rst(PERIPH_PCNT_MODULE); periph_ll_disable_clk_set_rst(PERIPH_ETM_MODULE); @@ -124,17 +156,24 @@ static void esp32_clock_perip_init(void) periph_ll_disable_clk_set_rst(PERIPH_TEMPSENSOR_MODULE); periph_ll_disable_clk_set_rst(PERIPH_UHCI0_MODULE); periph_ll_disable_clk_set_rst(PERIPH_SARADC_MODULE); +#if defined(CONFIG_SOC_SERIES_ESP32C6) periph_ll_disable_clk_set_rst(PERIPH_SDIO_SLAVE_MODULE); +#endif periph_ll_disable_clk_set_rst(PERIPH_RSA_MODULE); periph_ll_disable_clk_set_rst(PERIPH_AES_MODULE); periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE); periph_ll_disable_clk_set_rst(PERIPH_ECC_MODULE); periph_ll_disable_clk_set_rst(PERIPH_HMAC_MODULE); periph_ll_disable_clk_set_rst(PERIPH_DS_MODULE); +#if defined(CONFIG_SOC_SERIES_ESP32H2) + periph_ll_disable_clk_set_rst(PERIPH_ECDSA_MODULE); +#endif REG_CLR_BIT(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); REG_CLR_BIT(PCR_TRACE_CONF_REG, PCR_TRACE_CLK_EN); +#if defined(CONFIG_SOC_SERIES_ESP32C6) REG_CLR_BIT(PCR_RETENTION_CONF_REG, PCR_RETENTION_CLK_EN); +#endif REG_CLR_BIT(PCR_MEM_MONITOR_CONF_REG, PCR_MEM_MONITOR_CLK_EN); REG_CLR_BIT(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN); REG_CLR_BIT(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_EN); @@ -150,8 +189,9 @@ static void esp32_clock_perip_init(void) (rst_reason == RESET_REASON_SYS_RTC_WDT) || (rst_reason == RESET_REASON_SYS_SUPER_WDT)) { +#if defined(CONFIG_SOC_SERIES_ESP32C6) periph_ll_disable_clk_set_rst(PERIPH_LP_I2C0_MODULE); - +#endif CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_RNG_CK_EN); CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_LP_UART_CK_EN); CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_OTP_DBG_CK_EN); @@ -544,7 +584,7 @@ static int clock_control_esp32_get_rate(const struct device *dev, clock_control_ static int esp32_select_rtc_slow_clk(uint8_t slow_clk) { -#if !defined(CONFIG_SOC_SERIES_ESP32C6) +#if !defined(CONFIG_SOC_SERIES_ESP32C6) && !defined(CONFIG_SOC_SERIES_ESP32H2) soc_rtc_slow_clk_src_t rtc_slow_clk_src = slow_clk & RTC_CNTL_ANA_CLK_RTC_SEL_V; #else soc_rtc_slow_clk_src_t rtc_slow_clk_src = slow_clk; @@ -600,7 +640,7 @@ static int esp32_select_rtc_slow_clk(uint8_t slow_clk) return -ENODEV; } } -#if defined(CONFIG_SOC_SERIES_ESP32C6) +#if defined(CONFIG_SOC_SERIES_ESP32C6) || defined(CONFIG_SOC_SERIES_ESP32H2) } else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) { rtc_clk_rc32k_enable(true); } @@ -642,11 +682,21 @@ static int esp32_cpu_clock_configure(const struct esp32_cpu_clock_config *cpu_cf #if defined(CONFIG_SOC_SERIES_ESP32C6) rtc_clk_modem_clock_domain_active_state_icg_map_preinit(); - REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, rtc_clk_cfg.clk_8m_dfreq); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_SCK_DCAP, rtc_clk_cfg.slow_clk_dcap); - REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, rtc_clk_cfg.rc32k_dfreq); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1); +#elif defined(CONFIG_SOC_SERIES_ESP32H2) + REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OC_SCK_DCAP, rtc_clk_cfg.slow_clk_dcap); + REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_RTC_DREG, 0); + REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_DIG_DREG, 0); +#else + REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_SCK_DCAP, rtc_clk_cfg.slow_clk_dcap); + REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DFREQ, rtc_clk_cfg.clk_8m_dfreq); +#endif + +#if defined(CONFIG_SOC_SERIES_ESP32C6) || defined(CONFIG_SOC_SERIES_ESP32H2) + REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, rtc_clk_cfg.clk_8m_dfreq); + REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, rtc_clk_cfg.rc32k_dfreq); uint32_t hp_cali_dbias = get_act_hp_dbias(); uint32_t lp_cali_dbias = get_act_lp_dbias(); @@ -657,15 +707,11 @@ static int esp32_cpu_clock_configure(const struct esp32_cpu_clock_config *cpu_cf hp_cali_dbias, PMU_HP_MODEM_HP_REGULATOR_DBIAS_S); SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias, PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S); - -#else - REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_SCK_DCAP, rtc_clk_cfg.slow_clk_dcap); - REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DFREQ, rtc_clk_cfg.clk_8m_dfreq); #endif #if defined(CONFIG_SOC_SERIES_ESP32) REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, rtc_clk_cfg.clk_8m_div - 1); -#elif defined(CONFIG_SOC_SERIES_ESP32C6) +#elif defined(CONFIG_SOC_SERIES_ESP32C6) || defined(CONFIG_SOC_SERIES_ESP32H2) clk_ll_rc_fast_tick_conf(); esp_rom_uart_tx_wait_idle(0); @@ -678,7 +724,7 @@ static int esp32_cpu_clock_configure(const struct esp32_cpu_clock_config *cpu_cf rtc_clk_8m_divider_set(rtc_clk_cfg.clk_8m_clk_div); #endif -#if !defined(CONFIG_SOC_SERIES_ESP32C6) +#if !defined(CONFIG_SOC_SERIES_ESP32C6) && !defined(CONFIG_SOC_SERIES_ESP32H2) /* Reset (disable) i2c internal bus for all regi2c registers */ regi2c_ctrl_ll_i2c_reset(); /* Enable the internal bus used to configure BBPLL */ @@ -699,7 +745,7 @@ static int esp32_cpu_clock_configure(const struct esp32_cpu_clock_config *cpu_cf * to make it run at 80MHz after the switch. PLL = 480MHz, so divider is 6. */ clk_ll_mspi_fast_set_hs_divider(6); -#else +#elif !defined(CONFIG_SOC_SERIES_ESP32H2) rtc_clk_apb_freq_update(rtc_clk_cfg.xtal_freq * MHZ(1)); #endif @@ -719,7 +765,8 @@ static int esp32_cpu_clock_configure(const struct esp32_cpu_clock_config *cpu_cf old_config.freq_mhz); #if defined(CONFIG_ESP_CONSOLE_UART) -#if !defined(CONFIG_SOC_SERIES_ESP32C2) && !defined(CONFIG_SOC_SERIES_ESP32C6) +#if !defined(CONFIG_SOC_SERIES_ESP32C2) && !defined(CONFIG_SOC_SERIES_ESP32C6) && \ + !defined(CONFIG_SOC_SERIES_ESP32H2) #if defined(CONFIG_MCUBOOT) && defined(ESP_ROM_UART_CLK_IS_XTAL) uint32_t uart_clock_src_hz = (uint32_t)rtc_clk_xtal_freq_get() * MHZ(1); #else @@ -775,7 +822,9 @@ static int clock_control_esp32_init(const struct device *dev) if (rst_reas == RESET_REASON_CHIP_POWER_ON) { esp_ocode_calib_init(); } -#else /* CONFIG_SOC_SERIES_ESP32C6 */ +#elif defined(CONFIG_SOC_SERIES_ESP32H2) + pmu_init(); +#else /* CONFIG_SOC_SERIES_ESP32C6 || CONFIG_SOC_SERIES_ESP32H2 */ rtc_config_t rtc_cfg = RTC_CONFIG_DEFAULT(); #if !defined(CONFIG_SOC_SERIES_ESP32) @@ -788,7 +837,7 @@ static int clock_control_esp32_init(const struct device *dev) } #endif /* !CONFIG_SOC_SERIES_ESP32 */ rtc_init(rtc_cfg); -#endif /* CONFIG_SOC_SERIES_ESP32C6 */ +#endif /* CONFIG_SOC_SERIES_ESP32C6 || CONFIG_SOC_SERIES_ESP32H2 */ ret = esp32_cpu_clock_configure(&cfg->cpu); if (ret) { diff --git a/include/zephyr/drivers/clock_control/esp32_clock_control.h b/include/zephyr/drivers/clock_control/esp32_clock_control.h index eb6bebc138ef8..a56e9142e9d5d 100644 --- a/include/zephyr/drivers/clock_control/esp32_clock_control.h +++ b/include/zephyr/drivers/clock_control/esp32_clock_control.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,8 @@ #include #elif defined(CONFIG_SOC_SERIES_ESP32C6) #include +#elif defined(CONFIG_SOC_SERIES_ESP32H2) +#include #endif /* CONFIG_SOC_SERIES_ESP32xx */ #define ESP32_CLOCK_CONTROL_SUBSYS_CPU 50 diff --git a/include/zephyr/dt-bindings/clock/esp32h2_clock.h b/include/zephyr/dt-bindings/clock/esp32h2_clock.h new file mode 100644 index 0000000000000..0ef72eb34e65f --- /dev/null +++ b/include/zephyr/dt-bindings/clock/esp32h2_clock.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_ESP32H2_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_ESP32H2_H_ + +/* Supported CPU clock Sources */ +#define ESP32_CPU_CLK_SRC_XTAL 0U +#define ESP32_CPU_CLK_SRC_PLL 1U +#define ESP32_CLK_SRC_RC_FAST 2U +#define ESP32_CPU_CLK_SRC_FLASH_PLL 3U + +/* Supported CPU frequencies */ +#define ESP32_CLK_CPU_PLL_48M 48000000 +#define ESP32_CLK_CPU_FLASH_PLL_64M 64000000 +#define ESP32_CLK_CPU_PLL_96M 96000000 +#define ESP32_CLK_CPU_RC_FAST_FREQ 8500000 + +/* Supported XTAL Frequencies */ +#define ESP32_CLK_XTAL_32M 32000000 + +/* Supported RTC fast clock sources */ +#define ESP32_RTC_FAST_CLK_SRC_RC_FAST 0 +#define ESP32_RTC_FAST_CLK_SRC_XTAL_D2 1 + +/* Supported RTC slow clock frequencies */ +#define ESP32_RTC_SLOW_CLK_SRC_RC_SLOW 0 +#define ESP32_RTC_SLOW_CLK_SRC_XTAL32K 1 +#define ESP32_RTC_SLOW_CLK_SRC_RC32K 2 +#define ESP32_RTC_SLOW_CLK_32K_EXT_OSC 9 + +/* RTC slow clock frequencies */ +#define ESP32_RTC_SLOW_CLK_SRC_RC_SLOW_FREQ 136000 +#define ESP32_RTC_SLOW_CLK_SRC_XTAL32K_FREQ 32768 +#define ESP32_RTC_SLOW_CLK_SRC_RC32K_FREQ 32768 + +/* Modules IDs + * These IDs are actually offsets in CLK and RST Control registers. + * These IDs shouldn't be changed unless there is a Hardware change + * from Espressif. + * + * Basic Modules + * Registers: DPORT_PERIP_CLK_EN_REG, DPORT_PERIP_RST_EN_REG + */ +#define ESP32_LEDC_MODULE 0 +#define ESP32_UART0_MODULE 1 +#define ESP32_UART1_MODULE 2 +#define ESP32_USB_DEVICE_MODULE 3 +#define ESP32_I2C0_MODULE 4 +#define ESP32_I2C1_MODULE 5 +#define ESP32_I2S1_MODULE 6 +#define ESP32_TIMG0_MODULE 7 +#define ESP32_TIMG1_MODULE 8 +#define ESP32_UHCI0_MODULE 9 +#define ESP32_RMT_MODULE 10 +#define ESP32_PCNT_MODULE 11 +#define ESP32_SPI_MODULE 12 +#define ESP32_SPI2_MODULE 13 +#define ESP32_TWAI0_MODULE 14 +#define ESP32_RNG_MODULE 15 +#define ESP32_RSA_MODULE 16 +#define ESP32_AES_MODULE 17 +#define ESP32_SHA_MODULE 18 +#define ESP32_ECC_MODULE 19 +#define ESP32_HMAC_MODULE 20 +#define ESP32_DS_MODULE 21 +#define ESP32_ECDSA_MODULE 22 +#define ESP32_GDMA_MODULE 23 +#define ESP32_MCPWM0_MODULE 24 +#define ESP32_ETM_MODULE 25 +#define ESP32_PARLIO_MODULE 26 +#define ESP32_SYSTIMER_MODULE 27 +#define ESP32_SARADC_MODULE 28 +#define ESP32_TEMPSENSOR_MODULE 29 +#define ESP32_REGDMA_MODULE 30 +/* Peripherals clock managed by the modem_clock driver must be listed last */ +#define ESP32_BT_MODULE 31 +#define ESP32_IEEE802154_MODULE 32 +#define ESP32_COEX_MODULE 33 +#define ESP32_PHY_MODULE 34 +#define ESP32_ANA_I2C_MASTER_MODULE 35 +#define ESP32_MODEM_ETM_MODULE 36 +#define ESP32_MODEM_ADC_COMMON_FE_MODULE 37 +#define ESP32_MODULE_MAX 38 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_ESP32H2_H_ */ From 1667728a31170363c96731609802d0ec23e0a1ea Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Tue, 5 Aug 2025 14:00:11 -0300 Subject: [PATCH 04/14] tests: clock: esp32h2: Add testcase Render test settings more generic regarding clock options, in order to better support new devices. Add ESP32-H2 testcase to rtc_clk suite. Signed-off-by: Raffael Rostagno --- .../espressif/rtc_clk/src/rtc_clk_test.c | 35 +++++++++++++------ tests/boards/espressif/rtc_clk/testcase.yaml | 1 + 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/tests/boards/espressif/rtc_clk/src/rtc_clk_test.c b/tests/boards/espressif/rtc_clk/src/rtc_clk_test.c index 41071af768f7e..6933849e3942f 100644 --- a/tests/boards/espressif/rtc_clk/src/rtc_clk_test.c +++ b/tests/boards/espressif/rtc_clk/src/rtc_clk_test.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,8 +15,7 @@ #define DT_CPU_COMPAT espressif_xtensa_lx6 #elif defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3) #define DT_CPU_COMPAT espressif_xtensa_lx7 -#elif defined(CONFIG_SOC_SERIES_ESP32C2) || defined(CONFIG_SOC_SERIES_ESP32C3) || \ - defined(CONFIG_SOC_SERIES_ESP32C6) +#elif defined(CONFIG_RISCV) #define DT_CPU_COMPAT espressif_riscv #endif @@ -74,14 +73,22 @@ ZTEST(rtc_clk, test_cpu_xtal_src) } uint32_t rtc_pll_src_freq_mhz[] = { +#if defined(ESP32_CLK_CPU_PLL_48M) + ESP32_CLK_CPU_PLL_48M, +#endif +#if defined(ESP32_CLK_CPU_PLL_80M) ESP32_CLK_CPU_PLL_80M, -#if defined(CONFIG_SOC_SERIES_ESP32C2) +#endif +#if defined(ESP32_CLK_CPU_PLL_96M) + ESP32_CLK_CPU_PLL_96M, +#endif +#if defined(ESP32_CLK_CPU_PLL_120M) ESP32_CLK_CPU_PLL_120M, -#else +#endif +#if defined(ESP32_CLK_CPU_PLL_160M) ESP32_CLK_CPU_PLL_160M, #endif -#if !defined(CONFIG_SOC_SERIES_ESP32C2) && !defined(CONFIG_SOC_SERIES_ESP32C3) && \ - !defined(CONFIG_SOC_SERIES_ESP32C6) +#if defined(ESP32_CLK_CPU_PLL_240M) ESP32_CLK_CPU_PLL_240M, #endif }; @@ -159,10 +166,13 @@ ZTEST(rtc_clk, test_rtc_fast_src) } uint32_t rtc_rtc_slow_clk_src[] = { +#if defined(ESP32_RTC_SLOW_CLK_SRC_RC_SLOW) ESP32_RTC_SLOW_CLK_SRC_RC_SLOW, -#if defined(CONFIG_SOC_SERIES_ESP32C6) +#endif +#if defined(ESP32_RTC_SLOW_CLK_SRC_RC32K) ESP32_RTC_SLOW_CLK_SRC_RC32K, -#else +#endif +#if defined(ESP32_RTC_SLOW_CLK_SRC_RC_FAST_D256) ESP32_RTC_SLOW_CLK_SRC_RC_FAST_D256, #endif #if CONFIG_FIXTURE_XTAL @@ -171,10 +181,13 @@ uint32_t rtc_rtc_slow_clk_src[] = { }; uint32_t rtc_rtc_slow_clk_src_freq[] = { +#if defined(ESP32_RTC_SLOW_CLK_SRC_RC_SLOW_FREQ) ESP32_RTC_SLOW_CLK_SRC_RC_SLOW_FREQ, -#if defined(CONFIG_SOC_SERIES_ESP32C6) +#endif +#if defined(ESP32_RTC_SLOW_CLK_SRC_RC32K_FREQ) ESP32_RTC_SLOW_CLK_SRC_RC32K_FREQ, -#else +#endif +#if defined(ESP32_RTC_SLOW_CLK_SRC_RC_FAST_D256_FREQ) ESP32_RTC_SLOW_CLK_SRC_RC_FAST_D256_FREQ, #endif #if CONFIG_FIXTURE_XTAL diff --git a/tests/boards/espressif/rtc_clk/testcase.yaml b/tests/boards/espressif/rtc_clk/testcase.yaml index 1090148d4661f..3cbc65b01b604 100644 --- a/tests/boards/espressif/rtc_clk/testcase.yaml +++ b/tests/boards/espressif/rtc_clk/testcase.yaml @@ -7,6 +7,7 @@ tests: - esp32_devkitc/esp32/procpu - esp32c3_devkitm - esp32c6_devkitc/esp32c6/hpcore + - esp32h2_devkitm - esp32s2_saola - esp32s3_devkitm/esp32s3/procpu boards.esp32.rtc_clk.xtal: From b604f0ad36817b7fa104aa1ae6b4085bd76b029f Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 30 Jul 2025 14:39:45 -0300 Subject: [PATCH 05/14] bindings: intmux: pinctrl: esp32h2: Add defines Add defines for interrupt management and pin control. Signed-off-by: Raffael Rostagno --- .../interrupt-controller/esp-esp32h2-intmux.h | 82 +++ .../dt-bindings/pinctrl/esp32h2-gpio-sigmap.h | 260 ++++++++++ .../dt-bindings/pinctrl/esp32h2-pinctrl.h | 480 ++++++++++++++++++ 3 files changed, 822 insertions(+) create mode 100644 include/zephyr/dt-bindings/interrupt-controller/esp-esp32h2-intmux.h create mode 100644 include/zephyr/dt-bindings/pinctrl/esp32h2-gpio-sigmap.h create mode 100644 include/zephyr/dt-bindings/pinctrl/esp32h2-pinctrl.h diff --git a/include/zephyr/dt-bindings/interrupt-controller/esp-esp32h2-intmux.h b/include/zephyr/dt-bindings/interrupt-controller/esp-esp32h2-intmux.h new file mode 100644 index 0000000000000..febe62c3ce060 --- /dev/null +++ b/include/zephyr/dt-bindings/interrupt-controller/esp-esp32h2-intmux.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_INTERRUPT_CONTROLLER_ESP32H2_INTMUX_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_INTERRUPT_CONTROLLER_ESP32H2_INTMUX_H_ + +#define PMU_INTR_SOURCE 0 +#define EFUSE_INTR_SOURCE 1 +#define LP_RTC_TIMER_INTR_SOURCE 2 +#define LP_BLE_TIMER_INTR_SOURCE 3 +#define LP_WDT_INTR_SOURCE 4 +#define LP_PERI_TIMEOUT_INTR_SOURCE 5 +#define LP_APM_M0_INTR_SOURCE 6 +#define FROM_CPU_INTR0_SOURCE 7 +#define FROM_CPU_INTR1_SOURCE 8 +#define FROM_CPU_INTR2_SOURCE 9 +#define FROM_CPU_INTR3_SOURCE 10 +#define ASSIST_DEBUG_INTR_SOURCE 11 +#define TRACE_INTR_SOURCE 12 +#define CACHE_INTR_SOURCE 13 +#define CPU_PERI_TIMEOUT_INTR_SOURCE 14 +#define BT_MAC_INTR_SOURCE 15 +#define BT_BB_INTR_SOURCE 16 +#define BT_BB_NMI_INTR_SOURCE 17 +#define COEX_INTR_SOURCE 18 +#define BLE_TIMER_INTR_SOURCE 19 +#define BLE_SEC_INTR_SOURCE 20 +#define ZB_MAC_INTR_SOURCE 21 +#define GPIO_INTR_SOURCE 22 +#define GPIO_NMI_SOURCE 23 +#define PAU_INTR_SOURCE 24 +#define HP_PERI_TIMEOUT_INTR_SOURCE 25 +#define HP_APM_M0_INTR_SOURCE 26 +#define HP_APM_M1_INTR_SOURCE 27 +#define HP_APM_M2_INTR_SOURCE 28 +#define HP_APM_M3_INTR_SOURCE 29 +#define MSPI_INTR_SOURCE 30 +#define I2S1_INTR_SOURCE 31 +#define UHCI0_INTR_SOURCE 32 +#define UART0_INTR_SOURCE 33 +#define UART1_INTR_SOURCE 34 +#define LEDC_INTR_SOURCE 35 +#define TWAI0_INTR_SOURCE 36 +#define USB_SERIAL_JTAG_INTR_SOURCE 37 +#define RMT_INTR_SOURCE 38 +#define I2C_EXT0_INTR_SOURCE 39 +#define I2C_EXT1_INTR_SOURCE 40 +#define TG0_T0_LEVEL_INTR_SOURCE 41 +#define TG0_WDT_LEVEL_INTR_SOURCE 42 +#define TG1_T0_LEVEL_INTR_SOURCE 43 +#define TG1_WDT_LEVEL_INTR_SOURCE 44 +#define SYSTIMER_TARGET0_EDGE_INTR_SOURCE 45 +#define SYSTIMER_TARGET1_EDGE_INTR_SOURCE 46 +#define SYSTIMER_TARGET2_EDGE_INTR_SOURCE 47 +#define APB_ADC_INTR_SOURCE 48 +#define MCPWM0_INTR_SOURCE 49 +#define PCNT_INTR_SOURCE 50 +#define PARL_IO_TX_INTR_SOURCE 51 +#define PARL_IO_RX_INTR_SOURCE 52 +#define DMA_IN_CH0_INTR_SOURCE 53 +#define DMA_IN_CH1_INTR_SOURCE 54 +#define DMA_IN_CH2_INTR_SOURCE 55 +#define DMA_OUT_CH0_INTR_SOURCE 56 +#define DMA_OUT_CH1_INTR_SOURCE 57 +#define DMA_OUT_CH2_INTR_SOURCE 58 +#define GSPI2_INTR_SOURCE 59 +#define AES_INTR_SOURCE 60 +#define SHA_INTR_SOURCE 61 +#define RSA_INTR_SOURCE 62 +#define ECC_INTR_SOURCE 63 +#define ECDSA_INTR_SOURCE 64 +#define MAX_INTR_SOURCE 65 + +/* Zero will allocate low/medium levels of priority (ESP_INTR_FLAG_LOWMED) */ +#define IRQ_DEFAULT_PRIORITY 0 + +#define ESP_INTR_FLAG_SHARED (1 << 8) /* Interrupt can be shared between ISRs */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_INTERRUPT_CONTROLLER_ESP32H2_INTMUX_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/esp32h2-gpio-sigmap.h b/include/zephyr/dt-bindings/pinctrl/esp32h2-gpio-sigmap.h new file mode 100644 index 0000000000000..f27fbeab0c8cc --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/esp32h2-gpio-sigmap.h @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_ESP32H2_GPIO_SIGMAP_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_ESP32H2_GPIO_SIGMAP_H_ + +#define ESP_NOSIG ESP_SIG_INVAL + +#define ESP_EXT_ADC_START 0 +#define ESP_LEDC_LS_SIG_OUT0 0 +#define ESP_MODEM_DIAG0 0 +#define ESP_LEDC_LS_SIG_OUT1 1 +#define ESP_MODEM_DIAG1 1 +#define ESP_LEDC_LS_SIG_OUT2 2 +#define ESP_MODEM_DIAG2 2 +#define ESP_LEDC_LS_SIG_OUT3 3 +#define ESP_MODEM_DIAG3 3 +#define ESP_LEDC_LS_SIG_OUT4 4 +#define ESP_MODEM_DIAG4 4 +#define ESP_LEDC_LS_SIG_OUT5 5 +#define ESP_MODEM_DIAG5 5 +#define ESP_U0RXD_IN 6 +#define ESP_U0TXD_OUT 6 +#define ESP_U0CTS_IN 7 +#define ESP_U0RTS_OUT 7 +#define ESP_U0DSR_IN 8 +#define ESP_U0DTR_OUT 8 +#define ESP_U1RXD_IN 9 +#define ESP_U1TXD_OUT 9 +#define ESP_U1CTS_IN 10 +#define ESP_U1RTS_OUT 10 +#define ESP_MODEM_DIAG6 10 +#define ESP_U1DSR_IN 11 +#define ESP_U1DTR_OUT 11 +#define ESP_I2S_MCLK_IN 12 +#define ESP_I2S_MCLK_OUT 12 +#define ESP_I2SO_BCK_IN 13 +#define ESP_I2SO_BCK_OUT 13 +#define ESP_I2SO_WS_IN 14 +#define ESP_I2SO_WS_OUT 14 +#define ESP_I2SI_SD_IN 15 +#define ESP_I2SO_SD_OUT 15 +#define ESP_I2SI_BCK_IN 16 +#define ESP_I2SI_BCK_OUT 16 +#define ESP_I2SI_WS_IN 17 +#define ESP_I2SI_WS_OUT 17 +#define ESP_I2SO_SD1_OUT 18 +#define ESP_USB_JTAG_TDO_BRIDGE 19 +#define ESP_USB_JTAG_TRST 19 +#define ESP_CPU_TESTBUS0 20 +#define ESP_CPU_TESTBUS1 21 +#define ESP_CPU_TESTBUS2 22 +#define ESP_CPU_TESTBUS3 23 +#define ESP_CPU_TESTBUS4 24 +#define ESP_CPU_TESTBUS5 25 +#define ESP_CPU_TESTBUS6 26 +#define ESP_CPU_TESTBUS7 27 +#define ESP_CPU_GPIO_IN0 28 +#define ESP_CPU_GPIO_OUT0 28 +#define ESP_CPU_GPIO_IN1 29 +#define ESP_CPU_GPIO_OUT1 29 +#define ESP_CPU_GPIO_IN2 30 +#define ESP_CPU_GPIO_OUT2 30 +#define ESP_CPU_GPIO_IN3 31 +#define ESP_CPU_GPIO_OUT3 31 +#define ESP_CPU_GPIO_IN4 32 +#define ESP_CPU_GPIO_OUT4 32 +#define ESP_CPU_GPIO_IN5 33 +#define ESP_CPU_GPIO_OUT5 33 +#define ESP_CPU_GPIO_IN6 34 +#define ESP_CPU_GPIO_OUT6 34 +#define ESP_CPU_GPIO_IN7 35 +#define ESP_CPU_GPIO_OUT7 35 +#define ESP_USB_JTAG_TCK 36 +#define ESP_USB_JTAG_TMS 37 +#define ESP_USB_JTAG_TDI 38 +#define ESP_USB_JTAG_TDO 39 +#define ESP_USB_EXTPHY_VP 40 +#define ESP_USB_EXTPHY_OEN 40 +#define ESP_USB_EXTPHY_VM 41 +#define ESP_USB_EXTPHY_SPEED 41 +#define ESP_USB_EXTPHY_RCV 42 +#define ESP_USB_EXTPHY_VPO 42 +#define ESP_USB_EXTPHY_VMO 43 +#define ESP_USB_EXTPHY_SUSPND 44 +#define ESP_I2CEXT0_SCL_IN 45 +#define ESP_I2CEXT0_SCL_OUT 45 +#define ESP_I2CEXT0_SDA_IN 46 +#define ESP_I2CEXT0_SDA_OUT 46 +#define ESP_PARL_RX_DATA0 47 +#define ESP_PARL_TX_DATA0 47 +#define ESP_PARL_RX_DATA1 48 +#define ESP_PARL_TX_DATA1 48 +#define ESP_PARL_RX_DATA2 49 +#define ESP_PARL_TX_DATA2 49 +#define ESP_PARL_RX_DATA3 50 +#define ESP_PARL_TX_DATA3 50 +#define ESP_PARL_RX_DATA4 51 +#define ESP_PARL_TX_DATA4 51 +#define ESP_PARL_RX_DATA5 52 +#define ESP_PARL_TX_DATA5 52 +#define ESP_PARL_RX_DATA6 53 +#define ESP_PARL_TX_DATA6 53 +#define ESP_PARL_RX_DATA7 54 +#define ESP_PARL_TX_DATA7 54 +#define ESP_I2CEXT1_SCL_IN 55 +#define ESP_I2CEXT1_SCL_OUT 55 +#define ESP_I2CEXT1_SDA_IN 56 +#define ESP_I2CEXT1_SDA_OUT 56 +#define ESP_CTE_ANT0 57 +#define ESP_CTE_ANT1 58 +#define ESP_CTE_ANT2 59 +#define ESP_CTE_ANT3 60 +#define ESP_CTE_ANT4 61 +#define ESP_CTE_ANT5 62 +#define ESP_FSPICLK_IN 63 +#define ESP_FSPICLK_OUT 63 +#define ESP_FSPIQ_IN 64 +#define ESP_FSPIQ_OUT 64 +#define ESP_FSPID_IN 65 +#define ESP_FSPID_OUT 65 +#define ESP_FSPIHD_IN 66 +#define ESP_FSPIHD_OUT 66 +#define ESP_FSPIWP_IN 67 +#define ESP_FSPIWP_OUT 67 +#define ESP_FSPICS0_IN 68 +#define ESP_FSPICS0_OUT 68 +#define ESP_MODEM_DIAG7 68 +#define ESP_PARL_RX_CLK_IN 69 +#define ESP_PARL_RX_CLK_OUT 69 +#define ESP_PARL_TX_CLK_IN 70 +#define ESP_PARL_TX_CLK_OUT 70 +#define ESP_RMT_SIG_IN0 71 +#define ESP_RMT_SIG_OUT0 71 +#define ESP_MODEM_DIAG8 71 +#define ESP_RMT_SIG_IN1 72 +#define ESP_RMT_SIG_OUT1 72 +#define ESP_MODEM_DIAG9 72 +#define ESP_TWAI_RX 73 +#define ESP_TWAI_TX 73 +#define ESP_MODEM_DIAG10 73 +#define ESP_TWAI_BUS_OFF_ON 74 +#define ESP_MODEM_DIAG11 74 +#define ESP_TWAI_CLKOUT 75 +#define ESP_MODEM_DIAG12 75 +#define ESP_TWAI_STANDBY 76 +#define ESP_MODEM_DIAG13 76 +#define ESP_CTE_ANT6 77 +#define ESP_CTE_ANT7 78 +#define ESP_CTE_ANT8 79 +#define ESP_CTE_ANT9 80 +#define ESP_EXTERN_PRIORITY_I 81 +#define ESP_EXTERN_PRIORITY_O 81 +#define ESP_EXTERN_ACTIVE_I 82 +#define ESP_EXTERN_ACTIVE_O 82 +#define ESP_GPIO_SD0_OUT 83 +#define ESP_GPIO_SD1_OUT 84 +#define ESP_GPIO_SD2_OUT 85 +#define ESP_GPIO_SD3_OUT 86 +#define ESP_PWM0_SYNC0_IN 87 +#define ESP_PWM0_OUT0A 87 +#define ESP_MODEM_DIAG14 87 +#define ESP_PWM0_SYNC1_IN 88 +#define ESP_PWM0_OUT0B 88 +#define ESP_MODEM_DIAG15 88 +#define ESP_PWM0_SYNC2_IN 89 +#define ESP_PWM0_OUT1A 89 +#define ESP_MODEM_DIAG16 89 +#define ESP_PWM0_F0_IN 90 +#define ESP_PWM0_OUT1B 90 +#define ESP_MODEM_DIAG17 90 +#define ESP_PWM0_F1_IN 91 +#define ESP_PWM0_OUT2A 91 +#define ESP_MODEM_DIAG18 91 +#define ESP_PWM0_F2_IN 92 +#define ESP_PWM0_OUT2B 92 +#define ESP_MODEM_DIAG19 92 +#define ESP_PWM0_CAP0_IN 93 +#define ESP_ANT_SEL0 93 +#define ESP_PWM0_CAP1_IN 94 +#define ESP_ANT_SEL1 94 +#define ESP_PWM0_CAP2_IN 95 +#define ESP_ANT_SEL2 95 +#define ESP_ANT_SEL3 96 +#define ESP_SIG_IN_FUNC_97 97 +#define ESP_SIG_IN_FUNC97 97 +#define ESP_SIG_IN_FUNC_98 98 +#define ESP_SIG_IN_FUNC98 98 +#define ESP_SIG_IN_FUNC_99 99 +#define ESP_SIG_IN_FUNC99 99 +#define ESP_SIG_IN_FUNC_100 100 +#define ESP_SIG_IN_FUNC100 100 +#define ESP_PCNT_SIG_CH0_IN0 101 +#define ESP_FSPICS1_OUT 101 +#define ESP_MODEM_DIAG20 101 +#define ESP_PCNT_SIG_CH1_IN0 102 +#define ESP_FSPICS2_OUT 102 +#define ESP_MODEM_DIAG21 102 +#define ESP_PCNT_CTRL_CH0_IN0 103 +#define ESP_FSPICS3_OUT 103 +#define ESP_MODEM_DIAG22 103 +#define ESP_PCNT_CTRL_CH1_IN0 104 +#define ESP_FSPICS4_OUT 104 +#define ESP_MODEM_DIAG23 104 +#define ESP_PCNT_SIG_CH0_IN1 105 +#define ESP_FSPICS5_OUT 105 +#define ESP_MODEM_DIAG24 105 +#define ESP_PCNT_SIG_CH1_IN1 106 +#define ESP_CTE_ANT10 106 +#define ESP_PCNT_CTRL_CH0_IN1 107 +#define ESP_CTE_ANT11 107 +#define ESP_PCNT_CTRL_CH1_IN1 108 +#define ESP_CTE_ANT12 108 +#define ESP_PCNT_SIG_CH0_IN2 109 +#define ESP_CTE_ANT13 109 +#define ESP_PCNT_SIG_CH1_IN2 110 +#define ESP_CTE_ANT14 110 +#define ESP_PCNT_CTRL_CH0_IN2 111 +#define ESP_CTE_ANT15 111 +#define ESP_PCNT_CTRL_CH1_IN2 112 +#define ESP_MODEM_DIAG25 112 +#define ESP_PCNT_SIG_CH0_IN3 113 +#define ESP_MODEM_DIAG26 113 +#define ESP_PCNT_SIG_CH1_IN3 114 +#define ESP_SPICLK_OUT 114 +#define ESP_PCNT_CTRL_CH0_IN3 115 +#define ESP_SPICS0_OUT 115 +#define ESP_MODEM_DIAG27 115 +#define ESP_PCNT_CTRL_CH1_IN3 116 +#define ESP_SPICS1_OUT 116 +#define ESP_MODEM_DIAG28 116 +#define ESP_GPIO_EVENT_MATRIX_IN0 117 +#define ESP_GPIO_TASK_MATRIX_OUT0 117 +#define ESP_GPIO_EVENT_MATRIX_IN1 118 +#define ESP_GPIO_TASK_MATRIX_OUT1 118 +#define ESP_GPIO_EVENT_MATRIX_IN2 119 +#define ESP_GPIO_TASK_MATRIX_OUT2 119 +#define ESP_GPIO_EVENT_MATRIX_IN3 120 +#define ESP_GPIO_TASK_MATRIX_OUT3 120 +#define ESP_SPIQ_IN 121 +#define ESP_SPIQ_OUT 121 +#define ESP_SPID_IN 122 +#define ESP_SPID_OUT 122 +#define ESP_SPIHD_IN 123 +#define ESP_SPIHD_OUT 123 +#define ESP_SPIWP_IN 124 +#define ESP_SPIWP_OUT 124 +#define ESP_CLK_OUT_OUT1 125 +#define ESP_MODEM_DIAG29 125 +#define ESP_CLK_OUT_OUT2 126 +#define ESP_MODEM_DIAG30 126 +#define ESP_CLK_OUT_OUT3 127 +#define ESP_MODEM_DIAG31 127 +#define ESP_SIG_GPIO_OUT 128 +#define ESP_GPIO_MAP_DATE 0x2201120 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_ESP32H2_GPIO_SIGMAP_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/esp32h2-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/esp32h2-pinctrl.h new file mode 100644 index 0000000000000..91d6c2f5872a7 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/esp32h2-pinctrl.h @@ -0,0 +1,480 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * NOTE: Autogenerated file using esp_genpinctrl.py + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_ESP32H2_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_ESP32H2_PINCTRL_H_ + +/* UART0_CTS */ +#define UART0_CTS_GPIO0 ESP32_PINMUX(0, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO1 ESP32_PINMUX(1, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO2 ESP32_PINMUX(2, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO3 ESP32_PINMUX(3, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO4 ESP32_PINMUX(4, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO5 ESP32_PINMUX(5, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO8 ESP32_PINMUX(8, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO9 ESP32_PINMUX(9, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO10 ESP32_PINMUX(10, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO11 ESP32_PINMUX(11, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO12 ESP32_PINMUX(12, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO13 ESP32_PINMUX(13, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO14 ESP32_PINMUX(14, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO22 ESP32_PINMUX(22, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO23 ESP32_PINMUX(23, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO24 ESP32_PINMUX(24, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO25 ESP32_PINMUX(25, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO26 ESP32_PINMUX(26, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO27 ESP32_PINMUX(27, ESP_U0CTS_IN, ESP_NOSIG) + +/* UART0_DSR */ +#define UART0_DSR_GPIO0 ESP32_PINMUX(0, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO1 ESP32_PINMUX(1, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO2 ESP32_PINMUX(2, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO3 ESP32_PINMUX(3, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO4 ESP32_PINMUX(4, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO5 ESP32_PINMUX(5, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO8 ESP32_PINMUX(8, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO9 ESP32_PINMUX(9, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO10 ESP32_PINMUX(10, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO11 ESP32_PINMUX(11, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO12 ESP32_PINMUX(12, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO13 ESP32_PINMUX(13, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO14 ESP32_PINMUX(14, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO22 ESP32_PINMUX(22, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO23 ESP32_PINMUX(23, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO24 ESP32_PINMUX(24, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO25 ESP32_PINMUX(25, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO26 ESP32_PINMUX(26, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO27 ESP32_PINMUX(27, ESP_U0DSR_IN, ESP_NOSIG) + +/* UART0_DTR */ +#define UART0_DTR_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_U0DTR_OUT) + +/* UART0_RTS */ +#define UART0_RTS_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_U0RTS_OUT) + +/* UART0_RX */ +#define UART0_RX_GPIO0 ESP32_PINMUX(0, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO1 ESP32_PINMUX(1, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO2 ESP32_PINMUX(2, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO3 ESP32_PINMUX(3, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO4 ESP32_PINMUX(4, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO5 ESP32_PINMUX(5, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO8 ESP32_PINMUX(8, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO9 ESP32_PINMUX(9, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO10 ESP32_PINMUX(10, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO11 ESP32_PINMUX(11, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO12 ESP32_PINMUX(12, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO13 ESP32_PINMUX(13, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO14 ESP32_PINMUX(14, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO22 ESP32_PINMUX(22, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO23 ESP32_PINMUX(23, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO24 ESP32_PINMUX(24, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO25 ESP32_PINMUX(25, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO26 ESP32_PINMUX(26, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO27 ESP32_PINMUX(27, ESP_U0RXD_IN, ESP_NOSIG) + +/* UART0_TX */ +#define UART0_TX_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_U0TXD_OUT) + +/* UART1_CTS */ +#define UART1_CTS_GPIO0 ESP32_PINMUX(0, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO1 ESP32_PINMUX(1, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO2 ESP32_PINMUX(2, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO3 ESP32_PINMUX(3, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO4 ESP32_PINMUX(4, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO5 ESP32_PINMUX(5, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO8 ESP32_PINMUX(8, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO9 ESP32_PINMUX(9, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO10 ESP32_PINMUX(10, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO11 ESP32_PINMUX(11, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO12 ESP32_PINMUX(12, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO13 ESP32_PINMUX(13, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO14 ESP32_PINMUX(14, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO22 ESP32_PINMUX(22, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO23 ESP32_PINMUX(23, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO24 ESP32_PINMUX(24, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO25 ESP32_PINMUX(25, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO26 ESP32_PINMUX(26, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO27 ESP32_PINMUX(27, ESP_U1CTS_IN, ESP_NOSIG) + +/* UART1_DSR */ +#define UART1_DSR_GPIO0 ESP32_PINMUX(0, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO1 ESP32_PINMUX(1, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO2 ESP32_PINMUX(2, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO3 ESP32_PINMUX(3, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO4 ESP32_PINMUX(4, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO5 ESP32_PINMUX(5, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO8 ESP32_PINMUX(8, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO9 ESP32_PINMUX(9, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO10 ESP32_PINMUX(10, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO11 ESP32_PINMUX(11, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO12 ESP32_PINMUX(12, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO13 ESP32_PINMUX(13, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO14 ESP32_PINMUX(14, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO22 ESP32_PINMUX(22, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO23 ESP32_PINMUX(23, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO24 ESP32_PINMUX(24, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO25 ESP32_PINMUX(25, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO26 ESP32_PINMUX(26, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO27 ESP32_PINMUX(27, ESP_U1DSR_IN, ESP_NOSIG) + +/* UART1_DTR */ +#define UART1_DTR_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_U1DTR_OUT) + +/* UART1_RTS */ +#define UART1_RTS_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_U1RTS_OUT) + +/* UART1_RX */ +#define UART1_RX_GPIO0 ESP32_PINMUX(0, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO1 ESP32_PINMUX(1, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO2 ESP32_PINMUX(2, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO3 ESP32_PINMUX(3, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO4 ESP32_PINMUX(4, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO5 ESP32_PINMUX(5, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO8 ESP32_PINMUX(8, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO9 ESP32_PINMUX(9, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO10 ESP32_PINMUX(10, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO11 ESP32_PINMUX(11, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO12 ESP32_PINMUX(12, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO13 ESP32_PINMUX(13, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO14 ESP32_PINMUX(14, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO22 ESP32_PINMUX(22, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO23 ESP32_PINMUX(23, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO24 ESP32_PINMUX(24, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO25 ESP32_PINMUX(25, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO26 ESP32_PINMUX(26, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO27 ESP32_PINMUX(27, ESP_U1RXD_IN, ESP_NOSIG) + +/* UART1_TX */ +#define UART1_TX_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_U1TXD_OUT) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_ESP32H2_PINCTRL_H_ */ From 0f907f0d170c9cc69ca7d7fa143be23f4d48a3db Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 6 Aug 2025 10:16:44 -0300 Subject: [PATCH 06/14] drivers: pinctrl: esp32h2: Add support Add pinctrl support for ESP32-H2. Signed-off-by: Raffael Rostagno --- drivers/pinctrl/pinctrl_esp32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl_esp32.c b/drivers/pinctrl/pinctrl_esp32.c index 4ed39229d5625..eacf62a668135 100644 --- a/drivers/pinctrl/pinctrl_esp32.c +++ b/drivers/pinctrl/pinctrl_esp32.c @@ -23,8 +23,8 @@ #define in in.data #define out_w1ts out_w1ts.val #define out_w1tc out_w1tc.val -#elif CONFIG_SOC_SERIES_ESP32C6 -/* gpio structs in esp32c6 are also different */ +#elif defined(CONFIG_SOC_SERIES_ESP32C6) || defined(CONFIG_SOC_SERIES_ESP32H2) +/* gpio structs in esp32c6/h2 are also different */ #define out out.out_data_orig #define in in.in_data_next #define out_w1ts out_w1ts.val From af76ef6768322c246196b6de6b973a47972c47c2 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 30 Jul 2025 14:41:29 -0300 Subject: [PATCH 07/14] drivers: gpio: esp32h2: Add support Add gpio support for ESP32-H2. Signed-off-by: Raffael Rostagno --- drivers/gpio/gpio_esp32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio_esp32.c b/drivers/gpio/gpio_esp32.c index 289565302bffd..33d7396997520 100644 --- a/drivers/gpio/gpio_esp32.c +++ b/drivers/gpio/gpio_esp32.c @@ -44,8 +44,8 @@ LOG_MODULE_REGISTER(gpio_esp32, CONFIG_LOG_DEFAULT_LEVEL); #define out_w1tc out_w1tc.val /* arch_curr_cpu() is not available for riscv based chips */ #define ESP32_CPU_ID() 0 -#elif defined(CONFIG_SOC_SERIES_ESP32C6) -/* gpio structs in esp32c6 are also different */ +#elif defined(CONFIG_SOC_SERIES_ESP32C6) || defined(CONFIG_SOC_SERIES_ESP32H2) +/* gpio structs in esp32c6/h2 are also different */ #define out out.out_data_orig #define in in.in_data_next #define out_w1ts out_w1ts.val From 45937d4d0cb374d6bf0df403aa55da63e02f0e7d Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 30 Jul 2025 14:41:52 -0300 Subject: [PATCH 08/14] drivers: uart: esp32h2: Add support Add UART support for ESP32-H2. Signed-off-by: Raffael Rostagno --- drivers/serial/uart_esp32.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/serial/uart_esp32.c b/drivers/serial/uart_esp32.c index bf519b041943e..32505a4750cf5 100644 --- a/drivers/serial/uart_esp32.c +++ b/drivers/serial/uart_esp32.c @@ -33,6 +33,10 @@ #include #include #include +#elif defined(CONFIG_SOC_SERIES_ESP32H2) +#include +#include +#include #endif #ifdef CONFIG_UART_ASYNC_API #include From de6cb7db24aa4d54168b4e46d164bed92f13306c Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Tue, 5 Aug 2025 14:26:54 -0300 Subject: [PATCH 09/14] tests: drivers: uart: esp32h2: Add test config Add test config for ESP32-H2. Signed-off-by: Raffael Rostagno --- .../uart/uart_elementary/socs/esp32h2.overlay | 28 +++++++++++++++++++ .../uart/uart_elementary/testcase.yaml | 1 + 2 files changed, 29 insertions(+) create mode 100644 tests/drivers/uart/uart_elementary/socs/esp32h2.overlay diff --git a/tests/drivers/uart/uart_elementary/socs/esp32h2.overlay b/tests/drivers/uart/uart_elementary/socs/esp32h2.overlay new file mode 100644 index 0000000000000..62292552f6d47 --- /dev/null +++ b/tests/drivers/uart/uart_elementary/socs/esp32h2.overlay @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart1_test: uart1_test { + group1 { + pinmux = , + ; + input-enable; + output-high; + }; + group2 { + pinmux = , + ; + output-enable; + bias-pull-up; + }; + }; +}; + +dut: &uart1 { + status = "okay"; + pinctrl-0 = <&uart1_test>; + pinctrl-names = "default"; + current-speed = <115200>; +}; diff --git a/tests/drivers/uart/uart_elementary/testcase.yaml b/tests/drivers/uart/uart_elementary/testcase.yaml index cbf222fa72cf7..d1da7ca19489a 100644 --- a/tests/drivers/uart/uart_elementary/testcase.yaml +++ b/tests/drivers/uart/uart_elementary/testcase.yaml @@ -22,6 +22,7 @@ tests: - esp8684_devkitm - esp32c3_devkitm - esp32c6_devkitc/esp32c6/hpcore + - esp32h2_devkitm - esp32s2_saola - esp32s3_devkitm/esp32s3/procpu integration_platforms: From 3842d85063a6ec2a146b51fbd72286fe87b43419 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 13 Aug 2025 10:04:58 -0300 Subject: [PATCH 10/14] tests: drivers: counter: esp32h2: Add config Add test config for ESP32-H2. Signed-off-by: Raffael Rostagno --- .../counter/counter_basic_api/socs/esp32h2.overlay | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/drivers/counter/counter_basic_api/socs/esp32h2.overlay diff --git a/tests/drivers/counter/counter_basic_api/socs/esp32h2.overlay b/tests/drivers/counter/counter_basic_api/socs/esp32h2.overlay new file mode 100644 index 0000000000000..654ca2b00155f --- /dev/null +++ b/tests/drivers/counter/counter_basic_api/socs/esp32h2.overlay @@ -0,0 +1,13 @@ +&timer0 { + status = "okay"; + counter { + status = "okay"; + }; +}; + +&timer1 { + status = "okay"; + counter { + status = "okay"; + }; +}; From f3354ceaf3509db5f1b81f4bafcb868034e59926 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 30 Jul 2025 14:42:19 -0300 Subject: [PATCH 11/14] drivers: systimer: esp32h2: Add support Add systimer support for ESP32-H2. Signed-off-by: Raffael Rostagno --- drivers/timer/Kconfig.esp32 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/timer/Kconfig.esp32 b/drivers/timer/Kconfig.esp32 index ff10f017866d7..1a61d02d46966 100644 --- a/drivers/timer/Kconfig.esp32 +++ b/drivers/timer/Kconfig.esp32 @@ -1,11 +1,13 @@ # Copyright (c) 2014-2015 Wind River Systems, Inc. # Copyright (c) 2016 Cadence Design Systems, Inc. # Copyright (c) 2019 Intel Corp. +# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. # SPDX-License-Identifier: Apache-2.0 config ESP32_SYS_TIMER bool "ESP32 sys-timer support (ESP32Cx series)" - depends on SOC_SERIES_ESP32C2 || SOC_SERIES_ESP32C3 || (SOC_SERIES_ESP32C6 && !SOC_ESP32C6_LPCORE) + depends on SOC_SERIES_ESP32C2 || SOC_SERIES_ESP32C3 || \ + (SOC_SERIES_ESP32C6 && !SOC_ESP32C6_LPCORE) || SOC_SERIES_ESP32H2 default y select TICKLESS_CAPABLE select TIMER_HAS_64BIT_CYCLE_COUNTER From 1cc5d25ec64cd187c0160542f77d2cebd5c0a4b5 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 6 Aug 2025 11:43:02 -0300 Subject: [PATCH 12/14] drivers: wdt: esp32h2: Add support Add WDT support for ESP32-H2. Signed-off-by: Raffael Rostagno --- drivers/watchdog/wdt_esp32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/watchdog/wdt_esp32.c b/drivers/watchdog/wdt_esp32.c index acaf7d7ce0c31..c045d8922bab9 100644 --- a/drivers/watchdog/wdt_esp32.c +++ b/drivers/watchdog/wdt_esp32.c @@ -7,7 +7,7 @@ #define DT_DRV_COMPAT espressif_esp32_watchdog -#if defined(CONFIG_SOC_SERIES_ESP32C6) +#if defined(CONFIG_SOC_SERIES_ESP32C6) || defined(CONFIG_SOC_SERIES_ESP32H2) #include #else #include From b7bb51f3cd091bb4f6ec89da2f83aa8204a64694 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 6 Aug 2025 11:59:21 -0300 Subject: [PATCH 13/14] drivers: hwinfo: esp32h2: Add support Add hwinfo support for ESP32-H2. Signed-off-by: Raffael Rostagno --- drivers/hwinfo/hwinfo_esp32.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/hwinfo/hwinfo_esp32.c b/drivers/hwinfo/hwinfo_esp32.c index 5a453a000518d..39fbc5b18691b 100644 --- a/drivers/hwinfo/hwinfo_esp32.c +++ b/drivers/hwinfo/hwinfo_esp32.c @@ -18,6 +18,9 @@ ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length) #if defined(CONFIG_SOC_SERIES_ESP32C2) uint32_t rdata1 = sys_read32(EFUSE_RD_BLK2_DATA0_REG); uint32_t rdata2 = sys_read32(EFUSE_RD_BLK2_DATA1_REG); +#elif defined(CONFIG_SOC_SERIES_ESP32H2) + uint32_t rdata1 = sys_read32(EFUSE_RD_MAC_SYS_0_REG); + uint32_t rdata2 = sys_read32(EFUSE_RD_MAC_SYS_1_REG); #elif !defined(CONFIG_SOC_SERIES_ESP32) uint32_t rdata1 = sys_read32(EFUSE_RD_MAC_SPI_SYS_0_REG); uint32_t rdata2 = sys_read32(EFUSE_RD_MAC_SPI_SYS_1_REG); From 900d1afadd95a95fa3219dd17dc70a487edb00f8 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 30 Jul 2025 15:13:34 -0300 Subject: [PATCH 14/14] boards: esp32h2_devkitm: Add initial support Add initial support for esp32h2_devkitm. Signed-off-by: Raffael Rostagno --- boards/espressif/esp32h2_devkitm/Kconfig | 6 + .../esp32h2_devkitm/Kconfig.esp32h2_devkitm | 7 + .../esp32h2_devkitm/Kconfig.sysbuild | 10 + boards/espressif/esp32h2_devkitm/board.cmake | 9 + boards/espressif/esp32h2_devkitm/board.yml | 6 + .../doc/img/esp32h2_devkitm.webp | Bin 0 -> 37406 bytes .../espressif/esp32h2_devkitm/doc/index.rst | 259 ++++++++++++++++++ .../esp32h2_devkitm-pinctrl.dtsi | 23 ++ .../esp32h2_devkitm/esp32h2_devkitm.dts | 62 +++++ .../esp32h2_devkitm/esp32h2_devkitm.yaml | 13 + .../esp32h2_devkitm/esp32h2_devkitm_defconfig | 6 + .../esp32h2_devkitm/support/openocd.cfg | 4 + 12 files changed, 405 insertions(+) create mode 100644 boards/espressif/esp32h2_devkitm/Kconfig create mode 100644 boards/espressif/esp32h2_devkitm/Kconfig.esp32h2_devkitm create mode 100644 boards/espressif/esp32h2_devkitm/Kconfig.sysbuild create mode 100644 boards/espressif/esp32h2_devkitm/board.cmake create mode 100644 boards/espressif/esp32h2_devkitm/board.yml create mode 100644 boards/espressif/esp32h2_devkitm/doc/img/esp32h2_devkitm.webp create mode 100644 boards/espressif/esp32h2_devkitm/doc/index.rst create mode 100644 boards/espressif/esp32h2_devkitm/esp32h2_devkitm-pinctrl.dtsi create mode 100644 boards/espressif/esp32h2_devkitm/esp32h2_devkitm.dts create mode 100644 boards/espressif/esp32h2_devkitm/esp32h2_devkitm.yaml create mode 100644 boards/espressif/esp32h2_devkitm/esp32h2_devkitm_defconfig create mode 100644 boards/espressif/esp32h2_devkitm/support/openocd.cfg diff --git a/boards/espressif/esp32h2_devkitm/Kconfig b/boards/espressif/esp32h2_devkitm/Kconfig new file mode 100644 index 0000000000000..c96fa92d3431f --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/Kconfig @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +config HEAP_MEM_POOL_ADD_SIZE_BOARD + int + default 4096 diff --git a/boards/espressif/esp32h2_devkitm/Kconfig.esp32h2_devkitm b/boards/espressif/esp32h2_devkitm/Kconfig.esp32h2_devkitm new file mode 100644 index 0000000000000..905e66f73c662 --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/Kconfig.esp32h2_devkitm @@ -0,0 +1,7 @@ +# ESP32-H2 DevKitM board configuration + +# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ESP32H2_DEVKITM + select SOC_ESP32_H2_MINI_H4 diff --git a/boards/espressif/esp32h2_devkitm/Kconfig.sysbuild b/boards/espressif/esp32h2_devkitm/Kconfig.sysbuild new file mode 100644 index 0000000000000..95e4e1d103975 --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/Kconfig.sysbuild @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +choice BOOTLOADER + default BOOTLOADER_MCUBOOT +endchoice + +choice BOOT_SIGNATURE_TYPE + default BOOT_SIGNATURE_TYPE_NONE +endchoice diff --git a/boards/espressif/esp32h2_devkitm/board.cmake b/boards/espressif/esp32h2_devkitm/board.cmake new file mode 100644 index 0000000000000..2f04d1fe8861e --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/board.cmake @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(NOT "${OPENOCD}" MATCHES "^${ESPRESSIF_TOOLCHAIN_PATH}/.*") + set(OPENOCD OPENOCD-NOTFOUND) +endif() +find_program(OPENOCD openocd PATHS ${ESPRESSIF_TOOLCHAIN_PATH}/openocd-esp32/bin NO_DEFAULT_PATH) + +include(${ZEPHYR_BASE}/boards/common/esp32.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/espressif/esp32h2_devkitm/board.yml b/boards/espressif/esp32h2_devkitm/board.yml new file mode 100644 index 0000000000000..55e4ccba12051 --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/board.yml @@ -0,0 +1,6 @@ +board: + name: esp32h2_devkitm + full_name: ESP32-H2-DevKitM + vendor: espressif + socs: + - name: esp32h2 diff --git a/boards/espressif/esp32h2_devkitm/doc/img/esp32h2_devkitm.webp b/boards/espressif/esp32h2_devkitm/doc/img/esp32h2_devkitm.webp new file mode 100644 index 0000000000000000000000000000000000000000..187f8192d5fb2cc7adb6f63405ae5029e54dc04f GIT binary patch literal 37406 zcmaHSV|XP&xAloV@x-=m+qO@fNiq}LnAn-v#>AP}wr$&X&dvMY@BaPzdHPR1-Bo+< zUb|}5s@NuOx7B1M@FlFfJp*H_Y=5uBwCRx!nhpbu#W?VivRnr$zj|hap3+ ztSqO;6|c%B$$rRf&<6aA1c0CQxi2h-C!1 zd`S1ZOiC+mS?m8$+zt>JgC0a%S+Y9FaXQ+~gNOZoDt$Hcy#i;8s?(VgM2% z3qaRF2Fa3{42PV}(h1$N3i`q?9~#j>37C|q1BMBlciO3V0?wgd5y4$pngA$$-U6CH z&4m9s5aRNS98<@E)8Nc^^dF+g0w{{gw{!zJOe=a9;9nnJZ9EZRM8KNJA$g_+EjOJJ$No{V(M zc73N$xIuDG19Vp%wac=q+8G_jc$(BkquGI61J6TWJON&I4Z@_v3M|lXX=T!KIKk#GaWx2QpUMw$xjM9I-KkBFD zU<#*1WjV?KwJ?b_pi%Htl6P%7YN`sMlCu9gx<$%O1PoE&deD${Ihk^D6;@LsY==7m zw2q(X`gS9qpktDeelx<6hZ($MW|95;=;HJh;l^s59BnLJjDlo0)~Y zg}}vY0m??XunLoYB31f6+D8a2_Qo+wY z1H!X_?yunTqs&m0VDKssH3J8cIOm9Dv+>F_T^N7$IYHS!XOMu)Fib|GynF-p+2C{? z7-xc#j+4B{o1ao_U-&%24i^%y+*eJzr}iS-+bW)tHY)^5;e_W1SI(o&fy^X}qsSBM z_wKc8@G8vEXh=CSN1`6G`Ip0aw^p$lR7U`b_$(0Lj3elmN4{DJG)ZY%+W=r+_bD3Nt)ch8{dP44j>Cb`u1~Y+vL(MBxey|=9dmh9MSo1(cUUoREUy9Y7%jmmYR`C zVKQi{Oh<+2&w&ErT;CGa?#MFR_7xJ*FyJ#ZJQQ)U@RB8{E{>we=}=tzgt(iFP|tPi zQke~K=3_@GCx2wL6r6;ZPgX@Tau5p7d}*r1M7&Y(54f9%*E*Bvo|dhZ z&1hg{!aDZ7F0g+PiB&l9!%^O$UwHD! zxVh2DBS;xpqzfeP!x_=Jq}=4tFPcM56fF+PVfjlIbYM5QC01CV0!56}4*)(V-nXlA z-)PS$N(MZ9(?{1Wfd*FJU3DfE)eXJJ$4yGqPPjzAjGLvVf;W6zTAZAF4^OwyHtGmd zZVKQ7ir>${SXFNwXs11wiujBD_hpsSXIgdw^;WhG#F>_3w zh>vGm`t8c-DCl(jpQvSK>R(5q9+MXp|CYa|76{#;&mfD>^m)e+=7R;x{j%@8lby8M z`B8i@D+dobHP=Z!>UHr_8LS_&yK{-bq9!T^WB=^v>RUGkL7~aI!TE(p`#d^h7y=L7$VDD94zk386lt6X9w!Whgm_;3jxP zlW<9&Lq^8))~^6a&7D)nA23X~r@+CX(H8U~oy*E0Kq!UdRcz2WYFUaO&pdD{BsLOo z!U7Z@LrO%1(+KwVufrx!WlIa*esF-Xh)9+CTSKTogvh^1xf{Y=C^EJk<{JCc@QM%A zIQTDygQY$X_|^T35qDe+*8?z%lvpial%-T}!BZ9s{~R*4jNdu*od~KO+(m;}xu9rr)~7YxMCk_JxW+isY7`?g9YH zV`|JJHnNjUp;)t9pw7o*mmd%|H{#ozS@oYl@}PSR`Z6+4zXlQjx^ud2--G;kG|+?K z<}&%1Q{=5WzagCy1s!-AXg@{MlohM!pZ}q?4-a60s`*&4OF*T-&U&f<`}u~!x8=Fu zV6;YP0uAgS+ME-Emb>l8G0pv%z3U?V#;TCM)Oa&)8A^vQB<|{ zVdx?s@hPwx&H+gO3P=vXTURgj%W>^}<>RFfWB&tx<@Qu0qUST%&GrD<5=FaY+WGiYy)U{9v_02;8B& zr=@4TMX!`GTi&}L9YcS4eIm9R2|3Bu(5D%05z@g6T-5I?Nu#Y4znvkHheWK@9oiDD zt~+k>v7!bBF8<~)M6Rv~T)G7BhOAs?&MGT+G=vC)(`_5Yy~EK+Jfg^EG_d-Ja3a%? zBeZoEbVgxb2~weGNmP31GLAQ(*o)DCxN^}3_92b|xPm6byDKj-KBia7a z@DKuMz-5e}KeAfh2Ap(8mX*u!+imoF9%%teVXcwpWO%z+tgv0r!%q(r-=@D-uq+^@ zzp-uvG0yvNF4&A$T6x;A$tbEkIl7%cxc@1EJb9L#Eg}IuB2m5;>&T0e{%DlhpqeoN zBhk=&pI;D{Ra-bjK)hO{@N?862J@Be)925P9bsT_x*ycX6N6VGiW*_&qkhj0|XU1eOkw5R;n4; zuM|)BKt<4uk(ML4-Ny1cPZcJPKfBDIT0aY_O?C`(oKFEa0vlimtS+2A)nQR3dPlq- zAwmSzvEnbl#`qYi_D*VAale_8p1dz9_W6u8>n>GWv*v?zDpDX&7y< z7bK4k%pA~crvprG=k8B|C#;f+adzHv#Kp_&GP5sKr~s5G&j>}y`(GI)%>qL&pFOZ4 z9SKqranBQKsi%QV-fjlnfPpGha<**5ziQ{ho=2u)aW>7}=qKLx!9ZqC{c&|v@y3_d zNbJJ9gJ=MR|9^~1drp$%D`}0w5^=KT4iPBh8gmW$CL5uU%uE}w9oR6`u9@=8=ZtWx zI1Hy~^Djke614_DDVm6UBry*=6KaV~1JX`$y)>nQPYnra@-G782Bfa#Gg_8e|0WVK zwo|`M7bqqiQI!&gjTTHPQu0!1>ILl-Qh8nZ$lHOxuIhw(Tn?P1K%0biNen^Y*FEPZf-puLp-{5Sfc4rXoDHM9PX+DDj|Vj3Th@av^V+&i}i!4$ze zTaoqo6TBchpN-qkMLPa*{(6RW48fh$h}V`C;LS#LBM6J@ofD48xCOroJjaJt(}xmS z`|F9N_Cw>n!Keyex-!Iw^*|qa;_r^7hn*rL^N9vD8zH!jA0kXkipCgdrt~RWObfyq z9NTweyO(rmk;gJNc%QoXk$GLK9cJ}YID{X&?2qFlp$BG`*)9!09w6-Cr8t<=hnto1 z#D%&Kn;vCpFXuP3DMq)0tt%mER7BudI8EZ30v5XWvRF)v}L=wHU ztiA{~3}*8ir3Qie0|s=)JCbpdFCmSa*QUj2R0&tqci56MamQ3nRg>*~KPt+;BX4GJ#eZvOpb~@;`Czp971c;T;IQ}g`BX4$pI=Ro>&Uyos!U6hxU3y+@#I)f3 zeH1^AqMpQN9B{vxh`+?UGhMUAwqGc-iFE7)xlCdWifMk&g%^RLb=9{MhjWa%Lirs92ShLMy#8I;xj#@yoED4pPO|4f>p}>c z8B81`VYgXdfY5!t^K!|y2_a!=`^?#)PkiEmYIgyjTMWQBV*s+#-Dpz7!!NEorQ|6) z%dat5{(veS3Rz#!;EOheVNd}PF< zB#cQX=@Jt85-5>~kMA*I5;r}dER{Yci|DXH>;7*X=s4lF=b8;tQ?M$ zukW<})ag`D%p715JBg4K#iNpPq`co5jbvl-j|gl4)}?j{JMD+UVDp9T{@c2qp}UzJ zEJ#afQwuJm&*+GgdigeiK`PrOX%7iRj2NY!cIwNA7|16e+aZgzSaXk(tqR1FDt0=) zCi{ak+l~>-Y?Z+xY8_ z&EzVr>G-pc4u@^>*?aF}ul_WSn0ge4=kuYaw~SX1KvGI-BTPPWNxq}@Iaj~*sMh|e z0=;SFT8ZSupL3yCM+UPcb&EBjO>W_qfW5A3Ey>B01?AF|p6$9PQ3M~JtLp^m+Ecd6 zpILrNtpOu;tf!O0YMWWBp|RqVT(YFpzJ2qP=IhAC4aQ2dXN*>pdS?$i0N%7+GV}Q1 z^raH3wfs;nL@iYIR|6u>E92>xeS2xJ0Zux8{sDC>9>{?ZI?~lT>2PmrG)QLsDfOqf zLw=TjC>U7GWK${5}vjIeIo7tHD)1%kVjem>e6H2-dduh;c~AS96^-sWh3? zqscG&^0jY-vrQxAo>@^Q^!z>(%V1V}yQWxt_@&}2;(();k$3~4JVU}AmtAiwiyr7i zg`q01lf3RTGg!1NdDpuZy6+%$4l3a+?rv;CTr#C@{pUQ}_jfr)r{C9mgJA>u-& zT930x`{P(9#BtpodJed|*$(7%MUcdRo&1E&9sVgkm^{!JNt~thEffPCD)%6Dbe>`- zNTQHfAiW9LfRyq*JhhE+ewyltU7KuR-VMiD(8>o)9Fn4CHxwVAlxIYze))boGSPa9 z**reQov?MLS$LN!0#S-%YH-{=gu8PlWg2S(wG@oZuXV2kMmD6>T zPrYzBCR$L_b~*8Y2=R^F&LKO~`z*rl=kM38*$nhA7T3DC`4p9c?J*TC1vaqn5tSK> z6)+kt?<}Z&D&oMPh7gHCZfQ^h1z=&xsv~ZvalS-?syUr=PUzt(5ygX(6qK8KaVF_& z$UeT2UTL~;jMc;p-xvDzd8sWd4<_sYo{{tz81A~GB+nD+M$2jK8dUwTWA>#*jsdCf zFjH7<6fVtLpG?KTN=c2(_95;m#U+0sLCJqEZ)asiMrY4$?~9U}+EI)c$O-nv2+TzA z4?}5PQTnIm<{IZ@cY2U+y*$98cH4^t6}4gD-HHd@!HZ10?7zQkh2*bet@qD6s>a3Q ze<{Z3_bLbQ#e&>CM_OueHr&NMe0*47_cPE(--7^&OTTmXxxBkO8opN4o!D4_IFyg3 zZ9RRv@^x)>ELcSkGA{jUL)`8qbk_w$KS1Jy$&*VBAzb|S^yDKxbdGM?5L(?!+dwvU>g%gbDMsQ-UNo z(`2pO_RH8BE;~@)b*l5rvzPqGyQAS@Iet~d3GGHBBG*V_GEcWaO|;ZHX76qZ$Anm= zEz!J?q|VipON)Z7++{30dLJW_;cKZh>{|B^Yw(c0H0V^Sg!;*sYgj-?QZ=A+7F}f4 z!$6^Mc=Ntg@1G@0-w~N9lcj5RntKEkip1PRP zbW)EG3mu0oC%pRVn*>KdG!|m+aG>|AlpYu}`n^{Cf|1Sj5vl~FO?xs|7qYUqkD@C` zow{76$J%KfMwZlLC=VULA|mu1(JwjM$&v)PoOs{5$RNT`r5`$u#F5hT(m; ziwt0v5W-r|*=zUFCK+&%ce!&7zz70YR>xX?XY>R`ir)%tA%wxbcI;XdXX1rmux4gI zd2SKYmNH}FF%&tJwYA#$1o$$>6b=aB|c^vn5S*dpf zX7b}!S{M^z$=)F-vIwQ{?MmMH(?$OPyk|P+N%B63806Uf6*=tTkiFD+`F2Rv;cE%X z;^rpGBm{ALXrF`MOoE=&xs=$;A=O;XxPkekWR`F6x60V%S_?PzeOjt!Jxapz%-cv; zB}e+m@ubZ7vQ^Ju7#bBj+Qms|insI}A_(fXbA6?4c+}86SbnWg7)ceQf10o-BE>r$ z&H}(i=rH8n)5+AA8(umsjQ zxG-krygjTFA%P(Uj;qf10seUJ$4rHqHnK!~SFA+rA{9Zkyfa#;xz4W>Th ziIl?3vL{fik+6f}X-J+B`(dR9D7PAjxTvGwOEAbQje|1H$xpl&e_Vf$-}wT*#9w`d z$u*b=*_CS!i|ouyzsW^_{7frULD$2AOI~TR24#n6f)Y{7cVfyfnX6pqCdo3p<4mpq zOzod{*#hK3J@A|xK>5s+@uiP}lGMbn|F`I%3p6J2RpmfT?f?KV2ZLpS(F%jRg9*k9 zrpZtgkdn}GM_ARM!CC&=lXA|yhPejIgW(R%cI zGioscbp6W#efSFixHY?KKB;``y@PLrZgS$gItZ(uKOd*AwvPRFKz>jBLw**XS?^2N zpzE$4FO|>4PtdC!)~6__MrLVv;iXNWbvbG+%f|>fZ9HmYK&@yfS{yLx;vPi z&{ID%0qc*U52jCKd#01EHK7|&^b_8v$OGDEar zOQcY(b#Wq3fP_C@UAhhqs-RdhR^d5W3RC!+0`^kR^qc$>RPm@E6d12!ttI zK+RX8J=v1JzGkLRf%{^O4qft6?%i;4nJp-riEkGO-q2v+NW^6LL#Tcm2X^%&2#)b+1Ykz1fBj#i^gOcV#CYnZ&zdr z8&1|l8T5KyMP3Z$l28_A4=4r0fzzc=gPQkl)lRMvTQWHhAFN>&=-Zp zs#aq(+=?l$e;0Y<&-9Z}Ja3u_BbH=e@#k3VEfBsGK&z@OQ2WqjTh2=-47RK5f7V)r z(L4Qz$?yFJA{RYV3t!7^=AK=%y7}qy-H6fV8zrKT0o{GO@P?aa%nr+Ut1i;{Bjd@e zzN+NVk>-lbc_NVKOykfEM+JPb#~-nlRio-Bcley+mv$Ej-G$4RNrwURSUDNL208{F z7jHx=P^J*3KqJC)Kx2bQ2QN}+PUpW=;R7LhSE;yLuby|8MnHrVNQd;fyotY7j&Dp9 z^f5NG>n84gu;3G&SW)}9WUNX`TRR{G_Xn+NPR5J?27`p0@f)mI@ALSpyB zjOmaXCMX56NT>=N|W3lWBI;VV*K9FSH@73 zVQ9t^@h|R{@-1C|ta9}@StkVc#L6&TGphe)gi zjkFadfIgS@wy1Lk%^V=N>gO%%mH7M{1Y}uZ2hp-;pLS9)Nv4(GL&*_-ItZtAMU>;; z;=itQFUfFzf+L-8Zbw@zV@n`|8go&#vwhavHy3ft_EaXmQ^BRVXDS(31-;%?GL4Qv zJowD()X2k`z6=wYdyS|Bw(z%Q+ebg@GgZY_s;qkJx8uRwS9?bO1V6R^b^7c?Iny(ZOQY&M*`&!JS;}7; zV#y?cSog07>>8TzB-lo8nkfT&vL*;LBwo*5nJx4lWK26!^<0;_@cX%ByP|IYP-am$x-Ncb;Ek#N%3oI;dd@MpCh%lUy+pQp{5euE za*L%=s5MUPC+JfO^x2^qtv333Urf$E98QG)e3%CxFG2qlgjOS4r>Z6b$<4Vjt23`H)qGoA-`IqKM~Qk%v2Hgp`S zHdwBAmQkfKo$68zj${`!`YxZFJ?&5>BOu-T?Z%CVhgFR25OPGUAHA3I-tITG_?;yH z9F4No_Qve5k;;t9r#w5?sI0~>lu-qEF)ZJe)@Hmc?e#xmf!ZkXLt13e!WRQT_!v0>^gd!4)bWTy_^q z!wpmg7YlNR8M;Z-(9(5X@Bgq(Cdgwt-|gi!L>zUkCfO^`CEMigRZ5~Ve)z_>WTds)(AR8YW5fNupNA6-60sW_PfG0Wo*Smj*N_M+_OmqBV3gW z7e`}ngOv9kj$&^1Tc1}Jhw6i5>Uxp>bs*GKpR({$Cmi|G`i!T%mD97_E`-}v*P@Aj z=jp_urb_e?eQxDY4f2HH}&_5b};56+=Z~!+Z zlxwab{LKdBLa_6H$=7rnsmgX`-0IKD6UJgq&}U8A&k}c$Kt014?}D_abz|JQ5!qcyyVxpr7#^9 zZM@?D(m|nqn^+opu933iznuDvL!Y6HejnVF69!kRJ;C0Je|sxy;>0K+-Lf+rh=d)) zgQ|WFcKuG98WZF{VX1b+ACiglhgz+!GmGG8^A;}OPOsw`=<1L~D(L<{0;$7oO{eEz zqi$EC^LJ@BM@gwx2oz^53GxW6+&W~;cmJ#kZczHPYTvzrHFsn(C7R=?#)7G@q(DnG zcw+iArMJDXMHnFaFXNg1fpM`3XE1@ghT+}{ao4QH3VAuX=5E=E48e>45B+`m>i>Kj@Ht5SRTBN53u_Bq;UYdH zN1kcJB!xOA-K)23(V^-)PoSO!#`}o6`qXh&>=hwVMQ{-BH9cdg3c4A=e~muIO&0?ezclukzDR}T`BL&uaq2E zR!^9fraO8z#CVHol?1SMoH!(h%CwkH%**G(i&U+h1#yy+!|q~T8F99(W=Z8MT+g`s zqJD4dTL@y*RU8o?ZTS8K8Z%3KrVDQL>xjQKI6cM~{h}3OQGP;lKuIg1=vp|C`JEq6 zR|c@8Qk7xa(g^d~9#jo+CCp&+4B2 z*m0=1b1m5whYX&#lKd7s-WR39aDV@u)Qqd#Bmn{f3(QJqOs_rYP{v}FN&VWHlr|s+ zTky70f>C;%6UH^8;`}=#5uX$&MC>!>SrO~?xA}|Sce)lT9Xv~{vyN&*nhI|D+K~`m ztR-2=ZUQ}|Tny#OUKYn>nY0e^pVvO{xe0CgjhSiXr*3JI)K4eA^bAQ3-UmAj9Q3Vc zfBFk##ed7MiGRZwsi1`995~ZU7OPFsKt0VzN~zkSE-g!x4SMBLMRdph z1j*TXq*;Z|vI)gUz<_XFwn-kg;tkji8>CD?nYi5k{XBc2>cA**0D*@$X&kIEP-&50 zn9Oy)&f-uDN)8s>O`lKl#~MDIYNnL@vBON-+)VHS6Vo0{^^eG#jEVcM?J|eagw)d? z{ur-hT`i})iw+NzGFv)x2q1(SRk`IFup)tMjYM{7OhfVknl38s9^Ti8z38j;755Qg zMUu!Ra^~K2J2T_q5SVTm_7XVFVZY{-`izuFUg!z2{dd#!pD7X*8L{U9qS%es<)=2- zyqCC;Z8^V+zk%3;W>Rl1oD)KKWQ0dcUv{Z9;KVY^F4hHKHpHV(cn#5r$$mC*yHt4u zDF=l7f&7;xk<@9BH--zvz4n6LGQJ0ug7G*9Ee-_{&rd0}l>)Vwz-%O&L#W6V)sX=( zNEo&3)btlrZaQnhJ|+oJxr7r4ta5N-0wNq{d>*pfGdizTlm*)r05(|FIKt z%@_=g8aEa}l)G^ny|0VMnBS#&HK=Qj*~1QDif_Rqp3L<}fL=0QRml<@JW$c`h|^+F zK&Mv`ZnGs^l{8PDv;@=K@yxt6wwNsS1tuozMr+FUJH&vh2lBKJ5@9m;dAVZMoAC3o;#*f-{X4K z3W%{Es5mVvw4%j_iY8%wWC=dIr_gUuz99BmB!iP3Ih#kHBApZqrH$+p;@Zb6cEa+5 zH&w0lb6FMb)}^>r?8LlSmK0A{o%2&0%~5zj)7-Xt*%X)aO?@L+sbb}8*gipOC8?M( zkFBEyjtcLTSz|!QFx{Rw#WMRVl$kLO!RSa>D;#UP?b||K!pu24M0j11lJ^mEB&Oy- zmWKxQ=~#SJM7>NMtT;eUYiY}l|3SoW-3W3dCD3lpQ7lXLxX{m)EXn^8+pQ6lg`5;} zpMSW~Q_aWYZSHfWhfq~YoLIzWOBiqCI5DYlYWKuppzDqyGI=xIKdYLGKx`M>Ey;@d zDn|H2Qc`ij#BRXq<@;G96_G!!y72||@?sr&_R^by?J3@3Bu^yq@F%Uc)CL4^(*r*_ z#4onZ)f1Y#LSq5c^cNTUq~Fp4Cd4C|O6KFUBI1nbusx;062i3Jp7xl?QUd>mvd~9g zYVRvFDD9fE3zm1nyAr0GdL^@}o4vx{DY>F#%Sm!`hn81vibC5A#r_mfhJ6;*m5lOO zzK(7u`_+FWStnF!+3uJuyo1f&0o=m<89&-5KMVlS`=Z|}#xw~^o1?K4qVAFSEa*9DGe~v-jAc%HQ#K7@6L`g7M(_#F+x!&D zVTosmgr?7)sFbd--!JoUvvl-r@N~vR(8-2U00`JG*Ax@@k*_o(wH7 zo+#_&5~d0bsuWi0j;@#G*VY_*dhls(MJ(Ul3O(h~A>B9Wj)ahouj&}4u;(|tX?R3} zkM4ol%iqH=4o+HkqPtfhE{7tv*@S$2@38u71-Gm#U1$)>G!&algjC=g37f-Ed2&trwPrY&fPeVe#^1SDH|XIEi;t3=w10!2o(3vK(ZmGw-0(UX&$@=xn zYC9GlzZ9?$p7(9)MzNNB_;_qJ?}0HN%?x2yZQYwHcA!WvCPc^7A|A% znE^Heumo)4VDG{MA|j@!)GREUsr+U4vF(Jkm}3ad&cgw#3;2a# z>G7^HRw>0Wl2_g#6`6>F-}>j~TAO(($?*1UfrE`h>iKw-%FlM_dvc%xs2tOu_WkSO zLh;0(k|&dq&BB@nDd#+3U--B1pG}q!zXDiGpZ0vRqG#qixM>B$;kD7q6bw#O9k?Rf z|50ogc^pj{TaxVQwIFZ9q=&pNC-LwiMDGsv6=2|TB@|;pWkdZD7c=+$iEn07Ylbz| zNa-j2DWrPzutpL9^^&^vM)Gg`ycypXRjr0~FGiHHq}vM(SAJInEsb8h~@QBF~yB8UnBBf?n-blYjO729lweh5HYe zyI@o7!=ucc2XFFLH+ZeL+@ob~hQ#|1;yN$V7(PbeR8J9=`prMkY4Iyn@b0&a`E(g-e;ksm>g|Avt#O*C|^l_^v|e??!jqxkn?nE(wBTEF z#cLv>Sr*~WL#O9DP^j!9HrkZIa^6Y}=-Ws6_dTQl$&E~^k(ri|hoI5ZFRQFjeEFLZ z5yjKsdG4IVOZ)i+LC1Up+v4~2-@g;f=Jvc(3IvaKyj~D3Ri63MZCGzv+U&E7ZeFHXVF-lZNu2-!*?>o(h}q4$>#TEv;7QV7*%LT zD#W5LwN%63wsI`cyKjCR-@VUqykP`ZsYdCWH7aG3{|x$;j@aO3R_1-1!1)8ghie#_ z0=!V-#2&sY-aN#Qtdm&}6NU@JMdGab*Mgl`yh*3njJ!2Be!0@riU2EE-N)-G?TlE- z4*kEW5Fhj8J?BZDG)*@2>H3AN5BN<^VP}Yftcy!(Lh0sRX~qJD4ulG&s;tPYVCHZ8 zG!^a>kbr2#aa8m*S0tD^ifeCXY#P16U-B{%jjS>47<6S<{O7XfJh0wiAxGu>PUxPX+1m#X9D3U-6}_rbx#1KT`DSl{N2;g%>h*ysDqEp)s*~G#o8L44fX=k^?U8JaBnD4HaTFRO+M-bBKi= z;I)5ezNTAWIkmKc+kK;RFlqkl%c8Gx(DAVrn_l-P0$m&*E~O`BLI8Iz(@gt~CG^5usy{!N|hZCOQH74YTV9k&N7or?TJCWue z{p{Uf@QxB?pD=Y0*K`tcM>0{m+HWjLq3a`#?i$ue!Q^ZLVoZpl_@Q%hEd%TvM3bIL z80@VoX61)p`lG%K&Dd>Q>`a=`<~`%vUilIGX^)JwHsVFqyHAkP$qL^^v1w|LJ&N#M zQowCT<^B7AZ`DZnE-b@>)$5+(o_{~#d{h@nlq66ks;S7CpnOPL#DIoWrvJ4YmTX}Y zuVL$P_Cf|{bG+4?_Js8eyx3Q8&OWjxnC>U%TjX1dKK&IO1LB2&vl5-{5*zy0)ElKW zasH7HnC=ZyqOb{B?ap5+fXai@6|EuE-{GbCj&Q=t6$a?}jL`}m4Ba?j-IZ75hjKIDW#3t;lJlXX=ZS%OtMI4+4SEYCk38QBW9^ z@_7td>1%$n{o#S@{+6cU&oohZqCFCPo0{*OSE@6QWZ8_~t<#7}je5ulWr0EDH!K{r zXWqt^fUR*$Csmz3;+`E#QQWeq37cNVPCr@F+DH-;|5m3}g_pixYVKo*5)0En0;MW5 z7i`R){Ova%12xTdCI!oYv^PQTY|9DD6Z|7X0nL5VX{tfAZ>3>s2~Bm;YCI$eOh-L| zfXNHfNRZLQl3{Bla#RI|(cV67lL`I+U0tB#dM7BZ`xah#^jDAYRBJ%Nm=)Qn3t~6h zXa=57?&_zf+LZpP0|gXgV_+bx6P{(lGJ|)t2U#7D0J)2RnO(36-^Z3pqyjz2vj_FaJ{idP#{g`?HK(1%HgRjs;{3 zzMAhvgRLzOzmD#x**dU}e&Zt3lVrKDwUY1<@O{1)5jKzMx7sZ5Xw&=^@bjC`8eVtLgP9;QljhRo(dgPf%!9|m&(_N=Lw&i=>ALIb9`M^HB} zO+b;kRZa*R3U3Ug2p@dQ{$g)%%8MAVxf*IbNOeg~eL5ItHiv&Ik@;xqi6{YyN;Z%o*J9gq*CyT(^6!DHOp+K1@L_9BX80 zgO#8@XJ-oGs|Cb8L|Iu0YOu(97l zBaBsQ(-(W*>`#LWgaF_$O;Tw_YYLXEJa00zIX65>;u87`rj5k|=dmqPce_aI^?NR7 z7yp*;Gps+_5IlaWg5qL5L$BWGeguifQ!ogYMY)MKdG~9&(WU)Y8R(T)q2?tBzM4E~ z%d9*!X&QCR_oqyK#)5)Nd4LOJ0BU?a($7CQl%5+l7q zj7Oz#Vk6M=&EMIQFBcYF1blQh;p$h^w_A&j+OQ|I5xlX3Af8YtLXP_seo=5Ap^QZ)9SazrQVQCuDEc2)(atVcB)Q4W+p#GU*01Vi$H6oA{$c?Gnp_UNUX zj-$B~XPkzTrFQZT8eAHv`Rkfz50XX3vG5ydpr5AqV{I|aZvtWM5qPmOaS~Qoip! z)@U)P%L(0VgvX^glm>4plpZt>!9gHjv%_4|Fdr+nX4^p@!WuK#k2J7syn?=E9}l+7 z>~#iPE@wu|?oo_cFbTI26jPfFoV-3hDhaXQuB_Q=6NB-~4D(DL83(mF7k_r!uOO)NJ>#eq!#(P-JQ-%U;H(;K^KBEtgJim*cx{O{vE1g&vxyS%D2fc&xV z!(65(v>Srp(xqsk7VxiaHL1Rya%ELmxmZLrY9HF_l%F`44#~GmT78NSeSk;;hVNc2aGH2XlKfHwR@O2gBh_um3*jE2~cnWwvhxe>WJhG z1ToDjtPhh6G(~8Nr5GnEM@?Nvy0Wk#bSw&FDfOS`Km0M>E3NXX^C}}(G22)ov;qp= zFWtRq4|SaN5;vjGSbU#!LL(I@m*S%so02xhMdw6}*6Mz0i@*bUdV$!<*qd75gp$Cg zy7daBVSyK>fm@{)Me#Hu0&Imx-EU1jEsSYMi54DL#h_@NO@yzzj&vhB@gg;A>tveQy%4wpO>}7(9Qn5jVX#} z1>VzThH&0Y^t0aCO}u#0<2Xf?JfMuHUmCm;=kr}5v_s7IXLhj|_j+d@hm8Z3zX@X4 zmaP!)c6cMzk(U|*`D$`Y-Eh(A&ifGL3xVdZ#4zUJ^b=LB(+M8eW3pfY=*T7O6AJQwsI`0(Kz-+GxGHF${l#voQJVJZI0{Tm& z=Qw0uzN+CWigxwQ9Z~!>B7c3H4VXlwb3-7DNm{yGsKBMp!Hyef`n@TSpk1p8mt50z z^7nlD{!nS2jBE~Z7^VlWUe6b82Aj7|c5&zJj2)BW_GHTS2?*Fya~Nq_xj_08>Xl2y z=;&&6mv!RWwr2z20z|6JQ4FZDPryWj1Q}gMWJz1=kE;oFULFin40O9j(X#8gzK3SQ zwc;N7-+^&F9yn5HEJx0k1?2ZgG?+HNRW!)?ATOwU^XXfisU2agqb**p`eW8@Fs4k4 z@HeA+nct=<9^4uWf7|P1XA!z$i(-W*PgCQu0M60}DObs#uXmQgB|Fa+o~f}WUrBkSS11t~-8oIH028IM)@*JcI<6%?2~1dK<R3XK49&MMIw{J(SPyrZtr1O`cqdirD2>QiyP7TvOA|gCS1rIoOT+Kh`O`q_drM5@ zIR}DP@4i}tC7AS6yT({Xo{VC z)auEu=;YC`4ckL$j73>BgVK$+}24A`1<(V4cQ zcomeBfJl)D8h)`G*T#PW_U$Ko#%5=S{S5ow64}o+O*}f{DCSd9)Q7;bP0nt;^@rD} zC9#V%3Ot|Njb0gJT!WWTB8~BO=NY^O@ZxIvNC#XLs$zde zat->&ES7CNGl+h(!ZfgyVPp{K)TA3eJUP-V%&{OTU{aT~toBAj5sr60uX`mrAVa8* zYxjW^?m!Iqz-`kgTNyp72pC^=`F%2%^h6pUQygE}a#4A?+T)54BVK5+@`p zYB+EGws;k__A@c_%1qwg`+6A~ory)40pFtY-pAQ!s+sDOx6-^~;-zm-8MB_RxZreEy`Y4GKKVci;~_5m zI33e_-YB6*v$lyJrYTKl89|*3yPE+3Z%=D=Tco6a{JX3;qTTw}6?=_H9dg&`QhIm;DdS`jf4bWP|1>HZShLY)oUHnold02pCG#_VE`^|kmU zO7w{A3r}n6{1hR|Jim+gPL~{?deY=?Hk?jfeFraf|85&cZ*JYQT7mISkJ&-OlWa73 zK^ZqDV4wv$JGY7?7PTaSv5OPJUy??g(882s@ ziAMZgjrOx!*p22d;?||jUuYqbnoKm-^=7JeXb`87gP+0gq3EYCRUZ_!WdW*+wLCo; zlMc;ueLL=5Bu?r|w+VN}%M}*xguIe_WkE&af+CRoUUSz!qJ4mtH3-I&5Mzzlo9FpVRjKXvaJg`ySlN%Y=14F@K!t3({|^!a0IYS1w>eeTBW^z2SiQ0 z=#v-yoMXG|dh}=!S!D9EQf~W-s&xipqU4AyBtC5AYa|JoPe8iHT2qZHY-_!?Q*fr~ ze~noO9q3~Oj)uLSQRA_nu!+!YXBt%XI1 z5iuxPM6}w!`WAjb5ni(SiExWuoD!DKCNpft%Wx5=BiHO)Og! zw#_Bh^m1+=W#6u``AN9ReVb~noIP58L;-Vrg63@w^p<5q3m3dB$Kp${NXT!6iHblu zGWE62W3pQNU;=C3U8%_~2-3c`qmK>}Bn|dcwwtXzE12$~(A|Zj$K3UAO;Nr$uw263 zaCE7N!fXCB*9ciO+Pf3hB*T7SFKKP?nz1nS3u8uDI8mo3XSB8p8^*vZ(xNFdknc ziFpZxjFq+65tD=inyl2A0b7}qHKm`30#)!B@o=xBW-04`jx>9?S<@17#Tzy$=!cd^ z-NflMrP)?)EiE86UCy0mjTbkF?Tqg%06;(-5V3H-aQ36IzFTv!7A%t6l`#o-~ z#yvLR6TRm&iv6o`J~vS`Qr;Wl@O$Df;6uB{pL=0gmK-)$-_9JrvO#5`NJl>LYue7r zB|n~t0!3Y9F3sX1c{aP30hfu9Xs?d#O*rQNi_Q?h5IP-Rh~3g}j7z^KSN#FkXStY{ zR4;iFhoH5(&|@b0hNg<70%Tvsu7OT0ius+!FOY?FU`Tha2?*BSPU|A7nb7MGF+$bd zAe@R z&e@D{lt`TN)lsckW6HBzXpDsl_gUc?wbagS4UDzf)N@$+v}W}c=+Wi*>i0HnV?4}~`59vd~V((Zsi`-UK7QdZJlQL>b!AbX@2qV5b9 z)N*^n=T_?(lrv3O6u>!!)`xM9qe{#(kb`E~MYhkFD78tG576_=Gn+m2yrX3#PXmI< z;y=-N!y?`|V}T_iq!v&W#mX7FW~<>@>?6;qGoe`6&2cHWh|JBCK(JJ=wGXuI!l4Nr zrAq+~#u3z*m()*cvw#D0CWL;SeHbG;Lu{U|9`jhkOqyJjilKkU5R-s^ z={ecuqj=8+_IjDZD!>~fAp7rA#VYLdZ!q>qg%r!)g~t4XE9101$s@gBg_4+g28dQb zIbI4Q(Yi^vBzeV&W$#?^(PW8-=(5L861kvgdUMo_9cs^-vnKI$+U8?nNn_sxu=b}X z>AoD?_O}QHiGZyZ`y+W9)rJh#62u}O&3V{(DUB`cIz3{c@m2%+2l(GGsi&Wy!druy zo!~E*ahiK8D40gk?bld$Pw~=K!l%BINV@9!yMoSTK~wMYS~7iIC%!IPF*wB^PZ?V< z@;gB17sC~>QxmvJKkK?CuD0x7Bmo6v)0b~3R>N+RL_zKwOCks5?Nf!H=53cMPdA4N z0qz+Mz5{1OoN9Bc7w~^om3!?)K?VIKvNwbPNdO4Fk9)7xiMN$!wsx1|t#cs9oEkl& zw7swZ9``ntoMj^N&bV?oM0}6K806M(@@J23@|4u{7rfm3;oDyXo9RDWcgM%EAk^ra zo|mL4sTze|X1w_RjtJa4lU%ERUtq9`!TMNUPE%g{ef_Vx_PF1V)SYo815HvAOZeLW z+%^OK@p0yw0B=s+e4B*7>zi@z--Rm<%LwHTd0DPQqpDC9+qAyEmB9eT)sgS6p8Zc= zk30pzqpI6`jGxoMQr7e-R{}-#6pH$hLDajQ3w2Ca=t;rIbG*@*-3|`jR%o#H3%Loa zxF>$e{BBmD+m-niOe?luVmlcc?5xDA^+=+GqEzr9C`t*=_7XZMvBd3Vk9__HLw36u z!i_$Kx7nuf$$s2ef4rV<8>Wp81yLFuyMU~L=+o<%-)kiKV_TY%^H`B|cOThsabLFu zBWF+VZU>4rqzA4~P%9kMp}zFz``6f_A%rR}yF(bDALlD3Yw$|E|^kXE+dvQHq zhWl9pYEm-tbS!kcbAcoNJx|R@6(XzYbz@e#+;D3=DJPe-H;0M@uBZak0FBddLds7# zd-|d=YpW*#E>cWGmaZT6cey1`$gttVAw=?9vx!w)6m?%;$w{wJ@fLMWy}}4V<7J_* zP%5=gvCE-u+nPh=;ee3)@mcl^}F^;rRaLUF13P0e&gS zP#tO*@hzT@^IJ{R>%tp?VKzrqevjb$Fj1j1xZyu=gv5GhhnF8-2xo+FOby)nW!n>X zv>3LayhC#uMCwhUzi-E$CJdoaE$>pX2SUV#Z}I&P9W;k1SbcHLJ0|g#`&7LL>rouL z&*MS-IU*sWHH@dL9HW7u!$Sq-oxztGmlL$H|0fR6#bc8t-_l*kBaIUKRQsC=`xPGh=L9ejBxD8`^sPoGg!18D zjrT~u>zL|>)zLK!&h_@XVSa+_^Dy=hN%Wi-gzl16WHbLm;sHzG@q);yRq#Ee6hptR zG6@G5I6psJ*95FI*e%|>ZGjmwNRv=2@H&gBnf{T~b5&kr_}YS1akhjJi^Spa+>j31 zAr}tKA}~1~{G1=Te&romP<*@OM~E}}>vGS-Uw!P87Z`Flcdf+p+Q*~?COtZu&Ba?N z+F0i{Mv8re$iEDAG41!N*<6$MEO{STaL{p6>sH|MJw{rxGnG2v789YA=!E$Z$3Z_= z7aS9Ij`IeMQ>uIKa!>xvgBq}f)mfl{>KGukowGs`#u`|J6pIe80C+^c5aBmIYuuS@ z+`XcJ*`QZ0dE7f=?015-CqEmgDp*}TpHN(iiptSHE)qshn&jTAaEe|^fYpe_nDHY) zj*usk+xb}>6pON4>lWReszYdk@T$`rl>CxGp*8Fjwf(^7WP`o;DHVc`Gb1FZB(<%1 zx20%FL6!D~A!?)wFZjN?>W$1y?;3A0`SC)ZWdu|&CT+w$xy7pDbQnK||FMp+ksll` z+^mq^*n970Fa5Eb0G=)mg2AY>pH^e|Ze()2b+WW}a~}8enFND=D>0~YI5>X3$ad2d z%^saxLC4iF*@pDHmySO5lh|6Z9J=tgM>|*iT$6(N8>iG^-9he!FgH^Z5gU}+%wyi_ zQ!WoJKf{8|op+k6gWmU{5P#5PI8ddcvcKH}5v@EuhJeY;aZyXEdV%H(p6BSE7n-K0 zMyRa)Nu5#VfwcBay7W@lQ^a3`3%c=Mro3V%vZR&%f8*& zXPY#~$K6oUX&M2&f8CtXJ*4~XK-6kL=uBocn8Jr>JE6zmg&HeU(piU^^J@pf zfzVZpVL-`F7C3w!VN9h&@;0elZO}8&)(F|fs64+Ukx)XcxS%% zliia}I*X=oVOcpi)-@sjlOseq3pY=f1L@2f__UJgk>rz{Yl=c>1v`RBgt?BsrsvSF z5(27VTplyDXkwk`>AMH(ohgkIUuY)Q8Z%fC36sMFiIoEruQq+vHvUnqq?NdJ$uYsQ z3&t!#`5Xi85X8p0?65DLO;5l)HhdX2lCQQ@CYK@=M9TVyp2T9m@qxt4D;>js$!P79 zz~sr4SyrH?e*hXfdOqoHeh2I)IPErM8rb{}4Cqy$pg>oee)73uVq&zsFp^t=N+T&r zDDB?QF}dl?eL(~OKd&d7L;ORG0B3B#I8YL!p3|+urlf=d9m3wM;=7K4=i2w(bX+}L z8lHN3z@~#}#VG0?aM=)U^&>@RTXF8v+9uN){2=%>%XoRX2n9?TvfvMnO^_T;sL&x z%5}nQ@8z_cV@{trOZMGeNiz%$&)n<|4Ktc=4XTzqhryKO6gs4J~PJIlC;g@x3*bF{IjNC89f=Gn>|Ia zBd>!{zHG9>=1DU!ox9H4K-jeUdCMjAdsH)Xzp-k@!3qVQ$^3@n37$gbu*q6uB*y@+d>hgCtLopfSOzp#l4#ED? z2(VQW!sQ<3U7Z}P<3ddvp`igpx*9YcCF6l0`V#}hn)x0^7kAVbE!?wt zoNI0TwWjF+mduI)m_@+r=Rr&chvNP*bKXrw7KX%-_eUNZXY0f)8D>D@q-~$Q8Xu(E zuIm`iCKN4t)6rOX(3ni@>36zQJ&;oWmHVKFgv`##!clxP(|ZGjyG1B>f5ZCNGr3;o zew)acRJ^y8Z-{n=p=t8I!>WX_0AAOam`LmE=p#0O-tO)(D%e)k%>xNaSBcN!fbHfJ zn-|$^IC8t@XAyXj-tp^vJ|*F`#j=B0uXa4B`MamYi!{Gm#MF+xKMN2hmD+yhuLU;u z_ZL7|Q0uf37@TwkA4I-Ea`_XxvRF>)sb zV1y1ANJXa!SjzdN-+_3~WJhqt#BkSffPZx(67R$S zC2s%t>uwQCF;1-|DO3rYRpsDoZg!ta zq%qiUwkMR6d7{PPMtG^-OjYGwM7U(~JI|^C^X<{g9SOSR3p}6)OH={dpE7hjjWV70 zVa*?m_}WJLA@LOi%}w}q2di{(gF%${ z$h~Abh7?9dhgFg*;EgxRCifCHRD(qUytD}ZR)3I0uJxhSqg_6)%9590 zZNvzKJ#^_hVOl*)L?1bk}3f|HyBTy6vLV0C>#sCIiDG5 zaj_JT0H0@Uvu@eJ>U+)FB%l&s;$w6;CHaPe1IeB|Oy2EE0l` zS+qx{uXgj92gRuin*WRUZg*G*7!Mt4qY0)DoPrMrh1{sn;&C3$jogAbkWJ3dY9^?e zL9T_x)c8Q`PckZ#BQGe#>ks$-;{!&{y*Di;#KRb&GJ=i!3tVQv|a|TfgK&; zSzJd{6BQ{nH*VO|SPHiW4>kb=aUUe;vjew*Eo!o&0G01e=SwrhK>t%_2cMu1*X;FG zm_=@mk!2xG3#PiWa0CKBL)r{T7fnAzgJ$I>)b^Xr&#wGzv>FT$SyN25- z3^dp3@=wIkaNjJiGveKs|9#Esz;_9YJjjoaW*@VR9)fxvG9P;K2Xm#gzoBwQ-im|)PP{!z&t z}h z4qx7emh4n@s_%|Nza|jNU_ejL;BxfQNb$BTM9IVqDgqfJf)O6Hr5h3WYv9m17`NEL zmL8|I1Z3WEv2I!hSurgC)h6qu9k0Jc-!M|tF-^?AuYI*0dM6UR?wS$`3G?HcrFINeiO%WY7-Qfp2mQ@)8p@oX6p#jq&^;$(%%Ay#*32}A3+xO|AViGLs{;0}MD^9u zverh{po^u#K&-FGKzDq_KF(oa1@p-wWPKTa{sOrG?^K}ZOFX~+ z=9jJ_Q-IoHb8P^uot6zVz1haJncl-0H~0hfrDu6myH0pK>(=$6JB=KFQe)H+fvdw| zf~d7aPpoOct)XHCR&ppFG`qR^b5h?|&#xN3&`8tVUX`#;qlR2F#B~Uytf-FFc#^V# ziwng)EOc9q2G(mqH!Li57Mi3hBwmI^0}#Rgjt^ATqR9#aBMOT}`OqThf*rZzI0I2Y zP*Uxh%lSEM2vZ>^2H(oW{|X~VP5~BUy0--ZC+6~g26s`_!beoZSw)BF6cW7fu}Qez z%UfckM)CGZStcTGy!THL(Gz~)fwm)HrP;j%i@ag%DH3HLcTyIfUq-BFz{xzgWV6SW z@Ro%L%hliK0>_mkdd6=}o)b`$ceyNpOD(2cZpzb(DDibvXf@-UaC`~;$lC2#ZzB3X z4kep(ba@Sl9)-TLC8j6Z!+b}zXdo^8$E&@S>jH)!3)2z_)>T($v!suQeJb#6iC8$D zQ@$5j)5;VEB~f=e4hEl1N7Gd9J}j_0=oeRbbw7QzcOa(q^0Ju^hPkn}+K)#w=96>b zx0y{=@UJM5Q`AnL=176>$pr=vA29HXx~HppX%DAemnMXE65a|(OcrWTI13oi8XL=A zrh9%XT3_M@T5dy~krcS^=ll9T9t+C72k2R!;AU(dl2Q1^)9!rs&ja5g`hQaW!tjy7 z38>X#4OQhRXp(Z>t;juHMm)~D$VHKhx6~mv)_7GPwarI+q9xj93SWCzJW+#n8fGq` zsIQ;)>Cgj-W5n62?Y@~|JAu%t-^e-*v?_KeIs&FuW4l~@WiMSmM6w|)HW)pt6C+8w zlJE6E4t6q{m4}QvSFV(OcCT^>)cLD zTxPBQgKG_bPUB0+OtXghg$uu_{r-D?4~({=JQrtiY;7=IK+omTJym=SSyOA%O)bGw z=~>$?2=1Lq9RSH*u-mv9R-#3Cn<7Mt@s>`6N2#XL)S)m*wj&h28i=}W%7B#b|4i1l z^=8-i_oZnK;Ce4ZL4l>BR}ON(I%7qRsEHvNTb(`Q@I+U2<~YJG3&NDdYZV0vmL)BB zzE-E9WTp|X7W-1Iv!p_RKGw}L^GF9pwGZls)4wR08;(J^r~pKWlR#h3W>7L>UDl~f zS&%YmVM1tOqufEeT=-fr$hDCeG@vKw^ZUN82Pwv_-Vy|wFDrT2qVbSsXCQdRp8;kJ z0#LI$Vld_~HHjVBuL-yhULYE+sAJhER50wKtYIYd_^j#8uw!aN>#KG)pvnkScLT(L za)h<#orIJ9vP`+JxwZvlnw|kuZu5iXyQKiT2}m>g_S12EIv`eVHH-b`$e0#@ufb5c zrNyL$>g>SZAs`E~?J9b=M(X^DU8DI}Zy@e~?7D7uNR=l*b$z^qn(EC$yQ8|kN^ZC4 zuO@N3QJi_NewgiBFqTjv?4{(5s3>_7*oiY7 zs0V*`k7M z%|Z&>wi4R|#|wMS#!QPpeYzzr8nyDmJx4@5cuQK!#Wv`rTY$|p;^FOatuAxkw^hez zW28JHU10mwZM<-$Q$~i|Y3mSFn~(4tmdOGdgpTzxH)o*_PN>ECvOx-6!iTaF;KBRFn!J&X%z;Mi4PTrAojKvEKO^;hgeGt|&aaSLn8?l0dFo zCa&imzTnJc^6(@?0hy2+< zTbZLf=wJTy`7QiPUaAc(yMrtq8MDIw=CBZ;KO}b()TXFy<9k0m^fq(_AYln@n&e2^(v2! zcAAK{!D*#b@9D1PvZg6p868`lKP9!n@uth(bXuqkHz`e?BXs6t(l^vLJ7gh)HQrvO zXu&YFNyuz0I@XloaVZ^9?5Q|9ZxM)4YgA3$AJYrr87n)+%{r@Au7+~*sDfC^)YH)@ z>cQGG7&c%MLepBHZ;RDPF7<1+t7`>_xk)L`wlU4X!Y507weGoAt*E@sl=g6pMnzbI z?Wp~zF4@A>32Zvpw1zI^P*?239Q@jefGIh3eopv@`aO<^X`*WBDSS7}m?=NVOi!>Q z1~lgw0+V{gG`#CDteEv0Y}8EsLn_$6>%S0WaUtFDnZN$KYO4a#q(^e#FKlUyrRSGk z%VE1W&i&H6dl;Q6-(y2V2*%8VT~u|bGkq_kF#S$PGPz{YLv1eOBtOV*)O8*_v9}m< z5MJIl9cR!0x;=AlJC4lFxnT7GQc;lXwch`Lf9J8Ir*`J=>4QuD4h(sBOQtDxT+-0{77Ak| zJG0~qc$SWIlCsk6c-d%Fex8eDy1#jGmMebT$n`CsEz{BXl#FGs8cC%(0@9S9+^!|a z`$ez^|5n|Uce*XQ!Mh1XMpfOj3^xPexL;^-(B4mx?S#2yVnySy?=(T=eP3jsiEC0G zUc)T%bc?|AFYh0%i&f%%Wu2WL%z3V~AMXL|05UOcN;!PnMli9akvJk@QlGu|#TcIh z6GI-b`;V1ul_^<*&#TnvU8P0DYW0vQl|sTlAVtI(({nxo|G@Fig7)tad-$&!C%k`$c+lH!nYJaH$5*Cu4*1pgH@d&a= zNIY*RcIqaKLmQqDKV>~!$@^rF7Zbm$dJeF)Z|PfWn3h{xSG*;;<&mCUhCS#3gvMJ! zDzCNI&7abU_vvcaUn@rB?6b|Pdx|iZ6piY+bS(40Zli^)7_3lPJfa1q;5= z4o2OgmD=?y)Rk&;C!>Afk*uPwE7S&Wyht@+8E?6`JljV}briYjZ|2KFruOJIMcw1h zm7>FtCynB5;L#u@vmAat<-Jtmb@pFL`jkv70=8NjHZIY-C_-8CJ{-3)4|DM~5U!~r=ZpB+tQ4O+>;TcM4KDl%hx(joTQVXuNx) z=*rl%1m>LTqzOi0p#j{8P!QEH{_YNx&DeiY`JbfH{g(cu<4iyBdJ^Vf-HKxRjjKYi zgsI0?MYzpB+b-?V@fBN#9FwUDT!Xl=_A;NK1E*lb?-Ej$7X#v__?d{?TMpK$LNe2~ z9ZzsHd47Ofz5sU4T2i$w?r9ZHbg-C4eQ9Sa9N*mdAf#?>|E7cAU>0s~P@c=@rb?w& zK>aBSFcDT`M7`u-=cY{TP=~49M0arx00_|%C8$D~T64*B? zMwobe(qbuOoxCn?5<9@ET4ZCReTGG@H~x3Jik0P1Mf3KGO^SpLnFO5b)EiqKxmWEA z`iZocEZDAMTVxJbkh=KmiBO+2j=ObE0 z6tPGQa)pg=80;J*WFDEaF7Y3hwTb~JTd*eG+0KzW0Y<7`h2ate!KB<&ynGG>+60w? zwy}_I3GcG`J8k))?0A}+{o0Uh^kdC)#4vt@b~lSVKwTLnT2l0HP;shrpQ*_l4NZJ0 z)ntNReT9ruv0?1WJxL$1XiMd>lvyEdI+Hdy$~AOt(+=?|<4)nf9SnC$ zVg8jGK0O^G%vXwdunKny_Y7tE12ugQ7qJJ?F7dEo_Q!$ji$5aXG}rf}zebym1X-Yo zO$}gY5yk2mY`?lnDIj|Nt638kX#su6XimUT`R)xUX4dlqhNJj02kT$IUH`zvn7^|(BTy#Sosacy# zYJ$eb>8AU7=hv|oboUqh+cmO<7JYCsnxsqy)vgzIcu5@IhR?H5jF9+WJ{P)LANKJXmDkq=aTQK9chDD>_W8 z=VS{TgbA3dv(vT7nq}wDp4gR@lF@CXRYXbA*Tv8F;tqA-K#z(p`^8n;>l{woQZ1Y!Xr}R%oVe!}{ROz`=jxB_Rgv{aZvBUo&KHl`} zy+n`04JFJtz&Jz~L&_FI{7CmPf9-P>&Jc&w?W~=pX*qlHi-rQuk(IE?hv?qy6u=$1Flkq#v)G|Cx@*qSRVv= zlCgAYTPiN*MWwjz`B_7m%&ua_BS)n z)1KgM1;DC|`n6TgUy#`%U+VsL8O3ZO5_a)BR`u&O#y|s+K4X&)*!{9#-#%KMfnsy- zn4?Wd5kc2FUI5eKm+a~tT?a2@cV|3!(4`7|SV4tX{1(=p*HRz(i5E+Ws4Ux*Kj>?g zqgPJA{d#~o9!Sj||A#dd-4+W5TAAPWKgVEgCKU)sa255Ent05cg(z4ByE_u?e#Evm zTn>?|_dvC7LcE*ovNLt@lTaRFiqV�#j#mra-{G?T#m9 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 K000000002{%U1#b literal 0 HcmV?d00001 diff --git a/boards/espressif/esp32h2_devkitm/doc/index.rst b/boards/espressif/esp32h2_devkitm/doc/index.rst new file mode 100644 index 0000000000000..991552e9f2786 --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/doc/index.rst @@ -0,0 +1,259 @@ +.. zephyr:board:: esp32h2_devkitm + +Overview +******** + +ESP32-H2-DevKitM-1 is an entry-level development board based on the ESP32-H2-MINI-1 module, +which integrates Bluetooth® Low Energy (LE) and IEEE 802.15.4 connectivity. It features +the ESP32-H2 SoC — a 32-bit RISC-V core designed for low-power, secure wireless communication, +supporting Bluetooth 5 (LE), Bluetooth Mesh, Thread, Matter, and Zigbee protocols. +This module is ideal for a wide range of low-power IoT applications. + +Hardware +******** + +ESP32-H2 combines IEEE 802.15.4 connectivity with Bluetooth 5 (LE). The SoC is powered by +a single-core, 32-bit RISC-V microcontroller that can be clocked up to 96 MHz. The ESP32-H2 has +been designed to ensure low power consumption and security for connected devices. ESP32-H2 has +320 KB of SRAM with 16 KB of Cache, 128 KB of ROM, 4 KB LP of memory, and a built-in 2 MB or 4 MB +SiP flash. It has 19 programmable GPIOs with support for ADC, SPI, UART, I2C, I2S, RMT, GDMA +and LED PWM. + +Most of ESP32-H2-DevKitM-1's I/O pins are broken out to the pin headers on both sides for easy +interfacing. Developers can either connect peripherals with jumper wires or mount the board +on a breadboard. + +ESP32-H2 main features: + +- RISC-V 32-bit single-core microprocessor +- 320 KB of internal RAM +- 4 KB LP Memory +- Bluetooth LE: Bluetooth 5.3 certified +- IEEE 802.15.4 (Zigbee and Thread) +- 19 programmable GPIOs +- Numerous peripherals (details below) + +Digital interfaces: + +- 19x GPIOs +- 2x UART +- 2x I2C +- 1x General-purpose SPI +- 1x I2S +- 1x Pulse counter +- 1x USB Serial/JTAG controller +- 1x TWAI® controller, compatible with ISO 11898-1 (CAN Specification 2.0) +- 1x LED PWM controller, up to 6 channels +- 1x Motor Control PWM (MCPWM) +- 1x Remote Control peripheral (RMT), with up to 2 TX and 2 RX channels +- 1x Parallel IO interface (PARLIO) +- General DMA controller (GDMA), with 3 transmit channels and 3 receive channels +- Event Task Matrix (ETM) + +Analog interfaces: + +- 1x 12-bit SAR ADCs, up to 5 channels +- 1x Temperature sensor (die) + +Timers: + +- 1x 52-bit system timer +- 2x 54-bit general-purpose timers +- 3x Watchdog timers + +Low Power: + +- Four power modes designed for typical scenarios: Active, Modem-sleep, Light-sleep, Deep-sleep + +Security: + +- Secure boot +- Flash encryption +- 4-Kbit OTP, up to 1792 bits for users +- Cryptographic hardware acceleration: (AES-128/256, ECC, HMAC, RSA, SHA, Digital signature, Hash) +- Random number generator (RNG) + +For detailed information, check the datasheet at `ESP32-H2 Datasheet`_ or the Technical Reference +Manual at `ESP32-H2 Technical Reference Manual`_. + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +System requirements +******************* + +Prerequisites +============= + +Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command +below to retrieve those files. + +.. code-block:: console + + west blobs fetch hal_espressif + +.. note:: + + It is recommended running the command above after :file:`west update`. + +Building & Flashing +******************* + +.. zephyr:board-supported-runners:: + +Simple boot +=========== + +The board could be loaded using the single binary image, without 2nd stage bootloader. +It is the default option when building the application without additional configuration. + +.. note:: + + Simple boot does not provide any security features nor OTA updates. + +MCUboot bootloader +================== + +User may choose to use MCUboot bootloader instead. In that case the bootloader +must be built (and flashed) at least once. + +There are two options to be used when building an application: + +1. Sysbuild +2. Manual build + +.. note:: + + User can select the MCUboot bootloader by adding the following line + to the board default configuration file. + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y + +Sysbuild +======== + +The sysbuild makes possible to build and flash all necessary images needed to +bootstrap the board with the EPS32-H2 SoC. + +To build the sample application using sysbuild use the command: + +.. zephyr-app-commands:: + :tool: west + :zephyr-app: samples/hello_world + :board: esp32h2_devkitm + :goals: build + :west-args: --sysbuild + :compact: + +By default, the ESP32-H2 sysbuild creates bootloader (MCUboot) and application +images. But it can be configured to create other kind of images. + +Build directory structure created by sysbuild is different from traditional +Zephyr build. Output is structured by the domain subdirectories: + +.. code-block:: + + build/ + ├── hello_world + │   └── zephyr + │   ├── zephyr.elf + │   └── zephyr.bin + ├── mcuboot + │ └── zephyr + │ ├── zephyr.elf + │ └── zephyr.bin + └── domains.yaml + +.. note:: + + With ``--sysbuild`` option the bootloader will be re-build and re-flash + every time the pristine build is used. + +For more information about the system build please read the :ref:`sysbuild` documentation. + +Manual build +============ + +During the development cycle, it is intended to build & flash as quickly possible. +For that reason, images can be built one at a time using traditional build. + +The instructions following are relevant for both manual build and sysbuild. +The only difference is the structure of the build directory. + +.. note:: + + Remember that bootloader (MCUboot) needs to be flash at least once. + +Build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: esp32h2_devkitm + :goals: build + +The usual ``flash`` target will work with the ``esp32h2_devkitm`` board +configuration. Here is an example for the :zephyr:code-sample:`hello_world` +application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: esp32h2_devkitm + :goals: flash + +Open the serial monitor using the following command: + +.. code-block:: shell + + west espressif monitor + +After the board has automatically reset and booted, you should see the following +message in the monitor: + +.. code-block:: console + + ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** + Hello World! esp32h2_devkitm/esp32h2 + +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants + +Debugging +********* + +As with much custom hardware, the ESP32-H2 modules require patches to +OpenOCD that are not upstreamed yet. Espressif maintains their own fork of +the project. The custom OpenOCD can be obtained at `OpenOCD ESP32`_. + +The Zephyr SDK uses a bundled version of OpenOCD by default. You can overwrite that behavior by adding the +``-DOPENOCD= -DOPENOCD_DEFAULT_PATH=`` +parameter when building. + +Here is an example for building the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: esp32h2_devkitm + :goals: build flash + :gen-args: -DOPENOCD= -DOPENOCD_DEFAULT_PATH= + +You can debug an application in the usual way. Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: esp32h2_devkitm + :goals: debug + +References +********** + +.. target-notes:: + +.. _`ESP32-H2-DevKitM-1`: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32h2/esp32-h2-devkitm-1/user_guide.html +.. _`ESP32-H2 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf +.. _`ESP32-H2 Technical Reference Manual`: https://www.espressif.com/sites/default/files/documentation/esp32-h2_technical_reference_manual_en.pdf +.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/espressif/esp32h2_devkitm/esp32h2_devkitm-pinctrl.dtsi b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm-pinctrl.dtsi new file mode 100644 index 0000000000000..52206c1e66ba3 --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm-pinctrl.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +&pinctrl { + + uart0_default: uart0_default { + group1 { + pinmux = ; + output-high; + }; + group2 { + pinmux = ; + bias-pull-up; + }; + }; +}; diff --git a/boards/espressif/esp32h2_devkitm/esp32h2_devkitm.dts b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm.dts new file mode 100644 index 0000000000000..c05e910198a8e --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm.dts @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "esp32h2_devkitm-pinctrl.dtsi" +#include +#include + +/ { + model = "Espressif ESP32H2-DevkitM"; + compatible = "espressif,esp32h2"; + + chosen { + zephyr,sram = &sramhp; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + }; + + aliases { + sw0 = &user_button1; + watchdog0 = &wdt0; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button1: button_1 { + label = "User SW1"; + gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + zephyr,code = ; + }; + }; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; +}; + +&gpio0 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&trng0 { + status = "okay"; +}; + +&coretemp { + status = "okay"; +}; diff --git a/boards/espressif/esp32h2_devkitm/esp32h2_devkitm.yaml b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm.yaml new file mode 100644 index 0000000000000..06c340f11efb7 --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm.yaml @@ -0,0 +1,13 @@ +identifier: esp32h2_devkitm/esp32h2 +name: ESP32-H2-DevKitM +vendor: espressif +type: mcu +arch: riscv +toolchain: + - zephyr +supported: + - gpio + - watchdog + - uart + - counter + - entropy diff --git a/boards/espressif/esp32h2_devkitm/esp32h2_devkitm_defconfig b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm_defconfig new file mode 100644 index 0000000000000..187793c76e8cc --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm_defconfig @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_GPIO=y diff --git a/boards/espressif/esp32h2_devkitm/support/openocd.cfg b/boards/espressif/esp32h2_devkitm/support/openocd.cfg new file mode 100644 index 0000000000000..5dac2bad03f9e --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/support/openocd.cfg @@ -0,0 +1,4 @@ +# ESP32H2 has built-in JTAG interface over USB port in pins GPIO26/GPIO27 (D-/D+). +set ESP_RTOS none + +source [find board/esp32h2-builtin.cfg]